home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / sampcode / alde_c / lattice / cflow / cflow.c next >
Encoding:
C/C++ Source or Header  |  1988-12-27  |  9.0 KB  |  323 lines

  1.  
  2. /*
  3. **   CFLOW.C : find module call structure of c program
  4. **   refer to cflow.doc for how to use
  5. **                                       Mark Ellington
  6. **                                       05-27-84
  7. */
  8.  
  9. /*
  10. **    Modified for Lattice C.
  11. **    Changed logic in skipline() to correct problem with '#'.
  12. **    Changed logic in comout() to correct problem with '/'.
  13. **                                       Lew Paper
  14. **                                       7/21/85
  15. */
  16.  
  17. #include <stdio.h>
  18.  
  19. #define LINS 256
  20. #define TRUE 1
  21. #define FALSE 0
  22.  
  23. FILE *fptr;       /* input file pointer */ 
  24. int level;      /* keep track of level of open "{"s */
  25. char name[100]; /* module name buffer */
  26.  
  27. char ins[LINS];  /* source input line buffer */
  28. int curchar;     /* current character in input line buffer
  29.                    array subscript */    
  30.  
  31. main(argc,argv)
  32. int argc; char *argv[];
  33. {
  34.  
  35.         printf("\nCFLOW --> function declarations and calls in C source");
  36.         printf("\n by Mark Ellington"); 
  37.  
  38.         if (argc != 2) {
  39.                 printf("\nusage: cflow [infilename.ext] "); 
  40.                 exit();
  41.         }
  42.  
  43.         if ((fptr = fopen(argv[1],"r")) == NULL) {
  44.                 printf("\nCan't open %s\n",argv[1]);
  45.                 exit();
  46.         }
  47.  
  48.         printf("\nSource file: %s",argv[1]);
  49.  
  50.         modules(); 
  51.  
  52.         fclose(fptr);
  53.         exit();
  54. }
  55.  
  56.  
  57. modules()    /* find function declarations and calls */
  58. {
  59.         int j;
  60.         char c;
  61.         int incom;       /* comment flag */
  62.         int decl;        /* module declaration line flag */
  63.         char *lastlin;   /* Pointer to ins if not last line and no error */
  64.                          /* NULL if error or last line */
  65.         int quoted;      /* within " quotes */
  66.         int header;      /* within function header (before 1st '{') */
  67.  
  68.         incom = quoted  = header = FALSE;
  69.  
  70.         lastlin = NULL;
  71.         
  72.         level = 0;
  73.  
  74.         do {
  75.  
  76.                 lastlin = fgets(ins, LINS, fptr);    /* read a line of source */
  77.                 
  78.                 decl = FALSE;  /* assume nothing */
  79.                 curchar = 0;
  80.                 while (curchar < LINS) {/* read for significant characters */
  81.  
  82.                         if (skipline()) break;
  83.  
  84.                         quotes();        /* skip single quoted character */
  85.  
  86.                         incom = comment(incom);  /* true if in comment */
  87.  
  88.                         c = ins[curchar];
  89.                 
  90.                         /* read for significant characters */
  91.  
  92.                         if (!incom) {
  93.  
  94.                                 /* skip double quoted strings */
  95.                         
  96.                                 if (c == '\042') quoted = !quoted;
  97.                                 
  98.                                 if (!quoted) {
  99.                         
  100.                                     switch(c) { 
  101.  
  102.                                         case '{' :       
  103.                                                 level++;
  104.                                                 header = FALSE;
  105.                                                 break;
  106.  
  107.                                         case '}' :       
  108.                                                 level--;
  109.                                                 break;   
  110.  
  111.                                         /* "(" always follows function call */
  112.                                         /* or declaration */
  113.                         
  114.                                         case '(' :       
  115.  
  116.                                         if (!ischar(ins[curchar-1])) 
  117.                                                 break;
  118.                                         lookbak(curchar);
  119.                                         j = modname();
  120.                                         if (!j) break;
  121.                                         else decl = TRUE;
  122.                                         if (j == 2) 
  123.                                                 header = TRUE;   
  124.                                         break;
  125.  
  126.  
  127.                                         default : 
  128.                                                   break;
  129.                                     }
  130.                                 }
  131.                         }
  132.                 
  133.                         ++curchar;     /* next character */
  134.                 }
  135.                 
  136.                 /* display argument declarations */
  137.                 comout(ins);                     
  138.                 if (header && !decl) printf("%s",ins);
  139.  
  140.         } while (lastlin != NULL);    /* = NULL if last line */
  141.  
  142. }
  143.  
  144. /* skip this line ? */
  145.  
  146. skipline()
  147. {
  148. char c;
  149. int sk; /* Return value for function */
  150.  
  151.         c = ins[curchar];
  152.  
  153.         if (c == '\0') return(TRUE);     /* end of line */
  154.  
  155.         sk = FALSE;  /* No except for macro defines */
  156.         
  157.         if (c == '#') {              /* skip macro defs */
  158.                 if (curchar < 5) /* at beginning of line */
  159.                         sk = (!strcmp("define",&ins[curchar+1]));
  160.         }
  161.  
  162.         return(sk);
  163.  
  164. }
  165.  
  166.  
  167. /* skip characters quoted (for instance '}' would throw off level count */
  168.  
  169. quotes()
  170. {  
  171.         if (flowchar(ins[curchar]))          /* test critical chars only */
  172.             if (ins[curchar+1] == '\047')   /* next char single quote? */
  173.                 if (curchar+2 < LINS)         /* don't pass end of string */
  174.                         curchar = curchar + 2; /* skip past quote */
  175. }
  176.  
  177.  
  178. /* return TRUE if entering comment, FALSE if exiting */
  179.  
  180. comment(incom)
  181. int incom;
  182. {
  183.         if (ins[curchar] == '/') {
  184.                 if (ins[curchar+1] == '*') {
  185.                          if (curchar + 1 < LINS)   /* stay within string */ 
  186.                               return(TRUE);
  187.                          else return(incom);  /* unchanged */
  188.                 }
  189.                 else if (ins[curchar-1] == '*') {
  190.                         if(curchar - 1 >= 0)  /* stay within string */
  191.                                 return(FALSE);
  192.                         else return(incom);  /* unchanged */
  193.                 }
  194.                 else return(incom); /* An isolated slash, so unchanged */
  195.         }
  196.         else return(incom);  /* unchanged */
  197. }
  198.  
  199.  
  200. /* look back from position n in string.  called with n indicating '('.
  201.    determine function name  */
  202.  
  203. lookbak(n)
  204. int n;
  205. {
  206.         int i;
  207.  
  208.         while (!ischar(ins[n])) {
  209.                 if (n == 0) break;
  210.                 --n;
  211.         }
  212.  
  213.         /* find leading blank */
  214.         while (ischar(ins[n-1])) {
  215.                 if (n == 0) break;
  216.                 --n;
  217.         }
  218.  
  219.         /* save name */
  220.         /* include variable declarations if module declaration */
  221.  
  222.         i = 0;
  223.         if (level == 0) {
  224.                 while (ins[n])               /* full line if declaration */
  225.                         name[i++] = ins[n++];
  226.         }
  227.         else {
  228.                 while (ischar(ins[n]))      /* function call within function */
  229.                         name[i++] = ins[n++];
  230.         }
  231.  
  232.         name[i] = '\0';
  233.  
  234.         comout(name);    /* remove comment from name string */
  235.                 
  236. }
  237.  
  238.  
  239. /* terminate string at comment */
  240.  
  241. comout(s)
  242. char *s;
  243. {
  244. char c;  
  245.         
  246.         while(c = *s++) 
  247.                 if (c == '/')
  248.                         if (*s == '*') {
  249.                                 --s;
  250.                                 *s++ = '\n';
  251.                                 *s = '\0';
  252.                                 break;
  253.                         }
  254.  
  255. }
  256.  
  257.  
  258.  
  259. /* display module name with indentation according to { level */
  260. /* returns 0 if not module, 1 if call within module, 2 if    */
  261. /* module declaration  */
  262.  
  263. modname()
  264. {
  265.         int j;
  266.  
  267.         if (unreserved()) {              /* test if builtin like while */
  268.                 if (level == 0) {
  269.                         printf("\n\n\n");
  270.                         printf("**\n");
  271.                         comout(ins);
  272.                         printf("%s",ins);
  273.                         return(2);
  274.                 }
  275.                 else {
  276.                         printf("\n");
  277.                         for (j=0; j < level; ++j) 
  278.                                 putchar('\t');
  279.                         printf("%s()",name);
  280.                         return(1);
  281.                 }
  282.         }
  283.         return(0);
  284.         
  285. }
  286.  
  287. /* test for names that are operators not functions */
  288.  
  289. unreserved()
  290. {
  291.  
  292.         if (!strcmp(name,"return")) return(0);
  293.         else if (!strcmp(name,"if")) return(0);
  294.         else if (!strcmp(name,"while")) return(0);
  295.         else if (!strcmp(name,"for")) return(0);
  296.         else if (!strcmp(name,"switch")) return(0);
  297.  
  298.         else return(1);
  299.  
  300. }
  301.  
  302.  
  303. /* test if character is one that program tracks */
  304.  
  305. flowchar(c)
  306. char c;
  307. {
  308.         if (c == '{' || c == '}' || c == '\"') return(TRUE);
  309.         else return(FALSE);
  310.         
  311.  
  312.  
  313. /* test for character */
  314.  
  315. ischar(c)
  316. char c;
  317. {
  318.         if (isalpha(c) || isdigit(c)) return(TRUE);
  319.         else return(FALSE);
  320. }
  321.  
  322.