00001
00002
00003
00004
00005
00006
00007
00008 #include "common.h"
00009 #include "xap.h"
00010 #include "errabort.h"
00011 #include "xp.h"
00012
00013 static char const rcsid[] = "$Id: xap.c,v 1.11 2005/12/19 05:18:26 kent Exp $";
00014
00015 void xapError(struct xap *xap, char *format, ...)
00016
00017 {
00018 va_list args;
00019 va_start(args, format);
00020 vaWarn(format, args);
00021 errAbort("line %d of %s", xpLineIx(xap->xp), xap->fileName);
00022 va_end(args);
00023 }
00024
00025 static void xapStartTag(void *userData, char *name, char **atts)
00026
00027 {
00028 struct xap *xap = userData;
00029 struct xapStack *stack;
00030
00031 stack = --xap->stack;
00032 if (stack < xap->stackBuf)
00033 xapError(xap, "xap stack overflow");
00034 ++xap->stackDepth;
00035 if (stack->text == NULL)
00036 stack->text = newDyString(256);
00037 stack->elName = (char*)name;
00038 if (xap->skipDepth == 0)
00039 stack->object = xap->startHandler(xap, (char*)name, (char**)atts);
00040 if (xap->stackDepth == 1)
00041 {
00042 freeMem(xap->topType);
00043 xap->topType = cloneString(stack->elName);
00044 xap->topObject = stack->object;
00045 }
00046 }
00047
00048 static void xapEndTag(void *userData, char *name, char *text)
00049
00050 {
00051 struct xap *xap = userData;
00052 struct xapStack *stack;
00053
00054 dyStringAppend(xap->stack->text, text);
00055 if (xap->skipDepth == 0 || xap->skipDepth <= xap->stackDepth)
00056 {
00057 xap->skipDepth = 0;
00058 if (xap->endHandler)
00059 xap->endHandler(xap, (char*)name);
00060 }
00061 stack = xap->stack++;
00062 if (xap->stack > xap->endStack)
00063 xapError(xap, "xap stack underflow");
00064 --xap->stackDepth;
00065 dyStringClear(stack->text);
00066 }
00067
00068 #ifdef EXPAT
00069 static void xapText(void *userData, char *s, int len)
00070
00071 {
00072 struct xap *xap = userData;
00073 if (xap->skipDepth == 0)
00074 dyStringAppendN(xap->stack->text, (char *)s, len);
00075 }
00076 #endif
00077
00078 static int xapRead(void *userData, char *buf, int bufSize)
00079
00080 {
00081 struct xap *xap = userData;
00082 return fread(buf, 1, bufSize, xap->f);
00083 }
00084
00085 struct xap *xapNew(void *(*startHandler)(struct xap *xap, char *name, char **atts),
00086 void (*endHandler)(struct xap *xap, char *name) , char *fileName)
00087
00088 {
00089 struct xap *xap;
00090 AllocVar(xap);
00091 xap->endStack = xap->stack = xap->stackBuf + ArraySize(xap->stackBuf) - 1;
00092 xap->startHandler = startHandler;
00093 xap->endHandler = endHandler;
00094 xap->xp = xpNew(xap, xapStartTag, xapEndTag, xapRead, fileName);
00095 xap->fileName = cloneString(fileName);
00096 return xap;
00097 }
00098
00099 void xapFree(struct xap **pXp)
00100
00101 {
00102 struct xap *xap = *pXp;
00103 if (xap != NULL)
00104 {
00105 struct xapStack *stack;
00106 for (stack = xap->stackBuf; stack < xap->endStack; ++stack)
00107 {
00108 if (stack->text != NULL)
00109 freeDyString(&stack->text);
00110 }
00111 xpFree(&xap->xp);
00112 freeMem(xap->fileName);
00113 freeMem(xap->topType);
00114 freez(pXp);
00115 }
00116 }
00117
00118 void xapParseFile(struct xap *xap, char *fileName)
00119
00120 {
00121 xap->f = mustOpen(fileName, "r");
00122 xpParse(xap->xp);
00123 carefulClose(&xap->f);
00124 }
00125
00126 void xapIndent(int count, FILE *f)
00127
00128 {
00129 int i;
00130 for (i=0; i<count; ++i)
00131 {
00132 fputc(' ', f);
00133 }
00134 }
00135
00136 void xapSkip(struct xap *xap)
00137
00138 {
00139 xap->skipDepth = xap->stackDepth;
00140 }
00141
00142 void xapParseAny(char *fileName, char *type,
00143 void *(*startHandler)(struct xap *xap, char *name, char **atts),
00144 void (*endHandler)(struct xap *xap, char *name),
00145 char **retType, void *retObj)
00146
00147
00148
00149
00150 {
00151 struct xap *xap = xapNew(startHandler, endHandler, fileName);
00152 void **pObj = retObj;
00153 xapParseFile(xap, fileName);
00154 if (type != NULL && !sameString(xap->topType, type))
00155 xapError(xap, "Got %s, expected %s\n", xap->topType, type);
00156 if (retType != NULL)
00157 *retType = cloneString(xap->topType);
00158 *pObj = xap->topObject;
00159 xapFree(&xap);
00160 }
00161
00162 struct xap *xapOpen(char *fileName,
00163 void *(*startHandler)(struct xap *xap, char *name, char **atts),
00164 void (*endHandler)(struct xap *xap, char *name))
00165
00166
00167
00168 {
00169 struct xap *xap = xapNew(startHandler, endHandler, fileName);
00170 xap->f = mustOpen(fileName, "r");
00171 return xap;
00172 }
00173
00174 void *xapNext(struct xap *xap, char *tag)
00175
00176 {
00177 if (!xpParseNext(xap->xp, tag))
00178 return NULL;
00179 if (!sameString(xap->topType, tag))
00180 errAbort("Expecting %s tag, got %s tag", tag, xap->topType);
00181 return xap->topObject;
00182 }
00183