📄 wrappergen.c
字号:
#include <stdio.h>#include <string.h>#include <sys/types.h>#include <sys/stat.h>#include "wrappergen.h"#ifndef DEBUG#define DEBUG 0#endif#define RETURN_VAR_NAME "returnVal"void WriteWrappers( outf, wrapperFiles, nwrapperFiles, fn_list, n_fn )FILE *outf;char **wrapperFiles;fn_def *fn_list;int n_fn, nwrapperFiles;{ int fn_num, argNum, fileNum, i; fn_def fn; wrapperinfo winfo; ListCreate( winfo.wrapperDefs, wrapperdef, 10 ); for (fn_num=0; fn_num<n_fn; fn_num++) ListCreate( fn_list[fn_num].wrapperdefs, int, 2 );#if DEBUG for (i=0; i<nwrapperFiles; i++) { printf( "wrapper file: %s\n", wrapperFiles[i] ); } for (i=0; i<n_fn; i++) { printf( ":%s: :%s:\n", fn_list[i].returnType, fn_list[i].name ); for (argNum=0; argNum<fn_list[i].nargs; argNum++) { printf( "Arg[%d] :%s: :%s: :%s:\n", argNum, fn_list[i].argTypePrefix[argNum], fn_list[i].argNames[argNum], fn_list[i].argTypeSuffix[argNum] ); } putchar( '\n' ); }#endif for (fileNum=0; fileNum<nwrapperFiles; fileNum++) { ReadWrapperFile( outf, wrapperFiles[fileNum], fileNum, fn_list, n_fn, &winfo ); /* read all wrapper definitions and write external info */ } WriteFunctionCalls( outf, fn_list, n_fn, &winfo ); return;}void ReadWrapperFile( outf, fileName, filenum, fn_list, n_fn, winfo )FILE *outf;char *fileName;fn_def *fn_list;int n_fn;wrapperinfo *winfo;{ FILE *inf; fileinfo finfo; rpcinfo rinfo; replacement rpc; char *tmpStr; if (!(inf = fopen( fileName, "r" ))) { fprintf( stderr, "Cannot open wrapper definition file \"%s\".\n", fileName ); return; } finfo.str = ReadFileIntoString( inf ); finfo.name = fileName; finfo.filenum = filenum; finfo.lineno = 1; rinfo.fn_list = fn_list; rinfo.n_fn = n_fn; ListCreate( rinfo.rpc, replacement, 5 ); /* create replacement for the file number */ rpc.from = "fileno"; rpc.to = (char *)malloc( 10 ); sprintf( rpc.to, "%d", filenum ); ListAddItem( rinfo.rpc, replacement, rpc ); ProcessString( outf, &finfo, &rinfo, winfo );}void ProcessString( outf, finfo, rinfo, winfo )FILE *outf;fileinfo *finfo;rpcinfo *rinfo;wrapperinfo *winfo;{ int escBodyLen, i, startingLine; char **escBodyList, *escBody, *ptr, *preceding;#if DEBUG fprintf( stderr, "Process String %s in file %s (%d) on line %d\n", finfo->str, finfo->name, finfo->filenum, finfo->lineno );#endif while (ReadUntilEscape( finfo, &preceding, &escBodyList, &escBodyLen, &escBody, &startingLine )) {#if DEBUG>1 printf( "Escape on line %d. body is:\n", startingLine ); for (i=0; i<escBodyLen; i++) { printf( " %s\n", escBodyList[i] ); } printf( "Or:%s:\n", escBody );#endif fprintf( outf, "%s", preceding ); ProcessEscape( outf, finfo, rinfo, winfo, escBodyList, escBodyLen, escBody, startingLine ); free( escBodyList ); free( escBody ); free( preceding ); preceding = 0; } if (preceding) fprintf( outf, "%s", preceding ); return;}static int fn_num = 0;void ProcessEscape( outf, finfo, rinfo, winfo, escBodyList, escBodyLen, escBody, startingLine )FILE *outf;fileinfo *finfo;rpcinfo *rinfo;wrapperinfo *winfo;int escBodyLen, startingLine;char **escBodyList, *escBody;{ char c, repNo, format[20]; char *body, *varName, *space; xpandList fnNames; int strRead; /* if the excape sequence ("{{...") does not start with an identifier or the identifier is not recognized, assume it's not prof_wrapper stuff, and spit it out */ /* if null body, just copy it out and return */ if (!escBodyLen) { fprintf( outf, "%s", escBody ); return; }#if DEBUG>1 fprintf( stderr, "command is '%s' on line %d\n", escBodyList[0], startingLine );#endif /* check for simple replacement */ for (repNo=0; repNo<ListSize( rinfo->rpc, replacement ); repNo++) { if (!strcmp( escBodyList[0], ListItem( rinfo->rpc, replacement, repNo).from )) { /* successful replacement */#if DEBUG fprintf( stderr, "replacing with '%s'\n", ListItem( rinfo->rpc, replacement, repNo).to );#endif fprintf( outf, "%s", ListItem( rinfo->rpc, replacement, repNo).to ); return; } } if (!strcmp( escBodyList[0], "foreachfn" )) { if (escBodyLen>2) { /* if a variable name was found (syntax check) */ if (ReadUntilMatch( finfo, "foreachfn", "endforeachfn", &body, startingLine )) DoForEach( outf, finfo, rinfo, escBodyList, escBodyLen, escBody, startingLine, body ); } else { /* if valid syntax */ fprintf( stderr, "(file %s, line %d) foreachfn needs a function name \replacement string and at least one function name.\n", finfo->name, startingLine ); } } else if (!strcmp( escBodyList[0], "forallfn" )) { if (escBodyLen>1) { /* if a variable name was found (syntax check) */ if (ReadUntilMatch( finfo, "forallfn", "endforallfn", &body, startingLine )) DoForAll( outf, finfo, rinfo, escBodyList, escBodyLen, escBody, startingLine, body ); } else { /* if valid syntax */ fprintf( stderr, "(file %s, line %d) forallfn needs a function name \replacement string.\n", finfo->name, startingLine ); } /* if winfo is NULL, ProcessString has been called within a function wrapper, and thus a function wrapper should not be encountered */ } else if (!strcmp( escBodyList[0], "fnall" )) { if (!winfo) { fprintf( stderr, "Illegal nested function definition in file %s, line %d.\n", finfo->name, startingLine ); } else if (escBodyLen>1) { /* syntax check */ if (ReadUntilMatch( finfo, "fnall", "endfnall", &body, startingLine )) { DoFnAll( finfo, rinfo, winfo, escBodyList, escBodyLen, body, startingLine ); } } else { /* if valid syntax */ fprintf( stderr, "(file %s, line %d) fnall needs a function name \replacement string.\n", finfo->name, startingLine ); } } else if (!strcmp( escBodyList[0], "fn" )) { if (!winfo) { fprintf( stderr, "Illegal nested function definition in file %s, line %d.\n", finfo->name, startingLine ); } else if (escBodyLen>2) { if (ReadUntilMatch( finfo, "fn", "endfn", &body, startingLine )) { DoFn( finfo, rinfo, winfo, escBodyList, escBodyLen, body, startingLine ); } } else { fprintf( stderr, "(file %s, line %d) fn needs a function name \replacement string and at least one function name.\n", finfo->name, startingLine ); } } else if (!strcmp( escBodyList[0], "fn_num" )) { fprintf( outf, "%d", fn_num++ ); } else { fprintf( stderr, "Unrecognized escape '%s' in file %s, line %d.\n", escBody, finfo->name, startingLine ); fprintf( outf, "%s", escBody ); }}int ReadUntilEscape( finfo, preceding, escBodyList, escBodyLen, escBodyLiteral, startingLine )fileinfo *finfo;char ***escBodyList, **escBodyLiteral, **preceding;int *escBodyLen, *startingLine;{ /* anything read before reaching an escape sequence is returned in 'preceding' */ xpandList escBodyChars, escBodyIdx, escBodyLit; char *escBegin, *escEnd; char c; int escapeFound, tmpInt; /* first job, read until {{ is found */#if DEBUG>1 fprintf( stderr, "Reading until escape at line %d\n", finfo->lineno );#endif escBegin = strstr( finfo->str, "{{" ); /* {{}} escape not found */ if (!escBegin) { finfo->lineno += CountNewlines( finfo->str, finfo->str+strlen(finfo->str) ); *preceding = STRDUP( finfo->str ); } else { *startingLine = finfo->lineno += CountNewlines( finfo->str, escBegin ); *preceding = (char *)malloc( escBegin - finfo->str + 1 ); strncpy( *preceding, finfo->str, escBegin - finfo->str ); (*preceding)[escBegin-finfo->str] = '\0'; escEnd = strstr( escBegin+2, "}}" ); /* }} not found */ if (!escEnd) { finfo->lineno += CountNewlines( escBegin, escBegin+strlen( escBegin ) ); fprintf( stderr, "No matching '}}' for '{{' in file %s, line %d.\n", finfo->name, *startingLine ); } else { /* count the lines in the body */ finfo->lineno += CountNewlines( escBegin, escEnd ); /* make copy of the body */ *escBodyLiteral = (char *)malloc( escEnd+2 - escBegin + 1 ); strncpy( *escBodyLiteral, escBegin, escEnd+2 - escBegin ); (*escBodyLiteral)[escEnd+2 - escBegin] = '\0'; /* break up the string into words, inserting \0 here and there */ c = *escEnd; *escEnd = '\0'; ListizeString( escBegin+2, escBodyList, escBodyLen ); *escEnd = c; finfo->str = escEnd+2; return 1; } } return 0;}int CountNewlines( ptr, end )char *ptr, *end;{ int n; n = 0; while (ptr<end) { if (*ptr == '\n') n++; ptr++; } return n;}/* chop a string up into a list of whitespace separated elements */void ListizeString( str, list, len )char *str, ***list;int *len;{ char *ptr, *copy; int i; xpandList strList; /* create list of strings */ ListCreate( strList, char *, 5 ); /* make a copy of the string */ copy = STRDUP( str ); /* break the copy up into whitespace delimited strings */ ptr = strtok( copy, " \n\t" ); while (ptr) { ListAddItem( strList, char *, ptr ); ptr = strtok( (char *)0, " \n\t" ); } ListClose( strList, char *, *list, *len );#if DEBUG>1 fprintf( stderr,"broke %s up into:\n", str ); for (i=0; i<*len; i++) fprintf( stderr, " %s\n", (*list)[i] );#endif return;} /* returns 1 if found match */int ReadUntilMatch( finfo, start, end, escbody, initialLine )fileinfo *finfo;int initialLine;char *start, *end, **escbody;{ char **bodyList, *bodyLit, *preceding; int stackLevel, i, bodyLen, reachedEnd, startingLine; xpandList body; stackLevel = 1; ListCreate( body, char, 100 ); reachedEnd = 0;#if DEBUG>1 fprintf( stderr, "ReadUntilMatch looking for %s to match %s\n", end, start );#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -