আমি লিখেছি জাভা মত ব্যতিক্রম হ্যান্ডলিং প্রক্রিয়া সি ব্যবহার setjmp(), longjmp()এবং সিস্টেম ফাংশন। এটি কাস্টম ব্যতিক্রম তবে সিগন্যালগুলিও পছন্দ করে SIGSEGV। এতে ব্যতিক্রম হ্যান্ডলিং ব্লকগুলির অসীম বাসা বাঁধার বৈশিষ্ট্য রয়েছে, যা পুরো ফাংশন কলগুলিতে কাজ করে, এবং দুটি সবচেয়ে সাধারণ থ্রেডিং বাস্তবায়ন সমর্থন করে। এটি আপনাকে লিংক-টাইম উত্তরাধিকার বৈশিষ্ট্যযুক্ত ব্যতিক্রম শ্রেণীর একটি গাছের শ্রেণিবিন্যাস সংজ্ঞায়িত করতে অনুমতি দেয় এবং catchবিবৃতিটি এই গাছটিকে ধরে ফেলতে বা পাস করতে হবে কিনা তা দেখার জন্য এটি হাঁটা করে।
কোডটি কীভাবে এটি ব্যবহার করে তা দেখে এর একটি নমুনা এখানে দেওয়া হয়েছে:
try
{
*((int *)0) = 0;
}
catch (SegmentationFault, e)
{
long f[] = { 'i', 'l', 'l', 'e', 'g', 'a', 'l' };
((void(*)())f)();
}
finally
{
return(1 / strcmp("", ""));
}
এবং এখানে অন্তর্ভুক্ত করা ফাইলটির অংশটিতে অনেক যুক্তি রয়েছে:
#ifndef _EXCEPT_H
#define _EXCEPT_H
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <setjmp.h>
#include "Lifo.h"
#include "List.h"
#define SETJMP(env) sigsetjmp(env, 1)
#define LONGJMP(env, val) siglongjmp(env, val)
#define JMP_BUF sigjmp_buf
typedef void (* Handler)(int);
typedef struct _Class *ClassRef;
struct _Class
{
int notRethrown;
ClassRef parent;
char * name;
int signalNumber;
};
typedef struct _Class Class[1];
typedef enum _Scope
{
OUTSIDE = -1,
INTERNAL,
TRY,
CATCH,
FINALLY
} Scope;
typedef enum _State
{
EMPTY,
PENDING,
CAUGHT
} State;
typedef struct _Except /* exception handle */
{
int notRethrown;
State state;
JMP_BUF throwBuf;
JMP_BUF finalBuf;
ClassRef class;
void * pData;
char * file;
int line;
int ready;
Scope scope;
int first;
List * checkList;
char* tryFile;
int tryLine;
ClassRef (*getClass)(void);
char * (*getMessage)(void);
void * (*getData)(void);
void (*printTryTrace)(FILE*);
} Except;
typedef struct _Context /* exception context per thread */
{
Except * pEx;
Lifo * exStack;
char message[1024];
Handler sigAbrtHandler;
Handler sigFpeHandler;
Handler sigIllHandler;
Handler sigSegvHandler;
Handler sigBusHandler;
} Context;
extern Context * pC;
extern Class Throwable;
#define except_class_declare(child, parent) extern Class child
#define except_class_define(child, parent) Class child = { 1, parent, #child }
except_class_declare(Exception, Throwable);
except_class_declare(OutOfMemoryError, Exception);
except_class_declare(FailedAssertion, Exception);
except_class_declare(RuntimeException, Exception);
except_class_declare(AbnormalTermination, RuntimeException);
except_class_declare(ArithmeticException, RuntimeException);
except_class_declare(IllegalInstruction, RuntimeException);
except_class_declare(SegmentationFault, RuntimeException);
except_class_declare(BusError, RuntimeException);
#ifdef DEBUG
#define CHECKED \
static int checked
#define CHECK_BEGIN(pC, pChecked, file, line) \
ExceptCheckBegin(pC, pChecked, file, line)
#define CHECK(pC, pChecked, class, file, line) \
ExceptCheck(pC, pChecked, class, file, line)
#define CHECK_END \
!checked
#else
#define CHECKED
#define CHECK_BEGIN(pC, pChecked, file, line) 1
#define CHECK(pC, pChecked, class, file, line) 1
#define CHECK_END 0
#endif
#define except_thread_cleanup(id) ExceptThreadCleanup(id)
#define try \
ExceptTry(pC, __FILE__, __LINE__); \
while (1) \
{ \
Context * pTmpC = ExceptGetContext(pC); \
Context * pC = pTmpC; \
CHECKED; \
\
if (CHECK_BEGIN(pC, &checked, __FILE__, __LINE__) && \
pC->pEx->ready && SETJMP(pC->pEx->throwBuf) == 0) \
{ \
pC->pEx->scope = TRY; \
do \
{
#define catch(class, e) \
} \
while (0); \
} \
else if (CHECK(pC, &checked, class, __FILE__, __LINE__) && \
pC->pEx->ready && ExceptCatch(pC, class)) \
{ \
Except *e = LifoPeek(pC->exStack, 1); \
pC->pEx->scope = CATCH; \
do \
{
#define finally \
} \
while (0); \
} \
if (CHECK_END) \
continue; \
if (!pC->pEx->ready && SETJMP(pC->pEx->finalBuf) == 0) \
pC->pEx->ready = 1; \
else \
break; \
} \
ExceptGetContext(pC)->pEx->scope = FINALLY; \
while (ExceptGetContext(pC)->pEx->ready > 0 || ExceptFinally(pC)) \
while (ExceptGetContext(pC)->pEx->ready-- > 0)
#define throw(pExceptOrClass, pData) \
ExceptThrow(pC, (ClassRef)pExceptOrClass, pData, __FILE__, __LINE__)
#define return(x) \
{ \
if (ExceptGetScope(pC) != OUTSIDE) \
{ \
void * pData = malloc(sizeof(JMP_BUF)); \
ExceptGetContext(pC)->pEx->pData = pData; \
if (SETJMP(*(JMP_BUF *)pData) == 0) \
ExceptReturn(pC); \
else \
free(pData); \
} \
return x; \
}
#define pending \
(ExceptGetContext(pC)->pEx->state == PENDING)
extern Scope ExceptGetScope(Context *pC);
extern Context *ExceptGetContext(Context *pC);
extern void ExceptThreadCleanup(int threadId);
extern void ExceptTry(Context *pC, char *file, int line);
extern void ExceptThrow(Context *pC, void * pExceptOrClass,
void *pData, char *file, int line);
extern int ExceptCatch(Context *pC, ClassRef class);
extern int ExceptFinally(Context *pC);
extern void ExceptReturn(Context *pC);
extern int ExceptCheckBegin(Context *pC, int *pChecked,
char *file, int line);
extern int ExceptCheck(Context *pC, int *pChecked, ClassRef class,
char *file, int line);
#endif
এখানে একটি সি মডিউলও রয়েছে যাতে সংকেত হ্যান্ডলিং এবং কিছু বুককিপিংয়ের যুক্তি রয়েছে।
আমি আপনাকে বলতে পারি এটি বাস্তবায়ন করা অত্যন্ত জটিল ছিল এবং আমি প্রায় ছেড়ে দিয়েছি। আমি এটিকে যতটা সম্ভব জাভার কাছাকাছি করার জন্য সত্যই চাপ দিয়েছি; আমি অবাক করে দিয়েছি যে আমি কেবল সি দিয়ে কতটা দূরে এসেছি
আপনার আগ্রহ থাকলে আমাকে চিৎকার করুন।