#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] ...\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 write to file (instead of standard output).\n"); printf("-t change tab width (default 8).\n"); printf("-h
specifies text in header (default: none).\n"); printf("-v take variable substitutions from file.\n"); printf("-d use a different language definitions file, default:\ \n \"%s\"\n", defsfile); printf("-l 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='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; ivar=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; }