source: git/dyn_modules/modgen/misc.cc @ f9f879

spielwiese
Last change on this file since f9f879 was 3c473c, checked in by Kai Krüger <krueger@…>, 14 years ago
rename directory modules to dyn_modules anticipating "modules" directory for cmake. git-svn-id: file:///usr/local/Singular/svn/trunk@13033 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 21.8 KB
Line 
1/****************************************
2*  Computer Algebra System SINGULAR     *
3****************************************/
4/* $Id$ */
5/*
6* ABSTRACT: lib parsing
7*/
8
9#include <stdlib.h>
10#include <regex.h>
11
12#include "modgen.h"
13#include "typmap.h"
14
15#define NEW_PARAM 1
16
17#if 1
18#  define logx printf
19#else
20#  define logx
21#endif
22
23/* This is the same structure as in Singular's kernel/structs.h.
24 * Duplicating the following code sniplets is save, because it is used
25 * independently here.
26 * Moreover, it is recommended not to include structs.h here, because otherwise
27 * changing the latter could break modgen also.
28 */
29struct _scmdnames
30{
31  char *name;
32  short alias;
33  short tokval;
34  short toktype;
35};
36typedef struct _scmdnames cmdnames;
37
38
39
40
41typedef struct {
42  unsigned long nCmdUsed;      /**< number of commands used */
43  unsigned long nCmdAllocated; /**< number of commands-slots allocated */
44  unsigned long nLastIdentifier;
45  cmdnames *sCmds;             /**< array of existing commands */
46
47#ifndef GENTABLE
48  struct sValCmd1 *psValCmd1;
49  struct sValCmd2 *psValCmd2;
50  struct sValCmd3 *psValCmd3;
51  struct sValCmdM *psValCmdM;
52#endif /* GENTABLE */
53} SArithBase;
54
55
56/*---------------------------------------------------------------------*
57 * File scope Variables (Variables share by several functions in
58 *                       the same file )
59 *
60 *---------------------------------------------------------------------*/
61static SArithBase sArithBase;  /**< Base entry for arithmetic */
62
63
64BOOLEAN    expected_parms;
65int        cmdtok;
66BOOLEAN siq=FALSE;
67const char *lastreserved=NULL;
68#define SELF_CMD MAX_TOK+1
69
70/*---------------------------------------------------------------------*
71 * Extern Functions declarations
72 *
73 *---------------------------------------------------------------------*/
74static int _gentable_sort_cmds(const void *a, const void *b);
75extern int iiArithRemoveCmd(char *szName);
76extern int iiArithAddCmd(char *szName, short nAlias, short nTokval,
77                         short nToktype, short nPos=-1);
78extern void enter_id(FILE *fp, idtyp t, char *name, char *value,
79                     int lineno, char *file);
80extern void write_enter_id(FILE *fp);
81extern void write_add_singular_proc(FILE *fp);
82
83static void  mod_write_ctext(FILE *fp, FILE *fp_in);
84char type_conv[MAX_TOK][32];
85
86extern void write_intro(moddefv module);
87
88/*=============== types =====================*/
89struct sValCmdTab
90{
91  short cmd;
92  short start;
93};
94
95/* todo: ensure compiler picks the right header, without using paths here */
96/*#include "iparith.inc"*/
97#include "../../Singular/iparith.inc"
98
99/*=================== general utilities ============================*/
100int IsCmd(char *n, int & tok)
101{
102  int an=1;
103  int i,v;
104  int en=sArithBase.nLastIdentifier;
105
106  if( strcmp(n, "SELF") == 0)
107  {
108    tok = SELF_CMD;
109    logx("IsCmd: [%d] %s\n", tok, n);
110    return tok;
111  }
112
113  if( strcmp(n, "none") == 0)
114  {
115    tok = NONE;
116    logx("IsCmd: [%d] %s\n", tok, n);
117    return tok;
118  }
119
120  for(an=0; an<sArithBase.nCmdUsed; )
121  {
122    if(an>=en-1)
123    {
124      if (strcmp(n, sArithBase.sCmds[an].name) == 0)
125      {
126        i=an;
127        break;
128      }
129      else if ((an!=en) && (strcmp(n, sArithBase.sCmds[en].name) == 0))
130      {
131        i=en;
132        break;
133      }
134      else
135      {
136        return 0;
137      }
138    }
139    i=(an+en)/2;
140    if (*n < *(sArithBase.sCmds[i].name))
141    {
142      en=i-1;
143    }
144    else if (*n > *(sArithBase.sCmds[i].name))
145    {
146      an=i+1;
147    }
148    else
149    {
150      v=strcmp(n,sArithBase.sCmds[i].name);
151    if(v<0)
152    {
153        en=i-1;
154    }
155    else if(v>0)
156    {
157        an=i+1;
158    }
159    else /*v==0*/
160    {
161      break;
162    }
163  }
164  }
165  lastreserved=sArithBase.sCmds[i].name;
166  tok=sArithBase.sCmds[i].tokval;
167  if(sArithBase.sCmds[i].alias==2)
168    {
169    if(trace)printf("outdated identifier `%s` used - please change your code",
170    sArithBase.sCmds[i].name);
171    sArithBase.sCmds[i].alias=1;
172  }
173
174  logx("IsCmd: [%d] %s\n", tok, n);
175
176  if( (sArithBase.sCmds[i].toktype==ROOT_DECL) ||
177      (sArithBase.sCmds[i].toktype==ROOT_DECL_LIST) ||
178      (sArithBase.sCmds[i].toktype==RING_DECL) ||
179      (sArithBase.sCmds[i].toktype==IDEAL_CMD) ||
180      (sArithBase.sCmds[i].toktype==INTMAT_CMD) ||
181      (sArithBase.sCmds[i].toktype==MODUL_CMD) ||
182      (sArithBase.sCmds[i].toktype==MATRIX_CMD))// ||
183//      ((csArithBase.sCds[i].toktype>=DRING_CMD) && (cmds[i].toktype<=VECTOR_CMD)))
184    return sArithBase.sCmds[i].toktype;
185  return 0;
186}
187
188
189char * decl2str(int n, char *name)
190{
191  switch(n)
192  {
193#   include "decl.inc"
194
195    /* first and last entry of tok.h cannot be grepped */
196    case MAX_TOK: strcpy(name,"MAX_TOK");       break;
197    case ALIAS_CMD: strcpy(name,"ALIAS_CMD");       break;
198    default: strcpy(name,"(null)");
199  }
200  return(name);
201}
202
203/*========================================================================*/
204struct valid_cmds_def
205{
206  char *name;
207  void (*write_cmd)(moddefv module, procdefv pi, void *arg);
208  cmd_token id;
209  cmd_type  type;
210  int args;
211} valid_cmds[] =
212{
213  { "declaration",  write_function_declaration, CMD_DECL,   CMDT_SINGLE, 0 },
214  { "error",        write_function_error,       CMD_ERROR,  CMDT_ANY,    0 },
215  { "nodeclaration",write_function_nodecl,      CMD_NODECL, CMDT_SINGLE, 0 },
216  { "typecheck",    write_function_typecheck,   CMD_CHECK,  CMDT_SINGLE, 0 },
217  { "return",       write_function_result,      CMD_RETURN, CMDT_EQ,     0 },
218//{ "return",       write_function_return,      CMD_RETURN, CMDT_SINGLE, 1 },
219  { "return",       write_function_return,      CMD_RETURN, CMDT_0,     1 },
220  { "return",       write_function_return,      CMD_RETURN, CMDT_ANY,   1 },
221  { "singularcmd",  write_function_singularcmd, CMD_SINGULAR, CMDT_ANY, 1 },
222  { NULL,           0, CMD_NONE, CMDT_ANY, 0 }
223};
224
225cmd_token checkcmd(
226  char *cmdname,
227  void (**write_cmd)(moddefv module, procdefv pi, void *arg),
228  cmd_type  type,
229  int args
230  )
231{
232  int i;
233  cmd_token rc = CMD_NONE;
234
235  for(i=0; valid_cmds[i].name!=NULL; i++)
236  {
237    if(strcmp(valid_cmds[i].name, cmdname)==0)
238    {
239      rc = CMD_BADSYNTAX;
240      if(valid_cmds[i].type == type)
241      {
242        *write_cmd = valid_cmds[i].write_cmd;
243        return valid_cmds[i].id;
244      }
245    }
246  }
247  return rc;
248}
249
250/*========================================================================*/
251struct valid_vars_def
252{
253  char *name;
254  var_type type;
255  var_token id;
256  void (*write_cmd)(moddefv module, var_token type,
257                    idtyp t, void *arg1, void *arg2);
258} valid_vars[] =
259{
260  { "help",         VAR_STRING,  VAR_HELP,     write_main_variable },
261  { "info",         VAR_STRING,  VAR_INFO,     write_main_variable },
262  { "package",      VAR_STRING,  VAR_MODULE,   0 },
263  { "version",      VAR_STRING,  VAR_VERSION,  write_main_variable },
264  { "category",     VAR_STRING,  VAR_CATEGORY, write_main_variable },
265  { NULL,           VAR_UNKNOWN, VAR_NONE, 0 }
266};
267
268var_token checkvar(
269  char *varname,
270  var_type type,
271  void (**write_cmd)(moddefv module, var_token type,
272                    idtyp t, void *arg1, void *arg2)
273  )
274{
275  int i;
276  for(i=0; valid_vars[i].name!=NULL; i++)
277    if((strcmp(valid_vars[i].name, varname)==0) &&
278       (valid_vars[i].type == type) ) {
279      *write_cmd = valid_vars[i].write_cmd;
280      return valid_vars[i].id;
281    }
282  return VAR_NONE;
283}
284
285/*========================================================================*/
286void write_main_variable(
287  moddefv module,
288  var_token type,
289  idtyp t,
290  void *arg1,
291  void *arg2
292  )
293{
294  enter_id(module->fmtfp, t, (char *)arg1, (char *)arg2, yylineno,
295           module->filename);
296  switch(type)
297  {
298    case VAR_INFO:
299          module->info = (char *)malloc(strlen((char *)arg2)+1);
300          memset(module->info, '\0', strlen((char *)arg2)+1);
301          memcpy(module->info,(char *)arg2,strlen((char *)arg2));
302          break;
303    case VAR_VERSION:
304          module->version = (char *)malloc(strlen((char *)arg2)+1);
305          memset(module->version, '\0', strlen((char *)arg2)+1);
306          memcpy(module->version,(char *)arg2,strlen((char *)arg2));
307          break;
308    case VAR_CATEGORY:
309          module->category = (char *)malloc(strlen((char *)arg2)+1);
310          memset(module->category, '\0', strlen((char *)arg2)+1);
311          memcpy(module->category,(char *)arg2,strlen((char *)arg2));
312          break;
313    default: break;
314  }
315}
316
317/*========================================================================*/
318void PrintProc(
319  procdefv pi
320  )
321{
322  int i;
323
324  printf("%4d proc: %s(", pi->lineno, pi->procname);
325
326  for(i=0; i<pi->paramcnt; i++)
327  {
328    printf("%s (%s)", (pi->param[i]).name, (pi->param[i]).typname);
329    if(i < (pi->paramcnt-1)) printf(",");
330  }
331  printf(")\n");
332  if(pi->return_val.typ!=0)
333  {
334    printf("\treturn = %s (%s)\n", pi->return_val.name,
335           pi->return_val.typname);
336  }
337  printf("{%s}\n", pi->c_code);
338}
339
340/*========================================================================*/
341void make_version(char *p, moddefv module)
342{
343  char ver[10];
344  char date[16];
345  char libnamebuf[128];
346
347  module->major = 0;
348  module->minor = 0;
349  module->level = 0;
350
351  ver[0]='0'; ver[1]='.'; ver[2]='0'; ver[3]='.'; ver[4]='0'; ver[5]='\0';
352  date[0]='?'; date[1]='\0';
353  sscanf(p,"%*s %*s %10s %16s",ver,date);
354  sscanf(ver, "%d.%d.%d", &module->major, &module->minor, &module->level);
355
356  sprintf(libnamebuf,"(%s,%s)", ver, date);
357  if(strcmp(libnamebuf, "(0.0.0,?)")==0)
358  {
359    sscanf(p,"%*[^\"]\"%[^\"]\"",libnamebuf);
360  }
361  module->revision = (char *)malloc(strlen(libnamebuf)+1);
362  memset(module->revision, '\0', strlen(libnamebuf)+1);
363  memcpy(module->revision, libnamebuf, strlen(libnamebuf));
364}
365
366/*========================================================================*/
367void make_module_name(char *p, moddefv module)
368{
369  if(strlen(p)>=1)
370  {
371    module->targetname = (char *)malloc(strlen(p)+1);
372    memset(module->targetname, '\0', strlen(p)+1);
373    memcpy(module->targetname,p,strlen(p));
374  }
375  else
376  {
377    module->targetname = (char *)malloc(strlen(module->name)+1);
378    memset(module->targetname, '\0', strlen(module->name)+1);
379    memcpy(module->targetname,module->name,strlen(module->name));
380  }
381
382}
383
384/*========================================================================*/
385void Add2files(
386  moddefv module,
387  char *name
388  )
389{
390  cfiles cfnew;
391  memset((void *)&cfnew, '\0', sizeof(cfiles));
392
393  cfnew.filename = (char *)malloc(strlen(name)+1);
394  memset(cfnew.filename, '\0', strlen(name)+1);
395  memcpy(cfnew.filename, name, strlen(name));
396
397  if(module->filecnt==0)
398  {
399    module->files = (cfilesv)malloc(sizeof(cfiles)+1);
400  }
401  else
402  {
403    module->files = (cfilesv)realloc(module->files,
404                                   (module->filecnt+1)*sizeof(cfiles));
405  }
406  if(module->files == NULL) { printf("ERROR\n"); return; }
407
408  memset((void *) &module->files[module->filecnt], '\0', sizeof(cfiles));
409  memcpy((void *)(&(module->files[module->filecnt])),
410         (void *)&cfnew, sizeof(cfiles));
411  (module->filecnt)++;
412}
413
414/*========================================================================*/
415void PrintProclist(
416  moddefv module
417  )
418{
419  logx("PrintProclist()\n");
420  int j;
421  for(j=0; j<module->proccnt; j++)
422  {
423    PrintProc(&(module->procs[j]));
424  }
425}
426
427/*========================================================================*/
428void generate_mod(
429  moddefv module,
430  int section
431  )
432{
433  procdefv v = NULL;
434  cfilesv c_filelist = NULL;
435  int proccnt;
436  FILE *fp_h;
437  char *filename;
438
439  switch(section)
440  {
441      case 1:
442        write_intro(module);
443        return;
444
445      case 2:
446        printf("Writing %s, section %d", filename, section);fflush(stdout);
447        break;
448  }
449
450  sprintf(filename, "%s.h", module->name);
451  fp_h = fopen(filename, "w");
452  write_header(fp_h, module->name);
453  printf("%s  ...", filename);fflush(stdout);
454
455  /* building mod_init() */
456
457  for(proccnt=0; proccnt<module->proccnt; proccnt++)
458  {
459    printf("->%s, %s\n", module->procs[proccnt].procname,
460           module->procs[proccnt].funcname);
461    fprintf(module->modfp, "  psModulFunctions->iiAddCproc(\"%s\",\"%s\",%s, mod_%s);\n",
462            module->name, module->procs[proccnt].procname,
463            module->procs[proccnt].is_static ? "TRUE" : "FALSE",
464            module->procs[proccnt].funcname);
465  }
466  fprintf(module->modfp, "  return 0;\n}\n\n");
467
468  /* building entry-functions */
469  for(proccnt=0; proccnt<module->proccnt; proccnt++)
470  {
471    //generate_function(&module->procs[proccnt], module->modfp);
472    //generate_header(&module->procs[proccnt], fp_h);
473  }
474  printf("  done.\n");fflush(stdout);
475  fclose(module->modfp);
476  fclose(fp_h);
477}
478
479
480
481
482/*========================================================================*/
483void  write_procedure_text(
484  moddefv module,
485  int lineno
486)
487{
488  int i;
489  procdefv pi = &module->procs[module->proccnt-1];
490
491  fprintf(module->fmtfp, "#line %d \"%s\"\n", lineno, module->filename);
492  fprintf(module->fmtfp, "%s\n", module->procs[module->proccnt-1].c_code);
493  free(module->procs[module->proccnt-1].c_code);
494  module->procs[module->proccnt-1].c_code = NULL;
495
496#if 0
497  if(pi->paramcnt>0)
498  {
499  }
500  else
501  {
502    switch( pi->return_val.typ)
503    {
504        case SELF_CMD:
505          fprintf(module->fmtfp, "  return(%s(res));", pi->funcname);
506          break;
507
508        case NONE:
509          fprintf(module->fmtfp, "  return FALSE;");
510          break;
511
512        default:
513          fprintf(module->fmtfp, "  res->rtyp = %s;\n",
514                  pi->return_val.typname);
515          fprintf(module->fmtfp, "  res->data = (void *)%s();\n",
516                  pi->funcname);
517          fprintf(module->fmtfp, "  return FALSE;");
518    }
519  }
520#endif
521  fprintf(module->fmtfp, "/*\n}\n\n*/");
522
523}
524
525
526/*========================================================================*/
527void  mod_write_header(FILE *fp, char *module, char what)
528{
529
530  write_header(fp, module);
531  fprintf(fp, "#line %d \"%s.cc\"\n", modlineno++, module);
532  if(what != 'h')
533  {
534    fprintf(fp, "#include <stdlib.h>\n");
535    fprintf(fp, "#include <stdio.h>\n");
536    fprintf(fp, "#include <string.h>\n");
537    fprintf(fp, "#include <ctype.h>\n");
538
539    fprintf(fp, "#if defined(HPUX_9) || defined(HPUX_10)\n");
540    fprintf(fp, "#  include <dl.h>\n");
541    fprintf(fp, "#else\n");
542    fprintf(fp, "#  include <dlfcn.h>\n");
543    fprintf(fp, "#endif\n");
544
545    fprintf(fp, "#include <unistd.h>\n");
546    fprintf(fp, "#include <sys/stat.h>");
547    fprintf(fp, "\n");
548    fprintf(fp, "#include <mod2.h>\n");
549    fprintf(fp, "#include <tok.h>\n");
550    fprintf(fp, "#include <structs.h>\n");
551    fprintf(fp, "#include <ipid.h>\n\n");
552    fprintf(fp, "#include <locals.h>\n");
553    fprintf(fp, "#include <omalloc.h>\n");
554    fprintf(fp, "#include \"%s.h\"\n", module);
555    modlineno+=8;
556
557    fprintf(fp, "#line %d \"%s.cc\"\n", modlineno++, module);
558    write_enter_id(fp);
559    fprintf(fp, "\n");    modlineno+=1;
560    fprintf(fp, "#line %d \"%s.cc\"\n", modlineno++, module);
561    write_add_singular_proc(fp);
562    write_crccheck(fp);
563    fprintf(fp, "\n");
564
565    fprintf(fp, "void fill_help_package();\n");
566    fprintf(fp, "void fill_example_package();\n");
567    modlineno+=3;
568  }
569  fprintf(fp, "\n");
570
571}
572
573/*========================================================================*/
574void write_header(FILE *fp, char *module, char *comment)
575{
576  fprintf(fp, "%s/*\n%s * This was automatically generated by modgen\n",
577          comment, comment);
578  fprintf(fp, "%s * version %s\n", comment, MOD_GEN_VERSION);
579  fprintf(fp, "%s * module %s\n", comment, module);
580  fprintf(fp, "%s * Don't edit this file\n%s */\n", comment, comment);
581  fprintf(fp, "%s\n", comment);
582  fprintf(fp, "%s\n", comment);
583  if(strlen(comment)==1)modlineno+=10;
584}
585
586/*========================================================================*/
587void enter_id(
588  FILE *fp,
589  idtyp t,
590  char *name,
591  char *value,
592  int lineno,
593  char *file
594  )
595{
596  unsigned int i;
597  char tname[32];
598
599  if(lineno)
600    fprintf(fp, "#line %d \"%s\"\n", lineno, file);
601  if(strcmp(decl2str(t, tname),"STRING_CMD")==0)
602  {
603    fprintf(fp, "  enter_id(\"%s\",\"",name);
604    for(i=0;i<strlen(value);i++)
605    {
606       if(value[i]=='\n') fprintf(fp,"\\n");
607       else fprintf(fp,"%c",value[i]);
608    }
609    fprintf(fp,"\", %s);\n",decl2str(t,tname));
610  }
611  else
612  {
613    fprintf(fp, "  enter_id(\"%s\",\"%s\", %s);\n",name, value,
614          decl2str(t, tname));
615  }
616}
617
618/*========================================================================*/
619void init_type_conv()
620{
621  strcpy(type_conv[NONE], "none");
622//  strcpy(type_conv[NONE], "void");
623  strcpy(type_conv[INT_CMD], "int");
624  strcpy(type_conv[RING_CMD], "ring");
625  strcpy(type_conv[QRING_CMD], "ring");
626  strcpy(type_conv[POLY_CMD], "poly");
627  strcpy(type_conv[NUMBER_CMD], "number");
628  strcpy(type_conv[MODUL_CMD], "ideal");
629  strcpy(type_conv[VECTOR_CMD], "poly");
630  strcpy(type_conv[IDEAL_CMD], "ideal");
631  strcpy(type_conv[MAP_CMD], "map");
632  strcpy(type_conv[MATRIX_CMD], "matrix");
633  strcpy(type_conv[STRING_CMD], "char *");
634  strcpy(type_conv[INTMAT_CMD], "intvec *");
635  strcpy(type_conv[INTVEC_CMD], "intvec *");
636  strcpy(type_conv[LIST_CMD], "lists");
637  strcpy(type_conv[LINK_CMD], "si_link");
638  strcpy(type_conv[PACKAGE_CMD], "package");
639  strcpy(type_conv[PROC_CMD], "procinfo *");
640  strcpy(type_conv[RESOLUTION_CMD], "syStrategy");
641/*
642  strcpy(type_conv[], "");
643  strcpy(type_conv[], "");
644  strcpy(type_conv[], "");
645  strcpy(type_conv[], "");
646  strcpy(type_conv[], "");
647  strcpy(type_conv[], "");
648  strcpy(type_conv[], "");
649  printf("[%d] %s\n", INT_CMD, type_conv[INT_CMD]);
650  printf("[%d] %s\n", MODUL_CMD, type_conv[MODUL_CMD]);
651  printf("[%d] %s\n", STRING_CMD, type_conv[STRING_CMD]);
652  printf("[%d] %s\n", LINK_CMD, type_conv[LINK_CMD]);
653  printf("[%d] %s\n", PACKAGE_CMD, type_conv[PACKAGE_CMD]);
654  / **/
655}
656
657/*========================================================================*/
658/*---------------------------------------------------------------------*/
659/**
660 * @brief compares to entry of cmdsname-list
661
662 @param[in] a
663 @param[in] b
664
665 @return <ReturnValue>
666**/
667/*---------------------------------------------------------------------*/
668static int _gentable_sort_cmds(
669  const void *a,
670  const void *b
671  )
672{
673  cmdnames *pCmdL = (cmdnames*)a;
674  cmdnames *pCmdR = (cmdnames*)b;
675
676  if(a==NULL || b==NULL)             return 0;
677
678  /* empty entries goes to the end of the list for later reuse */
679  if(pCmdL->name==NULL) return 1;
680  if(pCmdR->name==NULL) return -1;
681
682  /* $INVALID$ must come first */
683  if(strcmp(pCmdL->name, "$INVALID$")==0) return -1;
684  if(strcmp(pCmdR->name, "$INVALID$")==0) return  1;
685
686  /* tokval=-1 are reserved names at the end */
687  if( (pCmdL->tokval==-1) && pCmdR->tokval==-1)
688    return strcmp(pCmdL->name, pCmdR->name);
689
690  /* pCmdL->tokval==-1, pCmdL goes at the end */
691  if(pCmdL->tokval==-1) return 1;
692  /* pCmdR->tokval==-1, pCmdR goes at the end */
693  if(pCmdR->tokval==-1) return -1;
694
695  return strcmp(pCmdL->name, pCmdR->name);
696}
697
698/*---------------------------------------------------------------------*/
699/**
700 * @brief initialisation of arithmetic structured data
701
702 @retval 0 on success
703
704**/
705/*---------------------------------------------------------------------*/
706int iiInitArithmetic()
707{
708  int i;
709  //printf("iiInitArithmetic()\n");
710#ifndef GENTABLE
711  memset(&sArithBase, 0, sizeof(sArithBase));
712  iiInitCmdName();
713  /* fix last-identifier */
714#endif   /* !GENTABLE */
715}
716
717int iiArithFindCmd(const char *szName)
718{
719  int an=0;
720  int i = 0,v = 0;
721#ifndef GENTABLE
722  int en=sArithBase.nLastIdentifier;
723
724  for(an=0; an<sArithBase.nCmdUsed; )
725  {
726    if(an>=en-1)
727    {
728      if (strcmp(szName, sArithBase.sCmds[an].name) == 0)
729      {
730        //Print("RET-an=%d %s\n", an, sArithBase.sCmds[an].name);
731        return an;
732      }
733      else if (strcmp(szName, sArithBase.sCmds[en].name) == 0)
734      {
735        //Print("RET-en=%d %s\n", en, sArithBase.sCmds[en].name);
736        return en;
737      }
738      else
739      {
740        //Print("RET- 1\n");
741        return -1;
742      }
743    }
744    i=(an+en)/2;
745    if (*szName < *(sArithBase.sCmds[i].name))
746    {
747      en=i-1;
748    }
749    else if (*szName > *(sArithBase.sCmds[i].name))
750    {
751      an=i+1;
752    }
753    else
754    {
755      v=strcmp(szName,sArithBase.sCmds[i].name);
756      if(v<0)
757      {
758        en=i-1;
759      }
760      else if(v>0)
761      {
762        an=i+1;
763      }
764      else /*v==0*/
765      {
766        //Print("RET-i=%d %s\n", i, sArithBase.sCmds[i].name);
767        return i;
768      }
769    }
770  }
771  //if(i>=0 && i<sArithBase.nCmdUsed)
772  //  return i;
773  //Print("RET-2\n");
774  return -2;
775#else
776  return 0;
777#endif
778}
779
780int iiArithAddCmd(
781  char *szName,
782  short nAlias,
783  short nTokval,
784  short nToktype,
785  short nPos
786  )
787{
788  //printf("AddCmd(%s, %d, %d, %d, %d)\n", szName, nAlias,
789  //       nTokval, nToktype, nPos);
790  if(nPos>=0)
791  {
792    if(nPos>=sArithBase.nCmdAllocated) return -1;
793    if(szName!=NULL) sArithBase.sCmds[nPos].name    = strdup(szName);
794    else sArithBase.sCmds[nPos].name = NULL;
795    sArithBase.sCmds[nPos].alias   = nAlias;
796    sArithBase.sCmds[nPos].tokval  = nTokval;
797    sArithBase.sCmds[nPos].toktype = nToktype;
798    sArithBase.nCmdUsed++;
799    //if(nTokval>0) sArithBase.nLastIdentifier++;
800  }
801  else
802  {
803    if(szName==NULL) return -1;
804    int nIndex = iiArithFindCmd(szName);
805    if(nIndex>=0)
806    {
807      printf("'%s' already exists at %d\n", szName, nIndex);
808      return -1;
809    }
810
811    if(sArithBase.nCmdUsed>=sArithBase.nCmdAllocated)
812    {
813      /* needs to create new slots */
814      unsigned long nSize = (sArithBase.nCmdAllocated+1)*sizeof(cmdnames);
815      sArithBase.sCmds = (cmdnames *)realloc(sArithBase.sCmds, nSize);
816      if(sArithBase.sCmds==NULL) return -1;
817      sArithBase.nCmdAllocated++;
818    }
819    /* still free slots available */
820    sArithBase.sCmds[sArithBase.nCmdUsed].name    = strdup(szName);
821    sArithBase.sCmds[sArithBase.nCmdUsed].alias   = nAlias;
822    sArithBase.sCmds[sArithBase.nCmdUsed].tokval  = nTokval;
823    sArithBase.sCmds[sArithBase.nCmdUsed].toktype = nToktype;
824    sArithBase.nCmdUsed++;
825
826    qsort(sArithBase.sCmds, sArithBase.nCmdUsed, sizeof(cmdnames),
827          (&_gentable_sort_cmds));
828    for(sArithBase.nLastIdentifier=sArithBase.nCmdUsed-1;
829        sArithBase.nLastIdentifier>0; sArithBase.nLastIdentifier--)
830    {
831      if(sArithBase.sCmds[sArithBase.nLastIdentifier].tokval>=0) break;
832    }
833    //Print("L=%d\n", sArithBase.nLastIdentifier);
834  }
835  return 0;
836}
837
Note: See TracBrowser for help on using the repository browser.