Есть основной модуль, у него свой набор основных ошибок:
/* Name Code Description */ \
/* No error */ \
SML(SUCCESS , (0x00), "Successfull ") \
/* System general errors */ \
SML(SYSTEM_GENERALERROR , (0x01), "Generic error ") \
SML(SYSTEM_MISUSEOFBLTNS, (0x02), "Misuse of shell built-ins ") \
/* Memory errors */ \
SML(USER_BADALLOC , (0x10 + 0x01), "Memory allocation failed ") \
/* Checking errors */ \
SML(USER_BADPOINTER , (0x20 + 0x01), "Bad pointer provided ") \
SML(USER_BADVALUE , (0x20 + 0x02), "Bad value provided ") \
SML(USER_BADTYPE , (0x20 + 0x03), "Bad type provided ") \
/* System errors */ \
SML(SYSTEM_CANNOTEXECUTE, (0x7E), "Command invoked cannot execute") \
SML(SYSTEM_NOTFOUND , (0x7F), "Command not found ") \
SML(SYSTEM_INVALIDEXIT , (0x80), "Invalid argument to exit ") \
/* System signals */ \
SML(SYSTEM_SIGHUP , (0x80 + 0x01), "Hangup ") \
SML(SYSTEM_SIGINT , (0x80 + 0x02), "Interrupt ") \
SML(SYSTEM_SIGQUIT , (0x80 + 0x03), "Quit ") \
SML(SYSTEM_SIGILL , (0x80 + 0x04), "Illegal Instruction ") \
SML(SYSTEM_SIGTRAP , (0x80 + 0x05), "Trace/Breakpoint Trap ") \
SML(SYSTEM_SIGABRT , (0x80 + 0x06), "Abort ") \
SML(SYSTEM_SIGEMT , (0x80 + 0x07), "Emulation Trap ") \
SML(SYSTEM_SIGFPE , (0x80 + 0x08), "Arithmetic Exception ") \
SML(SYSTEM_SIGKILL , (0x80 + 0x09), "Killed ") \
SML(SYSTEM_SIGBUS , (0x80 + 0x0A), "Bus Error ") \
SML(SYSTEM_SIGSEGV , (0x80 + 0x0B), "Segmentation Fault ") \
SML(SYSTEM_SIGSYS , (0x80 + 0x0C), "Bad System Call ") \
SML(SYSTEM_SIGPIPE , (0x80 + 0x0D), "Broken Pipe ") \
SML(SYSTEM_SIGALRM , (0x80 + 0x0E), "Alarm Clock ") \
SML(SYSTEM_SIGTERM , (0x80 + 0x0F), "Terminated ") \
SML(SYSTEM_SIGUSR1 , (0x80 + 0x10), "User Signal 1 ") \
SML(SYSTEM_SIGUSR2 , (0x80 + 0x11), "User Signal 2 ") \
SML(SYSTEM_SIGCHLD , (0x80 + 0x12), "Child Status ") \
SML(SYSTEM_SIGPWR , (0x80 + 0x13), "Power Fail/Restart ") \
SML(SYSTEM_SIGWINCH , (0x80 + 0x14), "Window Size Change ") \
SML(SYSTEM_SIGURG , (0x80 + 0x15), "Urgent Socket Condition ") \
SML(SYSTEM_SIGPOLL , (0x80 + 0x16), "Socket I/O Possible ") \
SML(SYSTEM_SIGSTOP , (0x80 + 0x17), "Stopped (signal) ") \
SML(SYSTEM_SIGTSTP , (0x80 + 0x18), "Stopped (user) ") \
SML(SYSTEM_SIGCONT , (0x80 + 0x19), "Continued ") \
SML(SYSTEM_SIGTTIN , (0x80 + 0x1A), "Stopped (tty input) ") \
SML(SYSTEM_SIGTTOU , (0x80 + 0x1B), "Stopped (tty output) ") \
SML(SYSTEM_SIGVTALRM , (0x80 + 0x1C), "Virtual Timer Expired ") \
SML(SYSTEM_SIGPROF , (0x80 + 0x1D), "Profiling Timer Expired ") \
SML(SYSTEM_SIGXCPU , (0x80 + 0x1E), "CPU time limit exceeded ") \
SML(SYSTEM_SIGXFSZ , (0x80 + 0x1F), "File size limit exceeded ") \
SML(SYSTEM_SIGWAITING , (0x80 + 0x20), "All LWPs blocked ") \
SML(SYSTEM_SIGLWP , (0x80 + 0x21), "VI Interrupt for T. Library ") \
SML(SYSTEM_SIGAIO , (0x80 + 0x22), "Asynchronous I/O ") \
\
SML(SYSTEM_OUTOFRANGE , (0xFF), "Exit status unknown ") \
/* Maximum is 255, as this index will be sent to exit() function */
И есть пара модулей, каждый из которых делает какую-нибудь свою вещь, абсолютно не связанную (или наследованный от другого) с другим модулем. Выполнены в виде .so либ. К примеру модуль работы с иксами. У него свои коды ошибок:
/* X-Server errors */ \
SML(USER_XBADINIT , (0x30 + 0x01), "Bad X-Server initialisation ") \
SML(USER_XBADVALUE , (0x30 + 0x02), "Bad X-Resource value ") \
SML(USER_XBADWINDOW , (0x30 + 0x03), "Bad X-Window ") \
SML(USER_XBADPIXMAP , (0x30 + 0x04), "Bad X-Pixmap ") \
SML(USER_XBADATOM , (0x30 + 0x05), "Bad X-Atom ") \
SML(USER_XBADCURSOR , (0x30 + 0x06), "Bad X-Cursor ") \
SML(USER_XBADFONT , (0x30 + 0x07), "Bad X-Font ") \
SML(USER_XBADMATCH , (0x30 + 0x08), "Bad X-Match ") \
SML(USER_XBADDRAWABLE , (0x30 + 0x09), "Bad X-Drawable ") \
SML(USER_XBADACCESS , (0x30 + 0x0A), "Bad X-Access ") \
SML(USER_XBADALLOC , (0x30 + 0x0B), "Bad X-Alloc ") \
SML(USER_XBADCOLOUR , (0x30 + 0x0C), "Bad X-Colour ") \
SML(USER_XBADGC , (0x30 + 0x0D), "Bad X-GC ") \
SML(USER_XBADID , (0x30 + 0x0E), "Bad X-ID ") \
SML(USER_XBADNAME , (0x30 + 0x0F), "Bad X-Name ") \
SML(USER_XBADLENGTH , (0x30 + 0x10), "Bad X-Length ") \
SML(USER_XBADIMPLEMENT , (0x30 + 0x11), "Bad X-Implement ") \
Ну для примера, возьмем еще один модуль, модуль юза шаред памяти, у него скажем тоже будет пара своих ошибок ну и пр.
И, собственно, архитектурный вопрос (с ЯП не связанный): как лучше сделать функцию, возвращающую описание ошибки по коду? У каждого модуля своя? А если он также может вернуть какую-нибудь generic ошибку? Типа bad pointer из главного модуля. Или лучше сделать функцию RegisterError(int code, char * desc), вызываемую при ините модуля? И тогда юзать единую функцию из главного модуля? А что если ошибок понадобится > 255? Сейчас модулей уже 8 штук, каждый хочет 5-8 кодов, а все это дело я хочу возвращать в совместимом с exit(code) виде (0..255).
Ну, собственно, сабж. Есть какое-нибудь общепринятое решение?