diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/lgrind/source/lgutil.c |
Initial commit
Diffstat (limited to 'support/lgrind/source/lgutil.c')
-rw-r--r-- | support/lgrind/source/lgutil.c | 323 |
1 files changed, 323 insertions, 0 deletions
diff --git a/support/lgrind/source/lgutil.c b/support/lgrind/source/lgutil.c new file mode 100644 index 0000000000..121ba366a0 --- /dev/null +++ b/support/lgrind/source/lgutil.c @@ -0,0 +1,323 @@ +#ifndef lint +#ifdef standalone_lgutil +static char sccsid[] = "@(#)lgutil.c 3.6 (MPi) 24/3/98"; +static char rcsid[] = + "$Id: lgutil.c,v 1.7 1999/12/18 21:54:29 mike Exp $"; +#endif /* standalone_lgutil */ +#endif + +/* lgutil.c + * Utility Functions for LGrind + * This file is @#include@d from lgrind.c (likely to change) + */ + +/* Copyright %%\copyright%% 1998,1999 Michael Piefel + * + * This file is something like GPL, though LGrind is BSD. + * I don't want to become a lawyer. + */ + +/* + * Internal_Help() --- show help + */ + +void Internal_Help() +{ + printf("lgrind -- general purpose \"pretty printer\" for use with LaTeX.\n"); + printf("usage: lgrind [options] <name> ...\n"); + printf("-e process embedded text in a LaTeX file\n"); + printf("-i format source code for inclusion in a LaTeX document.\n"); + printf("-n don't boldface keywords.\n"); + printf("-a don't treat @, etc. specially in LaTeX.\n"); + printf("-c don't treat @, etc. specially in comments.\n"); + printf("- take input from standard input.\n"); + printf("-o <file> write to file (instead of standard output).\n"); + printf("-t <width> change tab width (default 8).\n"); + printf("-h <header> specifies text in header (default: none).\n"); + printf("-v <varfile> take variable substitutions from file.\n"); + printf("-d <deffile> use a different language definitions file, default:\ +\n \"%s\"\n", defsfile); + printf("-l<language> choose the language to use.\n"); + printf("-s show a list of currently known languages.\n\n"); + printf("If neither -e nor -i are specified, a complete LaTeX-file is produced.\n\n"); + printf("Direct comments and questions to lgrind@gmx.net\n"); +} + + +typedef struct langRec { + char *name; + char *alternatives; + struct langRec *next; } langRec; + +void AddToLList(char *line, langRec **into, int *chainLength) +{ + char *token, *item, *alts; + + if (*line!='#' && *line!='\n') + { + item=strdup(line); + if ((token=strtok(item, "|:\\\n")) == NULL) return; + (**into).next=(langRec*)malloc(sizeof(langRec)); + *into=(**into).next; + (**into).name=strdup(token); + (*chainLength)++; + if ((token=strtok(NULL, "|:\\\n")) == NULL) + { + (**into).alternatives="\0"; + return; + } + (**into).alternatives=strdup(token); + while ((token=strtok(NULL, "|:\\\n")) != NULL) + { + alts=(**into).alternatives; + (**into).alternatives=(char*)malloc( + strlen((**into).alternatives)+strlen(token)+1); + /* This is extremely poor style and dangerous. I leave memory + * allocated here because after invocation of this help facility + * the program will stop anyway. In this context it is safe. */ + strcpy((**into).alternatives, alts); + strcat((**into).alternatives, ", "); + strcat((**into).alternatives, token); + } + } +} + +void Internal_Help_Language_List() +{ + FILE *tf; + int check, i, llch; + langRec *lch, *rch, *currlch; + /* @lch2@ was originally "language chain", but I guess + it's "left" as well */ + + printf("When specifying a language case is insignificant. You can use the\n"); + printf("name of the language, or, where available, one of the synonyms in\n"); + printf("parantheses. Thus the following are legal and mark Tcl/Tk, Pascal\n"); + printf("and Fortran input, respectively:\n"); + printf(" lgrind -ltcl/tk ...\n"); + printf(" lgrind -lpaSCAL ...\n"); + printf(" lgrind -lf ...\n"); + printf("The list of languages currently available in your lgrindef file:\n"); + tf = fopen(defsfile, "rt"); + if (tf == NULL) + { + fprintf(stderr, "cannot find lgrindef file `%s'\n", defsfile); + return; + } + + llch=0; + currlch=lch=(langRec*)malloc(sizeof(langRec)); + (*currlch).name=""; + *config='\n'; + do { + check=0; + if (*config=='\n' || config[strlen(config)-2]!='\\') + check=1; + if (fgets(config, BUFFERSIZE, tf)==NULL) break; + if (check!=0) AddToLList(config, &currlch, &llch); + } while (strcmp((*currlch).name, "EndOfLanguageDefinitions")!=0); + rch=lch; + for (check=0; check<llch/2; check++) + rch=(*rch).next; + for (check=0; check<llch/2; check++) + { + lch=(*lch).next; + rch=(*rch).next; + printf(" %s", (*lch).name); + if (*((*lch).alternatives)) printf(" (%s)", (*lch).alternatives); + else printf(" "); + for (i=strlen((*lch).name)+strlen((*lch).alternatives); + i<30; i++) putchar(' '); + if (rch!=currlch) + { + printf("%s", (*rch).name); + if (*((*rch).alternatives)) printf(" (%s)", (*rch).alternatives); + } + printf("\n"); + } +} + + +/* + * Redefine Chartab from lgrindef file + */ +void parsechartab(void) +{ + char *i=buf, *j=chartab, c; + int charnum=0; + + while (*i++!=':') {} + while ((c=*i++)!='\0') { + if (c==':') continue; + charnum=(c>='0' && c<='9') ? (int)c-48 : tolower(c)-87; + charnum=charnum << 4; c=*i++; + charnum+=(c>='0' && c<='9') ? (int)c-48 : tolower(c)-87; + i++; + + printtab[charnum]=j; + while (*i!=':') + if (*i=='\\') { + switch (*++i) { + case ':': *j++=':'; break; + case '\\': *j++='\\'; break; + }; i++; + } else *j++=*i++; + *j++='\0'; + } + +} + +/* + * Parses the %|lgrindef|% file for a preamble + */ +void parsepreamble(char *destination) +{ + char *i=buf, *j=destination; + + while (*i++!=':') ; + while (*i) { + if (*i=='\\') { + switch (*++i) { + case 'n': *j++='\n'; break; + case 't': *j++='\t'; break; + case 'f': *j++='\f'; break; + case '\\': *j++='\\'; break; + default: fprintf(stderr, "Bad preamble entry: incorrect '\\'\n"); + }; i++; + } else *j++=*i++; + *j='\0'; + } +} + +/* + * Sets the default preambles + */ +void setpreambles(void) +{ + strcpy(preamble, +"\\documentclass[a4paper]{article}\n\ +\\usepackage[procnames,noindent]{lgrind}\n\ +\\usepackage{fancyhdr}\n\ +\\pagestyle{fancy}\n\ +\\begin{document}\n"); + strcpy(postamble, "\\end{document}\n"); + strcpy(preamble2, +"\\lhead[\\fancyplain{}{\\bf\\thepage}]\ +{\\fancyplain{}{\\bf \f}}\n\ +\\rhead[\\fancyplain{}{\\bf \f}]\ +{\\fancyplain{}{\\bf\\thepage}}\n\ +\\cfoot{}\n"); + strcpy(config, ""); +} + +/* + * prints a preamble, substituting %|\f|% with the current + * file's name (sorry, no more form feeds) + */ +void printpreamble(char *string) +{ + char *i; + while (*string) + if (*string=='\f') + { i=fname-1; + while (*(++i)) outchar(*i); + string++; + } + else putchar(*string++); +} + +/* + * try to create an executable file to store the new lgrindef-file + */ +void writeDefsfileInExe(char *progname, char *newdefsfile) +{ + char *buffer, *i; + FILE *progfile, *newfile; + long pos=0; + int ret; + + buffer = (char*) malloc(30000); + /* So small? Why in chunks? Well, it's gotta run on machines with + only limited access to their resources (you know, the IBM PC) */ + progfile=fopen(progname, "rb"); + newfile=fopen("lgrind.new", "wb"); + + if (buffer && progfile && newfile) + { + fread(buffer, 1, 200, progfile); + do { + ret=fread(buffer+200, 1, 29500, progfile); + for(i=buffer; i<buffer+ret; i++) + if (*i=='D' && + *(i+1)=='e' && + *(i+2)=='F' && + *(i+3)=='s' && + *(i+4)=='B' && + *(i+5)=='u' && + *(i+6)=='F' && + strcmp(defsfile, i+7)==0) { + memcpy(i+7, newdefsfile, strlen(newdefsfile)+1); + } + fwrite(buffer, 1, ret==29500 ? ret : ret+200, newfile); + memcpy(buffer, buffer+29500, 200); + pos+=29500; + } while (ret==29500); + fclose(progfile); + fclose(newfile); + } + free(buffer); +} + +/* + * Reads a variable substitution table from a file + */ +varsubst *parsevartab(char* fname) +{ + FILE *f = fopen(fname, "rt"); + char linebuf[201], *cp; + varsubst *varsubsts=NULL, *substitem, *substlistpos; + + if (f==NULL) return; + while (!feof(f)) + { + fscanf(f, "%200[^\n]", linebuf); + fscanf(f, "\n"); + cp=strchr(linebuf, '='); + if (cp==NULL) continue; + *cp++='\0'; + substitem=(varsubst*)malloc(sizeof(varsubst)); + substitem->var=strdup(linebuf); + substitem->subst=strdup(cp); + substitem->next=NULL; + if (varsubsts==NULL) + { + varsubsts=substitem; + substlistpos=substitem; + } else { + substlistpos->next=substitem; + substlistpos=substitem; + } + } + fclose(f); + return varsubsts; +} + +/* + * Replaces a variable by alternate representation + */ +int substvarname(char **ident, int i) +{ + varsubst *substlistpos = varsubstlist; + + while (substlistpos!=NULL) + { + if (re_strncmp(*ident, substlistpos->var, i)==0) + { + *ident+=i; /* skip i characters in input */ + printf("%s", substlistpos->subst); + return 0; + } + substlistpos=substlistpos->next; + } + return i; +} |