1 /****************************************
2 *  Computer Algebra System SINGULAR     *
3 ****************************************/
4 /*
5 * ABSTRACT: generate iparith.inc etc.
6 */
7 
8 #include <stdlib.h>
9 #include <string.h>
10 #include <ctype.h>
11 #include <stdio.h>
12 #include <unistd.h>
13 #include <sys/stat.h>
14 
15 // need global defines:
16 #include "kernel/mod2.h"
17 // need to include all tokens: *_CMD:
18 #include "Singular/tok.h"
19 
20 #ifdef HAVE_RINGS
21   #define RING_MASK        4
22   #define ZERODIVISOR_MASK 8
23 #else
24   #define RING_MASK        0
25   #define ZERODIVISOR_MASK 0
26 #endif
27 
RingDependend(int t)28 static inline int RingDependend(int t) { return (BEGIN_RING<t)&&(t<END_RING); }
29 
30 // to produce convert_table.texi for doc:
31 VAR int produce_convert_table=0;
32 
33 // bits 0,1 for PLURAL
34 #define NO_NC            0
35 #define ALLOW_PLURAL     1
36 #define COMM_PLURAL      2
37 // bit 6: non-commutative letterplace
38 #define ALLOW_LP         64
39 #define NC_MASK          (3+64)
40 #define ALLOW_NC         ALLOW_LP|ALLOW_PLURAL
41 
42 // bit 2 for RING-CF
43 #define ALLOW_RING       4
44 #define NO_RING          0
45 
46 // bit 3 for zerodivisors
47 #define NO_ZERODIVISOR   8
48 #define ALLOW_ZERODIVISOR  0
49 #define ZERODIVISOR_MASK 8
50 
51 #define ALLOW_ZZ (ALLOW_RING|NO_ZERODIVISOR)
52 
53 // bit 4 for warning, if used at toplevel
54 #define WARN_RING        16
55 // bit 5: do no try automatic conversions
56 #define NO_CONVERSION    32
57 
58 /*=============== types =====================*/
59 struct _scmdnames
60 {
61   const char *name;
62   short alias;
63   short tokval;
64   short toktype;
65 };
66 typedef struct _scmdnames cmdnames;
67 
68 
69 struct sValCmd2
70 {
71   int p;
72   short cmd;
73   short res;
74   short arg1;
75   short arg2;
76   short valid_for;
77 };
78 struct sValCmd1
79 {
80   int p;
81   short cmd;
82   short res;
83   short arg;
84   short valid_for;
85 };
86 struct sValCmd3
87 {
88   int p;
89   short cmd;
90   short res;
91   short arg1;
92   short arg2;
93   short arg3;
94   short valid_for;
95 };
96 struct sValCmdM
97 {
98   int p;
99   short cmd;
100   short res;
101   short number_of_args; /* -1: any, -2: any >0, .. */
102   short valid_for;
103 };
104 struct sValAssign_sys
105 {
106   int p;
107   short res;
108   short arg;
109 };
110 
111 struct sValAssign
112 {
113   int p;
114   short res;
115   short arg;
116 };
117 
118 struct sConvertTypes
119 {
120   int i_typ;
121   int o_typ;
122   int p;
123   int pl;
124 };
125 
126 
127 #define jjWRONG   1
128 #define jjWRONG2  1
129 #define jjWRONG3  1
130 
131 #define D(A)     2
132 #define NULL_VAL 0
133 #define IPARITH
134 #define GENTABLE
135 #define IPCONV
136 #define IPASSIGN
137 
138 #include "table.h"
139 
Tok2Cmdname(int tok)140 const char * Tok2Cmdname(int tok)
141 {
142   if (tok < 0)
143   {
144     return cmds[0].name;
145   }
146   if (tok==COMMAND) return "command";
147   if (tok==ANY_TYPE) return "any_type";
148   if (tok==NONE) return "nothing";
149   //if (tok==IFBREAK) return "if_break";
150   //if (tok==VECTOR_FROM_POLYS) return "vector_from_polys";
151   //if (tok==ORDER_VECTOR) return "ordering";
152   //if (tok==REF_VAR) return "ref";
153   //if (tok==OBJECT) return "object";
154   //if (tok==PRINT_EXPR) return "print_expr";
155   if (tok==IDHDL) return "identifier";
156   // we do not blackbox objects during table generation:
157   //if (tok>MAX_TOK) return getBlackboxName(tok);
158   int i = 0;
159   while (cmds[i].tokval!=0)
160   {
161     if ((cmds[i].tokval == tok)&&(cmds[i].alias==0))
162     {
163       return cmds[i].name;
164     }
165     i++;
166   }
167   i=0;// try again for old/alias names:
168   while (cmds[i].tokval!=0)
169   {
170     if (cmds[i].tokval == tok)
171     {
172       return cmds[i].name;
173     }
174     i++;
175   }
176   #if 0
177   char *s=(char*)malloc(10);
178   sprintf(s,"(%d)",tok);
179   return s;
180   #else
181   return cmds[0].name;
182   #endif
183 }
184 /*---------------------------------------------------------------------*/
185 /**
186  * @brief compares to entry of cmdsname-list
187 
188  @param[in] a
189  @param[in] b
190 
191  @return <ReturnValue>
192 **/
193 /*---------------------------------------------------------------------*/
_gentable_sort_cmds(const void * a,const void * b)194 static int _gentable_sort_cmds( const void *a, const void *b )
195 {
196   cmdnames *pCmdL = (cmdnames*)a;
197   cmdnames *pCmdR = (cmdnames*)b;
198 
199   if(a==NULL || b==NULL)             return 0;
200 
201   /* empty entries goes to the end of the list for later reuse */
202   if(pCmdL->name==NULL) return 1;
203   if(pCmdR->name==NULL) return -1;
204 
205   /* $INVALID$ must come first */
206   if(strcmp(pCmdL->name, "$INVALID$")==0) return -1;
207   if(strcmp(pCmdR->name, "$INVALID$")==0) return  1;
208 
209   /* tokval=-1 are reserved names at the end */
210   if (pCmdL->tokval==-1)
211   {
212     if (pCmdR->tokval==-1)
213        return strcmp(pCmdL->name, pCmdR->name);
214     /* pCmdL->tokval==-1, pCmdL goes at the end */
215     return 1;
216   }
217   /* pCmdR->tokval==-1, pCmdR goes at the end */
218   if(pCmdR->tokval==-1) return -1;
219 
220   return strcmp(pCmdL->name, pCmdR->name);
221 }
222 
_texi_sort_cmds(const void * a,const void * b)223 static int _texi_sort_cmds( const void *a, const void *b )
224 {
225   cmdnames *pCmdL = (cmdnames*)a;
226   cmdnames *pCmdR = (cmdnames*)b;
227 
228   if(a==NULL || b==NULL)             return 0;
229 
230   /* empty entries goes to the end of the list for later reuse */
231   if(pCmdL->name==NULL) return 1;
232   if(pCmdR->name==NULL) return -1;
233 
234   /* $INVALID$ must come first */
235   if(strcmp(pCmdL->name, "$INVALID$")==0) return -1;
236   if(strcmp(pCmdR->name, "$INVALID$")==0) return  1;
237   char *ls=strdup(pCmdL->name);
238   char *rs=strdup(pCmdR->name);
239   char *s=ls;
240   while (*s) { *s=tolower(*s); s++; }
241   s=rs;
242   while (*s) { *s=tolower(*s); s++; }
243 
244   /* tokval=-1 are reserved names at the end */
245   if (pCmdL->tokval==-1)
246   {
247     if (pCmdR->tokval==-1)
248        { int r=strcmp(ls,rs); free(ls); free(rs); return r; }
249     /* pCmdL->tokval==-1, pCmdL goes at the end */
250     free(ls);free(rs);
251     return 1;
252   }
253   /* pCmdR->tokval==-1, pCmdR goes at the end */
254   if(pCmdR->tokval==-1)
255   { free(ls);free(rs);return -1;}
256 
257   { int r=strcmp(ls,rs); free(ls); free(rs); return r; }
258 }
259 
260 /*generic*/
iiTwoOps(int t)261 const char * iiTwoOps(int t)
262 {
263   if (t<127)
264   {
265     STATIC_VAR char ch[2];
266     switch (t)
267     {
268       case '&':
269         return "and";
270       case '|':
271         return "or";
272       default:
273         ch[0]=t;
274         ch[1]='\0';
275         return ch;
276     }
277   }
278   switch (t)
279   {
280     case COLONCOLON:  return "::";
281     case DOTDOT:      return "..";
282     //case PLUSEQUAL:   return "+=";
283     //case MINUSEQUAL:  return "-=";
284     case MINUSMINUS:  return "--";
285     case PLUSPLUS:    return "++";
286     case EQUAL_EQUAL: return "==";
287     case LE:          return "<=";
288     case GE:          return ">=";
289     case NOTEQUAL:    return "<>";
290     default:          return Tok2Cmdname(t);
291   }
292 }
293 //
294 // automatic conversions:
295 //
296 /*2
297 * try to convert 'inputType' in 'outputType'
298 * return 0 on failure, an index (<>0) on success
299 * GENTABLE variant!
300 */
iiTestConvert(int inputType,int outputType)301 int iiTestConvert (int inputType, int outputType)
302 {
303   if ((inputType==outputType)
304   || (outputType==DEF_CMD)
305   || (outputType==IDHDL)
306   || (outputType==ANY_TYPE))
307   {
308     return -1;
309   }
310   if (inputType==UNKNOWN) return 0;
311 
312   // search the list
313   int i=0;
314   while (dConvertTypes[i].i_typ!=0)
315   {
316     if((dConvertTypes[i].i_typ==inputType)
317     &&(dConvertTypes[i].o_typ==outputType))
318     {
319       //Print("test convert %d to %d (%s -> %s):%d\n",inputType,outputType,
320       //Tok2Cmdname(inputType), Tok2Cmdname(outputType),i+1);
321       return i+1;
322     }
323     i++;
324   }
325   //Print("test convert %d to %d (%s -> %s):0\n",inputType,outputType,
326   // Tok2Cmdname(inputType), Tok2Cmdname(outputType));
327   return 0;
328 }
329 VAR char *iparith_inc;
ttGen1()330 void ttGen1()
331 {
332   iparith_inc=strdup("iparith.xxxxxx");
333   int pid=getpid();
334   iparith_inc[8]=(pid %10)+'0'; pid/=10;
335   iparith_inc[9]=(pid %10)+'0'; pid/=10;
336   iparith_inc[10]=(pid %10)+'0'; pid/=10;
337   iparith_inc[11]=(pid %10)+'0'; pid/=10;
338   iparith_inc[12]=(pid %10)+'0'; pid/=10;
339   iparith_inc[13]=(pid %10)+'0';
340   FILE *outfile = fopen(iparith_inc,"w");
341   int i,j,l1=0,l2=0;
342   fprintf(outfile,
343   "/****************************************\n"
344   "*  Computer Algebra System SINGULAR     *\n"
345   "****************************************/\n\n");
346 /*-------------------------------------------------------------------*/
347   fprintf(outfile,"// syntax table for Singular\n//\n");
348   fprintf(outfile,"// - search for an exact match of the argument types\n");
349   fprintf(outfile,"// - otherwise search for the first possibility\n");
350   fprintf(outfile,"//   with converted types of the arguments\n");
351   fprintf(outfile,"// - otherwise report an error\n//\n");
352   fprintf(outfile,"// --------------------------------------------------\n");
353   fprintf(outfile,"// depends on Singular/table.h and kernel/mod2.h\n\n");
354 
355   int op;
356   i=0;
357   while ((op=dArith1[i].cmd)!=0)
358   {
359     if (dArith1[i].p==jjWRONG)
360       fprintf(outfile,"// DUMMY ");
361     const char *s = iiTwoOps(op);
362     fprintf(outfile,"// operation: %s (%s)  ->  %s",
363           s,
364           Tok2Cmdname(dArith1[i].arg),
365           Tok2Cmdname(dArith1[i].res));
366     if (RingDependend(dArith1[i].res) && (!RingDependend(dArith1[i].arg)))
367       fprintf(outfile," requires currRing");
368     if ((dArith1[i].valid_for & NC_MASK)==2)
369       fprintf(outfile,", commutative subalgebra");
370     else if ((dArith1[i].valid_for & NC_MASK)==ALLOW_LP)
371       fprintf(outfile,", letterplace rings");
372     else if ((dArith1[i].valid_for & NC_MASK)==0)
373       fprintf(outfile,", only commutative rings");
374     if ((dArith1[i].valid_for & RING_MASK)==0)
375       fprintf(outfile,", field coeffs");
376     else if ((dArith1[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
377       fprintf(outfile,", domain coeffs");
378     else if ((dArith1[i].valid_for & WARN_RING)==WARN_RING)
379       fprintf(outfile,", QQ coeffs");
380 
381     fprintf(outfile,"\n");
382     i++;
383   }
384   fprintf(outfile,"/*---------------------------------------------*/\n");
385   i=0;
386   while ((op=dArith2[i].cmd)!=0)
387   {
388     if (dArith2[i].p==jjWRONG2)
389       fprintf(outfile,"// DUMMY ");
390     const char *s = iiTwoOps(op);
391     fprintf(outfile,"// operation: %s (%s, %s)  ->  %s",
392           s,
393           Tok2Cmdname(dArith2[i].arg1),
394           Tok2Cmdname(dArith2[i].arg2),
395           Tok2Cmdname(dArith2[i].res));
396     if (RingDependend(dArith2[i].res)
397        && (!RingDependend(dArith2[i].arg1))
398        && (!RingDependend(dArith2[i].arg2)))
399     {
400       fprintf(outfile," requires currRing");
401     }
402     if ((dArith2[i].valid_for & NC_MASK)==COMM_PLURAL)
403       fprintf(outfile,", commutative subalgebra");
404     else if ((dArith2[i].valid_for & NC_MASK)==0)
405       fprintf(outfile,", only commutative rings");
406     if ((dArith2[i].valid_for & RING_MASK)==0)
407       fprintf(outfile,", field coeffs");
408     else if ((dArith2[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
409       fprintf(outfile,", domain coeffs");
410     else if ((dArith2[i].valid_for & WARN_RING)==WARN_RING)
411       fprintf(outfile,", QQ coeffs");
412 
413     fprintf(outfile,"\n");
414     i++;
415   }
416   fprintf(outfile,"/*---------------------------------------------*/\n");
417   i=0;
418   while ((op=dArith3[i].cmd)!=0)
419   {
420     const char *s = iiTwoOps(op);
421     if (dArith3[i].p==jjWRONG3)
422       fprintf(outfile,"// DUMMY ");
423     fprintf(outfile,"// operation: %s (%s, %s, %s)  ->  %s",
424           s,
425           Tok2Cmdname(dArith3[i].arg1),
426           Tok2Cmdname(dArith3[i].arg2),
427           Tok2Cmdname(dArith3[i].arg3),
428           Tok2Cmdname(dArith3[i].res));
429     if (RingDependend(dArith3[i].res)
430        && (!RingDependend(dArith3[i].arg1))
431        && (!RingDependend(dArith3[i].arg2))
432        && (!RingDependend(dArith3[i].arg3)))
433     {
434       fprintf(outfile," requires currRing");
435     }
436     if ((dArith3[i].valid_for & NC_MASK)==COMM_PLURAL)
437       fprintf(outfile,", commutative subalgebra");
438     else if ((dArith3[i].valid_for & NC_MASK)==0)
439       fprintf(outfile,", only commutative rings");
440     if ((dArith3[i].valid_for & RING_MASK)==0)
441       fprintf(outfile,", field coeffs");
442     else if ((dArith3[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
443       fprintf(outfile,", domain coeffs");
444     else if ((dArith3[i].valid_for & WARN_RING)==WARN_RING)
445       fprintf(outfile,", QQ coeffs");
446 
447     fprintf(outfile,"\n");
448     i++;
449   }
450   fprintf(outfile,"/*---------------------------------------------*/\n");
451   i=0;
452   while ((op=dArithM[i].cmd)!=0)
453   {
454     const char *s = iiTwoOps(op);
455     fprintf(outfile,"// operation: %s (...)  ->  %s",
456           s,
457           Tok2Cmdname(dArithM[i].res));
458     switch(dArithM[i].number_of_args)
459     {
460       case -2:
461          fprintf(outfile," ( number of arguments >0 )\n");
462          break;
463       case -1:
464          fprintf(outfile," ( any number of arguments )\n");
465          break;
466       default:
467          fprintf(outfile," ( %d arguments )\n",dArithM[i].number_of_args);
468          break;
469     }
470     i++;
471   }
472   fprintf(outfile,"/*---------------------------------------------*/\n");
473   i=0;
474   while ((op=dAssign[i].res)!=0)
475   {
476     fprintf(outfile,"// assign: %s =  %s\n",
477           Tok2Cmdname(op/*dAssign[i].res*/),
478           Tok2Cmdname(dAssign[i].arg));
479     i++;
480   }
481 /*-------------------------------------------------------------------*/
482   fprintf(outfile,"/*---------------------------------------------*/\n");
483   FILE *doctable=NULL; /*to silence "may be used uninitialized"*/
484   if (produce_convert_table)
485   {
486     doctable=fopen("convert_table.texi","w");
487     fprintf(doctable,"@multitable @columnfractions .05 .18 .81\n");
488   }
489   int doc_nr=1;
490   for (j=257;j<=MAX_TOK+1;j++)
491   {
492     for(i=257;i<=MAX_TOK+1;i++)
493     {
494       if ((i!=j) && (j!=IDHDL) && (j!=DEF_CMD) && (j!=ANY_TYPE)
495       && iiTestConvert(i,j))
496       {
497         fprintf(outfile,"// convert %s -> %s\n",
498           Tok2Cmdname(i), Tok2Cmdname(j));
499         if (produce_convert_table)
500         {
501           fprintf(doctable,
502           "@item\n@   %d. @tab @code{%s}  @tab @expansion{} @code{%s}\n",
503           doc_nr,Tok2Cmdname(i),Tok2Cmdname(j));
504           doc_nr++;
505         }
506         if (j==ANY_TYPE) break;
507       }
508     }
509   }
510   if (produce_convert_table)
511   {
512     fprintf(doctable,"@end multitable\n");
513     fclose(doctable);
514   }
515   fprintf(outfile,"/*---------------------------------------------*/\n");
516   char ops[]="=><+*/[.^,%(;";
517   for(i=0;ops[i]!='\0';i++)
518     fprintf(outfile,"// token %d : %c\n", (int)ops[i], ops[i]);
519   for (i=257;i<=MAX_TOK;i++)
520   {
521     const char *s=iiTwoOps(i);
522     if (s[0]!='$')
523     {
524       fprintf(outfile,"// token %d : %s\n", i, s);
525     }
526   }
527 /*-------------------------------------------------------------------*/
528   fprintf(outfile,"/*--max. token: %d, gr: %d --*/\n",MAX_TOK,UMINUS);
529 /*-------------------------------------------------------------------*/
530   fprintf(outfile,"/*---------------------------------------------*/\n");
531   fprintf(outfile,
532   "const struct sValCmdTab dArithTab1[]=\n"
533   "{\n");
534   for (j=1;j<=MAX_TOK+1;j++)
535   {
536     for(i=0;dArith1[i].cmd!=0;i++)
537     {
538       if (dArith1[i].cmd==j)
539       {
540         fprintf(outfile," { %d,%d },\n",j,i);
541         l1++;
542         break;
543       }
544     }
545   }
546   fprintf(outfile," { 10000,0 }\n};\n");
547   fprintf(outfile,"#define JJTAB1LEN %d\n",l1);
548 /*-------------------------------------------------------------------*/
549   fprintf(outfile,
550   "const struct sValCmdTab dArithTab2[]=\n"
551   "{\n");
552   for (j=1;j<=MAX_TOK+1;j++)
553   {
554     for(i=0;dArith2[i].cmd!=0;i++)
555     {
556       if (dArith2[i].cmd==j)
557       {
558         fprintf(outfile," { %d,%d },\n",j,i);
559         l2++;
560         break;
561       }
562     }
563   }
564   fprintf(outfile," { 10000,0 }\n};\n");
565   fprintf(outfile,"#define JJTAB2LEN %d\n",l2);
566   fclose(outfile);
567 }
568 /*---------------------------------------------------------------------*/
569 /**
570  * @brief generate cmds initialisation
571 **/
572 /*---------------------------------------------------------------------*/
573 
ttGen2b()574 void ttGen2b()
575 {
576   int cmd_size = (sizeof(cmds)/sizeof(cmdnames))-1;
577 
578   FILE *outfile = fopen(iparith_inc,"a");
579   fprintf(outfile,
580   "/****************************************\n"
581   "*  Computer Algebra System SINGULAR     *\n"
582   "****************************************/\n\n");
583 /*-------------------------------------------------------------------*/
584   fprintf(outfile,"// identifier table for Singular\n//\n");
585 
586   fprintf(
587     outfile,
588     "void iiInitCmdName()\n{\n"
589     "  sArithBase.nCmdUsed      = 0;\n"
590     "  sArithBase.nCmdAllocated = %d;\n"
591     "  sArithBase.sCmds = (cmdnames*)omAlloc0(%d/*sArithBase.nCmdAllocated*/ *sizeof(cmdnames));\n"
592     "\n"
593     "  // name-string                   alias  tokval toktype index\n",
594     cmd_size,cmd_size);
595   int m=0;
596   int id_nr=0;
597 
598   qsort(&cmds, cmd_size, sizeof(cmdnames), (&_gentable_sort_cmds));
599 
600   for(m=0; m<cmd_size; m++)
601   {
602     if(cmds[m].tokval>0) id_nr++;
603     fprintf(outfile,"  iiArithAddCmd(\"%s\", %*d, %3d, ",cmds[m].name,
604             (int)(20-strlen(cmds[m].name)),
605             cmds[m].alias,
606             cmds[m].tokval);
607     switch(cmds[m].toktype)
608     {
609         case CMD_1:            fprintf(outfile,"CMD_1"); break;
610         case CMD_2:            fprintf(outfile,"CMD_2"); break;
611         case CMD_3:            fprintf(outfile,"CMD_3"); break;
612         case CMD_12:           fprintf(outfile,"CMD_12"); break;
613         case CMD_123 :         fprintf(outfile,"CMD_123"); break;
614         case CMD_13 :          fprintf(outfile,"CMD_13"); break;
615         case CMD_23:           fprintf(outfile,"CMD_23"); break;
616         case CMD_M:            fprintf(outfile,"CMD_M"); break;
617         case SYSVAR:           fprintf(outfile,"SYSVAR"); break;
618         case ROOT_DECL:        fprintf(outfile,"ROOT_DECL"); break;
619         case ROOT_DECL_LIST:   fprintf(outfile,"ROOT_DECL_LIST"); break;
620         case RING_DECL:        fprintf(outfile,"RING_DECL"); break;
621         case NONE:             fprintf(outfile,"NONE"); break;
622         default:
623           if((cmds[m].toktype>' ') &&(cmds[m].toktype<127))
624           {
625             fprintf(outfile,"'%c'",cmds[m].toktype);
626           }
627           else
628           {
629             fprintf(outfile,"%d",cmds[m].toktype);
630           }
631           break;
632 #if 0
633           fprintf(outfile,"  iiArithAddCmd(\"%s\", %*d,  -1, 0 );\n",
634               cmds[m].name, 20-strlen(cmds[m].name),
635               0/*cmds[m].alias*/
636               /*-1 cmds[m].tokval*/
637               /*0 cmds[m].toktype*/);
638 #endif
639     }
640     fprintf(outfile,", %d);\n", m);
641   }
642   fprintf(outfile, "/* end of list marker */\n");
643   fprintf(outfile,
644           "  sArithBase.nLastIdentifier = %d;\n",
645           id_nr);
646 
647 
648   fprintf(outfile,
649 "}\n"
650 "#define LAST_IDENTIFIER %d\n"
651   ,id_nr);
652   fclose(outfile);
653 }
is_ref_cmd(cmdnames * c)654 int is_ref_cmd(cmdnames *c)
655 {
656   if( c->tokval==0) return 0;
657   if (c->alias > 0) return 0;
658   if  ((c->toktype==CMD_1)
659         || (c->toktype==CMD_2)
660         || (c->toktype==CMD_3)
661         || (c->toktype==CMD_M)
662         || (c->toktype==CMD_12)
663         || (c->toktype==CMD_13)
664         || (c->toktype==CMD_23)
665         || (c->toktype==CMD_123)) return 1;
666   return 0;
667 }
ttGen2c()668 void ttGen2c()
669 {
670   int cmd_size = (sizeof(cmds)/sizeof(cmdnames))-1;
671 
672   FILE *outfile = fopen("reference_table.texi","w");
673   fprintf(outfile, "@menu\n");
674 /*-------------------------------------------------------------------*/
675   qsort(&cmds, cmd_size, sizeof(cmdnames), (&_texi_sort_cmds));
676 
677   int m;
678   for(m=0; m<cmd_size; m++)
679   {
680     // assume that cmds[0].tokval== -1 and all others with tokval -1 at the end
681     if(is_ref_cmd(&(cmds[m])))
682     {
683       fprintf(outfile,"* %s::\n",cmds[m].name);
684     }
685   }
686   fprintf(outfile, "@end menu\n@c ---------------------------\n");
687   for(m=0; m<cmd_size; m++)
688   {
689     // assume that cmds[0].tokval== -1 and all others with tokval -1 at the end
690     if(is_ref_cmd(&(cmds[m])))
691     {
692       fprintf(outfile,"@node %s,",cmds[m].name);
693       // next:
694       int mm=m-1;
695       while((mm>0)&& (is_ref_cmd(&cmds[mm]))) mm--;
696       if((mm>0)&& (is_ref_cmd(&cmds[mm])))
697         fprintf(outfile,"%s,",cmds[mm].name);
698       else
699         fprintf(outfile,",");
700       // prev:
701       mm=m+1;
702       while((mm>0)&& (is_ref_cmd(&cmds[mm]))) mm++;
703       if((mm>0)&& (is_ref_cmd(&cmds[mm])))
704         fprintf(outfile,"%s,",cmds[m-1].name);
705       else
706         fprintf(outfile,",");
707       // up:, and header
708       fprintf(outfile,"Functions\n"
709       "@subsection %s\n"
710       "@cindex %s\n",cmds[m].name,cmds[m].name);
711       fprintf(outfile,"@include %s.part\n",cmds[m].name);
712       char partName[50];
713       sprintf(partName,"%s.part",cmds[m].name);
714       struct stat buf;
715       if (lstat(partName,&buf)!=0)
716       {
717         int op,i;
718         int only_field=0,only_comm=0,no_zerodiv=0;
719         FILE *part=fopen(partName,"w");
720         fprintf(part,"@table @code\n@item @strong{Syntax:}\n");
721         if ((cmds[m].toktype==CMD_1)
722         || (cmds[m].toktype==CMD_12)
723         || (cmds[m].toktype==CMD_13)
724         || (cmds[m].toktype==CMD_123))
725         {
726           op= cmds[m].tokval;
727           i=0;
728           while ((dArith1[i].cmd!=op) && (dArith1[i].cmd!=0)) i++;
729           while (dArith1[i].cmd==op)
730           {
731             if (dArith1[i].p!=jjWRONG)
732             {
733               fprintf(part,"@code{%s (} %s @code{)}\n",cmds[m].name,Tok2Cmdname(dArith1[i].arg));
734               fprintf(part,"@item @strong{Type:}\n%s\n",Tok2Cmdname(dArith1[i].res));
735               if ((dArith1[i].valid_for & ALLOW_PLURAL)==0)
736                 only_comm=1;
737               if ((dArith1[i].valid_for & ALLOW_RING)==0)
738                 only_field=1;
739               if ((dArith1[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
740                 no_zerodiv=1;
741             }
742             i++;
743           }
744         }
745         if ((cmds[m].toktype==CMD_23)
746         || (cmds[m].toktype==CMD_12)
747         || (cmds[m].toktype==CMD_2)
748         || (cmds[m].toktype==CMD_123))
749         {
750           op= cmds[m].tokval;
751           i=0;
752           while ((dArith2[i].cmd!=op) && (dArith2[i].cmd!=0)) i++;
753           while (dArith2[i].cmd==op)
754           {
755             if (dArith2[i].p!=jjWRONG)
756             {
757               fprintf(part,"@code{%s (} %s, %s @code{)}\n",cmds[m].name,Tok2Cmdname(dArith2[i].arg1),Tok2Cmdname(dArith2[i].arg2));
758               fprintf(part,"@item @strong{Type:}\n%s\n",Tok2Cmdname(dArith2[i].res));
759               if ((dArith2[i].valid_for & ALLOW_PLURAL)==0)
760                  only_comm=1;
761               if ((dArith2[i].valid_for & ALLOW_RING)==0)
762                  only_field=1;
763               if ((dArith2[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
764                 no_zerodiv=1;
765             }
766             i++;
767           }
768         }
769         if ((cmds[m].toktype==CMD_23)
770         || (cmds[m].toktype==CMD_13)
771         || (cmds[m].toktype==CMD_3)
772         || (cmds[m].toktype==CMD_123))
773         {
774           op= cmds[m].tokval;
775           i=0;
776           while ((dArith3[i].cmd!=op) && (dArith3[i].cmd!=0)) i++;
777           while (dArith3[i].cmd==op)
778           {
779             if (dArith3[i].p!=jjWRONG)
780             {
781               fprintf(part,"@code{%s (} %s, %s, %s @code{)}\n",cmds[m].name,
782                 Tok2Cmdname(dArith3[i].arg1),
783                 Tok2Cmdname(dArith3[i].arg2),
784                 Tok2Cmdname(dArith3[i].arg3));
785               fprintf(part,"@item @strong{Type:}\n%s\n",Tok2Cmdname(dArith3[i].res));
786               if ((dArith3[i].valid_for & ALLOW_PLURAL)==0)
787                 only_comm=1;
788               if ((dArith3[i].valid_for & ALLOW_RING)==0)
789                 only_field=1;
790               if ((dArith3[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
791                 no_zerodiv=1;
792             }
793             i++;
794           }
795         }
796         if (cmds[m].toktype==CMD_M)
797         {
798           op= cmds[m].tokval;
799           i=0;
800           while ((dArithM[i].cmd!=op) && (dArithM[i].cmd!=0)) i++;
801           while (dArithM[i].cmd==op)
802           {
803             if (dArithM[i].p!=jjWRONG)
804             {
805               fprintf(part,"@code{%s (} ... @code{)}\n",cmds[m].name);
806               fprintf(part,"@item @strong{Type:}\n%s\n",Tok2Cmdname(dArithM[i].res));
807               if ((dArithM[i].valid_for & ALLOW_PLURAL)==0)
808                 only_comm=1;
809               if ((dArithM[i].valid_for & ALLOW_RING)==0)
810                 only_field=1;
811               if ((dArithM[i].valid_for & ZERODIVISOR_MASK)==NO_ZERODIVISOR)
812                 no_zerodiv=1;
813             }
814             i++;
815           }
816         }
817         if (only_comm)
818               fprintf(part,"@item @strong{Remark:}\n"
819                            "only for commutive polynomial rings\n");
820         if (only_field)
821               fprintf(part,"@item @strong{Remark:}\n"
822                            "only for polynomial rings over fields\n");
823         if (no_zerodiv)
824               fprintf(part,"@item @strong{Remark:}\n"
825                            "only for polynomial rings over domains\n");
826         fprintf(part,"@item @strong{Purpose:}\n"
827                      "@item @strong{Example:}\n"
828                      "@smallexample\n"
829                      "@c example\n"
830                      "@c example\n"
831                      "@end smallexample\n"
832                      "@c ref\n"
833                      "@c See\n"
834                      "@c ref{....};\n"
835                      "@c ref{....}.\n"
836                      "@c ref\n");
837         fclose(part);
838       }
839     }
840   }
841   fclose(outfile);
842 }
843 /*-------------------------------------------------------------------*/
ttGen4()844 void ttGen4()
845 {
846   FILE *outfile = fopen("plural_cmd.xx","w");
847   int i;
848   const char *old_s="";
849   fprintf(outfile,
850   "@c *****************************************\n"
851   "@c *  Computer Algebra System SINGULAR     *\n"
852   "@c *****************************************\n\n");
853 /*-------------------------------------------------------------------*/
854   fprintf(outfile,"@multicolumn .45 .45\n");
855   int op;
856   i=0;
857   while ((op=dArith1[i].cmd)!=0)
858   {
859     if (dArith1[i].p!=jjWRONG)
860     {
861       const char *s = iiTwoOps(op);
862       if ((s!=NULL) && (isalpha(s[0])) && (strcmp(s,old_s)!=0))
863       {
864         old_s=s;
865         #ifdef HAVE_PLURAL
866         switch (dArith1[i].valid_for & NC_MASK)
867         {
868           case NO_NC:
869             fprintf(outfile,"@item @ref{%s} @tab @code{---}\n",s);
870             break;
871           case ALLOW_PLURAL:
872             fprintf(outfile,"@item @ref{%s} @tab @ref{%s (plural)}\n",s,s);
873             break;
874           case COMM_PLURAL:
875             fprintf(outfile,"@item @ref{%s} @tab %s\n",s,s);
876             break;
877         }
878         #endif
879         #ifdef HAVE_RINGS
880         #endif
881       }
882     }
883     i++;
884   }
885   fprintf(outfile,"@c ---------------------------------------------\n");
886   i=0;
887   while ((op=dArith2[i].cmd)!=0)
888   {
889     if (dArith2[i].p!=jjWRONG2)
890     {
891       const char *s = iiTwoOps(op);
892       if ((s!=NULL) && (isalpha(s[0])) && (strcmp(s,old_s)!=0))
893       {
894         old_s=s;
895         #ifdef HAVE_PLURAL
896         switch (dArith2[i].valid_for & NC_MASK)
897         {
898           case NO_NC:
899             fprintf(outfile,"@item @ref{%s} @tab @code{---}\n",s);
900             break;
901           case ALLOW_PLURAL:
902             fprintf(outfile,"@item @ref{%s} @tab @ref{%s (plural)}\n",s,s);
903             break;
904           case COMM_PLURAL:
905             fprintf(outfile,"@item @ref{%s} @tab %s\n",s,s);
906             break;
907         }
908         #endif
909         #ifdef HAVE_RINGS
910         #endif
911       }
912     }
913     i++;
914   }
915   fprintf(outfile,"@c ---------------------------------------------\n");
916   i=0;
917   while ((op=dArith3[i].cmd)!=0)
918   {
919     const char *s = iiTwoOps(op);
920     if (dArith3[i].p!=jjWRONG3)
921     {
922       if ((s!=NULL) && (isalpha(s[0])) && (strcmp(s,old_s)!=0))
923       {
924         old_s=s;
925         #ifdef HAVE_PLURAL
926         switch (dArith3[i].valid_for & NC_MASK)
927         {
928           case NO_NC:
929             fprintf(outfile,"@item @ref{%s} @tab @code{---}\n",s);
930             break;
931           case ALLOW_PLURAL:
932             fprintf(outfile,"@item @ref{%s} @tab @ref{%s (plural)}\n",s,s);
933             break;
934           case COMM_PLURAL:
935             fprintf(outfile,"@item @ref{%s} @tab %s\n",s,s);
936             break;
937         }
938         #endif
939         #ifdef HAVE_RINGS
940         #endif
941       }
942     }
943     i++;
944   }
945   fprintf(outfile,"@c ---------------------------------------------\n");
946   i=0;
947   while ((op=dArithM[i].cmd)!=0)
948   {
949     const char *s = iiTwoOps(op);
950     if ((s!=NULL) && (isalpha(s[0])) && (strcmp(s,old_s)!=0))
951     {
952         old_s=s;
953         #ifdef HAVE_PLURAL
954         switch (dArithM[i].valid_for & NC_MASK)
955         {
956           case NO_NC:
957             fprintf(outfile,"@item @ref{%s} @tab @code{---}\n",s);
958             break;
959           case ALLOW_PLURAL:
960             fprintf(outfile,"@item @ref{%s} @tab @ref{%s (plural)}\n",s,s);
961             break;
962           case COMM_PLURAL:
963             fprintf(outfile,"@item @ref{%s} @tab %s\n",s,s);
964             break;
965         }
966         #endif
967         #ifdef HAVE_RINGS
968         #endif
969     }
970     i++;
971   }
972   fprintf(outfile,"@c ---------------------------------------------\n");
973   fprintf(outfile,"@end table\n");
974   fclose(outfile);
975   rename("plural_cmd.xx","plural_cmd.inc");
976 }
977 /*-------------------------------------------------------------------*/
978 
main(int argc,char ** argv)979 int main(int argc, char** argv)
980 {
981   if (argc>1)
982   {
983     produce_convert_table=1; /* for ttGen1 */
984     ttGen1();
985     unlink(iparith_inc);
986     ttGen4();
987     ttGen2c();
988   }
989   else
990   {
991     ttGen1();
992     ttGen2b();
993     rename(iparith_inc,"iparith.inc");
994   }
995   return 0;
996 }
997