00001 /* COPIED from SOI's liberrstk.d, then modified. This wouldn't compile as is with gcc. 00002 * Specifically, there is no <varargs.h>. Changed to <stdarg.h>, and modified 00003 * errstk() to use new va_args syntax. 00004 * 00005 * arta 5/30/2007 00006 */ 00007 00008 static char rcsid[] = "$Header: /home/cvsuser/cvsroot/JSOC/base/local/libs/soi/errstk.c,v 1.1 2007/10/16 22:48:16 arta Exp $"; 00009 /* errstk.c 00010 * 00011 * This is a library of routines to maintain an error stack. Each time a 00012 * called procedure gets an error, it can push a message onto the error stack. 00013 * The top level procedure can then print the error stack to view the 00014 * errors reported in the calling sequence. 00015 * 00016 * errstk("vararg type string"); 00017 * 00018 * Add error onto the error stack. This routine mallocs storage and puts 00019 * the error string in it and links this string to the 00020 * head of any previous error strings, thereby forming an error stack. 00021 * If errstk() itself gets an error, like can't malloc, 00022 * it will put a pre-assigned string such as "errstk() can't malloc" on top 00023 * of the error stack and return. The calling error string will be lost, but 00024 * any previous error stack will be intact. Any further calls to errstk() 00025 * will also be lost, until the error stack is re-initialized. 00026 * 00027 * perrstk(int (*function)()); 00028 * 00029 * This routine prints all strings in the current error stack in LIFO order 00030 * by calling the function pointed to. The function must be one that takes 00031 * a vararg sting and prints it to where you want, e.g. printf() or write_log(). * Normally this will just be the errlog() arg passed to a strategy module. 00032 * perrstk then initializes the error stack. 00033 * 00034 * initerrstk(); 00035 * 00036 * Lets you explicitly clear the error stack and free any storage. 00037 */ 00038 00039 #include <stdlib.h> 00040 #include <stdio.h> 00041 #include <stdarg.h> 00042 00043 struct estack { 00044 struct estack *next; 00045 char *msg; 00046 }; 00047 typedef struct estack ESTK; 00048 00049 static ESTK *estkhead = NULL; 00050 static ESTK efix = {NULL, "errstk() can't malloc. err msg(s) lost\n"}; 00051 00052 /* Put vararg stuff on the error stack */ 00053 void errstk(const char *fmt, ...) 00054 { 00055 va_list args; 00056 char string[512]; 00057 ESTK *estk; 00058 00059 if(estkhead == &efix) /* a malloc err has already occured */ 00060 return; /* nop until initerrstk() is called */ 00061 va_start(args, fmt); 00062 vsprintf(string, fmt, args); 00063 va_end(args); 00064 if((estk = (ESTK *)malloc(sizeof(ESTK))) == NULL) { 00065 efix.next = estkhead; 00066 estkhead = &efix; 00067 return; 00068 } 00069 if((estk->msg = (char *)malloc(strlen(string)+1)) == NULL) { 00070 efix.next = estkhead; 00071 estkhead = &efix; 00072 return; 00073 } 00074 strcpy(estk->msg, string); 00075 estk->next = estkhead; /* put at top of error stack */ 00076 estkhead = estk; 00077 } 00078 00079 /* Initialize the error stack */ 00080 void initerrstk() 00081 { 00082 ESTK *eptr; 00083 ESTK *nptr; 00084 00085 for(eptr=estkhead; eptr != NULL; eptr=nptr) { 00086 if(eptr == &efix) continue; 00087 free(eptr->msg); 00088 nptr=eptr->next; /* save the next before free it */ 00089 free(eptr); 00090 } 00091 estkhead = NULL; 00092 } 00093 00094 /* Print the error stack and initialize it */ 00095 void perrstk(int (*errfunc)()) 00096 { 00097 ESTK *eptr; 00098 00099 for(eptr=estkhead; eptr != NULL; eptr=eptr->next) { 00100 (*errfunc)(eptr->msg); 00101 } 00102 initerrstk(); 00103 } 00104 00105 /* 00106 * Revision History 00107 * 00108 * V 1.0 95.06.01 Rick Bogart removed unused variable msgtxt 00109 */ 00110 00111 /* 00112 $Id: errstk.c,v 1.1 2007/10/16 22:48:16 arta Exp $ 00113 $Source: /home/cvsuser/cvsroot/JSOC/base/local/libs/soi/errstk.c,v $ 00114 $Author: arta $ 00115 */ 00116 /* $Log: errstk.c,v $ 00117 /* Revision 1.1 2007/10/16 22:48:16 arta 00118 /* Move JSOC/src/base to JSOC/base and JSOC/src/proj to JSOC/proj. 86 JSOC/src. 00119 /* 00120 /* Revision 1.1.1.1 2007/10/02 00:12:20 arta 00121 /* First new, reorganized JSOC tree 00122 /* 00123 /* Revision 1.1 2007/06/21 19:45:40 arta 00124 /* Rechecking these in. CVS checked them into su_interal, not su_internal last time. 00125 /* 00126 /* Revision 1.1 2007/06/21 16:42:34 arta 00127 /* SOI library plug-in. Called from libdsds.so to open DSDS records and read data. Not to be exported outside of Stanford. 00128 /* 00129 * Revision 1.6 1997/11/06 18:06:19 kay 00130 * delete "static" from struct definition to eliminate compiler warning 00131 * 00132 * Revision 1.5 1995/08/21 22:24:06 jim 00133 * fix initerrstk to pick up next before free eptr 00134 * 00135 * Revision 1.4 1995/06/01 23:03:26 rick 00136 * removed unused variable 00137 * 00138 * Revision 1.3 1994/03/31 20:02:30 jim 00139 * changed perrstk() to take a function pointer 00140 * 00141 * Revision 1.2 1994/03/30 18:14:55 jim 00142 * initial version 00143 * */