main.c
来自「SRI international 发布的OAA框架软件」· C语言 代码 · 共 1,115 行 · 第 1/2 页
C
1,115 行
tail = (ListNode *) (*list)->elem; /* get tail pointer */
tail->next = p;
(*list)->elem = (char *) p; /* reset tail */
}
}
static void
#ifdef __USE_PROTOS
ProcessArgs( int argc, char **argv, Opt *options )
#else
ProcessArgs( argc, argv, options )
int argc;
char **argv;
Opt *options;
#endif
{
Opt *p;
require(argv!=NULL, "ProcessArgs: command line NULL");
while ( argc-- > 0 )
{
p = options;
while ( p->option != NULL )
{
if ( strcmp(p->option, "*") == 0 ||
cistrequ(p->option, *argv))
{
if ( p->arg )
{
(*p->process)( *argv, *(argv+1) );
argv++;
argc--;
}
else
(*p->process)( *argv );
break;
}
p++;
}
argv++;
}
}
/*
* Given a string, this function allocates and returns a pointer to a
* hash table record of size 'sz' whose "str" pointer is reset to a position
* in the string table.
*/
Entry *
#ifdef __USE_PROTOS
newEntry( char *text, int sz )
#else
newEntry( text, sz )
char *text;
int sz;
#endif
{
Entry *p;
require(text!=NULL, "new: NULL terminal");
if ( (p = (Entry *) calloc(1,sz)) == 0 )
{
fatal("newEntry: out of memory for terminals\n");
exit(1);
}
p->str = mystrdup(text);
return(p);
}
void
#ifdef __USE_PROTOS
token_association(int token_type, char *text)
#else
token_association( token_type, text )
int token_type;
char *text;
#endif
{
if ( token_type >= token_table_size ) /* overflow? */
{
char **p;
int i, more;
more = 100;
token_table_size += more;
token_dict = (char **) realloc(token_dict, token_table_size*sizeof(char *));
require(token_dict != NULL, "token_association: can't extend token_dict");
for (p= &token_dict[token_table_size-more],i=1; i<=more; i++) *p++ = NULL;
}
token_dict[token_type] = text;
}
/*
* Return a string corresponding to the output file name associated
* with the input file name passed in.
*
* Observe the following rules:
*
* f.e --> f".c"
* f --> f".c"
* f. --> f".c"
* f.e.t --> f.e".c"
*
* Where f,e,t are arbitrarily long sequences of characters in a file
* name.
*
* In other words, if a ".x" appears on the end of a file name, make it
* ".c". If no ".x" appears, append ".c" to the end of the file name.
*
* Use malloc() for new string.
*/
char *
#ifdef __USE_PROTOS
outname( char *fs )
#else
outname( fs )
char *fs;
#endif
{
static char buf[MaxFileName+1];
char *p;
p = buf;
strcpy(buf, fs);
while ( *p != '\0' ) {p++;} /* Stop on '\0' */
while ( *p != '.' && p != buf ) {--p;} /* Find '.' */
if ( p != buf ) *p = '\0'; /* Found '.' */
require(strlen(buf) + 2 < (size_t)MaxFileName, "outname: filename too big");
if ( GenCPP ) strcat(buf, CPP_FILE_SUFFIX);
else strcat(buf, ".c");
return( buf );
}
void
#ifdef __USE_PROTOS
ensure_no_C_file_collisions(char *class_c_file)
#else
ensure_no_C_file_collisions(class_c_file)
char *class_c_file;
#endif
{
int i;
for (i=0; i<NumFiles; i++)
{
#ifdef PCCTS_CASE_INSENSITIVE_FILE_NAME
/* assume that file names are case insensitive */
if ( STRICMP(outname(FileStr[i]), class_c_file)==0 )
#else
if ( strcmp(outname(FileStr[i]), class_c_file)==0 )
#endif
{
fatal(eMsg1("class def output file conflicts with parser output file: %s",
outname(FileStr[i])));
}
}
}
/* MR10: Jeff Vincent
MR10: Changed to remove directory information from n only if
MR10: if OutputDirectory was changed by user (-o option)
*/
char *
#ifdef __USE_PROTOS
OutMetaName(char *n)
#else
OutMetaName(n)
char *n;
#endif
{
static char *dir_sym = DirectorySymbol;
static char newname[MaxFileName+1];
char *p;
/* If OutputDirectory is same as TopDirectory (platform default) then leave n alone. */
if (strcmp(OutputDirectory, TopDirectory) == 0)
return n;
/* p will point to filename without path information */
if ((p = strrchr(n, *dir_sym)) != NULL)
p++;
else
p = n;
/* Copy new output directory into newname[] */
strcpy(newname, OutputDirectory);
/* if new output directory does not have trailing dir_sym, add it! */
if (newname[strlen(newname)-1] != *dir_sym)
strcat(newname, dir_sym);
/* contatenate FILE NAME ONLY to new output directory */
strcat(newname, p);
return newname;
}
void
#ifdef __USE_PROTOS
set_fprint( FILE *f, set e )
#else
set_fprint( f, e )
FILE *f;
set e;
#endif
{
int t;
if ( set_nil(e) ) return;
fprintf(f, "{");
while ( !set_nil(e) )
{
t = set_int(e);
set_rm(t, e);
fprintf(f, " %s", token_dict[t]);
}
fprintf(f, " }");
}
/* Given a list of ANSI-style parameter declarations, print out a
* comma-separated list of the symbols (w/o types).
* Basically, we look for a comma, then work backwards until start of
* the symbol name. Then print it out until 1st non-alnum char. Now,
* move on to next parameter.
*/
void
#ifdef __USE_PROTOS
DumpListOfParmNames( char *pdecl, FILE *output )
#else
DumpListOfParmNames( pdecl, output )
char *pdecl;
FILE *output;
#endif
{
int firstTime = 1, done = 0;
require(output!=NULL, "DumpListOfParmNames: NULL parm");
if ( pdecl == NULL ) return;
while ( !done )
{
if ( !firstTime ) putc(',', output);
done = DumpNextNameInDef(&pdecl, output);
firstTime = 0;
}
}
/* given a list of parameters or return values, dump the next
* name to output. Return 1 if last one just printed, 0 if more to go.
*/
int
#ifdef __USE_PROTOS
DumpNextNameInDef( char **q, FILE *output )
#else
DumpNextNameInDef( q, output )
char **q;
FILE *output;
#endif
{
char *p = *q; /* where did we leave off? */
int done=0;
while ( *p!='\0' && *p!=',' ) p++; /* find end of decl */
if ( *p == '\0' ) done = 1;
while ( !isalnum(*p) && *p!='_' ) --p; /* scan back until valid var character */
while ( isalnum(*p) || *p=='_' ) --p; /* scan back until beginning of variable */
p++; /* move to start of variable */
while ( isalnum(*p) || *p=='_' ) {putc(*p, output); p++;}
while ( *p!='\0' && *p!=',' ) p++; /* find end of decl */
p++; /* move past this parameter */
*q = p; /* record where we left off */
return done;
}
/* Given a list of ANSI-style parameter declarations, dump K&R-style
* declarations, one per line for each parameter. Basically, convert
* comma to semi-colon, newline.
*/
void
#ifdef __USE_PROTOS
DumpOldStyleParms( char *pdecl, FILE *output )
#else
DumpOldStyleParms( pdecl, output )
char *pdecl;
FILE *output;
#endif
{
require(output!=NULL, "DumpOldStyleParms: NULL parm");
if ( pdecl == NULL ) return;
while ( *pdecl != '\0' )
{
if ( *pdecl == ',' )
{
pdecl++;
putc(';', output); putc('\n', output);
while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++;
}
else {putc(*pdecl, output); pdecl++;}
}
putc(';', output);
putc('\n', output);
}
/* Take in a type definition (type + symbol) and print out type only */
void
#ifdef __USE_PROTOS
DumpType( char *s, FILE *f, char *file, int line )
#else
DumpType( s, f, file, line )
char *s;
FILE *f;
char *file;
int line;
#endif
{
char *p, *end;
require(s!=NULL, "DumpType: invalid type string");
p = &s[strlen(s)-1]; /* start at end of string and work back */
/* scan back until valid variable character */
while ( !isalnum(*p) && *p!='_' ) --p;
/* scan back until beginning of variable */
while ( isalnum(*p) || *p=='_' ) --p;
if ( p<=s )
{
warnFL(eMsg1("invalid parameter/return value: '%s'",s), file, line);
return;
}
end = p; /* here is where we stop printing alnum */
p = s;
while ( p!=end ) {putc(*p, f); p++;} /* dump until just before variable */
while ( *p!='\0' ) /* dump rest w/o variable */
{
if ( !isalnum(*p) && *p!='_' ) putc(*p, f);
p++;
}
}
char *
#ifdef __USE_PROTOS
actiondup(char *s)
#else
actiondup(s)
char *s;
#endif
{
char *p = (char *) malloc(strlen(s)+1);
require(p!=NULL, "actiondup: no memory");
strcpy(p, s);
return p;
}
#ifdef OLD
RefVarRec *
#ifdef __USE_PROTOS
newRefVarRec(char *t,char *lab, char *init)
#else
newRefVarRec(t,lab,init)
char *t,*lab,*init;
#endif
{
RefVarRec *p;
SymEntry *q;
q = (SymEntry *) hash_get(symbols, lab);
if ( q==NULL )
{
q = (SymEntry *) hash_add(symbols, lab, (Entry *) newSymEntry(lab));
q->token = REFVAR;
q->defined = 1;
}
else err(eMsg2("Reference variable clashes with %s: '%s'", zztokens[q->token], lab));
p = (RefVarRec *) calloc(1, sizeof(RefVarRec));
require(p!=NULL, "newRefVarRec: no memory");
strcpy(p->type, t);
strcpy(p->label, lab);
strcpy(p->init, init);
return p;
}
#endif
/* From one of the following ref var defs, create a record to track
* the info:
*
* @(int *p);
* @(int *p=NULL); -- initialized
* @(static int *p); -- global
*
* The 'def' pointer should point to the first char after the '('
*/
RefVarRec *
#ifdef __USE_PROTOS
refVarRec(char *def)
#else
refVarRec(def)
char *def;
#endif
{
RefVarRec *p;
char *s,*decl;
p = (RefVarRec *) calloc(1, sizeof(RefVarRec));
require(p!=NULL, "newRefVarRec: no memory");
/* find first word; must be type or "static" */
s = def;
while ( isalpha(*s) ) s++;
if ( strncmp(def, "static", s-def)==0 ) p->global = 1;
else s = def;
/* now get type from s position until '=' or ')' */
decl = s;
while ( *s!='=' && *s!='\0' ) s++;
if ( *s=='=' ) {
/* there is an initializer */
strcpy(p->init, s+1);
*s='\0';
}
strcpy(p->decl, decl);
strcpy(p->var, id_in_decl(decl));
return p;
}
/* given a decl (type + id) return a ptr to the id; nondestructive to 'decl'.
* Just scan backwards from the end looking for the start of the first id.
*/
char *
#ifdef __USE_PROTOS
id_in_decl( char *decl )
#else
id_in_decl( decl )
char *decl;
#endif
{
static char id[MaxAtom+1];
char *p = &(decl[strlen(decl)-1]);
char *end, *start;
require(decl!=NULL, "id_in_decl: NULL decl");
require(strlen(decl)>(size_t)0, "id_in_decl: empty decl");
/* scan back until valid var character */
while ( !isalnum(*p) || *p=='_' ) --p;
end = p+1;
/* scan back until beginning of variable */
while ( isalnum(*p) || *p=='_' ) --p;
p++; /* move to start of variable */
start = p;
strncpy(id, start, end-start);
id[end-start] = '\0';
return id;
}
/* Take in a decl (type + id) and print it out with a prefix on id */
void
#ifdef __USE_PROTOS
dump_prefixed_decl( char *prefix, char *s, FILE *f )
#else
dump_prefixed_decl( prefix, s, f )
char *prefix;
char *s;
FILE *f;
#endif
{
char *p, *id;
require(s!=NULL, "invalid type string");
p = &s[strlen(s)-1]; /* start at end of string and work back */
/* scan back until valid variable character */
while ( !isalnum(*p) && *p!='_' ) --p;
/* scan back until beginning of variable */
while ( isalnum(*p) || *p=='_' ) --p;
require(p>s, "invalid decl");
p++;
id = p; /* here is where id is */
p = s;
while ( p!=id ) {fputc(*p, f); p++;} /* dump until just before variable */
fprintf(f, prefix);
while ( isspace(*p) ) p++;
while ( *p!='\0' ) /* dump rest */
{
fputc(*p, f);
p++;
}
}
/*
* Convert
*
* 0, "#( RangeOp #(Minus %1:IConst %2:Var) #(Plus %3:Var %4:Var) )",
* t, &w, &x, &y, &z);
*
* to
*
* 0, "#( 6 #(5 %1:4 %2:3) #(1 %3:3 %4:3) )",
* t, &w, &x, &y, &z);
*/
char *
#ifdef __USE_PROTOS
cvt_token_str(char *prefix, char *s)
#else
cvt_token_str(prefix, s)
char *prefix, *s;
#endif
{
SymEntry *q;
char *b, *e, *p;
char tname[MaxRuleName+1];
char duh[MaxRuleName+1];
static char call[MaxAtom+1];
require(prefix!=NULL&&s!=NULL, "cvt_token_str: NULL string");
require(s[0]!='\0', "cvt_token_str: empty string");
/* printf("cvt incoming: '%s'\n", s);*/
strcpy(call, prefix);
p = &call[strlen(prefix)];
while ( *s!='"' ) *p++ = *s++; /* ignore until string start */
*p++ = *s++;
do
{
while ( !isalpha(*s) )
{
if ( *s=='"' ) { *p='\0'; goto done; }
*p++ = *s++; /* ignore until a token name */
}
*p='\0';
b = s;
while ( isalpha(*s) ) s++; /* ignore until end of token name */
e = s-1;
strncpy(tname, b, e-b+1);
tname[e-b+1] = '\0';
/* printf("looking up %s\n", tname);*/
q = (SymEntry *) hash_get(symbols, tname);
if ( q==NULL )
{
warnNoFL(eMsg1("call to ast_scan() has reference to unknown token: '%s'",tname));
}
else
{
sprintf(duh, "%d", q->token_type);
strcpy(p, duh);
p += strlen(duh);
*p='\0';
}
} while ( *s!='\0' && *s!='"' );
done:
strcat(call, s);
/* printf("cvt: result is '%s'\n", call);*/
return call;
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?