Annotation of OpenXM/src/util/oxgentexi.c, Revision 1.3
1.3 ! takayama 1: /* $OpenXM: OpenXM/src/util/oxgentexi.c,v 1.2 2005/04/04 07:36:44 takayama Exp $ */
1.1 takayama 2:
3: #include <stdio.h>
4: int Debug = 0;
5: #define VMAX 20
1.2 takayama 6: #define LIMIT 65536
1.1 takayama 7: #define ITEMMAX 1024
8: struct item {
9: char *category; /* base */
10: char *category2; /* taka_base */
11: char *name; /* base_replace */
12: int argc;
13: char *argv[VMAX]; /* A and Rule of base_replace(A,Rule) */
14: int optc;
15: char *optv[VMAX];
16: char *shortDescription;
17: char *description;
18: char *algorithm;
19: char *examplev[VMAX];
20: char *exampleDescv[VMAX];
21: int examplec;
22: int refc;
23: char *refv[VMAX];
24: char *author;
1.2 takayama 25: char *sortKey;
26: int type;
1.1 takayama 27: };
28: struct item *getItem(void);
29: char *str(char *key);
30: char *str2(char *key,int size);
31: int cmpItem(struct item *it,struct item *it2);
32:
33: char *S;
34: int Ssize = 256;
35: int Sp = 0;
36: char *Upnode;
37: char *Category=NULL;
38: char *Lang="en";
39: int Include = 0;
40: int GenExample = 0;
1.2 takayama 41: int DebugItem = 0;
1.3 ! takayama 42: char *Title = NULL;
! 43: char *Author = NULL;
1.1 takayama 44:
45: main(int argc,char *argv[]) {
46: char *t;
47: int p,c,n,i;
48: struct item *tt;
49: struct item *items[ITEMMAX];
50:
51: Upnode = str("UNKNOWN");
52: for (i=1; i<argc; i++) {
53: if (strcmp(argv[i],"--upnode") == 0) {
54: i++; if (i >= argc) { fprintf(stderr,"--upnode node-name\n"); exit(1);}
55: Upnode = str(argv[i]);
56: }else if (strcmp(argv[i],"--category") == 0) {
57: i++; if (i >= argc) { fprintf(stderr,"--category category-name\n"); exit(1);}
58: Category = str(argv[i]);
59: }else if (strcmp(argv[i],"--en") == 0) {
60: Lang = "en";
61: }else if (strcmp(argv[i],"--ja") == 0) {
62: Lang = "ja";
63: }else if (strcmp(argv[i],"--include") == 0) {
64: Include = 1;
65: }else if (strcmp(argv[i],"--example") == 0) {
66: GenExample = 1;
67: }else if (strcmp(argv[i],"--debug") == 0) {
68: Debug = 1;
1.2 takayama 69: }else if (strcmp(argv[i],"--debugItem") == 0) {
70: DebugItem = 1;
1.3 ! takayama 71: }else if (strcmp(argv[i],"--title") == 0) {
! 72: i++; Title = str(argv[i]);
! 73: }else if (strcmp(argv[i],"--author") == 0) {
! 74: i++; Author = str(argv[i]);
1.1 takayama 75: }else {
76: fprintf(stderr,"Unknown option\n"); exit(1);
77: }
78: }
79: S = (char *)malloc(Ssize);
80: /* Read data from stdin to the string buffer S */
81: while ((c=getchar()) != EOF) {
82: S[Sp++] = c; S[Sp] = 0;
83: if (Sp >= Ssize-3) {
84: Ssize = 2*Ssize;
85: t = S;
86: S = (char *)malloc(Ssize);
87: if (S == NULL) {
88: fprintf(stderr,"No more memory to allocate S.\n");
89: exit(20);
90: }
91: strcpy(S,t);
92: }
93: }
94:
95: /* Read items */
96: n = 0;
97: while ((tt = getItem()) != NULL) {
98: if (Debug) printItem(tt);
99: if (n >= ITEMMAX) {
100: fprintf(stderr,"Too many entries.\n"); exit(1);
101: }
102: if (Category != NULL) {
103: if (strcmp(Category,tt->category) == 0 ||
104: strcmp(Category,tt->category2) == 0) {
105: items[n++] = tt;
106: }
107: }else{
108: items[n++] = tt;
109: }
110: }
111: if (Debug) fprintf(stderr,"Sorting...\n");
112: shell(items,n);
113: if (Debug) fprintf(stderr,"Done.\n");
1.2 takayama 114:
115: if (DebugItem) {
116: for (i=0; i<n; i++) {
117: printItem(items[i]);
118: }
119: exit(0);
120: }
121:
1.3 ! takayama 122: if (Title) printTitlePage(Title,Author);
! 123:
1.1 takayama 124: printMenu(stdout,items,n);
125:
126: for (i=0; i<n; i++) {
127: printTexi(stdout,items[i]);
128: }
1.3 ! takayama 129:
! 130: if (Title) printBye();
1.1 takayama 131: exit(0);
132: }
133:
134: genInclude(char *name) {
135: char fname[4098];
136: FILE *fp;
137: int c;
138:
139: sprintf(fname,"tmp/%s-auto-%s.texi",name,Lang);
140: fp = fopen(fname,"r");
141: if (fp == NULL) {
142: /* fprintf(stderr,"No file %s\n",fname); */
143: return 0;
144: }
145: while ((c=fgetc(fp)) != EOF) {
146: putchar(c);
147: }
148: putchar('\n');
149: fclose(fp);
150: return 0;
151: }
152:
153: cmpItem(struct item *it,struct item *it2) {
1.2 takayama 154: return strcmp(it->sortKey,it2->sortKey);
1.1 takayama 155: }
156: struct item * newItem(){
157: struct item *a;
158: a = (struct item *)malloc(sizeof(struct item));
159: if (a == NULL) {
160: fprintf(stderr,"newItem: No more memory.\n");
161: exit(20);
162: }
163: a->argc = 0; a->optc = 0; a->refc=0; a->examplec = 0;
1.2 takayama 164: a->type=0;
1.1 takayama 165: a->category = a->category2 = a->name = a->shortDescription
1.2 takayama 166: = a->description = a->author = a->algorithm = a->sortKey = NULL;
1.1 takayama 167: return a;
168: }
169:
170: nextToken(char *key,int n) {
171: static int pos = 0;
172: int i = 0;
173: if (pos >= Ssize) return -1;
174: while (S[pos] <= ' ') {
175: pos++;
176: if (pos >= Ssize) return -1;
177: }
178: while (S[pos] > ' ') {
179: key[i++] = S[pos++]; key[i] = 0;
180: if (i >= n-1) {
181: fprintf(stderr,"Too big key word.\n");
182: fprintf(stderr,"key=%s\n",key);
183: exit(10);
184: }
185: if (S[pos-1] == '(' ||
186: S[pos-1] == ')' ||
187: S[pos-1] == ',' ||
188: S[pos-1] == '{' ||
189: S[pos-1] == '}' ||
190: S[pos-1] == '|' ) {
191: return pos;
192: }
193: if (S[pos] == '(' ||
194: S[pos] == ')' ||
195: S[pos] == ',' ||
196: S[pos] == '{' ||
197: S[pos] == '}' ||
198: S[pos] == '|' ) {
199: return pos;
200: }
201:
202: }
203: if (Debug) fprintf(stderr,"token=%s\n",key);
204: return pos;
205: }
206:
207: printItem(struct item *it) {
208: int i;
209: if (it == NULL) return;
210: if (it->category != NULL)
211: printf("category=%s\n",it->category);
212: if (it->category2 != NULL)
213: printf("category2=%s\n",it->category2);
214: if (it->name != NULL)
215: printf("name=%s\n",it->name);
216: for (i=0; i<it->argc; i++)
217: printf(" argv[%d]=%s\n",i,it->argv[i]);
218: for (i=0; i<it->optc; i++)
219: printf(" optv[%d]=%s\n",i,it->optv[i]);
220: if (it->shortDescription != NULL)
221: printf("shortDescription=%s\n",it->shortDescription);
222: if (it->description != NULL)
223: printf("description=%s\n",it->description);
224: if (it->algorithm != NULL)
225: printf("algorithm=%s\n",it->algorithm);
226: for (i=0; i <it->examplec; i++)
227: printf("examplev[%d]=%s\n",i,it->examplev[i]);
228: for (i=0; i <it->examplec; i++)
229: printf("exampleDescv[%d]=%s\n",i,it->exampleDescv[i]);
230: for (i=0; i<it->refc; i++)
231: printf(" refv[%d]=%s\n",i,it->refv[i]);
232: if (it->author != NULL)
233: printf("author=%s\n",it->author);
1.2 takayama 234: if (it->sortKey != NULL)
235: printf("sortKey=%s\n",it->sortKey);
1.1 takayama 236: printf("\n");
237: }
238:
239: char *str(char *key) {
240: char *s;
241: s = (char *)malloc(strlen(key)+1);
242: if (s == NULL) {
243: fprintf(stderr,"str: No more memory.\n");
244: exit(20);
245: }
246: strcpy(s,key);
247: return s;
248: }
249: char *str2(char *key,int size) {
250: char *s;
251: int i;
252: s = (char *)malloc(size+1);
253: if (s == NULL) {
254: fprintf(stderr,"str2: No more memory.\n");
255: exit(20);
256: }
257: for (i=0; i<size; i++) {
258: s[i] = key[i]; s[i+1] = 0;
259: }
260: return s;
261: }
262: char *getCategory(char *key) {
263: int i,n;
264: char *s;
265: s = str(key);
266: for (i=0; i<strlen(s); i++) {
267: if ((s[i] == '_') || s[i] == '.') {
268: s[i] = 0;
269: return s;
270: }
271: }
272: return s;
273: }
274: char *getCategory2(char *key) {
275: int i,n;
276: char *s;
277: int count;
278: s = str(key);
279: for (i=0; i<strlen(s); i++) {
280: if ((s[i] == '_') || (s[i] == '.')) count++;
281: if (count == 2) {
282: s[i] = 0; return s;
283: }
284: }
285: return s;
286: }
287:
288:
289: struct item *getItem() {
290: char key[LIMIT];
291: char key2[LIMIT];
292: struct item *it;
293: int p;
294: int pp,pOld;
295: int argc;
296: int examplec = 0;
297: it = newItem();
298: do {
299: p = nextToken(key,LIMIT);
300: /* printf("%s\n",key); */
301: if (strcmp(key,"begin:") == 0) break;
302: }while (p >= 0);
303: if (p < 0) {
304: /* fprintf(stderr,"gentexi: End of input file.\n"); */
305: return NULL;
306: }
307: p = nextToken(key,LIMIT);
1.2 takayama 308: it->name = it->sortKey = str(key);
1.1 takayama 309: it->category = getCategory(key);
310: it->category2 = getCategory2(key);
311: nextToken(key,LIMIT);
312: if (strcmp(key,"(") != 0) {
1.2 takayama 313: pp = p+1;
314: it->type = 1; /* For non-functions */
1.3 ! takayama 315: goto LL ;
1.2 takayama 316: }else{
317: it->type = 0; /* For functions */
318: argc = 0;
319: while ((pp=nextToken(key,LIMIT)) >= 0) {
320: if (strcmp(key,"|") == 0) {
321: /* options */
322: argc = 0;
323: while ((pp=nextToken(key,LIMIT)) >= 0) {
324: if (strcmp(key,")") == 0) {
325: break;
326: }
327: if (strcmp(key,",") != 0) {
328: it->optv[argc] = str(key);
329: argc++; it->optc = argc;
330: }
331: if (argc >+ VMAX -1) {
332: fprintf(stderr,"Too many opt args at %s\n",it->name);
333: exit(10);
334: }
1.1 takayama 335: }
336: }
1.2 takayama 337: if (strcmp(key,")") == 0) {
338: break;
339: }else if (strcmp(key,",") != 0) {
340: it->argv[argc] = str(key);
341: argc++; it->argc=argc;
342: }
343: if (argc >= VMAX-1) {
344: fprintf(stderr,"Too many args at %s\n",it->name);
345: exit(10);
346: }
1.1 takayama 347: }
348: }
349:
350: /* Getting the short Description */
351: p = pp;
352: do {
353: pOld = p;
354: p = nextToken(key,LIMIT);
355: /* printf("%s\n",key); */
356: if (key[strlen(key)-1] == ':') break; /* Next keyword. */
357: }while (p >= 0);
358: it->shortDescription = str2(&(S[pp]),pOld-pp);
359:
1.3 ! takayama 360: LL: ;
! 361: if (it->type == 1 ) {strcpy(key,"description:"); p++; }
1.1 takayama 362: do {
363: /* Get Description or Examples */
364: if (strcmp(key,"end:") == 0) break;
365: if (strcmp(key,"description:") == 0 ||
366: strcmp(key,"algorithm:") == 0 ||
367: strcmp(key,"author:") == 0 ||
1.2 takayama 368: strcmp(key,"sortKey:") == 0 ||
1.1 takayama 369: strcmp(key,"example:") == 0 ||
1.2 takayama 370: strcmp(key,"example_description:") ==0 ) {
1.1 takayama 371: pp = p;
372: strcpy(key2,key);
373: do {
374: pOld = p;
375: p = nextToken(key,LIMIT);
376: /* printf("%s\n",key); */
377: if (key[strlen(key)-1] == ':') break; /* Next keyword. */
378: }while (p >= 0);
379: if (strcmp(key2,"description:") == 0) {
380: it->description = str2(&(S[pp]),pOld-pp);
381: }
382: if (strcmp(key2,"example:") == 0) {
383: it->examplev[examplec++] = str2(&(S[pp]),pOld-pp);
384: it->exampleDescv[examplec-1] = "";
385: it->examplec = examplec;
386: if (examplec > VMAX-1) {
387: fprintf(stderr,"Too many examples. \n");
388: exit(20);
389: }
390: }
391: if (strcmp(key2,"example_description:") == 0) {
392: it->exampleDescv[examplec-1] = str2(&(S[pp]),pOld-pp);
393: }
394: if (strcmp(key2,"author:") == 0) {
395: it->author = str2(&(S[pp]),pOld-pp);
396: }
1.2 takayama 397: if (strcmp(key2,"sortKey:") == 0) {
398: while (S[pp] <= ' ') pp++;
399: it->sortKey = str2(&(S[pp]),pOld-pp);
400: }
1.1 takayama 401: if (strcmp(key2,"algorithm:") == 0) {
402: it->algorithm = str2(&(S[pp]),pOld-pp);
403: }
404: }else if (strcmp(key,"ref:") == 0) {
405: argc = 0;
406: while ((pp=nextToken(key,LIMIT)) >= 0) {
407: p = pp;
408: if (key[strlen(key)-1] == ':') break;
409: if (strcmp(key,",") != 0) {
410: it->refv[argc] = str(key);
411: argc++; it->refc = argc;
412: }
413: if (argc >= VMAX-1) {
414: fprintf(stderr,"Too many args for Ref at %s\n",it->name);
415: exit(10);
416: }
417: }
418: }else{
419: fprintf(stderr,"Warning: unknown keyword << %s >> at %s. Ignored.\n",key, it->name);
420: p = nextToken(key,LIMIT);
421: }
422: }while (p >= 0);
423:
424: return it;
425: }
426:
427: shell(struct item *v[],int n) {
428: int gap,i,j;
429: struct item *temp;
430:
431: for (gap = n/2; gap > 0; gap /= 2) {
432: for (i = gap; i<n; i++) {
433: for (j=i-gap ; j>=0 && cmpItem(v[j],v[j+gap])>0 ; j -= gap) {
434: temp = v[j];
435: v[j] = v[j+gap];
436: v[j+gap] = temp;
437: }
438: }
439: }
440: }
441:
442: printMenu(FILE *fp, struct item **it, int n) {
1.2 takayama 443: int i,m;
1.1 takayama 444:
1.2 takayama 445: m = 0;
1.1 takayama 446: for ( i = 0; i < n; i++ )
1.2 takayama 447: if (it[i]->type != 1) m++;
448: if (m != 0) {
449: fprintf(fp,"@menu\n");
450: for ( i = 0; i < n; i++ )
451: if (it[i]->type != 1) fprintf(fp,"* %s::\n",it[i]->name);
452: fprintf(fp,"@end menu\n");
453: }
1.1 takayama 454: }
455:
456: printTexi(FILE *fp, struct item *it) {
457: int i;
1.2 takayama 458: if (it->type == 1) return printTexi1(fp,it);
459: else return printTexi0(fp,it);
460: }
461:
462: printTexi_common(FILE *fp,struct item *it) {
463: int i;
464: if (it->description != NULL) {
465: fprintf(fp,"%s\n\n",it->description);
466: }
467:
468: if (it->algorithm != NULL) {
469: fprintf(fp,"\n\n@noindent\nAlgorithm: \n");
470: fprintf(fp,"%s\n\n",it->algorithm);
471: }
472:
473: if (it->examplec > 0) {
474: for (i=0; i<it->examplec; i++) {
475: if (it->examplec == 1) {
476: fprintf(fp,"Example:\n");
477: }else{
478: fprintf(fp,"Example %d:\n",i);
479: }
480: fprintf(fp,"@example\n");
1.3 ! takayama 481: outputExample(fp,it->examplev[i]);
1.2 takayama 482: if (GenExample) {
483: outputOfExample(it->examplev[i]);
484: }
485: fprintf(fp,"@end example\n");
486: if (it->exampleDescv[i] != NULL && strlen(it->exampleDescv[i]) > 0) {
487: fprintf(fp,"%s\n\n",it->exampleDescv[i]);
488: }
489: }
490: }
491: if (it->author != NULL) {
492: fprintf(fp,"Author : %s\n\n",it->author);
493: }
494: if (it->refc > 0) {
495: fprintf(fp,"@table @t\n");
496: fprintf(fp,"@item References\n");
497: for (i=0; i <it->refc; i++) {
498: fprintf(fp,"@code{%s} ",it->refv[i]);
499: if (i != it->refc-1) fprintf(fp,", ");
500: }
501: fprintf(fp,"\n@end table\n");
502: }
503: fprintf(fp,"\n");
504: }
505:
506: printTexi0(FILE *fp, struct item *it) {
507: int i;
508:
509: fprintf(fp,"@c DO NOT EDIT THIS FILE. Generated by gentexi0.\n");
1.1 takayama 510: if (it == NULL) {
511: fprintf(fp,"@c item is NULL.\n");
512: return ;
513: }
1.3 ! takayama 514: fprintf(fp,"@c sortKey: %s\n",it->sortKey);
1.1 takayama 515: if (it->name == NULL) {
516: fprintf(fp,"@c item name is missing.\n");
517: return ;
518: }
519:
520: #if 0
521: fprintf(fp,"@menu\n");
522: fprintf(fp,"* %s::\n",it->name);
523: fprintf(fp,"@end menu\n");
524: #endif
525: fprintf(fp,"@node %s,,, %s\n",it->name,Upnode);
526: fprintf(fp,"@subsection @code{%s}\n",it->name);
527: fprintf(fp,"@findex %s\n",it->name);
528: fprintf(fp,"@table @t\n");
529: fprintf(fp,"@item %s(",it->name);
530: for (i=0; i<it->argc; i++) {
531: fprintf(fp,"@var{%s}",it->argv[i]);
532: if (i != it->argc-1) fprintf(fp,",");
533: }
534: fprintf(fp,")\n");
535: if (it->shortDescription != NULL) {
536: fprintf(fp,": ");
537: for (i=0; i<strlen(it->shortDescription); i++) {
538: if (it->shortDescription[i] == '{') {
539: fprintf(fp,"@var{");
540: }else {
541: fprintf(fp,"%c",it->shortDescription[i]);
542: }
543: }
544: fprintf(fp," \n");
545: }
546: if (it->optc > 0) {
547: fprintf(fp,"@item %s(",it->name);
548: for (i=0; i<it->argc; i++) {
549: fprintf(fp,"@var{%s}",it->argv[i]);
550: if (i != it->argc-1) fprintf(fp,",");
551: }
552: fprintf(fp," | ");
553: for (i=0; i<it->optc; i++) {
554: fprintf(fp,"@var{%s}=key%d",it->optv[i],i);
555: if (i != it->optc-1) fprintf(fp,",");
556: }
557: fprintf(fp,")\n");
558: fprintf(fp,": This function allows optional variables \n ");
559: for (i=0; i<it->optc; i++) {
560: fprintf(fp,"@var{%s}",it->optv[i]);
561: if (i != it->optc-1) fprintf(fp,", ");
562: }
563: fprintf(fp,"\n");
564: }
565: fprintf(fp,"@end table\n");
566:
567: /* include file */
568: if (Include) {
569: if (genInclude(it->name))
570: fprintf(fp,"@c @include tmp/%s-auto-en.texi\n",it->name);
571: }
572: fprintf(fp,"@c @itemize @bullet \n");
573: fprintf(fp,"@c @item \n");
574: fprintf(fp,"@c @end itemize\n");
575:
1.2 takayama 576: printTexi_common(fp,it);
577: }
578:
579: printTexi1(FILE *fp, struct item *it) {
580: int i;
581: /* For it->type == 1 */
582:
583: fprintf(fp,"@c DO NOT EDIT THIS FILE. Generated by gentexi1.\n");
584: if (it == NULL) {
585: fprintf(fp,"@c item is NULL.\n");
586: return ;
1.1 takayama 587: }
1.3 ! takayama 588: fprintf(fp,"@c sortKey: %s\n",it->sortKey);
1.1 takayama 589:
1.2 takayama 590: if (it->shortDescription != NULL) {
591: for (i=0; i<strlen(it->shortDescription); i++) {
592: fprintf(fp,"%c",it->shortDescription[i]);
1.1 takayama 593: }
1.2 takayama 594: fprintf(fp," \n");
1.1 takayama 595: }
1.2 takayama 596:
597: /* include file */
598: if (Include) {
599: if (genInclude(it->name))
600: fprintf(fp,"@c @include tmp/%s-auto-en.texi\n",it->name);
1.1 takayama 601: }
1.2 takayama 602:
603: printTexi_common(fp,it);
1.1 takayama 604: }
605:
1.3 ! takayama 606: outputExample(FILE *fp,char *s) {
! 607: int i;
! 608: for (i=0; s[i] != 0; i++) {
! 609: if (s[i] == '{') fprintf(fp,"%s","@{");
! 610: else if (s[i] == '}') fprintf(fp,"%s","@}");
! 611: else if (s[i] == '@') fprintf(fp,"%s","@@");
! 612: else fputc(s[i],fp);
! 613: }
! 614: }
! 615:
1.1 takayama 616: outputOfExample(char *com) {
617: FILE *fp2;
618: int c;
619: fp2 = fopen("gentexi-in.tmp","w");
620: if (fp2 == NULL) {
621: fprintf(stderr,"Cannot open tentexi-in.tmp\n");
622: exit(10);
623: }
624: system("rm -f gentexi-out.tmp");
625: fprintf(fp2,"output(\"gentexi-out.tmp\")$\n");
626: fprintf(fp2,"%s\n",com);
627: fprintf(fp2,"output()$\n");
628: fprintf(fp2,"quit;");
629: fclose(fp2);
630: system("asir <gentexi-in.tmp >/dev/null");
631:
632: fp2 = fopen("gentexi-out.tmp","r");
633: if (fp2 == NULL) {
634: fprintf(stderr,"Cannot open tentexi-in.tmp\n");
635: exit(10);
636: }
637: while ((c=fgetc(fp2)) != EOF) {
638: putchar(c);
639: }
640: putchar('\n');
641: }
642:
1.3 ! takayama 643: printTitlePage(char *title, char *author) {
! 644: printf("\\input texinfo\n");
! 645: printf("@def@pi{PI}\n");
! 646: printf("@def@colon{:}\n\n");
! 647: printf("@iftex\n");
! 648: printf("@catcode`@#=6\n");
! 649: printf("@def@b#1{{@bf@gt #1}}\n");
! 650: printf("@catcode`@#=@other\n");
! 651: printf("@end iftex\n");
! 652: printf("@overfullrule=0pt\n");
! 653:
! 654: printf("@setfilename %s\n",Title);
! 655: printf("@settitle %s\n",Title);
! 656:
! 657: printf("@titlepage\n");
! 658: printf("@title %s\n",Title);
! 659: printf("@subtitle Edition : auto generated by oxgentexi on @today{}\n");
! 660: if (author != NULL) printf("@author %s\n",author);
! 661: printf("@end titlepage\n\n");
! 662: printf("@synindex vr fn\n");
! 663: printf("@node Top,, (dir), (dir)\n\n");
! 664: }
! 665:
! 666: printBye() {
! 667: printf("\n@bye\n");
! 668: }
1.1 takayama 669: /* Old file was OpenXM/src/asir-contrib/packages/doc/gentexi.c */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>