home *** CD-ROM | disk | FTP | other *** search
- /*
- ** CFLOW.C : find module call structure of c program
- ** refer to cflow.doc for how to use
- ** Mark Ellington
- ** 05-27-84
- */
-
- /*
- ** Modified for Lattice C.
- ** Changed logic in skipline() to correct problem with '#'.
- ** Changed logic in comout() to correct problem with '/'.
- ** Lew Paper
- ** 7/21/85
- **
- */
- /* ^ */
- /* ;-) */
- /*
- **
- ** Modified for RiscOs C.
- ** Changed logic in ischar() to correct problem with '_' in function
- ** names.
- ** Directed output to a file.
- ** Made program into a callable module.
- **
- ** Briag
- ** 26/11/92
- */
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
-
- #define LINS 256
- #ifndef TRUE
- #define TRUE 1
- #endif
- #ifndef FALSE
- #define FALSE 0
- #endif
-
-
- static FILE *fptr; /* input file pointer */
- static FILE *fileptr; /* output file pointer */
- static int level; /* keep track of level of open "{"s */
- static char name[100]; /* module name buffer */
- static char ins[LINS]; /* source input line buffer */
- static int curchar; /* current character in input line buffer
- array subscript */
-
- /* function prototypes */
-
- static void modules(void);
- static void comout(char *s);
- static void lookbak(int n);
- static int comment(int incom);
- static void quotes(void);
- static int skipline(void);
- static int ischar(char c);
- static int flowchar(char c);
- static int unreserved(void);
- static int modname(void);
-
- extern void pr(char *message);
-
-
- int cflow(int argc,char *argv[]){
-
- pr("CFLOW --> function declarations and calls in C source by Mark Ellington");
-
- if(argc != 2) {
- pr("\nusage: cflow [infilename.ext] ");
- return 0;
- }
-
- if((fptr = fopen(argv[1],"r")) == FALSE){
- pr("\nCan't open source file\n");
- return 0;
- }
-
- if ((fileptr = fopen("<flow$scrapdir>.c_flow","w")) == FALSE) {
- pr("\nCan't open scrapfile\n");
- return 0;
- }
- fprintf(fileptr,"\nSource file: %s",argv[1]);
-
- modules();
- fprintf(fileptr,"\n\n\n***\n\n");
- fclose(fptr);
- fclose(fileptr);
- return TRUE;
- }
-
-
- static void modules(void){ /* find function declarations and calls */
- int j;
- char c;
- int incom; /* comment flag */
- int decl; /* module declaration line flag */
- char *lastlin; /* Pointer to ins if not last line and no error */
- /* NULL if error or last line */
- int quoted; /* within " quotes */
- int header; /* within function header (before 1st '{') */
-
- incom = quoted = header = FALSE;
-
- lastlin = NULL;
-
- level = 0;
-
- do{
-
- lastlin = fgets(ins, LINS, fptr); /* read a line of source */
-
- decl = FALSE; /* assume nothing */
- curchar = 0;
- while (curchar < LINS) {/* read for significant characters */
-
- if (skipline()) break;
-
- quotes(); /* skip single quoted character */
-
- incom = comment(incom); /* true if in comment */
-
- c = ins[curchar];
-
- /* read for significant characters */
-
- if (!incom) {
-
- /* skip double quoted strings */
-
- if (c == '\042') quoted = !quoted;
-
- if (!quoted) {
-
- switch(c) {
-
- case '{' :
- level++;
- header = FALSE;
- break;
-
- case '}' :
- level--;
- break;
-
- /* "(" always follows function call */
- /* or declaration */
-
- case '(' :
-
- if (!ischar(ins[curchar-1]))
- break;
- lookbak(curchar);
- j = modname();
- if (!j) break;
- else decl = TRUE;
- if (j == 2)
- header = TRUE;
- break;
-
-
- default :
- break;
- }
- }
- }
-
- ++curchar; /* next character */
- }
-
- /* display argument declarations */
- comout(ins);
- if (header && !decl) fprintf(fileptr,"%s",ins);
-
- }
- while (lastlin != NULL); /* = NULL if last line */
-
- }
-
- /* skip this line ? */
-
- static int skipline(void){
- char c;
- int sk; /* Return value for function */
-
- c = ins[curchar];
-
- if (c == '\0') return(TRUE); /* end of line */
-
- sk = FALSE; /* No except for macro defines */
-
- if (c == '#') { /* skip macro defs */
- if (curchar < 5) /* at beginning of line */
- sk = (!strcmp("define",&ins[curchar+1]));
- }
-
- return(sk);
-
- }
-
-
- /* skip characters quoted (for instance '}' would throw off level count */
-
- static void quotes(void){
- if (flowchar(ins[curchar])) /* test critical chars only */
- if (ins[curchar+1] == '\047') /* next char single quote? */
- if (curchar+2 < LINS) /* don't pass end of string */
- curchar = curchar + 2; /* skip past quote */
- }
-
-
- /* return TRUE if entering comment, FALSE if exiting */
-
- static int comment(int incom){
- if (ins[curchar] == '/') {
- if (ins[curchar+1] == '*') {
- if (curchar + 1 < LINS) /* stay within string */
- return(TRUE);
- else return(incom); /* unchanged */
- }
- else if (ins[curchar-1] == '*') {
- if(curchar - 1 >= 0) /* stay within string */
- return(FALSE);
- else return(incom); /* unchanged */
- }
- else return(incom); /* An isolated slash, so unchanged */
- }
- else return(incom); /* unchanged */
- }
-
-
- /* look back from position n in string. called with n indicating '('.
- determine function name */
-
- static void lookbak(int n){
- int i;
-
- while (!ischar(ins[n])){
- if (n == 0)
- break;
- --n;
- }
-
- /* find leading blank */
- while (ischar(ins[n-1])) {
- if (n == 0)
- break;
- --n;
- }
-
- /* save name */
- /* include variable declarations if module declaration */
-
- i = 0;
- if (level == 0){
- while (ins[n]) /* full line if declaration */
- name[i++] = ins[n++];
- }
- else{
- while (ischar(ins[n])) /* function call within function */
- name[i++] = ins[n++];
- }
- name[i] = '\0';
- comout(name); /* remove comment from name string */
- }
-
-
- /* terminate string at comment */
-
- static void comout(char *s){
- char c;
-
- while(c = *s++,c)
- if (c == '/')
- if (*s == '*'){
- --s;
- *s++ = '\n';
- *s = '\0';
- break;
- }
- }
-
-
-
- /* display module name with indentation according to { level */
- /* returns 0 if not module, 1 if call within module, 2 if */
- /* module declaration */
-
- static int modname(void){
- int j;
-
- if (unreserved()) { /* test if builtin like while */
- if (level == 0) {
- fprintf(fileptr,"\n\n\n");
- fprintf(fileptr,"**\n");
- comout(ins);
- fprintf(fileptr,"%s",ins);
- return(2);
- }
- else {
- fprintf(fileptr,"\n");
- for (j=0; j < level; ++j)
- fprintf(fileptr," ");
- fprintf(fileptr,"%s()",name);
- return(1);
- }
- }
- return(0);
- }
-
- /* test for names that are operators not functions */
-
- static int unreserved(void){
-
- if (!strcmp(name,"return"))
- return(0);
- else if (!strcmp(name,"if"))
- return(0);
- else if (!strcmp(name,"while"))
- return(0);
- else if (!strcmp(name,"for"))
- return(0);
- else if (!strcmp(name,"switch"))
- return(0);
-
- else return(1);
-
- }
-
-
- /* test if character is one that program tracks */
-
- static int flowchar(char c){
- if (c == '{' || c == '}' || c == '\"') return(TRUE);
- else return(FALSE);
- }
-
-
-
- /* test for character */
-
- static int ischar(char c){
- if (isalpha(c) || isdigit(c) || c == '_') return(TRUE);
- else return(FALSE);
- }
-
-