29 #define DISABLE_DEBUGLOG
31 #include <gwenhywfar/gwenhywfarapi.h>
32 #include <msgengine_p.h>
33 #include <gwenhywfar/xml.h>
34 #include <gwenhywfar/text.h>
35 #include <gwenhywfar/misc.h>
36 #include <gwenhywfar/path.h>
37 #include <gwenhywfar/debug.h>
38 #include <gwenhywfar/buffer.h>
53 e->charsToEscape=strdup(GWEN_MSGENGINE_CHARSTOESCAPE);
54 e->delimiters=strdup(GWEN_MSGENGINE_DEFAULT_DELIMITERS);
66 if (--(e->usage)==0) {
69 if (e->inheritorData && e->freeDataPtr)
73 free(e->charsToEscape);
109 return e->escapeChar;
116 free(e->charsToEscape);
117 e->charsToEscape=strdup(c);
124 return e->charsToEscape;
133 e->delimiters=strdup(s);
135 e->delimiters=strdup(GWEN_MSGENGINE_DEFAULT_DELIMITERS);
142 return e->delimiters;
177 if (e->getGlobalValuesPtr) {
178 globalValues=e->getGlobalValuesPtr(e);
180 globalValues=e->globalValues;
183 globalValues=e->globalValues;
185 assert(globalValues);
238 e->getGlobalValuesPtr=p;
246 return e->getGlobalValuesPtr;
262 return e->typeReadPtr;
278 return e->typeWritePtr;
294 return e->typeCheckPtr;
313 return e->binTypeReadPtr;
322 e->binTypeWritePtr=p;
330 return e->binTypeWritePtr;
339 e->getCharValuePtr=p;
365 return e->inheritorData;
373 if (e->inheritorData && e->freeDataPtr)
384 unsigned int minsize;
385 unsigned int maxsize;
386 unsigned int fixSize;
387 unsigned int startPos;
413 if (e->typeWritePtr) {
414 rv=e->typeWritePtr(e,
427 if (strcasecmp(type,
"bin")==0) {
445 else if (strcasecmp(type,
"num")==0) {
460 for (lj=0; lj<(maxsize-len); lj++)
464 for (lj=0; lj<len; lj++)
474 for (lj=0; lj<len; lj++)
478 for (lj=0; lj<(maxsize-len); lj++)
486 for (lj=0; lj<len; lj++)
506 case 'r': c=
'\r';
break;
507 case 'n': c=
'\n';
break;
508 case 'f': c=
'\f';
break;
509 case 't': c=
'\t';
break;
510 default: c=(
unsigned char)*p;
525 if (c==e->escapeChar)
528 if (e->charsToEscape)
529 if (strchr(e->charsToEscape, c))
552 "String for \"%s\" (type %s) is longer than expected "
573 "Data too long (size is %d, fixed size is %d)",
578 for (j=bs; j<fixSize; j++)
589 if (e->typeCheckPtr) {
592 vt=e->typeCheckPtr(e, type);
599 (strcasecmp(type,
"alpha")==0) ||
600 (strcasecmp(type,
"ascii")==0) ||
601 (strcasecmp(type,
"an")==0) ||
602 (strcasecmp(type,
"float")==0);
609 if (e->typeCheckPtr) {
612 vt=e->typeCheckPtr(e, type);
619 (strcasecmp(type,
"num")==0);
626 if (e->typeCheckPtr) {
629 vt=e->typeCheckPtr(e, type);
636 (strcasecmp(type,
"bin")==0);
651 "Getting data of type \"%s\" from within XML file", type);
698 unsigned int minsize;
699 unsigned int maxsize;
702 unsigned int datasize;
719 if (e->binTypeWritePtr &&
729 rv=e->binTypeWritePtr(e, node, gr, data);
787 "Unable to determine parameter "
788 "type (%s), assuming \"char\" for this matter", type);
800 datasize=strlen(pdata);
811 sizeof(numbuffer),0)) {
818 datasize=strlen(numbuffer);
841 node, copyOfNodePath, nptr,
875 "Value for element \"%s[%d]\" (mode \"%s\") not found",
913 const char *pvalue) {
923 const char *pvalue) {
931 if ((strlen(t)+4)>
sizeof(buffer)) {
952 if (strcasecmp(p, buffer)==0)
974 strcat(buffer,
"def");
979 if (strcasecmp(p, buffer)==0) {
981 if (strcasecmp(p, pvalue)==0) {
983 if (proto==0 || (
int)proto==i || i==0) {
985 if (version==0 || version==i) {
987 if (strcasecmp(p, mode)==0 || !*p) {
1013 const char *pvalue) {
1021 if ((strlen(t)+4)>
sizeof(buffer)) {
1042 if (strcasecmp(p, buffer)==0)
1064 strcat(buffer,
"def");
1069 if (strcasecmp(p, buffer)==0) {
1071 if (strcasecmp(p, pvalue)==0) {
1073 if (proto==0 || (
int)proto==i) {
1075 if (version==0 || version==i) {
1077 if (strcasecmp(p, mode)==0 || !*p) {
1103 unsigned int *datasize) {
1105 static char pbuffer[256];
1109 assert(globalValues);
1115 while (*p && isspace((
int)*p))
1117 if (*p==
'$' || *p==
'+') {
1143 *datasize=strlen(pvalue);
1148 const char *type =
"should_be_known";
1167 "Unable to determine type of \"%s\" (xml)", p);
1175 *datasize=strlen(pvalue);
1185 *datasize=strlen(pvalue);
1208 *datasize=strlen(pvalue);
1237 if (e->getCharValuePtr) {
1238 pvalue=e->getCharValuePtr(e, p, 0);
1240 *datasize=strlen(pvalue);
1245 if (e->getIntValuePtr) {
1246 z=e->getIntValuePtr(e, p, 0);
1252 *datasize=strlen(pvalue);
1267 *datasize=strlen(pvalue);
1281 const char *lastValue;
1319 if (value>highestTrust)
1325 if (value>highestTrust)
1333 if (value>highestTrust)
1337 return highestTrust;
1346 unsigned int *datasize) {
1351 const char *lastValue;
1352 unsigned int lastDataSize;
1353 unsigned int ldatasize;
1379 *datasize=ldatasize;
1384 lastDataSize=ldatasize;
1394 i=strlen(bufferPtr)+strlen(ppath)+2;
1395 tmpptr=(
char*)malloc(i);
1397 sprintf(tmpptr,
"%s/%s", ppath, bufferPtr);
1402 i=strlen(ppath)+strlen(name)+2;
1403 tmpptr=(
char*)malloc(i);
1405 sprintf(tmpptr,
"%s/%s", ppath, name);
1417 *datasize=lastDataSize;
1427 unsigned int *datasize) {
1441 if (strcasecmp(p,
"VALUES")==0) {
1449 if (strcasecmp(p,
"VALUE")==0) {
1456 if (strcasecmp(name, pname)==0) {
1498 const char *pvalue) {
1506 if ((strlen(t)+4)>
sizeof(buffer)) {
1520 "No definitions here for type \"%s\"", t);
1535 strcat(buffer,
"def");
1539 if (strcasecmp(p, buffer)==0 ||
1540 strcasecmp(p, t)==0) {
1542 if (strcasecmp(p, pvalue)!=0)
1544 if (strcasecmp(p, pvalue)==0) {
1546 if (proto==0 || (
int)proto==i || i==0) {
1548 if (version==0 || version==i) {
1550 if (strcasecmp(p, mode)==0 || !*p) {
1552 "Group definition for \"%s=%s\" found",
1564 "Group definition for \"%s=%s\"(%d) not found here",
1578 const char *pvalue) {
1625 if (!nRes && e->defs)
1630 "Group definition for \"%s=%s\"(%d) not found",
1650 int groupIsOptional,
1657 int omittedElements;
1701 unsigned int minnum;
1702 unsigned int maxnum;
1704 const char *addEmptyMode;
1705 unsigned int loopNr;
1722 if (strcasecmp(typ,
"ELEM")==0) {
1729 for (loopNr=0; loopNr<maxnum; loopNr++) {
1730 unsigned int posBeforeElement;
1738 for (j=0; j<omittedElements; j++) {
1744 if (!isFirstElement)
1758 (groupIsOptional && !hasEntries),
1782 if (strcasecmp(addEmptyMode,
"max")==0) {
1784 omittedElements+=(maxnum-loopNr);
1786 else if (strcasecmp(addEmptyMode,
"min")==0) {
1789 omittedElements+=(minnum-loopNr);
1791 else if (strcasecmp(addEmptyMode,
"one")==0) {
1795 else if (strcasecmp(addEmptyMode,
"none")==0) {
1806 else if (strcasecmp(typ,
"VALUES")==0) {
1808 else if (strcasecmp(typ,
"DESCR")==0) {
1816 unsigned int posBeforeGroup;
1854 for (loopNr=0; loopNr<maxnum; loopNr++) {
1867 for (j=0; j<omittedElements; j++) {
1873 if (!isFirstElement)
1913 loopNr>=minnum || groupIsOptional,
1948 if (strcasecmp(addEmptyMode,
"max")==0) {
1950 omittedElements+=(maxnum-loopNr);
1952 else if (strcasecmp(addEmptyMode,
"min")==0) {
1955 omittedElements+=(minnum-loopNr);
1957 else if (strcasecmp(addEmptyMode,
"one")==0) {
1961 else if (strcasecmp(addEmptyMode,
"none")==0) {
1996 return hasEntries?0:1;
2041 const char *msgName,
2115 unsigned int minsize;
2116 unsigned int maxsize;
2117 unsigned int minnum;
2118 unsigned int maxnum;
2143 if (strlen(path)+strlen(name)+10>=
sizeof(nbuffer)) {
2148 sprintf(nbuffer,
"%s/%s", path, name);
2150 sprintf(nbuffer,
"%s", name);
2167 fprintf(stdout,
" %s",
2169 j=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(npath);
2174 fprintf(stdout,
" ");
2176 fprintf(stdout,
"| %s", type);
2177 j=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(type);
2182 fprintf(stdout,
" ");
2184 fprintf(stdout,
"| %4d-%4d", minsize, maxsize);
2185 fprintf(stdout,
" | %3d ", maxnum);
2186 fprintf(stdout,
" |");
2188 fprintf(stdout,
" optvar");
2189 if (flags & GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL)
2190 fprintf(stdout,
" optgrp");
2193 fprintf(stdout,
" set");
2196 fprintf(stdout,
"\n");
2211 int omittedElements;
2229 if (strcasecmp(p,
"VALUES")==0)
2245 if (strcasecmp(p,
"VALUE")==0) {
2263 while (*p && isspace((
int)*p))
2265 if (strlen(path)+strlen(pname)+2>
sizeof(pbuffer)) {
2270 sprintf(pbuffer,
"%s/%s", path, pname);
2272 sprintf(pbuffer,
"%s", pname);
2295 unsigned int minnum;
2296 unsigned int maxnum;
2298 const char *addEmptyMode;
2299 unsigned int loopNr;
2300 unsigned int lflags;
2319 if (strcasecmp(typ,
"ELEM")==0) {
2335 else if (strcasecmp(typ,
"VALUES")==0) {
2337 else if (strcasecmp(typ,
"DESCR")==0) {
2346 lflags|=GWEN_MSGENGINE_SHOW_FLAGS_OPTIONAL;
2364 for (loopNr=0; loopNr<maxnum; loopNr++) {
2373 if (strlen(path)+strlen(gname)+1>
sizeof(pbuffer)) {
2377 sprintf(pbuffer,
"%s/%s", path, gname);
2382 if (strlen(path)+strlen(gname)+10>
sizeof(pbuffer)) {
2387 sprintf(pbuffer,
"%s/%s%d", path, gname, loopNr);
2389 sprintf(pbuffer,
"%s%d", gname, loopNr);
2420 const char *msgName,
2430 fprintf(stdout,
"Message \"%s\" version %d\n",
2431 msgName, msgVersion);
2432 for (i=0; i<76; i++)
2433 fprintf(stdout,
"=");
2434 fprintf(stdout,
"\n");
2436 fprintf(stdout,
"%s", p);
2437 i=GWEN_MSGENGINE_VARNAME_WIDTH-strlen(p);
2439 fprintf(stdout,
" ");
2441 fprintf(stdout,
" |");
2443 fprintf(stdout,
"%s", p);
2444 i=GWEN_MSGENGINE_TYPENAME_WIDTH-strlen(p);
2446 fprintf(stdout,
" ");
2448 fprintf(stdout,
" | Size | Num | Flags\n");
2449 for (i=0; i<76; i++)
2450 fprintf(stdout,
"-");
2451 fprintf(stdout,
"\n");
2505 if (strlen(path)+strlen(name)+10>=
sizeof(nbuffer)) {
2510 sprintf(nbuffer,
"%s/%s", path, name);
2512 sprintf(nbuffer,
"%s", name);
2565 if (strcasecmp(p,
"VALUES")==0)
2581 if (strcasecmp(p,
"VALUE")==0) {
2599 while (*p && isspace((
int)*p))
2601 if (strlen(path)+strlen(pname)+2>
sizeof(pbuffer)) {
2606 sprintf(pbuffer,
"%s/%s", path, pname);
2608 sprintf(pbuffer,
"%s", pname);
2631 unsigned int lflags;
2645 if (strcasecmp(typ,
"ELEM")==0) {
2658 else if (strcasecmp(typ,
"VALUES")==0) {
2660 else if (strcasecmp(typ,
"DESCR")==0) {
2689 if (strlen(path)+strlen(gname)+1>
sizeof(pbuffer)) {
2695 sprintf(pbuffer,
"%s/%s", path, gname);
2697 sprintf(pbuffer,
"%s", gname);
2732 const char *msgName,
2742 msgVersion, msgName);
2745 msgName, msgVersion);
2783 const char *delimiters,
2785 unsigned int minsize;
2786 unsigned int maxsize;
2788 unsigned int minnum;
2790 unsigned int posInMsg;
2793 unsigned int realSize;
2805 if (e->typeReadPtr) {
2806 rv=e->typeReadPtr(e,
2818 if (strcasecmp(type,
"bin")==0) {
2853 if (sscanf(lbuffer,
"%d", &l)!=1) {
2885 (size==0 || br<size)) {
2889 if (lastWasEscape) {
2895 if (c==e->escapeChar) {
2901 if (!isEscaped && (c && strchr(delimiters, c)!=0)) {
2907 if (c==
'\\' || iscntrl(c)) {
2909 "Found a bad character (%02x) in type \"%s\", "
2910 "converting to SPACE",
2947 if (minsize!=0 && realSize<minsize) {
2955 if (maxsize!=0 && realSize>maxsize) {
2967 unsigned int ustart;
2993 const char *delimiters,
2995 unsigned int minsize;
2996 unsigned int maxsize;
2997 unsigned int minnum;
2998 unsigned int maxnum;
3045 delimiters, delimiter);
3065 if (strcasecmp(type,
"ELEM")==0) {
3066 unsigned int loopNr;
3077 while((maxnum==0 || loopNr<maxnum) && !abortLoop) {
3091 "Checking delimiter at pos %x "
3092 "(whether \"%c\" is in \"%s\")",
3098 "Found delimiter (\"%c\" is in \"%s\")",
3149 e->binTypeReadPtr) {
3150 rv=e->binTypeReadPtr(e, n, gr, vbuf);
3217 if (loopNr<minnum) {
3225 else if (strcasecmp(type,
"VALUES")==0) {
3228 else if (strcasecmp(type,
"DESCR")==0) {
3237 unsigned int gversion;
3238 unsigned int loopNr;
3263 while((maxnum==0 || loopNr<maxnum) && !abortLoop) {
3314 if (loopNr<minnum) {
3355 "Terminating character missing (pos=%d [%x]) "
3356 "expecting \"%c\", got \"%c\")",
3408 assert(globalValues);
3424 assert(globalValues);
3435 const char *defValue){
3440 assert(globalValues);
3454 assert(globalValues);
3464 unsigned char escapeChar,
3465 unsigned char delimiter) {
3483 if (c==escapeChar) {
3506 if (sscanf(lbuffer,
"%d", &l)!=1) {
3517 else if (c==delimiter) {
3536 unsigned int segments;
3542 unsigned int posBak;
3600 unsigned int ustart;
3607 "Unknown segment \"%s\" (Segnum=%d, version=%d, ref=%d)",
3643 unsigned int startPos;
3713 const char *description,
3720 td->data=(
char*)malloc(size);
3722 memmove(td->data, data, size);
3724 td->description=strdup(description);
3725 td->trustLevel=trustLevel;
3735 free(td->description);
3736 free(td->replacement);
3770 return td->description;
3778 return td->trustLevel;
3786 return td->replacement;
3794 if (td->posCount>=GWEN_MSGENGINE_TRUSTEDDATA_MAXPOS)
3796 td->positions[td->posCount++]=pos;
3812 if (td->posPointer>=td->posCount)
3814 return td->positions[td->posPointer++];
3822 unsigned int nextNr;
3850 while(std && std!=ntd) {
3853 if (std->size==ntd->size) {
3854 for (i=0; i<td->size; i++) {
3855 if (std->data[i]!=ntd->data[i]) {
3871 rp=strdup(std->replacement);
3875 rp=(
char*)malloc(ntd->size+1);
3882 sprintf(numbuffer,
"%02X", nextNr++);
3883 for (i=0; i<ntd->size; i++) {
3887 rp[i]=numbuffer[1-(i&1)];
3896 free(ntd->replacement);
3897 ntd->replacement=rp;
3921 const char *description,
3939 if (td->size==size &&
3941 *(td->description) &&
3942 trustLevel==td->trustLevel &&
3943 strcasecmp(description, td->description)==0) {
3945 for (i=0; i<td->size; i++) {
3946 if (td->data[i]!=data[i]) {