Initial version of donated sources by Avertec, 3.4p5.
[tas-yagle.git] / distrib / sources / api / api / api_wrp_gns.cc
1 #include <ctype.h>
2 #include <unistd.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <dirent.h>
6
7 #include "api_wrp_gns.h"
8 extern "C" {
9 #include AVT_H
10 }
11
12 /* -------------------------------------------------------------------------- */
13
14 void GENIUS::parse_args (int argc, char *argv[])
15 {
16 int i;
17 char *c;
18 for (i = 0 ; i < argc; i++)
19 c = argv[i];
20 }
21
22 /* -------------------------------------------------------------------------- */
23
24 void GENIUS::parse ()
25 {
26 if (isatty (2))
27 fprintf (stderr, "\x1B[35m>>> Making wrappers for GENIUS <<<\x1B[0m\n");
28 else
29 fprintf (stderr, "Making wrappers for GENIUS\n");
30
31 yyparse ();
32 }
33
34 /* -------------------------------------------------------------------------- */
35
36 String *get_proto (char *name, WIGType *d, ParmList *l)
37 {
38 WIGType *pt;
39 Parm *p;
40 char *return_type;
41 char *arg_type, *arg_name;
42 char params[2048] = "";
43 char buf[1024];
44 char buf2[2048] = "";
45 char prototype[2048];
46
47 return_type = Char (WIGType_str (d, 0));
48
49 for (p = l; p; p = Getnext (p)) {
50 pt = Gettype (p);
51 arg_type = Char (WIGType_str (pt, 0));
52 arg_name = Char (WIGType_name (pt, 0));
53
54 if (Getnext (p)) {
55 if (WIGType_ispointer (pt))
56 sprintf (buf, "%s%s, ", Char (arg_type), Char (arg_name));
57 else
58 sprintf (buf, "%s %s, ", Char (arg_type), Char (arg_name));
59 } else {
60 if (WIGType_ispointer (pt))
61 sprintf (buf, "%s%s", Char (arg_type), Char (arg_name));
62 else
63 sprintf (buf, "%s %s", Char (arg_type), Char (arg_name));
64 }
65
66 sprintf (params, "%s%s", buf2, buf);
67 sprintf (buf2, "%s", params);
68 }
69
70 if (WIGType_ispointer (d))
71 sprintf (prototype, "%s%s(%s)", return_type, name, params);
72 else
73 sprintf (prototype, "%s %s(%s)", return_type, name, params);
74
75 return strdup (prototype);
76 }
77
78 /* -------------------------------------------------------------------------- */
79
80 String *get_short_proto (char *name, WIGType *d, ParmList *l)
81 {
82 WIGType *pt;
83 Parm *p;
84 char *return_type;
85 char *arg_type, *arg_name;
86 char params[2048] = "";
87 char buf[1024];
88 char buf2[2048] = "";
89 char prototype[2048];
90
91 return_type = Char (WIGType_str (d, 0));
92
93 for (p = l; p; p = Getnext (p)) {
94 pt = Gettype (p);
95 arg_type = Char (WIGType_str (pt, 0));
96 arg_name = Char (WIGType_name (pt, 0));
97
98 if (Getnext (p))
99 sprintf (buf, "%s, ", Char (arg_type));
100 else
101 sprintf (buf, "%s", Char (arg_type));
102
103 sprintf (params, "%s%s", buf2, buf);
104 sprintf (buf2, "%s", params);
105 }
106
107 if (WIGType_ispointer (d))
108 sprintf (prototype, "%-15s %s(%s)", return_type, name, params);
109 else
110 sprintf (prototype, "%-15s %s(%s)", return_type, name, params);
111
112 return strdup (prototype);
113 }
114
115
116 /* -------------------------------------------------------------------------- */
117
118 #ifdef USE_AVTWIG
119
120 /* -------------------------------------------------------------------------- */
121
122 char **xml_text_args (char *args)
123 {
124 int i, lnum = 0;
125 char *lines[128];
126 char **argtab;
127 char *token;
128
129 argtab = (char**)malloc (128 * sizeof (char*));
130
131 token = strtok (args, "\n");
132 lines[lnum++] = token;
133 while ((token = strtok (NULL, "\n"))) lines[lnum++] = token;
134 lines[lnum] = NULL;
135
136 for (i = 0; i < lnum; i++) {
137 token = strchr (lines[i], '%');
138 argtab[2 * i + 1] = strdup (token? token + 1: "No description");
139 argtab[2 * i] = strdup (strtok (lines[i], "%") + 2);
140 }
141 argtab[2 * i] = NULL;
142
143
144 return argtab;
145 }
146 /* -------------------------------------------------------------------------- */
147 void stripCR (char *str, char *buf)
148 {
149 int i = 0, j = 0;
150 while (str[i] != '\0') {
151 if (str[i] != '\n') buf[j++] = str[i];
152 i++;
153 }
154 buf[j] = '\0';
155 }
156
157 void GENIUS::create_online (char *name, WIGType *d, ParmList *l, functionman *man)
158 {
159 FILE *f;
160 char fname[1024], date[1024];
161 char *description;
162 char *return_value;
163 char *errors;
164 char *see_also;
165
166 if (!man)
167 {
168 avt_fprintf(stderr,"¤6¤~ ** WARNING: NO MAN FOR FUNCTION '%s' ** ¤.\n", name);
169 fflush(stderr);
170 return;
171 }
172 if (!MANPATH) return;
173
174 sprintf (fname, "%s/%s.3", MANPATH, name);
175 if (!(f = fopen (fname, "w+"))) {
176 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", fname);
177 fflush(stderr);
178 return;
179 }
180
181 fprintf (stdout, "Creating man page for `%s'\n", get_short_proto (name, d, l));
182 fflush(stdout);
183
184 avt_date (date);
185
186 fprintf (f, ".TH %s 3 \"%s\" \"Avertec\" \"Genius Dynamic Libraries\"\n", name, date);
187 // _____ prototype
188 fprintf (f, ".SH NAME\n");
189 fprintf (f, "%s\n", name);
190 fprintf (f, "\n.LP\n");
191 fprintf (f, ".SH SYNOPSIS\n");
192 fprintf (f, "%s;\n", man->synop?man->synop:get_proto (name, d, l));
193 fprintf (f, "\n.LP\n");
194 // _____ description
195 fprintf (f, ".SH DESCRIPTION\n");
196 // section = man;
197 description = man->desc;
198 fprintf (f, "%s", description);
199 fprintf (f, "\n.LP\n");
200 // _____ return value
201 fprintf (f, ".SH RETURN VALUE\n");
202 // section = Getnext (section);
203 return_value = man->retval;
204 fprintf (f, "%s", return_value);
205 fprintf (f, "\n.LP\n");
206 // _____ errors
207 fprintf (f, ".SH ERRORS\n");
208 // section = Getnext (section);
209 errors = man->errors;
210 fprintf (f, "%s", errors);
211 fprintf (f, "\n.LP\n");
212 // _____ see also
213 fprintf (f, ".SH SEE ALSO\n");
214 // section = Getnext (section);
215 see_also = man->seealso;
216 fprintf (f, "%s", see_also);
217 fprintf (f, "\n.LP\n");
218
219 fclose (f);
220 }
221 /*
222 void GENIUS::create_online (chain_list *proto_list, chain_list *man)
223 {
224 chain_list *pt;
225 Parm *function;
226 char *name, *proto;
227 FILE *f;
228 WIGType *return_type;
229 functionman *m;
230 char *args;
231 int i;
232 char **argtab;
233 char buf[8192];
234
235 if (!proto_list) return;
236
237 if (!(f = fopen (ONLINE_FILE, "w+"))) {
238 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", ONLINE_FILE);
239 return;
240 }
241
242 fprintf (stderr, "Creating online help %s\n", ONLINE_FILE);
243
244 fprintf (f, "#include <stdio.h>\n\n");
245 fprintf (f, "char *avt_API_COMMANDS[] =\n");
246 fprintf (f, "{\n");
247
248
249 for (pt = proto_list; pt; pt = Getnext (pt)) {
250 m=(functionman *)man->DATA;
251 function = (Parm*)Getdata (pt);
252 name = (char*)Getdata (function);
253 fprintf (f, "// ------------------- %s\n", name);
254 fprintf (f, "\"%s\", ", name);
255 function = Getnext (function);
256 return_type = (ApiType*)function;
257 proto = m->synop?m->synop:get_proto (name, return_type, Getnext (function));
258 fprintf (f, "\"%s\", ", proto);
259 if (m) {
260 stripCR (m->desc, buf);
261 fprintf (f, "\"%s\", ", buf);
262 stripCR (m->retval, buf);
263 fprintf (f, "\"%s\", ", buf);
264 if ((args = m->errors)) {
265 if (strcmp (args, "")) {
266 if ((argtab = xml_text_args (args))) {
267 fprintf (f, "\"");
268 for (i = 0; argtab[i]; i += 2)
269 fprintf (f, "%s %s\\\n", argtab[i], argtab[i + 1]);
270 fprintf (f, "\"");
271 for (i = 0; argtab[i]; i++) free (argtab[i]);
272 }
273 }
274 else
275 fprintf (f, "NULL");
276 }
277 }
278 else {
279 fprintf (f, "NULL,");
280 fprintf (f, "NULL,");
281 fprintf (f, "NULL");
282 }
283 fprintf (f, ",\n");
284 man = Getnext (man);
285 }
286 fprintf (f, "// ------------------- END OF ARRAY\n");
287 fprintf (f, "NULL};\n");
288
289 fclose (f);
290 }
291 */
292 void GENIUS::create_man_man (chain_list *proto_list)
293 {
294 chain_list *pt;
295 Parm *function;
296 char *name, *proto, *dot;
297 char buf[1024], date[1024], man[1024];
298 FILE *f;
299 WIGType *return_type;
300
301 if (!proto_list) return;
302 if (!MANPATH) return;
303
304 strcpy (man, wrapperfile);
305 if ((dot = strrchr (man, '.')))
306 *dot = '\0';
307
308 sprintf (buf, "%s/%s.3", MANPATH, man);
309 if (!(f = fopen (buf, "w+"))) {
310 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", man);
311 return;
312 }
313
314 fprintf (stderr, "Creating man page for %s\n", man);
315 avt_date (date);
316
317 fprintf (f, ".TH %s 3 \"%s\" \"Avertec\" \"Genius Dynamic Libraries\"\n",
318 man, date);
319
320 fprintf (f, ".SH SEE ALSO\n");
321 for (pt = proto_list; pt; pt = Getnext (pt)) {
322 function = (Parm*)Getdata (pt);
323 name = (char*)Getdata (function);
324 function = Getnext (function);
325 return_type = (ApiType*)function;
326 proto = get_proto (name, return_type, Getnext (function));
327 if (strstr(name,"_Action_")==NULL && strstr(name,"_TopLevel")==NULL && strstr(name,"_AtLoad_")==NULL && strstr(name,"_Restart")==NULL)
328 {
329 fprintf (f, "%s\n", proto);
330 fprintf (f, ".LP\n");
331 }
332 }
333
334 fclose (f);
335 }
336
337 void GENIUS::create_man (char *name, WIGType *d, ParmList *l, functionman *man)
338 {
339 FILE *f;
340 char fname[1024], date[1024];
341 char *description;
342 char *return_value;
343 char *errors;
344 char *see_also;
345
346 if (!man)
347 {
348 avt_fprintf(stderr,"¤6¤~ ** WARNING: NO MAN FOR FUNCTION '%s' ** ¤.\n", name);
349 fflush(stderr);
350 return;
351 }
352 if (!MANPATH) return;
353
354 sprintf (fname, "%s/%s.3", MANPATH, name);
355 if (!(f = fopen (fname, "w+"))) {
356 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", fname);
357 fflush(stderr);
358 return;
359 }
360
361 fprintf (stdout, "Creating man page for `%s'\n", get_short_proto (name, d, l));
362 fflush(stdout);
363
364 avt_date (date);
365
366 fprintf (f, ".TH %s 3 \"%s\" \"Avertec\" \"Genius Dynamic Libraries\"\n", name, date);
367 // _____ prototype
368 fprintf (f, ".SH NAME\n");
369 fprintf (f, "%s\n", name);
370 fprintf (f, "\n.LP\n");
371 fprintf (f, ".SH SYNOPSIS\n");
372 fprintf (f, "%s;\n", man->synop?man->synop:get_proto (name, d, l));
373 fprintf (f, "\n.LP\n");
374 // _____ description
375 fprintf (f, ".SH DESCRIPTION\n");
376 // section = man;
377 description = man->desc;
378 fprintf (f, "%s", description);
379 fprintf (f, "\n.LP\n");
380 // _____ return value
381 fprintf (f, ".SH RETURN VALUE\n");
382 // section = Getnext (section);
383 return_value = man->retval;
384 fprintf (f, "%s", return_value);
385 fprintf (f, "\n.LP\n");
386 // _____ errors
387 fprintf (f, ".SH ERRORS\n");
388 // section = Getnext (section);
389 errors = man->errors;
390 fprintf (f, "%s", errors);
391 fprintf (f, "\n.LP\n");
392 // _____ see also
393 fprintf (f, ".SH SEE ALSO\n");
394 // section = Getnext (section);
395 see_also = man->seealso;
396 fprintf (f, "%s", see_also);
397 fprintf (f, "\n.LP\n");
398
399 fclose (f);
400 }
401
402 /* -------------------------------------------------------------------------- */
403
404 static void
405 man_text(char *buf, char *src)
406 {
407 while (isspace(*src)) src++;
408 while (*src) {
409 if ((*src == '{' || *src == '}') && *(src+1)=='`') {
410 *buf = *src;
411 src++;
412 buf++;
413 }
414 else if (*src == '{') {
415 *buf = 0;
416 strcat(buf, "\\fI");
417 buf += 3;
418 }
419 else if (*src == '}') {
420 *buf = 0;
421 strcat(buf, "\\fR");
422 buf += 3;
423 }
424 else if (*src == '\\' && *(src+1)=='$') {
425 *buf = 0;
426 strcat(buf, "\n.br\n");
427 src++;
428 buf += 4;
429 }
430 else if (*src == '\\' && *(src+1)=='}') {
431 *buf = '}';
432 src++;
433 }
434 else if (*src == '\\' && *(src+1)=='{') {
435 *buf = '{';
436 src++;
437 }
438 else {
439 *buf = *src;
440 buf++;
441 }
442 src++;
443 }
444 *buf = 0;
445 }
446
447 static void
448 xml_text(char *buf, char *src)
449 {
450 while (*src) {
451 if (*src == '<') {
452 *buf = 0;
453 strcat(buf, "&lt;");
454 buf += 4;
455 }
456 else if (*src == '>') {
457 *buf = 0;
458 strcat(buf, "&gt;");
459 buf += 4;
460 }
461 else if ((*src == '{' || *src == '}') && *(src+1)=='`') {
462 *buf = *src;
463 src++;
464 buf++;
465 }
466 else if (*src == '{') {
467 *buf = 0;
468 strcat(buf, "<f>");
469 buf += 3;
470 }
471 else if (*src == '}') {
472 *buf = 0;
473 strcat(buf, "</f>");
474 buf += 4;
475 }
476 else if (*src == '\\')
477 {
478 char *add=NULL;
479 if (*(src+1)=='$') add="<br></br>";
480 if (*(src+1)=='{') add="{";
481 if (*(src+1)=='}') add="}";
482
483 if (add!=NULL) {
484 *buf = 0;
485 strcat(buf, add);
486 buf += strlen(add);
487 src++;
488 } else {
489 *buf = *src;
490 buf++;
491 }
492 }
493 else {
494 *buf = *src;
495 buf++;
496 }
497 src++;
498 }
499 *buf = 0;
500 }
501
502 void GENIUS::create_xml (char *filename, char *name, WIGType *d, ParmList *l, functionman *man, int first, int mode)
503 {
504 FILE *f;
505 char fname[1024];
506 char tmpname[1024];
507 char *description;
508 char *prototype;
509 char *basename;
510 char textbuf[10000];
511 char *args;
512 int i;
513 char **argtab;
514
515 if (!XMLPATH) return;
516
517 basename = strrchr(filename, '/');
518 if (basename == NULL) basename = filename;
519 strncpy(tmpname, basename, strlen(basename)-2);
520 tmpname[strlen(basename)-2] = 0;
521 sprintf (fname, "%s/%s.xml", XMLPATH, tmpname);
522
523 if (first) {
524 if (!(f = fopen (fname, "wt"))) {
525 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", fname);
526 return;
527 }
528 }
529 else {
530 if (!(f = fopen (fname, "a+"))) {
531 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", fname);
532 return;
533 }
534 }
535
536 if (first) {
537 fprintf (f, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\" ?>\n");
538 }
539 if (!man && (mode & 3)==0) {
540 fclose(f);
541 return;
542 }
543
544
545 if (mode==0 || mode==4) fprintf (stdout, "Creating XML page for `%s'\n", get_proto (name, d, l));
546
547 if (mode & 3)
548 {
549 if (mode & 2) // fermeture
550 fprintf (f, "</func>\n");
551
552 if (mode & 1) // ouverture
553 fprintf (f, "<func>\n");
554 fclose(f);
555 return;
556 }
557
558 fprintf (f, "<func>\n");
559 fprintf (f, "<funcname><section niv='%d'><title>%s</title></section></funcname>\n", xmllevel, name);
560
561 prototype = man->synop?man->synop:get_proto (name, d, l);
562 xml_text (textbuf, prototype);
563 fprintf (f, "<proto>%s</proto>", textbuf);
564
565 description = man->desc;
566 xml_text (textbuf, description);
567 fprintf (f, "<desc>%s</desc>", textbuf);
568
569 if ((args = man->errors)) {
570 if (strcmp (args, "")) {
571 argtab = xml_text_args (args);
572 if (argtab) {
573 for (i = 0; argtab[i]; i += 2) {
574 fprintf (f, "<arg>");
575 xml_text (textbuf, argtab[i]);
576 fprintf (f, "<argn>%s</argn>", textbuf);
577 xml_text (textbuf, argtab[i + 1]);
578 fprintf (f, "<argdef>%s</argdef>", textbuf);
579 fprintf (f, "</arg>\n");
580 }
581 for (i = 0; argtab[i]; i++) free (argtab[i]);
582 }
583 }
584 }
585 else {
586 fprintf (f, "<arg></arg>\n");
587 }
588 fprintf (f, "</func>\n");
589
590 fclose (f);
591 }
592
593 void GENIUS::create_db (char *filename, char *name, WIGType *d, ParmList *l, functionman *man, int first, int mode)
594 {
595 FILE *f;
596 char fname[1024];
597 char tmpname[1024];
598 char *prototype, *basename, *c;
599 char textbuf[10000];
600
601 if (!DBPATH) return;
602
603 basename = strrchr(filename, '/');
604 if (basename == NULL) basename = filename;
605 strncpy(tmpname, basename, strlen(basename)-2);
606 tmpname[strlen(basename)-2] = 0;
607 sprintf (fname, "%s/%s.db", DBPATH, tmpname);
608
609 if (first) {
610 if (!(f = fopen (fname, "wt"))) {
611 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", fname);
612 return;
613 }
614 }
615 else {
616 if (!(f = fopen (fname, "a+"))) {
617 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", fname);
618 return;
619 }
620 }
621
622 if (!man && (mode & 3)==0) {
623 fclose(f);
624 return;
625 }
626
627 if (mode & 3)
628 {
629 fclose(f);
630 return;
631 }
632
633 prototype = man->synop?man->synop:get_proto (name, d, l);
634 strcpy(textbuf, man->desc);
635 while ((c=strchr(textbuf,'\n'))!=NULL) *c='\\';
636 fprintf(f, "%10s || %10s || %100s || %s\n", tmpname, man->categ, prototype, textbuf);
637
638 fclose (f);
639 }
640
641 #endif
642
643 /* -------------------------------------------------------------------------- */
644 static int done=0;
645
646 void GENIUS::create_defines_function()
647 {
648 chain_list *cl;
649 defines *def;
650 char buf[1024], *dot;
651 int i;
652
653 if (done) return;
654 done=1;
655
656 strcpy(buf, wrapperfile);
657 if ((dot = strchr (buf, '.'))) *dot = '\0';
658 Printf (f_wrappers,"t_arg **%s_getdefines(int *nb)\n{\n", buf);
659 Printf (f_wrappers," static t_arg *tmp[1024];\n\n");
660
661 for (i=0, cl=alldefines; cl!=NULL; cl=cl->NEXT)
662 {
663 def=(defines *)cl->DATA;
664 Printf (f_wrappers," tmp[%d]=NewArg ();\n", i);
665 switch(def->type)
666 {
667 case 'I':
668 Printf (f_wrappers," tmp[%d]->POINTER=0; tmp[%d]->NAME=\"%s\";\n", i, i, def->VARNAME);
669 Printf (f_wrappers," tmp[%d]->TYPE=\"int\"; tmp[%d]->VALUE=(int *)malloc(sizeof(int));\n", i, i);
670 Printf (f_wrappers," *(int *)tmp[%d]->VALUE=%d;\n", i, def->T.I);
671 break;
672 case 'C':
673 Printf (f_wrappers," tmp[%d]->POINTER=0; tmp[%d]->NAME=\"%s\";\n", i, i, def->VARNAME);
674 Printf (f_wrappers," tmp[%d]->TYPE=\"char\"; tmp[%d]->VALUE=(char *)malloc(sizeof(char));\n", i, i);
675 Printf (f_wrappers," *(char *)tmp[%d]->VALUE='%c';\n", i, def->T.I);
676 break;
677 case 'D':
678 Printf (f_wrappers," tmp[%d]->POINTER=0; tmp[%d]->NAME=\"%s\";\n", i, i, def->VARNAME);
679 Printf (f_wrappers," tmp[%d]->TYPE=\"double\"; tmp[%d]->VALUE=(double *)malloc(sizeof(double));\n", i, i);
680 Printf (f_wrappers," *(double *)tmp[%d]->VALUE=%g;\n", i, def->T.D);
681 break;
682 }
683 Printf (f_wrappers,"\n");
684 i++;
685 }
686
687 Printf (f_wrappers," *nb=%d;\n",i);
688 Printf (f_wrappers," return tmp;\n}\n\n");
689
690
691 }
692
693 void GENIUS::create_function_getargs (char *name, char *iname, WIGType *d, ParmList *l)
694 {
695 int i;
696 WIGType *pt;
697 Parm *p;
698 int pcount = ParmList_len (l);
699 #ifdef __ALL__WARNING__
700 char err_incomp[1024];
701 char err_incomp_pt[1024];
702 char type_check[1024];
703 char pt_check[1024];
704 #else
705 d = NULL;
706 iname = NULL;
707 #endif // ..anto..
708
709 // on evite les fonctions a nombre de parametres variable
710 for (p = l; p; p = Getnext (p))
711 {
712 pt = Gettype (p);
713 if (!strcmp (Char (WIGType_base (pt)), "...") ||
714 (!strcmp (Char (WIGType_base (pt)), "void") && WIGType_ispointer (pt) == 0)) return ;
715 //if (!strcmp (Char (WIGType_base (pt)), "...")) return ;
716 }
717
718 Printf (f_wrappers, "\nvoid wrap_getargs_%s (t_arg ***ret, int *nb)\n", name);
719 Printf (f_wrappers, "{\n");
720 if (pcount>0)
721 {
722 Printf (f_wrappers, " *ret=(t_arg **)malloc(sizeof(t_arg *)*%d);\n",pcount);
723 }
724 else
725 Printf (f_wrappers, " *ret=NULL;\n");
726 Printf (f_wrappers, " *nb=%d;\n",pcount);
727
728 /* Type Checking for prm */
729 i = 0;
730 for (p = l; p; p = Getnext (p)) {
731 pt = Gettype (p);
732 Printf (f_wrappers, " (*ret)[%d] = NewArg();\n", i);
733 Printf (f_wrappers, " ((*ret)[%d])->NAME = \"?\";\n", i);
734 Printf (f_wrappers, " SetType ((*ret)[%d], \"%s\");\n", i, WIGType_base (pt));
735 Printf (f_wrappers, " SetPointer ((*ret)[%d], %d);\n", i, WIGType_ispointer (pt));
736 Printf (f_wrappers, " (*ret)[%d]->VALUE= (%s*)malloc (sizeof (%s));\n", i, WIGType_str (pt, WIGType_ispointer (pt)), WIGType_str (pt, WIGType_ispointer (pt)));
737 Printf (f_wrappers, "// ---\n");
738 i++;
739 }
740 Printf (f_wrappers, "}\n\n");
741 }
742
743 void GENIUS::create_function (char *name, char *iname, WIGType *d, ParmList *l)
744 {
745 int i;
746 WIGType *pt;
747 Parm *p;
748 int pcount = ParmList_len (l);
749 char err_incomp[1024];
750 char err_incomp_pt[1024];
751 char type_check[1024];
752 char pt_check[1024];
753
754 create_defines_function(); // it's a hack
755
756 create_function_getargs (name, iname, d, l);
757
758 // on evite les fonctions a nombre de parametres variable
759 for (p = l; p; p = Getnext (p))
760 {
761 pt = Gettype (p);
762 if (!strcmp (Char (WIGType_base (pt)), "...") ||
763 (!strcmp (Char (WIGType_base (pt)), "void") && WIGType_ispointer (pt) == 0)) return ;
764 }
765
766 Printf (f_wrappers, "\nint wrap_%s (t_arg **ret, t_arg **prm, int n_params, char *errstr)\n", name);
767 Printf (f_wrappers, "{\n");
768
769 Printf (f_wrappers, " int jmp;\n\n");
770 Printf (f_wrappers, " *ret = NewArg ();\n\n");
771
772 Printf (f_wrappers, " avt_PushSegVMessage (\"Segmentation violation in `%s'\");\n", get_proto (name, d, l));
773 Printf (f_wrappers, " avt_PushSegVExit (Exit, 2);\n");
774 Printf (f_wrappers, " avt_PushFPEMessage (\"Arithmetic exception in `%s'\");\n", get_proto (name, d, l));
775 Printf (f_wrappers, " avt_PushFPEExit (Exit, 3);\n");
776
777 /* Number of prm Checking */
778 Printf (f_wrappers, " /* Number of prm Checking */\n");
779 Printf (f_wrappers, " if (n_params == 0)\n");
780 Printf (f_wrappers, " prm = NULL;\n");
781 Printf (f_wrappers, " if (n_params > %d) {\n", pcount);
782 Printf (f_wrappers, " sprintf (errstr, \"too many arguments to function `%s'\");\n", get_proto (name, d, l));
783 Printf (f_wrappers, " return 1;\n");
784 Printf (f_wrappers, " }\n\n");
785 Printf (f_wrappers, " if (n_params < %d) {\n", pcount);
786 Printf (f_wrappers, " sprintf (errstr, \"too few arguments to function `%s'\");\n", get_proto (name, d, l));
787 Printf (f_wrappers, " return 1;\n");
788 Printf (f_wrappers, " }\n\n");
789
790 /* Type Checking for prm */
791 Printf (f_wrappers, " /* Type Checking for prm */\n");
792 i = 0;
793 for (p = l; p; p = Getnext (p)) {
794 pt = Gettype (p);
795 sprintf (err_incomp, "sprintf (errstr, \"incompatible type for argument %d of `%s'\");", i + 1, name);
796 sprintf (err_incomp_pt, "sprintf (errstr, \"passing arg %d of `%s' from incompatible pointer type\");", i + 1, name);
797
798 if (WIGType_type (pt) == T_POINTER && !strcmp (Char (WIGType_base (pt)), "void") && WIGType_ispointer (pt) == 1) {
799 sprintf (pt_check, "(GetPointer (prm[%d]) == 0)", i);
800 Printf (f_wrappers, " if %s {\n %s\n return 1;\n }\n", pt_check, err_incomp_pt);
801 }
802 else
803 if (WIGType_type (pt) == T_POINTER && WIGType_ispointer (pt) >= 1) {
804 sprintf (type_check, "(TypeCheck (prm[%d], \"%s\") && TypeCheck (prm[%d], \"void\"))", i, Char (WIGType_base (pt)), i);
805 sprintf (pt_check, "(GetPointer (prm[%d]) == 0)", i);
806 Printf (f_wrappers, " if %s {\n %s\n return 1;\n }\n", type_check, err_incomp);
807 Printf (f_wrappers, " if %s {\n %s\n return 1;\n }\n", pt_check, err_incomp_pt);
808 }
809 else {
810 sprintf (type_check, "(TypeCheck (prm[%d], \"%s\"))", i, Char (WIGType_base (pt)));
811 sprintf (pt_check, "(GetPointer (prm[%d]) != %d)", i, WIGType_ispointer (pt));
812 Printf (f_wrappers, " if %s {\n %s\n return 1;\n }\n", type_check, err_incomp);
813 Printf (f_wrappers, " if %s {\n %s\n return 1;\n }\n", pt_check, err_incomp_pt);
814 }
815
816 i++;
817 }
818
819 /* Function call */
820 Printf (f_wrappers, " /* Function call */\n");
821 switch (WIGType_type (d)) {
822 case T_VOID:
823 Printf (f_wrappers, " SetPointer (*ret, 0);\n");
824 Printf (f_wrappers, " SetType (*ret, \"void\");\n");
825 Printf (f_wrappers, " (*ret)->VALUE = NULL;\n");
826 Printf (f_wrappers, " if (!(jmp = setjmp (env))) {\n");
827 Printf (f_wrappers, " %s (", iname);
828 break;
829 case T_POINTER:
830 case T_STRING:
831 case T_CHAR:
832 case T_INT:
833 case T_LONG:
834 case T_DOUBLE:
835 String *type = WIGType_str (d, 0);
836 Printf (f_wrappers, " SetPointer (*ret, %d);\n", WIGType_ispointer (d));
837 Printf (f_wrappers, " SetType (*ret, \"%s\");\n", WIGType_base (d));
838 Printf (f_wrappers, " (*ret)->VALUE = (%s*)malloc (sizeof (%s));\n", type, type);
839 Printf (f_wrappers, " if (!(jmp = setjmp (env))) {\n");
840 Printf (f_wrappers, " *(%s*)(*ret)->VALUE = %s (", type, iname);
841 break;
842 }
843
844 /* Arguments passing */
845 i = 0;
846 for (p = l; p; p = Getnext (p)) {
847 pt = Gettype (p);
848 if (WIGType_type (pt) != T_VOID) {
849 Printf (f_wrappers, "\n *(%s*)(prm[%d]->VALUE)", WIGType_str (pt, 0), i);
850 if (Getnext (p))
851 Printf (f_wrappers, ", ");
852 }
853 i++;
854 }
855 Printf (f_wrappers, "\n );\n");
856 Printf (f_wrappers, " } else {\n");
857 Printf (f_wrappers, " avt_PopSegVMessage ();\n");
858 Printf (f_wrappers, " avt_PopSegVExit ();\n");
859 Printf (f_wrappers, " avt_PopFPEMessage ();\n");
860 Printf (f_wrappers, " avt_PopFPEExit ();\n");
861 Printf (f_wrappers, " return 2;\n");
862 Printf (f_wrappers, " }\n\n");
863
864 Printf (f_wrappers, " avt_PopSegVMessage ();\n");
865 Printf (f_wrappers, " avt_PopSegVExit ();\n");
866 Printf (f_wrappers, " avt_PopFPEMessage ();\n");
867 Printf (f_wrappers, " avt_PopFPEExit ();\n");
868
869 Printf (f_wrappers, " return 0;\n");
870 Printf (f_wrappers, "}\n\n");
871 create_command (name, iname);
872 }
873
874 /* -------------------------------------------------------------------------- */
875
876 void GENIUS::link_variable (char *name, char *iname, WIGType *t)
877 {
878 Printf (f_init, "\t/* Linking variable: %s%s (%s) */\n", WIGType_str (t, 0), iname, name);
879 }
880
881 /* -------------------------------------------------------------------------- */
882
883 void GENIUS::declare_const (char *name, char *iname, WIGType *t, char *value)
884 {
885 Printf (f_init, "\t/* Creating constant: %s%s (%s) = %s */\n", WIGType_str (t, 0), iname, name, value);
886 }
887
888 /* -------------------------------------------------------------------------- */
889
890 void GENIUS::initialize (void)
891 {
892 if (!module) module = "genius";
893 Printf (f_init, "void %s_initialize () {\n", module);
894 }
895
896 /* -------------------------------------------------------------------------- */
897
898 void GENIUS::headers (void)
899 {
900 WIG_banner (f_header);
901 Printf (f_header, "#include <stdio.h>\n");
902 Printf (f_header, "#include <stdlib.h>\n");
903 Printf (f_header, "#include <setjmp.h>\n");
904 Printf (f_header, "#include <strings.h>\n");
905 Printf (f_header, "#include <signal.h>\n");
906 //Printf (f_header, "#include MUT_H\n");
907 //Printf (f_header, "#include AVT_H\n");
908 //Printf (f_header, "#include API_H\n");
909
910 #include "headers.inc"
911
912 Printf (f_header, "static jmp_buf env;\n\n");
913 Printf (f_header, "static void Exit (int val)\n");
914 Printf (f_header, "{\n");
915 Printf (f_header, " longjmp (env, val);\n");
916 Printf (f_header, "}\n");
917
918 }
919
920 /* -------------------------------------------------------------------------- */
921
922 void GENIUS::close (void)
923 {
924 Printf (f_init, "}\n");
925 }
926
927 /* -------------------------------------------------------------------------- */
928
929 void GENIUS::set_module (char *mod_name)
930 {
931 if (module) return;
932 module = new char[strlen (mod_name) + 1];
933 strcpy (module, mod_name);
934 }
935
936 /* -------------------------------------------------------------------------- */
937
938 void GENIUS::create_command (char *cname, char *iname)
939 {
940 Printf (f_init, "\t/* Creating command %s (%s) */\n", iname, cname);
941 }
942
943 static chain_list *create_splitt(char *val)
944 {
945 char *c, *s;
946 chain_list *cl=NULL;
947 s=strtok_r(val, "+", &c);
948 while (s!=NULL)
949 {
950 cl=addchain(cl, s);
951 s=strtok_r(NULL, "+", &c);
952 }
953 return cl;
954 }
955
956 void GENIUS::create_filter (char *filter, char *filterfile, Man *mans)
957 {
958 FILE *f;
959 char *fname;
960 char *description;
961 char *prototype;
962 char textbuf[10000];
963 chain_list *man, *filt, *cfilt, *cl, *ch, *pt;
964 ApiType *return_type;
965 functionman *fman;
966 Parm *function;
967 char **argtab;
968 char *args;
969 int i;
970
971 if (!filter) return;
972
973 if (!(f = fopen (filterfile, "wt"))) {
974 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", filterfile);
975 return;
976 }
977
978 filt=create_splitt(filter);
979
980 man=mans;
981
982 fprintf (f, "<functions>\n");
983 for (pt = proto_list; pt; pt = Getnext (pt)) {
984 function = (Parm*)Getdata (pt);
985 fname = (char*)Getdata (function);
986 function = Getnext (function);
987 return_type = (ApiType*)function;
988 fman=(functionman *)man->DATA;
989
990 if (fman) {
991 cfilt = create_splitt(fman->categ);
992 for (cl = filt; cl; cl = cl->NEXT) {
993 for (ch = cfilt; ch; ch = ch->NEXT) {
994 if (strcmp((char *)ch->DATA, (char *)cl->DATA)==0) break;
995 }
996 if (ch==NULL) break;
997 }
998 freechain(cfilt);
999
1000 if (cl==NULL) {
1001 fprintf (stdout, "Filtering XML page for `%s'\n", get_proto (fname, return_type, Getnext (function)));
1002 fprintf (f, "<func>\n");
1003
1004 fprintf (f, "<funcname><section niv='%d'><title>%s</title></section></funcname>\n", xmllevel, fname);
1005
1006 prototype = fman->synop?fman->synop:get_proto (fname, return_type, Getnext (function));
1007 xml_text (textbuf, prototype);
1008 fprintf (f, "<proto>%s</proto>", textbuf);
1009
1010 description = fman->desc;
1011 xml_text (textbuf, description);
1012 fprintf (f, "<desc>%s</desc>", textbuf);
1013
1014 if ((args = fman->errors)) {
1015 if (strcmp (args, "")) {
1016 argtab = xml_text_args (args);
1017 if (argtab) {
1018 for (i = 0; argtab[i]; i += 2) {
1019 fprintf (f, "<arg>");
1020 xml_text (textbuf, argtab[i]);
1021 fprintf (f, "<argn>%s</argn>", textbuf);
1022 xml_text (textbuf, argtab[i + 1]);
1023 fprintf (f, "<argdef>%s</argdef>", textbuf);
1024 fprintf (f, "</arg>\n");
1025 }
1026 for (i = 0; argtab[i]; i++) free (argtab[i]);
1027 }
1028 }
1029 }
1030 else {
1031 fprintf (f, "<arg></arg>");
1032 }
1033 fprintf (f, "</func>\n");
1034 }
1035 }
1036 man = Getnext (man);
1037 }
1038 fprintf (f, "</functions>\n");
1039
1040 freechain(filt);
1041 fclose (f);
1042 }
1043
1044 void GENIUS::create_filter4xls (char *filter, char *filterfile, Man * mans)
1045 {
1046 FILE *f;
1047 char *fname;
1048 char *description;
1049 char *prototype;
1050 char textbuf[10000];
1051 chain_list *man, *filt, *cfilt, *cl, *ch, *pt;
1052 ApiType *return_type;
1053 functionman *fman;
1054 Parm *function;
1055 char **argtab;
1056 char *args;
1057 int i;
1058
1059 if (!filter)
1060 return;
1061
1062 if (!(f = fopen (filterfile, "wt"))) {
1063 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", filterfile);
1064 return;
1065 }
1066
1067 fprintf (f, "<?xml version=\"1.0\"?>\n");
1068 fprintf (f, "<?mso-application progid=\"Excel.Sheet\"?>\n");
1069 fprintf (f, "<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\n");
1070 fprintf (f, "xmlns:o=\"urn:schemas-microsoft-com:office:office\"\n");
1071 fprintf (f, "xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n");
1072 fprintf (f, "xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"\n");
1073 fprintf (f, "xmlns:html=\"http://www.w3.org/TR/REC-html40\">\n");
1074 fprintf (f, "<ExcelWorkbook xmlns=\"urn:schemas-microsoft-com:office:excel\"> </ExcelWorkbook>\n");
1075 fprintf (f, "<Styles>\n");
1076 fprintf (f, "<Style ss:ID=\"proto\">\n");
1077 fprintf (f, "<Alignment ss:Vertical=\"Top\"/>\n");
1078 fprintf (f, "<Font ss:FontName=\"Courier New\" x:Family=\"Modern\" ss:Size=\"11\" ss:Bold=\"1\"/>\n");
1079 fprintf (f, "</Style>\n");
1080 fprintf (f, "<Style ss:ID=\"def\">\n");
1081 fprintf (f, "<Alignment ss:Vertical=\"Top\" ss:WrapText=\"1\"/>\n");
1082 fprintf (f, "<Font ss:FontName=\"Times New Roman\" x:Family=\"Roman\" ss:Size=\"11\"/>\n");
1083 fprintf (f, "</Style>\n");
1084 fprintf (f, "<Style ss:ID=\"desc\">\n");
1085 fprintf (f, "<Alignment ss:Vertical=\"Bottom\" ss:WrapText=\"1\"/>\n");
1086 fprintf (f, "<Font ss:FontName=\"Times New Roman\" x:Family=\"Roman\" ss:Size=\"11\" ss:Italic=\"1\"/>\n");
1087 fprintf (f, "</Style>\n");
1088 fprintf (f, "<Style ss:ID=\"param\">\n");
1089 fprintf (f, "<Alignment ss:Horizontal=\"Right\" ss:Vertical=\"Top\" ss:WrapText=\"1\" ss:Indent=\"1\"/>\n");
1090 fprintf (f, "<Font ss:FontName=\"Courier New\" x:Family=\"Modern\" ss:Size=\"11\"/>\n");
1091 fprintf (f, "</Style>\n");
1092 fprintf (f, "</Styles>\n");
1093
1094 // table
1095 fprintf (f, "<Worksheet ss:Name=\"%s\">\n", filterfile);
1096 fprintf (f, "<Table ss:DefaultColumnWidth=\"60\" ss:DefaultRowHeight=\"15\">\n");
1097 fprintf (f, "<Column ss:AutoFitWidth=\"0\" ss:Width=\"99\"/>\n");
1098 fprintf (f, "<Column ss:AutoFitWidth=\"0\" ss:Width=\"522.75\"/>\n");
1099
1100 filt = create_splitt (filter);
1101
1102 man = mans;
1103
1104 for (pt = proto_list; pt; pt = Getnext (pt)) {
1105 function = (Parm *) Getdata (pt);
1106 fname = (char *)Getdata (function);
1107 function = Getnext (function);
1108 return_type = (ApiType *) function;
1109 fman = (functionman *) man->DATA;
1110
1111 if (fman != NULL) {
1112 cfilt = create_splitt (fman->categ);
1113
1114 for (cl = filt; cl != NULL; cl = cl->NEXT) {
1115 for (ch = cfilt; ch != NULL; ch = ch->NEXT) {
1116 if (strcmp ((char *)ch->DATA, (char *)cl->DATA) == 0)
1117 break;
1118 }
1119 if (ch == NULL)
1120 break;
1121 }
1122 freechain (cfilt);
1123
1124 if (cl == NULL) {
1125 fprintf (stdout, "Filtering XML page for `%s'\n", get_proto (fname, return_type, Getnext (function)));
1126
1127
1128 // prototype
1129 prototype = fman->synop?fman->synop:get_proto (fname, return_type, Getnext (function));
1130 xml_text (textbuf, prototype);
1131 fprintf (f, "<Row>\n");
1132 fprintf (f, "<Cell ss:StyleID=\"proto\"><Data ss:Type=\"String\">%s</Data></Cell>\n", prototype);
1133 fprintf (f, "<Cell ss:StyleID=\"def\"/>\n");
1134 fprintf (f, "</Row>\n");
1135
1136 // description
1137 description = fman->desc;
1138 xml_text (textbuf, description);
1139 fprintf (f, "<Row>\n");
1140 fprintf (f, "<Cell ss:StyleID=\"def\"/>\n");
1141 fprintf (f, "<Cell ss:StyleID=\"desc\"><Data ss:Type=\"String\">%s</Data></Cell>\n", description);
1142 fprintf (f, "</Row>\n");
1143
1144
1145 if ((args = fman->errors)) {
1146 if (strcmp (args, "")) {
1147 argtab = xml_text_args (args);
1148 if (argtab) {
1149 for (i = 0; argtab[i]; i += 2) {
1150 fprintf (f, "<Row>\n");
1151 fprintf (f, "<Cell ss:StyleID=\"param\"><Data ss:Type=\"String\">%s</Data></Cell>\n", argtab[i]);
1152 fprintf (f, "<Cell ss:StyleID=\"def\"><Data ss:Type=\"String\">%s</Data></Cell>\n", argtab[i + 1]);
1153 fprintf (f, "</Row>\n");
1154 }
1155 for (i = 0; argtab[i]; i++)
1156 free (argtab[i]);
1157 }
1158 }
1159 }
1160 fprintf (f, "<Row>");
1161 fprintf (f, "<Cell ss:StyleID=\"def\"/>");
1162 fprintf (f, "</Row>");
1163 }
1164 }
1165 man = Getnext (man);
1166 }
1167 fprintf (f, "</Table>\n");
1168 fprintf (f, "</Worksheet>\n");
1169 fprintf (f, "</Workbook>\n");
1170
1171 freechain (filt);
1172 fclose (f);
1173 }
1174
1175 void GENIUS::create_filter_online (char *filter, char *online_path, Man *mans)
1176 {
1177 FILE *f;
1178 DIR *dir;
1179 char *fname;
1180 char buf[10000];
1181 chain_list *man, *filt, *cfilt, *cl, *ch, *pt;
1182 ParmList *parms;
1183 ApiType *return_type;
1184 functionman *fman;
1185 Parm *function;
1186 char **argtab;
1187 char *args;
1188 char *section;
1189 int i;
1190
1191 if (!filter || !online_path || !mans) return;
1192 if ((dir = opendir(online_path)) == NULL) {
1193 fprintf (stderr, "[API WAR] Help directory '%s' does not exist\n", online_path);
1194 return;
1195 }
1196 closedir(dir);
1197
1198 filt=create_splitt(filter);
1199
1200 man=mans;
1201
1202 for (pt = proto_list; pt; pt = Getnext (pt)) {
1203 function = (Parm*)Getdata (pt);
1204 fname = (char*)Getdata (function);
1205 function = Getnext (function);
1206 return_type = (ApiType*)function;
1207 function = Getnext (function);
1208 parms = (ParmList*)function;
1209 fman=(functionman *)man->DATA;
1210
1211 if (fman) {
1212 cfilt = create_splitt(fman->categ);
1213 for (cl = filt; cl; cl = cl->NEXT) {
1214 for (ch = cfilt; ch; ch = ch->NEXT) {
1215 if (strcmp((char *)ch->DATA, (char *)cl->DATA)==0) break;
1216 }
1217 if (ch==NULL) break;
1218 }
1219 if (cfilt==NULL || (cl && !strcmp((char *)cfilt->DATA, (char *)cl->DATA))) {
1220 section="misc";
1221 }
1222 else section = (char *)cfilt->DATA;
1223 freechain(cfilt);
1224
1225 if (cl==NULL || !strcmp(section, "misc")) {
1226 fprintf (stdout, "Filtering help page for `%s'\n", get_proto (fname, return_type, parms));
1227 sprintf(buf, "%s/%s", online_path, section);
1228 if ((dir = opendir(buf)) == NULL) {
1229 if (mkdir(buf, S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH) != 0) {
1230 fprintf (stderr, "[API WAR] Cannot create help category '%s' \n", section);
1231 return;
1232 }
1233 }
1234 else closedir(dir);
1235
1236 sprintf(buf, "groff -man -Tascii | awk 'BEGIN { skip = 0 } /@@@BUILDHELP@@@/ { next } /^$/ { if (skip == 0) print $0 ; skip = 1 ; next } // { print $0 ; skip = 0 }' > %s/%s/%s", online_path, section, fname);
1237 if (!(f = popen (buf, "w"))) {
1238 fprintf (stderr, "[API WAR] Can't open file %s for writing\n", fname);
1239 fflush(stderr);
1240 return;
1241 }
1242 fprintf (f, ".TH @@@BUILDHELP@@@\n");
1243 fprintf (f, ".SH \" \"\n");
1244 fprintf (f, "%s;\n", fman->synop?fman->synop:get_proto (fname, return_type, parms));
1245 // _____ description
1246 fprintf (f, ".SH DESCRIPTION\n");
1247 man_text (buf, fman->desc);
1248 fprintf (f, "%s\n", buf);
1249 // _____ arguments
1250 if ((args = fman->errors)) {
1251 if (strcmp (args, "")) {
1252 argtab = xml_text_args (args);
1253 if (argtab) {
1254 fprintf (f, ".SH ARGUMENTS\n");
1255 for (i = 0; argtab[i]; i += 2) {
1256 fprintf (f, ".TP 14\n.B %s\n", argtab[i]);
1257 man_text (buf, argtab[i + 1]);
1258 fprintf (f, "%s\n", buf);
1259 }
1260 for (i = 0; argtab[i]; i++) free (argtab[i]);
1261 }
1262 }
1263 }
1264 pclose (f);
1265 }
1266 }
1267 man = Getnext (man);
1268 }
1269
1270 freechain(filt);
1271 }
1272