home *** CD-ROM | disk | FTP | other *** search
- /*
- LISTING 3
- */
-
- /* function module for the program 'cp'
- the cp program must be compiled with the large model */
-
- /***********************************************************
-
- cpfuncts.c - function module for the program 'cp'
-
- copyright 1987, Stewart A. Nutter
-
- written by: Stewart A. Nutter
-
- ***********************************************************/
-
-
- #define MAINMODULE 0
- #include "cp.h" /* v1.1 */
-
- /* v1.1 Global prototypes */
- int find_mod(char *buf);
- void getstats(void);
- int doprint(int n);
- void pagebreak(void);
- void leftmargin(void); /* v1.4 */
- char getnext(FILE *stream);
- void pushc(char c);
- int strcheck(char c);
- int addlist(struct Func_list *p, char *buf, int cnt);
-
- /* v1.1 local prototypes */
- static char getchars(FILE *stream);
- static void setpage(struct Mod_list *ptr);
- static void pblock(char *pre, char *fptr, char *mptr, char *sptr, int cnt);
- static int recur_chk(char *buf);
-
-
- /* getnext - get the next character from the stream */
-
- char getnext(FILE *stream)
-
- {
- register char c;
- static int qflag = 0, cflag = 0, eflag = 0;
- static int dflag = 0, aflag = 0, ncnt = 0;
- static int fp;
- int b, done;
-
- done = 1;
- do {
- if ((qflag | cflag | eflag | dflag | aflag) == 0)
- done = 1;
- c = getchars(stream);
-
- /* process escape sequence characters */
-
- if (eflag && c != 0x1a) {
- if (c >= '0' && c <= '7' && ncnt < 3)
- ncnt++;
- else {
-
- /* had less than the 3 octal digits */
-
- if (ncnt < 3 && ncnt > 0)
- pushc(c);
- ncnt = 0;
- eflag = 0;
- }
- } else if (cflag && c != 0x1a) { /* skipping a comment */
- if (firstcmt == 1) {
- if (c != '\n' && strlen(filecmt) < (width - 14)) {
- filecmt[fp] = c;
- fp++;
- filecmt[fp] = 0;
- } else {
- do { /* remove extraneous spaces and tabs */
- b = getchars(stream);
- }
- while (b == ' ' || b == '\t');
- pushc(b);
- filecmt[fp++] = ' ';
- filecmt[fp] = '\0';
- }
- }
- if (c == '*') {
- b = getchars(stream);
- if (b == '/') {
- firstcmt = 2; /* done with the comment */
- if (fp > 0)
- filecmt[fp - 1] = 0; /* terminate the line */
- cflag = 0;
- } else
- pushc(b);
- }
- } else if (qflag && c != 0x1a) { /* skipping a string */
- if (c == 0x27)
- eflag = 1;
- else if (c == '\"') {
- pushc(0x1b);
- qflag = 0;
- }
- } else if (dflag && c != 0x1a) { /* defines/includes etc. */
- if (c == '\n')
- dflag = 0;
- } else if (aflag && c != 0x1a) { /* skip a character */
- if (c == 0x27) {
- aflag = 0;
- pushc(0x1b);
- } else if (c == '\\')
- eflag = 1;
- } else {
- switch (c) {
- case '\"':
- qflag = 1;
- break;
- case 0x27:
- aflag = 1;
- break;
- case '#':
- dflag = 1;
- break;
- case '/':
- b = getchars(stream);
- if (b == '*') {
-
- /* this is the first comment of the file */
-
- if (firstcmt == 0) {
- firstcmt = 1;
- filecmt[0] = 0;
- fp = 0;
- }
- cflag = 1;
- } else {
- pushc(b);
- }
- break;
- }
- }
- if (aflag || dflag || qflag || eflag || cflag)
- done = 0;
- }
- while (!done && c != 0x1a);
- if (c == 0x1a) {
- ncnt = 0;
- aflag = 0;
- dflag = 0;
- qflag = 0;
- eflag = 0;
- cflag = 0;
- }
- return (c);
- }
-
-
- /* getchars - read inputs from the file */
-
- static char getchars(FILE *stream)
- {
- register char c;
-
- if (pp != pc)
- c = *--pp;
- else {
- c = fgetc(stream);
- if (c == (char) EOF) /* v1.1 */
- c = 0x1a;
- if (c == 0x0a) {
- pMnames->length++;
- pMnames->size++; /* count the unseen <cr> */
- }
- pMnames->size++;
- }
- return (c);
- }
-
- /* pushc - save the char. in a last in first out stack */
-
- void pushc(char c)
- {
- if ((pp - pc) < 1000)
- *pp++ = c;
- else {
- fprintf(stderr, "\nProgram syntax error:");
- fprintf(stderr, " Too many pushed characters.\n");
- exit(1);
- }
- }
-
-
- /* addlist - add the name to the list if different */
- /* and if not one of the 'c' key words */
-
- #define KEYS 5
-
- int addlist(struct Func_list *p, char *buf, int cnt)
-
- {
- int i, ret;
- static char *keywords[KEYS] =
- {
- "while",
- "if",
- "for",
- "switch",
- "return",
- };
-
- for (i = 0; i < KEYS && strcmp(buf, keywords[i]) != 0; i++);
-
- if (i < KEYS)
- return (0);
-
- for (i = 0; i < cnt && strcmp(buf, p->name); i++)
- p++;
-
- if (i == cnt) {
- ret = 1;
- if ((pFlist->name = strdup(buf)) == NULL) {
- fprintf(stderr, "Ran out of memory.\n");
- exit(1);
- }
- pFlist->used = 1;
- pFlist++; /* point to the next empty cell */
- Fqty++;
- if (Fqty > MAXFNCTS) {
- fprintf(stderr, "Too many functions.\n");
- exit(1);
- }
- } else {
- ret = 0;
- p->used++;
- }
- return (ret);
- }
-
-
- /* find_mod - return the index of the linked list for
- the indicated function. A -1 means that
- the function name was not found in the list */
-
- int find_mod(char *buf)
-
- {
- int lo, hi, mid;
- int d;
-
- lo = 0;
- hi = Mqty - 1;
- mid = (hi + lo) / 2;
-
- while (1) {
- d = strcmp(buf, pm[mid]->function);
- if (d == 0)
- break;
-
- if (lo >= hi) {
- mid = -1;
- break;
- }
- if (d < 0) {
- hi = mid - 1;
- } else {
- lo = mid + 1;
- }
- mid = (hi + lo) / 2;
- }
-
- return (mid);
- }
-
-
- /* doprint - print the function name and sub - functions */
-
- static char lib[] =
- {"(library)"};
- static char use[] =
- {"Used="};
- static char fct[] =
- {"Functs="};
-
- int doprint(int n)
- {
- int i, j, k, l, ret;
- struct Mod_list *p;
- struct Func_list *q;
-
- l = n;
- p = pm[l];
-
- /* add function to list for recursion check */
-
- rlist[depth] = p->function;
-
- pagebreak();
-
- setpage(pm[l]);
- ret = page - 1;
- pblock(bfr, p->function, (p->name)->name, fct, p->qty);
-
- depth++;
- strcat(bfr, " |");
-
- k = p->qty;
- for (j = 0, q = p->ptr; j < k; j++, q++) {
- pagebreak();
- i = find_mod(q->name);
-
- if (recur_chk(q->name)) {
- leftmargin(); /* v1.4 */
- printf("%s\n", bfr); /* v1.4 */
- if (i >= 0)
- setpage(pm[i]);
- pblock(bfr, q->name, "(recursive)", "", 0);
- line++;
- } else {
- if (i >= 0) {
- if (pm[i]->used == 1) {
-
- /* got a new function */
-
- leftmargin(); /* v1.4 */
- printf("%s\n", bfr); /* v1.4 */
- line++;
- doprint(i); /* used only once */
- } else {
-
- /* a previously defined function */
-
- leftmargin(); /* v1.4 */
- printf("%s\n", bfr); /* v1.4 */
- setpage(pm[i]);
- pblock(bfr, q->name, "(defined)",
- use, q->used);
- line++;
- }
- } else {
-
- /* a library function */
-
- leftmargin(); /* v1.4 */
- printf("%s\n", bfr); /* v1.4 */
- pblock(bfr, q->name, lib, use, q->used);
- line++;
- }
- }
- }
-
- /* remove the function from the recursion list */
-
- rlist[depth] = NULL;
- bfr[strlen(bfr) - 4] = 0;
- depth--;
- return (ret);
- }
-
-
- /* getstats - get the number of times each
- function is used */
-
- void getstats(void)
- {
- register int i;
- int j;
- register struct Func_list *p;
-
- p = Flist;
-
- for (i = 0; i < Fqty; i++) {
- j = find_mod(p->name); /* see if the name exists */
- if (j >= 0)
- pm[j]->used += p->used;
- p++;
- }
- }
-
-
- /* pblock - print a function block */
-
- static void pblock(char *pre, char *fptr, char *mptr, char *sptr, int cnt)
-
- {
- leftmargin(); /* v1.4 */
- printf("%s %s\n", pre, tline);
- leftmargin();
- printf("%s-+%-25s|\n", pre, fptr);
- leftmargin();
- printf("%s |%-12s %8s%3d |\n",
- pre, mptr, sptr, cnt);
- leftmargin();
- printf("%s %s\n", pre, tline);
- line += 4;
-
- }
-
-
- /* pagebreak - check for a page break and if so
- then print the page header */
-
- void pagebreak(void)
- {
- int i;
- static char title[] =
- {"C PRINTER - (c) 1987, 1988 rev. 1.2"};
-
- if (pl == 0 && line == 9999) {
- printf("\n\n\n\n"); /* v1.4 */
- line = 0;
- } else if (pl != 0) {
- if (line > (pl - 11)) {
- printf("%c", 0x0c); /* v1.4 */
- line = 0;
- }
- if (line == 0) {
- leftmargin(); /* v1.4 */
-
- printf("%s", title); /* v1.4 */
- for (i = strlen(title); i < width - 10; i++)
- fputc(' ', stdout); /* v1.4 */
- printf("Page:%4d\n", page); /* v1.4 */
-
- leftmargin(); /* v1.4 */
- for (i = 0; i < width; i++)
- fputc('-', stdout); /* v1.4 */
- printf("\n\n"); /* v1.4 */
- line = 3;
- page++;
- }
- }
- }
-
-
- /* recur_chk - check if the function just called
- is one being processed */
-
- int recur_chk(char *buf)
-
- {
- register char **p;
- int ret;
-
- p = rlist;
-
- while (*p != NULL && strcmp(*p, buf)) {
- p++;
- }
-
- if (*p == NULL)
- ret = 0; /* the function was not in the list */
- else
- ret = 1; /* found it */
-
- return ret;
- }
-
-
- /* setpage - put the current page number
- into the linked page list */
-
- static void setpage(struct Mod_list *ptr)
-
- {
- struct Pages *p;
-
- p = ptr->pg;
- if (p == NULL) {
- p = (struct Pages *) malloc(sizeof(struct Pages));
- if (p == NULL) {
- fprintf(stderr,
- "Ran out of memory for page # list.\n");
- exit(1);
- }
- ptr->pg = p;
- p->next = NULL;
- p->pg = page - 1;
- } else {
- while (p->next != NULL)
- p = p->next;
- p->next = (struct Pages *) malloc(sizeof(struct Pages));
- if (p->next == NULL) {
- fprintf(stderr,
- "Ran out of memory for page # list.\n");
- exit(1);
- }
- p = p->next;
- p->next = NULL;
- p->pg = page - 1;
- }
- }
-
-
- /* strcheck - check if the character is
- * in the variable name set
- */
-
- int strcheck(char c)
-
- {
- if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') ||
- c == '_' || (c >= '0' && c <= '9'))
- return (1);
- else
- return (0);
- }
-
-
- void stop(void)
- {
- printf("hello");
- }
-
-
- /* print the left margin for the printout */
-
- void leftmargin(void) /* v1.4 */
- {
- register int i;
-
- for (i = 0; i < lm; i++)
- fputc(' ', stdout); /* v1.4 */
- }
-