home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / forut062.zip / ForUtil-0.62 / fflow / fflow.c next >
C/C++ Source or Header  |  1997-01-23  |  57KB  |  2,239 lines

  1. /* A lexical scanner generated by flex */
  2.  
  3. /* Scanner skeleton version:
  4.  * $Header: /home/daffy/u0/vern/flex/RCS/flex.skl,v 2.85 95/04/24 10:48:47 vern Exp $
  5.  */
  6.  
  7. #define FLEX_SCANNER
  8. #define YY_FLEX_MAJOR_VERSION 2
  9. #define YY_FLEX_MINOR_VERSION 5
  10.  
  11. #include <stdio.h>
  12.  
  13.  
  14. /* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
  15. #ifdef c_plusplus
  16. #ifndef __cplusplus
  17. #define __cplusplus
  18. #endif
  19. #endif
  20.  
  21.  
  22. #ifdef __cplusplus
  23.  
  24. #include <stdlib.h>
  25. #include <unistd.h>
  26.  
  27. /* Use prototypes in function declarations. */
  28. #define YY_USE_PROTOS
  29.  
  30. /* The "const" storage-class-modifier is valid. */
  31. #define YY_USE_CONST
  32.  
  33. #else    /* ! __cplusplus */
  34.  
  35. #if __STDC__
  36.  
  37. #define YY_USE_PROTOS
  38. #define YY_USE_CONST
  39.  
  40. #endif    /* __STDC__ */
  41. #endif    /* ! __cplusplus */
  42.  
  43. #ifdef __TURBOC__
  44.  #pragma warn -rch
  45.  #pragma warn -use
  46. #include <io.h>
  47. #include <stdlib.h>
  48. #define YY_USE_CONST
  49. #define YY_USE_PROTOS
  50. #endif
  51.  
  52. #ifdef YY_USE_CONST
  53. #define yyconst const
  54. #else
  55. #define yyconst
  56. #endif
  57.  
  58.  
  59. #ifdef YY_USE_PROTOS
  60. #define YY_PROTO(proto) proto
  61. #else
  62. #define YY_PROTO(proto) ()
  63. #endif
  64.  
  65. /* Returned upon end-of-file. */
  66. #define YY_NULL 0
  67.  
  68. /* Promotes a possibly negative, possibly signed char to an unsigned
  69.  * integer for use as an array index.  If the signed char is negative,
  70.  * we want to instead treat it as an 8-bit unsigned char, hence the
  71.  * double cast.
  72.  */
  73. #define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
  74.  
  75. /* Enter a start condition.  This macro really ought to take a parameter,
  76.  * but we do it the disgusting crufty way forced on us by the ()-less
  77.  * definition of BEGIN.
  78.  */
  79. #define BEGIN yy_start = 1 + 2 *
  80.  
  81. /* Translate the current start state into a value that can be later handed
  82.  * to BEGIN to return to the state.  The YYSTATE alias is for lex
  83.  * compatibility.
  84.  */
  85. #define YY_START ((yy_start - 1) / 2)
  86. #define YYSTATE YY_START
  87.  
  88. /* Action number for EOF rule of a given start state. */
  89. #define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
  90.  
  91. /* Special action meaning "start processing a new file". */
  92. #define YY_NEW_FILE yyrestart( yyin )
  93.  
  94. #define YY_END_OF_BUFFER_CHAR 0
  95.  
  96. /* Size of default input buffer. */
  97. #define YY_BUF_SIZE 16384
  98.  
  99. typedef struct yy_buffer_state *YY_BUFFER_STATE;
  100.  
  101. extern int yyleng;
  102. extern FILE *yyin, *yyout;
  103.  
  104. #define EOB_ACT_CONTINUE_SCAN 0
  105. #define EOB_ACT_END_OF_FILE 1
  106. #define EOB_ACT_LAST_MATCH 2
  107.  
  108. /* The funky do-while in the following #define is used to turn the definition
  109.  * int a single C statement (which needs a semi-colon terminator).  This
  110.  * avoids problems with code like:
  111.  *
  112.  *     if ( condition_holds )
  113.  *        yyless( 5 );
  114.  *    else
  115.  *        do_something_else();
  116.  *
  117.  * Prior to using the do-while the compiler would get upset at the
  118.  * "else" because it interpreted the "if" statement as being all
  119.  * done when it reached the ';' after the yyless() call.
  120.  */
  121.  
  122. /* Return all but the first 'n' matched characters back to the input stream. */
  123.  
  124. #define yyless(n) \
  125.     do \
  126.         { \
  127.         /* Undo effects of setting up yytext. */ \
  128.         *yy_cp = yy_hold_char; \
  129.         yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
  130.         YY_DO_BEFORE_ACTION; /* set up yytext again */ \
  131.         } \
  132.     while ( 0 )
  133.  
  134. #define unput(c) yyunput( c, yytext_ptr )
  135.  
  136. /* The following is because we cannot portably get our hands on size_t
  137.  * (without autoconf's help, which isn't available because we want
  138.  * flex-generated scanners to compile on their own).
  139.  */
  140. typedef unsigned int yy_size_t;
  141.  
  142.  
  143. struct yy_buffer_state
  144.     {
  145.     FILE *yy_input_file;
  146.  
  147.     char *yy_ch_buf;        /* input buffer */
  148.     char *yy_buf_pos;        /* current position in input buffer */
  149.  
  150.     /* Size of input buffer in bytes, not including room for EOB
  151.      * characters.
  152.      */
  153.     yy_size_t yy_buf_size;
  154.  
  155.     /* Number of characters read into yy_ch_buf, not including EOB
  156.      * characters.
  157.      */
  158.     int yy_n_chars;
  159.  
  160.     /* Whether we "own" the buffer - i.e., we know we created it,
  161.      * and can realloc() it to grow it, and should free() it to
  162.      * delete it.
  163.      */
  164.     int yy_is_our_buffer;
  165.  
  166.     /* Whether this is an "interactive" input source; if so, and
  167.      * if we're using stdio for input, then we want to use getc()
  168.      * instead of fread(), to make sure we stop fetching input after
  169.      * each newline.
  170.      */
  171.     int yy_is_interactive;
  172.  
  173.     /* Whether we're considered to be at the beginning of a line.
  174.      * If so, '^' rules will be active on the next match, otherwise
  175.      * not.
  176.      */
  177.     int yy_at_bol;
  178.  
  179.     /* Whether to try to fill the input buffer when we reach the
  180.      * end of it.
  181.      */
  182.     int yy_fill_buffer;
  183.  
  184.     int yy_buffer_status;
  185. #define YY_BUFFER_NEW 0
  186. #define YY_BUFFER_NORMAL 1
  187.     /* When an EOF's been seen but there's still some text to process
  188.      * then we mark the buffer as YY_EOF_PENDING, to indicate that we
  189.      * shouldn't try reading from the input source any more.  We might
  190.      * still have a bunch of tokens to match, though, because of
  191.      * possible backing-up.
  192.      *
  193.      * When we actually see the EOF, we change the status to "new"
  194.      * (via yyrestart()), so that the user can continue scanning by
  195.      * just pointing yyin at a new input file.
  196.      */
  197. #define YY_BUFFER_EOF_PENDING 2
  198.     };
  199.  
  200. static YY_BUFFER_STATE yy_current_buffer = 0;
  201.  
  202. /* We provide macros for accessing buffer states in case in the
  203.  * future we want to put the buffer states in a more general
  204.  * "scanner state".
  205.  */
  206. #define YY_CURRENT_BUFFER yy_current_buffer
  207.  
  208.  
  209. /* yy_hold_char holds the character lost when yytext is formed. */
  210. static char yy_hold_char;
  211.  
  212. static int yy_n_chars;        /* number of characters read into yy_ch_buf */
  213.  
  214.  
  215. int yyleng;
  216.  
  217. /* Points to current character in buffer. */
  218. static char *yy_c_buf_p = (char *) 0;
  219. static int yy_init = 1;        /* whether we need to initialize */
  220. static int yy_start = 0;    /* start state number */
  221.  
  222. /* Flag which is used to allow yywrap()'s to do buffer switches
  223.  * instead of setting up a fresh yyin.  A bit of a hack ...
  224.  */
  225. static int yy_did_buffer_switch_on_eof;
  226.  
  227. void yyrestart YY_PROTO(( FILE *input_file ));
  228.  
  229. void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
  230. void yy_load_buffer_state YY_PROTO(( void ));
  231. YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
  232. void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
  233. void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
  234. void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
  235. #define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
  236.  
  237. YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
  238. YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *str ));
  239. YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
  240.  
  241. static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
  242. static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
  243. static void yy_flex_free YY_PROTO(( void * ));
  244.  
  245. #define yy_new_buffer yy_create_buffer
  246.  
  247. #define yy_set_interactive(is_interactive) \
  248.     { \
  249.     if ( ! yy_current_buffer ) \
  250.         yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
  251.     yy_current_buffer->yy_is_interactive = is_interactive; \
  252.     }
  253.  
  254. #define yy_set_bol(at_bol) \
  255.     { \
  256.     if ( ! yy_current_buffer ) \
  257.         yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
  258.     yy_current_buffer->yy_at_bol = at_bol; \
  259.     }
  260.  
  261. #define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
  262.  
  263.  
  264. #define YY_USES_REJECT
  265. typedef unsigned char YY_CHAR;
  266. FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
  267. typedef int yy_state_type;
  268. extern int yylineno;
  269. int yylineno = 1;
  270. extern char *yytext;
  271. #define yytext_ptr yytext
  272.  
  273. static yy_state_type yy_get_previous_state YY_PROTO(( void ));
  274. static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
  275. static int yy_get_next_buffer YY_PROTO(( void ));
  276. static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
  277.  
  278. /* Done after the current pattern has been matched and before the
  279.  * corresponding action - sets up yytext.
  280.  */
  281. #define YY_DO_BEFORE_ACTION \
  282.     yytext_ptr = yy_bp; \
  283.     yyleng = (int) (yy_cp - yy_bp); \
  284.     yy_hold_char = *yy_cp; \
  285.     *yy_cp = '\0'; \
  286.     yy_c_buf_p = yy_cp;
  287.  
  288. #define YY_NUM_RULES 9
  289. #define YY_END_OF_BUFFER 10
  290. static yyconst short int yy_acclist[40] =
  291.     {   0,
  292.         6,    6,   10,    8,    9,    7,    9,    8,    9,    8,
  293.         9,    1,    8,    9,    9,    9,    6,    9,    1,    1,
  294.         6,    1,    1,    1,    1,    5,    1,    5,    5,    1,
  295.         5,    5,    5,    2,    2,    3,    3,    4,    4
  296.     } ;
  297.  
  298. static yyconst short int yy_accept[77] =
  299.     {   0,
  300.         1,    1,    1,    2,    3,    4,    6,    8,   10,   12,
  301.        15,   16,   17,   19,   19,   19,   20,   21,   21,   22,
  302.        22,   22,   22,   23,   24,   24,   24,   25,   25,   25,
  303.        26,   27,   27,   29,   30,   30,   30,   30,   30,   30,
  304.        30,   30,   32,   32,   32,   32,   32,   32,   32,   32,
  305.        32,   33,   33,   33,   33,   34,   34,   34,   34,   34,
  306.        34,   34,   34,   34,   34,   34,   35,   36,   36,   37,
  307.        38,   38,   38,   39,   40,   40
  308.     } ;
  309.  
  310. static yyconst int yy_ec[256] =
  311.     {   0,
  312.         1,    1,    1,    1,    1,    1,    1,    1,    2,    3,
  313.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  314.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  315.         1,    4,    1,    1,    1,    1,    1,    1,    5,    5,
  316.         6,    7,    1,    1,    1,    1,    1,    8,    8,    8,
  317.         8,    8,    8,    8,    8,    8,    8,    1,    1,    1,
  318.         1,    1,    1,    1,   11,   12,   13,    8,   14,   15,
  319.        16,    8,   17,    8,    8,   18,   19,   20,   21,   22,
  320.         8,   23,   24,   25,   26,    8,    8,    8,    8,    8,
  321.         1,    1,    1,    1,   10,    1,   11,   12,   13,    8,
  322.  
  323.        14,   15,   16,    8,   17,    8,    8,   18,   19,   20,
  324.        21,   22,    8,   23,   24,   25,   26,    8,    8,    8,
  325.         8,    8,    1,    1,    1,    1,    1,    1,    1,    1,
  326.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  327.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  328.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  329.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  330.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  331.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  332.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  333.  
  334.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  335.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  336.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  337.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  338.         1,    1,    1,    1,    1,    1,    1,    1,    1,    1,
  339.         1,    1,    1,    1,    1
  340.     } ;
  341.  
  342. static yyconst int yy_meta[27] =
  343.     {   0,
  344.         1,    2,    3,    4,    5,    5,    2,    2,    2,    1,
  345.         2,    2,    2,    2,    2,    2,    2,    2,    2,    2,
  346.         2,    2,    2,    2,    2,    2
  347.     } ;
  348.  
  349. static yyconst short int yy_base[81] =
  350.     {   0,
  351.         0,    4,   17,   26,  127,    0,    8,  229,   11,   12,
  352.        35,  229,   44,   36,   37,    0,   50,   63,   72,   53,
  353.       115,   54,   58,  109,   91,   73,   76,   74,   74,   73,
  354.        64,   86,   55,   39,  109,    0,   32,   78,   80,   46,
  355.        81,   21,   82,   83,  100,  102,  110,  103,  121,  117,
  356.       137,  128,  127,  133,  142,  132,  149,  143,  153,  157,
  357.       160,  163,  169,  164,  178,  229,  175,  184,  229,  185,
  358.       187,  190,  229,  193,  229,  208,  213,  218,  223,  224
  359.     } ;
  360.  
  361. static yyconst short int yy_def[81] =
  362.     {   0,
  363.        76,   76,   77,   77,   75,   75,   75,   75,   75,   78,
  364.        79,   75,   79,   75,   75,   78,   78,   79,   79,   75,
  365.        75,   75,   78,   78,   75,   75,   78,   75,   75,   78,
  366.        75,   80,   78,   75,   80,   35,   80,   80,   80,   80,
  367.        80,   78,   80,   80,   80,   80,   80,   80,   80,   80,
  368.        80,   80,   80,   80,   80,   80,   80,   80,   80,   80,
  369.        80,   80,   80,   80,   80,   75,   80,   80,   75,   80,
  370.        80,   80,   75,   80,    0,   75,   75,   75,   75,   75
  371.     } ;
  372.  
  373. static yyconst short int yy_nxt[256] =
  374.     {   0,
  375.        75,   14,    7,   14,    8,    9,    7,    9,    8,   14,
  376.        10,   14,   15,   17,   15,   17,   10,   11,   11,   12,
  377.        12,   12,   12,   11,   42,   11,   11,   11,   12,   12,
  378.        12,   12,   11,   75,   11,   18,   18,   20,   22,   20,
  379.        22,   18,   34,   18,   18,   18,   39,   75,   21,   21,
  380.        18,   23,   18,   23,   20,   26,   20,   26,   42,   23,
  381.        39,   23,   24,   18,   18,   21,   21,   34,   45,   18,
  382.        24,   18,   18,   18,   29,   32,   29,   32,   18,   75,
  383.        18,   75,   75,   75,   75,   21,   21,   35,   43,   36,
  384.        33,   31,   39,   30,   39,   39,   39,   39,   38,   47,
  385.  
  386.        39,   75,   48,   75,   75,   44,   46,   40,   28,   41,
  387.        35,   75,   36,   50,   39,   52,   39,   39,   75,   27,
  388.        49,   38,   75,   39,   39,   25,   75,   51,   75,   75,
  389.        40,   39,   41,   75,   75,   39,   53,   75,   75,   54,
  390.        55,   39,   39,   75,   75,   55,   39,   39,   59,   57,
  391.        75,   39,   56,   58,   75,   75,   39,   39,   75,   60,
  392.        75,   75,   75,   39,   75,   75,   75,   39,   61,   75,
  393.        66,   39,   67,   62,   39,   63,   75,   39,   39,   69,
  394.        68,   70,   65,   39,   64,   75,   75,   75,   75,   39,
  395.        75,   73,   39,   74,   75,   75,   75,   75,   39,   39,
  396.  
  397.        72,   39,   75,   71,   39,   75,   75,   39,    6,    6,
  398.         6,    6,    6,   13,   13,   13,   13,   13,   16,   16,
  399.        75,   16,   16,   19,   19,   37,   75,   37,    5,   75,
  400.        75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
  401.        75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
  402.        75,   75,   75,   75,   75
  403.     } ;
  404.  
  405. static yyconst short int yy_chk[256] =
  406.     {   0,
  407.         0,    6,    1,    6,    1,    2,    2,    2,    2,    7,
  408.         2,    7,    9,   10,    9,   10,    2,    3,    3,    3,
  409.         3,    3,    3,    3,   42,    3,    4,    4,    4,    4,
  410.         4,    4,    4,   37,    4,   11,   11,   14,   15,   14,
  411.        15,   11,   34,   11,   13,   13,   37,   40,   14,   15,
  412.        13,   17,   13,   17,   20,   22,   20,   22,   33,   23,
  413.        40,   23,   17,   18,   18,   20,   22,   31,   40,   18,
  414.        23,   18,   19,   19,   26,   29,   26,   29,   19,   38,
  415.        19,   39,   41,   43,   44,   26,   29,   32,   38,   32,
  416.        30,   28,   38,   27,   39,   41,   43,   44,   32,   43,
  417.  
  418.        32,   45,   44,   46,   48,   39,   41,   32,   25,   32,
  419.        35,   47,   35,   46,   45,   48,   46,   48,   50,   24,
  420.        45,   35,   49,   35,   47,   21,    5,   47,   53,   52,
  421.        35,   50,   35,   56,   54,   49,   49,    0,   51,   50,
  422.        51,   53,   52,   55,   58,   55,   56,   54,   56,   53,
  423.        57,   51,   52,   54,   59,    0,   55,   58,   60,   57,
  424.         0,   61,    0,   57,   62,   64,    0,   59,   58,    0,
  425.        63,   60,   63,   59,   61,   60,   67,   62,   64,   65,
  426.        64,   65,   62,   63,   61,   68,   70,    0,   71,   67,
  427.         0,   72,   65,   72,   74,    0,    0,    0,   68,   70,
  428.  
  429.        71,   71,    0,   68,   72,    0,    0,   74,   76,   76,
  430.        76,   76,   76,   77,   77,   77,   77,   77,   78,   78,
  431.         0,   78,   78,   79,   79,   80,    0,   80,   75,   75,
  432.        75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
  433.        75,   75,   75,   75,   75,   75,   75,   75,   75,   75,
  434.        75,   75,   75,   75,   75
  435.     } ;
  436.  
  437. static yy_state_type yy_state_buf[YY_BUF_SIZE + 2], *yy_state_ptr;
  438. static char *yy_full_match;
  439. static int yy_lp;
  440. #define REJECT \
  441. { \
  442. *yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \
  443. yy_cp = yy_full_match; /* restore poss. backed-over text */ \
  444. ++yy_lp; \
  445. goto find_rule; \
  446. }
  447. #define yymore() yymore_used_but_not_detected
  448. #define YY_MORE_ADJ 0
  449. char *yytext;
  450. #line 1 "fflow.l"
  451. #define INITIAL 0
  452. #line 2 "fflow.l"
  453. #ifndef lint
  454. static char rcsId[]="$Source: /usr/local/rcs/ForUtil/fflow/RCS/fflow.l,v $";
  455. #endif
  456. /*****
  457. * fflow.l : lexical analyzer for Fortran Source files
  458. *
  459. * This file Version    $Revision: 1.9 $
  460. *
  461. * Creation date:    Mon Feb  5 02:26:23 GMT+0100 1996
  462. * Last modification:     $Date: 1996/08/28 17:45:21 $
  463. * By:            $Author: koen $
  464. * Current State:    $State: Exp $
  465. *
  466. * Author:        koen
  467. * (C)Copyright 1995-1996 Ripley Software Development
  468. * All Rights Reserved
  469. *
  470. * This program has one undocumented switch for debugging purposes:
  471. * -m for memory information under msdos
  472. *****/
  473. /*****
  474. * ChangeLog
  475. * $Log: fflow.l,v $
  476. * Revision 1.9  1996/08/28 17:45:21  koen
  477. * Added print_version_id; added the -llevel option and appropriate changes.
  478. *
  479. * Revision 1.8  1996/08/27 19:16:01  koen
  480. * Heavy changes: updated scanner rules; optimized memory allocation routines; 
  481. * moved a number of routines to libflow.c
  482. *
  483. * Revision 1.7  1996/08/07 21:14:24  koen
  484. * Updated for MSDOS and added warning messages when -I, -E or -x is exceeded
  485. *
  486. * Revision 1.6  1996/08/02 14:50:29  koen
  487. * Added the -n and -n- options. Moved all system dependencies to lib/sysdeps.h
  488. *
  489. * Revision 1.5  1996/07/30 02:00:57  koen
  490. * Changed output stuff.
  491. * Added missing things to command line options.
  492. * Added version information.
  493. * Changed the ignore_this_file routine to use strstr.
  494. * Fixed a bug which left files open when a file was to be ignored.
  495. *
  496. * Revision 1.4  1996/07/16 09:05:44  koen
  497. * cmd_line related bug fixed.
  498. * Changed all fprintf(stderr,...) to printf(...) where output on stdout is
  499. * expected
  500. *
  501. * Revision 1.3  1996/05/06 00:34:40  koen
  502. * Adapted for MSDOS.
  503. *
  504. * Revision 1.2  1996/02/05 01:45:29  koen
  505. * Added the inline define for systems without __inline__ (noticably HP-UX).
  506. *
  507. * Revision 1.1  1996/02/05 01:28:07  koen
  508. * Initial revision
  509. *
  510. *****/ 
  511. #ifdef HAVE_CONFIG_H
  512. #include "autoconf.h"
  513. #endif
  514.  
  515. #include <stdio.h> 
  516. #include <string.h>
  517. #include <errno.h>
  518.  
  519. #include "forutil.h"
  520. #include "memmacros.h"
  521. #include "version.h"
  522. #include "libflow.h"
  523.  
  524. /**** Private Variables ****/
  525. static int skip_unknowns, ignore_empty_funcs;
  526. static int start_at_program, ignore_unused_funcs, start_at_named_function;
  527. static int complete_graph, never_invoked, no_graph; 
  528. static int output_line, verbose, cutoff_depth;
  529. static char *sep_char, *base_function_name, *outfile;
  530. static char cmd_line[MAXPATHLEN];
  531. static FILE *output_file;
  532.  
  533. static char *usage = {"Usage: %s [-cefhinpqtuv] [-Eext] [-Idir] [-ddepth] [-ofile] [-llevel] [-sname] [-xname] [files]\n\n"
  534. " Generates a (partial) flowgraph of a collection of fortran files\n\n"
  535. " Options\n"
  536. "\t-c: generate a complete flowgraph for each subroutine or function\n"
  537. "\t-e: ignore functions without calls\n"
  538. "\t-f: print precise location of filenames. Otherwise print name\n"
  539. "\t    of file only.\n"
  540. "\t-h, --help: print this help\n"
  541. "\t-i: ignore unknown function calls\n"
  542. "\t-n: tell what subroutines are never invoked. Use -n- to only check for\n"
  543. "\t    this and you do not want a flowgraph\n"
  544. "\t-p: start flowgraph at PROGRAM definition\n"
  545. "\t-q: be really quiet (usefull if called from a script)\n"
  546. "\t-t: use tabs instead of | as depth indicator\n"
  547. "\t-u: ignore unused subroutines\n"
  548. "\t-v: be verbose\n"
  549. "\t--version: display version number\n"
  550. "\t-Eext: extensions to use for retrieving files. Multiple -E allowed.\n"
  551. "\t-Idir: get files from directory dir. Multiple -I allowed\n"
  552. "\t-ddepth: maximum recursion depth, default is %i\n"
  553. "\t-llevel: Generate a flowgraph up to level deep\n"
  554. "\t-ofile: file to write flowgraph to, default is stdout\n"
  555. "\t-sname: use <name> as the topmost function\n"
  556. "\t-xname.f: exclude file. Multiple -x allowed\n\n"
  557. " Currently, fflow only looks at CALL, so although FUNCTION is found, these \n"
  558. " do not show up in the flowgraph\n\n"
  559. "(C)Copyright 1995-1996 by Ripley Software Development\n"};
  560.  
  561. /**** Private Function prototypes ****/
  562. static void print_flow_graph(FILE *file, flowInfo *list);
  563. static void print_flow_calls(FILE *file, flowInfo *calls, int depth);
  564. static int set_global_option(char *arg);
  565.  
  566. #define FNAME 1
  567.  
  568. #line 569 "lex.yy.c"
  569.  
  570. /* Macros after this point can all be overridden by user definitions in
  571.  * section 1.
  572.  */
  573.  
  574. #ifndef YY_SKIP_YYWRAP
  575. #ifdef __cplusplus
  576. extern "C" int yywrap YY_PROTO(( void ));
  577. #else
  578. extern int yywrap YY_PROTO(( void ));
  579. #endif
  580. #endif
  581.  
  582. #ifndef YY_NO_UNPUT
  583. static void yyunput YY_PROTO(( int c, char *buf_ptr ));
  584. #endif
  585.  
  586. #ifndef yytext_ptr
  587. static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
  588. #endif
  589.  
  590. #ifndef YY_NO_INPUT
  591. #ifdef __cplusplus
  592. static int yyinput YY_PROTO(( void ));
  593. #else
  594. static int input YY_PROTO(( void ));
  595. #endif
  596. #endif
  597.  
  598. #if YY_STACK_USED
  599. static int yy_start_stack_ptr = 0;
  600. static int yy_start_stack_depth = 0;
  601. static int *yy_start_stack = 0;
  602. #ifndef YY_NO_PUSH_STATE
  603. static void yy_push_state YY_PROTO(( int new_state ));
  604. #endif
  605. #ifndef YY_NO_POP_STATE
  606. static void yy_pop_state YY_PROTO(( void ));
  607. #endif
  608. #ifndef YY_NO_TOP_STATE
  609. static int yy_top_state YY_PROTO(( void ));
  610. #endif
  611.  
  612. #else
  613. #define YY_NO_PUSH_STATE 1
  614. #define YY_NO_POP_STATE 1
  615. #define YY_NO_TOP_STATE 1
  616. #endif
  617.  
  618. #ifdef YY_MALLOC_DECL
  619. YY_MALLOC_DECL
  620. #else
  621. #if __STDC__
  622. #ifndef __cplusplus
  623. #include <stdlib.h>
  624. #endif
  625. #else
  626. /* Just try to get by without declaring the routines.  This will fail
  627.  * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
  628.  * or sizeof(void*) != sizeof(int).
  629.  */
  630. #endif
  631. #endif
  632.  
  633. /* Amount of stuff to slurp up with each read. */
  634. #ifndef YY_READ_BUF_SIZE
  635. #define YY_READ_BUF_SIZE 8192
  636. #endif
  637.  
  638. /* Copy whatever the last rule matched to the standard output. */
  639.  
  640. #ifndef ECHO
  641. /* This used to be an fputs(), but since the string might contain NUL's,
  642.  * we now use fwrite().
  643.  */
  644. #define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
  645. #endif
  646.  
  647. /* Gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
  648.  * is returned in "result".
  649.  */
  650. #ifndef YY_INPUT
  651. #define YY_INPUT(buf,result,max_size) \
  652.     if ( yy_current_buffer->yy_is_interactive ) \
  653.         { \
  654.         int c = '*', n; \
  655.         for ( n = 0; n < max_size && \
  656.                  (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
  657.             buf[n] = (char) c; \
  658.         if ( c == '\n' ) \
  659.             buf[n++] = (char) c; \
  660.         if ( c == EOF && ferror( yyin ) ) \
  661.             YY_FATAL_ERROR( "input in flex scanner failed" ); \
  662.         result = n; \
  663.         } \
  664.     else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
  665.           && ferror( yyin ) ) \
  666.         YY_FATAL_ERROR( "input in flex scanner failed" );
  667. #endif
  668.  
  669. /* No semi-colon after return; correct usage is to write "yyterminate();" -
  670.  * we don't want an extra ';' after the "return" because that will cause
  671.  * some compilers to complain about unreachable statements.
  672.  */
  673. #ifndef yyterminate
  674. #define yyterminate() return YY_NULL
  675. #endif
  676.  
  677. /* Number of entries by which start-condition stack grows. */
  678. #ifndef YY_START_STACK_INCR
  679. #define YY_START_STACK_INCR 25
  680. #endif
  681.  
  682. /* Report a fatal error. */
  683. #ifndef YY_FATAL_ERROR
  684. #define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
  685. #endif
  686.  
  687. /* Default declaration of generated scanner - a define so the user can
  688.  * easily add parameters.
  689.  */
  690. #ifndef YY_DECL
  691. #define YY_DECL int yylex YY_PROTO(( void ))
  692. #endif
  693.  
  694. /* Code executed at the beginning of each rule, after yytext and yyleng
  695.  * have been set up.
  696.  */
  697. #ifndef YY_USER_ACTION
  698. #define YY_USER_ACTION
  699. #endif
  700.  
  701. /* Code executed at the end of each rule. */
  702. #ifndef YY_BREAK
  703. #define YY_BREAK break;
  704. #endif
  705.  
  706. #define YY_RULE_SETUP \
  707.     if ( yyleng > 0 ) \
  708.         yy_current_buffer->yy_at_bol = \
  709.                 (yytext[yyleng - 1] == '\n'); \
  710.     YY_USER_ACTION
  711.  
  712. YY_DECL
  713.     {
  714.     register yy_state_type yy_current_state;
  715.     register char *yy_cp, *yy_bp;
  716.     register int yy_act;
  717.  
  718. #line 127 "fflow.l"
  719.  
  720. #line 721 "lex.yy.c"
  721.  
  722.     if ( yy_init )
  723.         {
  724.         yy_init = 0;
  725.  
  726. #ifdef YY_USER_INIT
  727.         YY_USER_INIT;
  728. #endif
  729.  
  730.         if ( ! yy_start )
  731.             yy_start = 1;    /* first start state */
  732.  
  733.         if ( ! yyin )
  734.             yyin = stdin;
  735.  
  736.         if ( ! yyout )
  737.             yyout = stdout;
  738.  
  739.         if ( ! yy_current_buffer )
  740.             yy_current_buffer =
  741.                 yy_create_buffer( yyin, YY_BUF_SIZE );
  742.  
  743.         yy_load_buffer_state();
  744.         }
  745.  
  746.     while ( 1 )        /* loops until end-of-file is reached */
  747.         {
  748.         yy_cp = yy_c_buf_p;
  749.  
  750.         /* Support of yytext. */
  751.         *yy_cp = yy_hold_char;
  752.  
  753.         /* yy_bp points to the position in yy_ch_buf of the start of
  754.          * the current run.
  755.          */
  756.         yy_bp = yy_cp;
  757.  
  758.         yy_current_state = yy_start;
  759.         yy_current_state += YY_AT_BOL();
  760.         yy_state_ptr = yy_state_buf;
  761.         *yy_state_ptr++ = yy_current_state;
  762. yy_match:
  763.         do
  764.             {
  765.             register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
  766.             while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
  767.                 {
  768.                 yy_current_state = (int) yy_def[yy_current_state];
  769.                 if ( yy_current_state >= 76 )
  770.                     yy_c = yy_meta[(unsigned int) yy_c];
  771.                 }
  772.             yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
  773.             *yy_state_ptr++ = yy_current_state;
  774.             ++yy_cp;
  775.             }
  776.         while ( yy_base[yy_current_state] != 229 );
  777.  
  778. yy_find_action:
  779.         yy_current_state = *--yy_state_ptr;
  780.         yy_lp = yy_accept[yy_current_state];
  781. find_rule: /* we branch to this label when backing up */
  782.         for ( ; ; ) /* until we find what rule we matched */
  783.             {
  784.             if ( yy_lp && yy_lp < yy_accept[yy_current_state + 1] )
  785.                 {
  786.                 yy_act = yy_acclist[yy_lp];
  787.                     {
  788.                     yy_full_match = yy_cp;
  789.                     break;
  790.                     }
  791.                 }
  792.             --yy_cp;
  793.             yy_current_state = *--yy_state_ptr;
  794.             yy_lp = yy_accept[yy_current_state];
  795.             }
  796.  
  797.         YY_DO_BEFORE_ACTION;
  798.  
  799.         if ( yy_act != YY_END_OF_BUFFER )
  800.             {
  801.             int yyl;
  802.             for ( yyl = 0; yyl < yyleng; ++yyl )
  803.                 if ( yytext[yyl] == '\n' )
  804.                     ++yylineno;
  805.             }
  806.  
  807. do_action:    /* This label is used only to access EOF actions. */
  808.  
  809.  
  810.         switch ( yy_act )
  811.     { /* beginning of action switch */
  812. case 1:
  813. YY_RULE_SETUP
  814. #line 128 "fflow.l"
  815. ; /* eat up comments entirely */  
  816.     YY_BREAK
  817. case 2:
  818. YY_RULE_SETUP
  819. #line 129 "fflow.l"
  820. {
  821.             action = ADDFUNC; 
  822.             Type   = PROGRAM; 
  823.             BEGIN FNAME;
  824.         }  
  825.     YY_BREAK
  826. case 3:
  827. YY_RULE_SETUP
  828. #line 134 "fflow.l"
  829. {
  830.             numfunc++;
  831.             action = ADDFUNC; 
  832.             Type   = FUNCTION; 
  833.             BEGIN FNAME;
  834.         }  
  835.     YY_BREAK
  836. case 4:
  837. YY_RULE_SETUP
  838. #line 140 "fflow.l"
  839. {
  840.             numroutine++;
  841.             action = ADDFUNC; 
  842.             Type   = SUBROUTINE; 
  843.             BEGIN FNAME;
  844.         } 
  845.     YY_BREAK
  846. case 5:
  847. YY_RULE_SETUP
  848. #line 146 "fflow.l"
  849. {
  850.             numcall++;
  851.             action = ADDCALL; 
  852.             Type   = UNKNOWN;
  853.             BEGIN FNAME;
  854.         }
  855.     YY_BREAK
  856. case 6:
  857. YY_RULE_SETUP
  858. #line 152 "fflow.l"
  859. {
  860.         /*
  861.         * Depending on the action taken,
  862.         * add a new function to the flowgraph list or
  863.         * add an entry for a call made in the current 
  864.         * function
  865.         */
  866.             if(action == ADDFUNC)
  867.                 add_new_func(yytext, yylineno, curr_path, 
  868.                     curr_file, 0);
  869.             else
  870.                 add_new_call(yytext, yylineno, 0);
  871.             BEGIN 0;
  872.         }
  873.     YY_BREAK
  874. case 7:
  875. YY_RULE_SETUP
  876. #line 166 "fflow.l"
  877. BEGIN 0;
  878.     YY_BREAK
  879. case 8:
  880. YY_RULE_SETUP
  881. #line 167 "fflow.l"
  882. ; /* do nothing  for all other remaining chars */ 
  883.     YY_BREAK
  884. case 9:
  885. YY_RULE_SETUP
  886. #line 168 "fflow.l"
  887. ECHO;
  888.     YY_BREAK
  889. #line 890 "lex.yy.c"
  890.             case YY_STATE_EOF(INITIAL):
  891.             case YY_STATE_EOF(FNAME):
  892.                 yyterminate();
  893.  
  894.     case YY_END_OF_BUFFER:
  895.         {
  896.         /* Amount of text matched not including the EOB char. */
  897.         int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
  898.  
  899.         /* Undo the effects of YY_DO_BEFORE_ACTION. */
  900.         *yy_cp = yy_hold_char;
  901.  
  902.         if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
  903.             {
  904.             /* We're scanning a new file or input source.  It's
  905.              * possible that this happened because the user
  906.              * just pointed yyin at a new source and called
  907.              * yylex().  If so, then we have to assure
  908.              * consistency between yy_current_buffer and our
  909.              * globals.  Here is the right place to do so, because
  910.              * this is the first action (other than possibly a
  911.              * back-up) that will match for the new input source.
  912.              */
  913.             yy_n_chars = yy_current_buffer->yy_n_chars;
  914.             yy_current_buffer->yy_input_file = yyin;
  915.             yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
  916.             }
  917.  
  918.         /* Note that here we test for yy_c_buf_p "<=" to the position
  919.          * of the first EOB in the buffer, since yy_c_buf_p will
  920.          * already have been incremented past the NUL character
  921.          * (since all states make transitions on EOB to the
  922.          * end-of-buffer state).  Contrast this with the test
  923.          * in input().
  924.          */
  925.         if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
  926.             { /* This was really a NUL. */
  927.             yy_state_type yy_next_state;
  928.  
  929.             yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
  930.  
  931.             yy_current_state = yy_get_previous_state();
  932.  
  933.             /* Okay, we're now positioned to make the NUL
  934.              * transition.  We couldn't have
  935.              * yy_get_previous_state() go ahead and do it
  936.              * for us because it doesn't know how to deal
  937.              * with the possibility of jamming (and we don't
  938.              * want to build jamming into it because then it
  939.              * will run more slowly).
  940.              */
  941.  
  942.             yy_next_state = yy_try_NUL_trans( yy_current_state );
  943.  
  944.             yy_bp = yytext_ptr + YY_MORE_ADJ;
  945.  
  946.             if ( yy_next_state )
  947.                 {
  948.                 /* Consume the NUL. */
  949.                 yy_cp = ++yy_c_buf_p;
  950.                 yy_current_state = yy_next_state;
  951.                 goto yy_match;
  952.                 }
  953.  
  954.             else
  955.                 {
  956.                 yy_cp = yy_c_buf_p;
  957.                 goto yy_find_action;
  958.                 }
  959.             }
  960.  
  961.         else switch ( yy_get_next_buffer() )
  962.             {
  963.             case EOB_ACT_END_OF_FILE:
  964.                 {
  965.                 yy_did_buffer_switch_on_eof = 0;
  966.  
  967.                 if ( yywrap() )
  968.                     {
  969.                     /* Note: because we've taken care in
  970.                      * yy_get_next_buffer() to have set up
  971.                      * yytext, we can now set up
  972.                      * yy_c_buf_p so that if some total
  973.                      * hoser (like flex itself) wants to
  974.                      * call the scanner after we return the
  975.                      * YY_NULL, it'll still work - another
  976.                      * YY_NULL will get returned.
  977.                      */
  978.                     yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
  979.  
  980.                     yy_act = YY_STATE_EOF(YY_START);
  981.                     goto do_action;
  982.                     }
  983.  
  984.                 else
  985.                     {
  986.                     if ( ! yy_did_buffer_switch_on_eof )
  987.                         YY_NEW_FILE;
  988.                     }
  989.                 break;
  990.                 }
  991.  
  992.             case EOB_ACT_CONTINUE_SCAN:
  993.                 yy_c_buf_p =
  994.                     yytext_ptr + yy_amount_of_matched_text;
  995.  
  996.                 yy_current_state = yy_get_previous_state();
  997.  
  998.                 yy_cp = yy_c_buf_p;
  999.                 yy_bp = yytext_ptr + YY_MORE_ADJ;
  1000.                 goto yy_match;
  1001.  
  1002.             case EOB_ACT_LAST_MATCH:
  1003.                 yy_c_buf_p =
  1004.                 &yy_current_buffer->yy_ch_buf[yy_n_chars];
  1005.  
  1006.                 yy_current_state = yy_get_previous_state();
  1007.  
  1008.                 yy_cp = yy_c_buf_p;
  1009.                 yy_bp = yytext_ptr + YY_MORE_ADJ;
  1010.                 goto yy_find_action;
  1011.             }
  1012.         break;
  1013.         }
  1014.  
  1015.     default:
  1016.         YY_FATAL_ERROR(
  1017.             "fatal flex scanner internal error--no action found" );
  1018.     } /* end of action switch */
  1019.         } /* end of scanning one token */
  1020.     } /* end of yylex */
  1021.  
  1022.  
  1023. /* yy_get_next_buffer - try to read in a new buffer
  1024.  *
  1025.  * Returns a code representing an action:
  1026.  *    EOB_ACT_LAST_MATCH -
  1027.  *    EOB_ACT_CONTINUE_SCAN - continue scanning from current position
  1028.  *    EOB_ACT_END_OF_FILE - end of file
  1029.  */
  1030.  
  1031. static int yy_get_next_buffer()
  1032.     {
  1033.     register char *dest = yy_current_buffer->yy_ch_buf;
  1034.     register char *source = yytext_ptr;
  1035.     register int number_to_move, i;
  1036.     int ret_val;
  1037.  
  1038.     if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
  1039.         YY_FATAL_ERROR(
  1040.         "fatal flex scanner internal error--end of buffer missed" );
  1041.  
  1042.     if ( yy_current_buffer->yy_fill_buffer == 0 )
  1043.         { /* Don't try to fill the buffer, so this is an EOF. */
  1044.         if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
  1045.             {
  1046.             /* We matched a singled characater, the EOB, so
  1047.              * treat this as a final EOF.
  1048.              */
  1049.             return EOB_ACT_END_OF_FILE;
  1050.             }
  1051.  
  1052.         else
  1053.             {
  1054.             /* We matched some text prior to the EOB, first
  1055.              * process it.
  1056.              */
  1057.             return EOB_ACT_LAST_MATCH;
  1058.             }
  1059.         }
  1060.  
  1061.     /* Try to read more data. */
  1062.  
  1063.     /* First move last chars to start of buffer. */
  1064.     number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
  1065.  
  1066.     for ( i = 0; i < number_to_move; ++i )
  1067.         *(dest++) = *(source++);
  1068.  
  1069.     if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
  1070.         /* don't do the read, it's not guaranteed to return an EOF,
  1071.          * just force an EOF
  1072.          */
  1073.         yy_n_chars = 0;
  1074.  
  1075.     else
  1076.         {
  1077.         int num_to_read =
  1078.             yy_current_buffer->yy_buf_size - number_to_move - 1;
  1079.  
  1080.         while ( num_to_read <= 0 )
  1081.             { /* Not enough room in the buffer - grow it. */
  1082. #ifdef YY_USES_REJECT
  1083.             YY_FATAL_ERROR(
  1084. "input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
  1085. #else
  1086.  
  1087.             /* just a shorter name for the current buffer */
  1088.             YY_BUFFER_STATE b = yy_current_buffer;
  1089.  
  1090.             int yy_c_buf_p_offset =
  1091.                 (int) (yy_c_buf_p - b->yy_ch_buf);
  1092.  
  1093.             if ( b->yy_is_our_buffer )
  1094.                 {
  1095.                 int new_size = b->yy_buf_size * 2;
  1096.  
  1097.                 if ( new_size <= 0 )
  1098.                     b->yy_buf_size += b->yy_buf_size / 8;
  1099.                 else
  1100.                     b->yy_buf_size *= 2;
  1101.  
  1102.                 b->yy_ch_buf = (char *)
  1103.                     /* Include room in for 2 EOB chars. */
  1104.                     yy_flex_realloc( (void *) b->yy_ch_buf,
  1105.                              b->yy_buf_size + 2 );
  1106.                 }
  1107.             else
  1108.                 /* Can't grow it, we don't own it. */
  1109.                 b->yy_ch_buf = 0;
  1110.  
  1111.             if ( ! b->yy_ch_buf )
  1112.                 YY_FATAL_ERROR(
  1113.                 "fatal error - scanner input buffer overflow" );
  1114.  
  1115.             yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
  1116.  
  1117.             num_to_read = yy_current_buffer->yy_buf_size -
  1118.                         number_to_move - 1;
  1119. #endif
  1120.             }
  1121.  
  1122.         if ( num_to_read > YY_READ_BUF_SIZE )
  1123.             num_to_read = YY_READ_BUF_SIZE;
  1124.  
  1125.         /* Read in more data. */
  1126.         YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
  1127.             yy_n_chars, num_to_read );
  1128.         }
  1129.  
  1130.     if ( yy_n_chars == 0 )
  1131.         {
  1132.         if ( number_to_move == YY_MORE_ADJ )
  1133.             {
  1134.             ret_val = EOB_ACT_END_OF_FILE;
  1135.             yyrestart( yyin );
  1136.             }
  1137.  
  1138.         else
  1139.             {
  1140.             ret_val = EOB_ACT_LAST_MATCH;
  1141.             yy_current_buffer->yy_buffer_status =
  1142.                 YY_BUFFER_EOF_PENDING;
  1143.             }
  1144.         }
  1145.  
  1146.     else
  1147.         ret_val = EOB_ACT_CONTINUE_SCAN;
  1148.  
  1149.     yy_n_chars += number_to_move;
  1150.     yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
  1151.     yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
  1152.  
  1153.     yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
  1154.  
  1155.     return ret_val;
  1156.     }
  1157.  
  1158.  
  1159. /* yy_get_previous_state - get the state just before the EOB char was reached */
  1160.  
  1161. static yy_state_type yy_get_previous_state()
  1162.     {
  1163.     register yy_state_type yy_current_state;
  1164.     register char *yy_cp;
  1165.  
  1166.     yy_current_state = yy_start;
  1167.     yy_current_state += YY_AT_BOL();
  1168.     yy_state_ptr = yy_state_buf;
  1169.     *yy_state_ptr++ = yy_current_state;
  1170.  
  1171.     for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
  1172.         {
  1173.         register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
  1174.         while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
  1175.             {
  1176.             yy_current_state = (int) yy_def[yy_current_state];
  1177.             if ( yy_current_state >= 76 )
  1178.                 yy_c = yy_meta[(unsigned int) yy_c];
  1179.             }
  1180.         yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
  1181.         *yy_state_ptr++ = yy_current_state;
  1182.         }
  1183.  
  1184.     return yy_current_state;
  1185.     }
  1186.  
  1187.  
  1188. /* yy_try_NUL_trans - try to make a transition on the NUL character
  1189.  *
  1190.  * synopsis
  1191.  *    next_state = yy_try_NUL_trans( current_state );
  1192.  */
  1193.  
  1194. #ifdef YY_USE_PROTOS
  1195. static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
  1196. #else
  1197. static yy_state_type yy_try_NUL_trans( yy_current_state )
  1198. yy_state_type yy_current_state;
  1199. #endif
  1200.     {
  1201.     register int yy_is_jam;
  1202.  
  1203.     register YY_CHAR yy_c = 1;
  1204.     while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
  1205.         {
  1206.         yy_current_state = (int) yy_def[yy_current_state];
  1207.         if ( yy_current_state >= 76 )
  1208.             yy_c = yy_meta[(unsigned int) yy_c];
  1209.         }
  1210.     yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
  1211.     *yy_state_ptr++ = yy_current_state;
  1212.     yy_is_jam = (yy_current_state == 75);
  1213.  
  1214.     return yy_is_jam ? 0 : yy_current_state;
  1215.     }
  1216.  
  1217.  
  1218. #ifndef YY_NO_UNPUT
  1219. #ifdef YY_USE_PROTOS
  1220. static void yyunput( int c, register char *yy_bp )
  1221. #else
  1222. static void yyunput( c, yy_bp )
  1223. int c;
  1224. register char *yy_bp;
  1225. #endif
  1226.     {
  1227.     register char *yy_cp = yy_c_buf_p;
  1228.  
  1229.     /* undo effects of setting up yytext */
  1230.     *yy_cp = yy_hold_char;
  1231.  
  1232.     if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
  1233.         { /* need to shift things up to make room */
  1234.         /* +2 for EOB chars. */
  1235.         register int number_to_move = yy_n_chars + 2;
  1236.         register char *dest = &yy_current_buffer->yy_ch_buf[
  1237.                     yy_current_buffer->yy_buf_size + 2];
  1238.         register char *source =
  1239.                 &yy_current_buffer->yy_ch_buf[number_to_move];
  1240.  
  1241.         while ( source > yy_current_buffer->yy_ch_buf )
  1242.             *--dest = *--source;
  1243.  
  1244.         yy_cp += (int) (dest - source);
  1245.         yy_bp += (int) (dest - source);
  1246.         yy_n_chars = yy_current_buffer->yy_buf_size;
  1247.  
  1248.         if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
  1249.             YY_FATAL_ERROR( "flex scanner push-back overflow" );
  1250.         }
  1251.  
  1252.     *--yy_cp = (char) c;
  1253.  
  1254.     if ( c == '\n' )
  1255.         --yylineno;
  1256.  
  1257.     yytext_ptr = yy_bp;
  1258.     yy_hold_char = *yy_cp;
  1259.     yy_c_buf_p = yy_cp;
  1260.     }
  1261. #endif    /* ifndef YY_NO_UNPUT */
  1262.  
  1263.  
  1264. #ifdef __cplusplus
  1265. static int yyinput()
  1266. #else
  1267. static int input()
  1268. #endif
  1269.     {
  1270.     int c;
  1271.  
  1272.     *yy_c_buf_p = yy_hold_char;
  1273.  
  1274.     if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
  1275.         {
  1276.         /* yy_c_buf_p now points to the character we want to return.
  1277.          * If this occurs *before* the EOB characters, then it's a
  1278.          * valid NUL; if not, then we've hit the end of the buffer.
  1279.          */
  1280.         if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
  1281.             /* This was really a NUL. */
  1282.             *yy_c_buf_p = '\0';
  1283.  
  1284.         else
  1285.             { /* need more input */
  1286.             yytext_ptr = yy_c_buf_p;
  1287.             ++yy_c_buf_p;
  1288.  
  1289.             switch ( yy_get_next_buffer() )
  1290.                 {
  1291.                 case EOB_ACT_END_OF_FILE:
  1292.                     {
  1293.                     if ( yywrap() )
  1294.                         {
  1295.                         yy_c_buf_p =
  1296.                         yytext_ptr + YY_MORE_ADJ;
  1297.                         return EOF;
  1298.                         }
  1299.  
  1300.                     if ( ! yy_did_buffer_switch_on_eof )
  1301.                         YY_NEW_FILE;
  1302. #ifdef __cplusplus
  1303.                     return yyinput();
  1304. #else
  1305.                     return input();
  1306. #endif
  1307.                     }
  1308.  
  1309.                 case EOB_ACT_CONTINUE_SCAN:
  1310.                     yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
  1311.                     break;
  1312.  
  1313.                 case EOB_ACT_LAST_MATCH:
  1314. #ifdef __cplusplus
  1315.                     YY_FATAL_ERROR(
  1316.                     "unexpected last match in yyinput()" );
  1317. #else
  1318.                     YY_FATAL_ERROR(
  1319.                     "unexpected last match in input()" );
  1320. #endif
  1321.                 }
  1322.             }
  1323.         }
  1324.  
  1325.     c = *(unsigned char *) yy_c_buf_p;    /* cast for 8-bit char's */
  1326.     *yy_c_buf_p = '\0';    /* preserve yytext */
  1327.     yy_hold_char = *++yy_c_buf_p;
  1328.  
  1329.     yy_current_buffer->yy_at_bol = (c == '\n');
  1330.     if ( yy_current_buffer->yy_at_bol )
  1331.         ++yylineno;
  1332.  
  1333.     return c;
  1334.     }
  1335.  
  1336.  
  1337. #ifdef YY_USE_PROTOS
  1338. void yyrestart( FILE *input_file )
  1339. #else
  1340. void yyrestart( input_file )
  1341. FILE *input_file;
  1342. #endif
  1343.     {
  1344.     if ( ! yy_current_buffer )
  1345.         yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
  1346.  
  1347.     yy_init_buffer( yy_current_buffer, input_file );
  1348.     yy_load_buffer_state();
  1349.     }
  1350.  
  1351.  
  1352. #ifdef YY_USE_PROTOS
  1353. void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
  1354. #else
  1355. void yy_switch_to_buffer( new_buffer )
  1356. YY_BUFFER_STATE new_buffer;
  1357. #endif
  1358.     {
  1359.     if ( yy_current_buffer == new_buffer )
  1360.         return;
  1361.  
  1362.     if ( yy_current_buffer )
  1363.         {
  1364.         /* Flush out information for old buffer. */
  1365.         *yy_c_buf_p = yy_hold_char;
  1366.         yy_current_buffer->yy_buf_pos = yy_c_buf_p;
  1367.         yy_current_buffer->yy_n_chars = yy_n_chars;
  1368.         }
  1369.  
  1370.     yy_current_buffer = new_buffer;
  1371.     yy_load_buffer_state();
  1372.  
  1373.     /* We don't actually know whether we did this switch during
  1374.      * EOF (yywrap()) processing, but the only time this flag
  1375.      * is looked at is after yywrap() is called, so it's safe
  1376.      * to go ahead and always set it.
  1377.      */
  1378.     yy_did_buffer_switch_on_eof = 1;
  1379.     }
  1380.  
  1381.  
  1382. #ifdef YY_USE_PROTOS
  1383. void yy_load_buffer_state( void )
  1384. #else
  1385. void yy_load_buffer_state()
  1386. #endif
  1387.     {
  1388.     yy_n_chars = yy_current_buffer->yy_n_chars;
  1389.     yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
  1390.     yyin = yy_current_buffer->yy_input_file;
  1391.     yy_hold_char = *yy_c_buf_p;
  1392.     }
  1393.  
  1394.  
  1395. #ifdef YY_USE_PROTOS
  1396. YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
  1397. #else
  1398. YY_BUFFER_STATE yy_create_buffer( file, size )
  1399. FILE *file;
  1400. int size;
  1401. #endif
  1402.     {
  1403.     YY_BUFFER_STATE b;
  1404.  
  1405.     b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
  1406.     if ( ! b )
  1407.         YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
  1408.  
  1409.     b->yy_buf_size = size;
  1410.  
  1411.     /* yy_ch_buf has to be 2 characters longer than the size given because
  1412.      * we need to put in 2 end-of-buffer characters.
  1413.      */
  1414.     b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
  1415.     if ( ! b->yy_ch_buf )
  1416.         YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
  1417.  
  1418.     b->yy_is_our_buffer = 1;
  1419.  
  1420.     yy_init_buffer( b, file );
  1421.  
  1422.     return b;
  1423.     }
  1424.  
  1425.  
  1426. #ifdef YY_USE_PROTOS
  1427. void yy_delete_buffer( YY_BUFFER_STATE b )
  1428. #else
  1429. void yy_delete_buffer( b )
  1430. YY_BUFFER_STATE b;
  1431. #endif
  1432.     {
  1433.     if ( ! b )
  1434.         return;
  1435.  
  1436.     if ( b == yy_current_buffer )
  1437.         yy_current_buffer = (YY_BUFFER_STATE) 0;
  1438.  
  1439.     if ( b->yy_is_our_buffer )
  1440.         yy_flex_free( (void *) b->yy_ch_buf );
  1441.  
  1442.     yy_flex_free( (void *) b );
  1443.     }
  1444.  
  1445.  
  1446. #ifndef YY_ALWAYS_INTERACTIVE
  1447. #ifndef YY_NEVER_INTERACTIVE
  1448. extern int isatty YY_PROTO(( int ));
  1449. #endif
  1450. #endif
  1451.  
  1452. #ifdef YY_USE_PROTOS
  1453. void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
  1454. #else
  1455. void yy_init_buffer( b, file )
  1456. YY_BUFFER_STATE b;
  1457. FILE *file;
  1458. #endif
  1459.  
  1460.  
  1461.     {
  1462.     yy_flush_buffer( b );
  1463.  
  1464.     b->yy_input_file = file;
  1465.     b->yy_fill_buffer = 1;
  1466.  
  1467. #if YY_ALWAYS_INTERACTIVE
  1468.     b->yy_is_interactive = 1;
  1469. #else
  1470. #if YY_NEVER_INTERACTIVE
  1471.     b->yy_is_interactive = 0;
  1472. #else
  1473.     b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
  1474. #endif
  1475. #endif
  1476.     }
  1477.  
  1478.  
  1479. #ifdef YY_USE_PROTOS
  1480. void yy_flush_buffer( YY_BUFFER_STATE b )
  1481. #else
  1482. void yy_flush_buffer( b )
  1483. YY_BUFFER_STATE b;
  1484. #endif
  1485.  
  1486.     {
  1487.     b->yy_n_chars = 0;
  1488.  
  1489.     /* We always need two end-of-buffer characters.  The first causes
  1490.      * a transition to the end-of-buffer state.  The second causes
  1491.      * a jam in that state.
  1492.      */
  1493.     b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
  1494.     b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
  1495.  
  1496.     b->yy_buf_pos = &b->yy_ch_buf[0];
  1497.  
  1498.     b->yy_at_bol = 1;
  1499.     b->yy_buffer_status = YY_BUFFER_NEW;
  1500.  
  1501.     if ( b == yy_current_buffer )
  1502.         yy_load_buffer_state();
  1503.     }
  1504.  
  1505.  
  1506. #ifndef YY_NO_SCAN_BUFFER
  1507. #ifdef YY_USE_PROTOS
  1508. YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
  1509. #else
  1510. YY_BUFFER_STATE yy_scan_buffer( base, size )
  1511. char *base;
  1512. yy_size_t size;
  1513. #endif
  1514.     {
  1515.     YY_BUFFER_STATE b;
  1516.  
  1517.     if ( size < 2 ||
  1518.          base[size-2] != YY_END_OF_BUFFER_CHAR ||
  1519.          base[size-1] != YY_END_OF_BUFFER_CHAR )
  1520.         /* They forgot to leave room for the EOB's. */
  1521.         return 0;
  1522.  
  1523.     b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
  1524.     if ( ! b )
  1525.         YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
  1526.  
  1527.     b->yy_buf_size = size - 2;    /* "- 2" to take care of EOB's */
  1528.     b->yy_buf_pos = b->yy_ch_buf = base;
  1529.     b->yy_is_our_buffer = 0;
  1530.     b->yy_input_file = 0;
  1531.     b->yy_n_chars = b->yy_buf_size;
  1532.     b->yy_is_interactive = 0;
  1533.     b->yy_at_bol = 1;
  1534.     b->yy_fill_buffer = 0;
  1535.     b->yy_buffer_status = YY_BUFFER_NEW;
  1536.  
  1537.     yy_switch_to_buffer( b );
  1538.  
  1539.     return b;
  1540.     }
  1541. #endif
  1542.  
  1543.  
  1544. #ifndef YY_NO_SCAN_STRING
  1545. #ifdef YY_USE_PROTOS
  1546. YY_BUFFER_STATE yy_scan_string( yyconst char *str )
  1547. #else
  1548. YY_BUFFER_STATE yy_scan_string( str )
  1549. yyconst char *str;
  1550. #endif
  1551.     {
  1552.     int len;
  1553.     for ( len = 0; str[len]; ++len )
  1554.         ;
  1555.  
  1556.     return yy_scan_bytes( str, len );
  1557.     }
  1558. #endif
  1559.  
  1560.  
  1561. #ifndef YY_NO_SCAN_BYTES
  1562. #ifdef YY_USE_PROTOS
  1563. YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
  1564. #else
  1565. YY_BUFFER_STATE yy_scan_bytes( bytes, len )
  1566. yyconst char *bytes;
  1567. int len;
  1568. #endif
  1569.     {
  1570.     YY_BUFFER_STATE b;
  1571.     char *buf;
  1572.     yy_size_t n;
  1573.     int i;
  1574.  
  1575.     /* Get memory for full buffer, including space for trailing EOB's. */
  1576.     n = len + 2;
  1577.     buf = (char *) yy_flex_alloc( n );
  1578.     if ( ! buf )
  1579.         YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
  1580.  
  1581.     for ( i = 0; i < len; ++i )
  1582.         buf[i] = bytes[i];
  1583.  
  1584.     buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
  1585.  
  1586.     b = yy_scan_buffer( buf, n );
  1587.     if ( ! b )
  1588.         YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
  1589.  
  1590.     /* It's okay to grow etc. this buffer, and we should throw it
  1591.      * away when we're done.
  1592.      */
  1593.     b->yy_is_our_buffer = 1;
  1594.  
  1595.     return b;
  1596.     }
  1597. #endif
  1598.  
  1599.  
  1600. #ifndef YY_NO_PUSH_STATE
  1601. #ifdef YY_USE_PROTOS
  1602. static void yy_push_state( int new_state )
  1603. #else
  1604. static void yy_push_state( new_state )
  1605. int new_state;
  1606. #endif
  1607.     {
  1608.     if ( yy_start_stack_ptr >= yy_start_stack_depth )
  1609.         {
  1610.         yy_size_t new_size;
  1611.  
  1612.         yy_start_stack_depth += YY_START_STACK_INCR;
  1613.         new_size = yy_start_stack_depth * sizeof( int );
  1614.  
  1615.         if ( ! yy_start_stack )
  1616.             yy_start_stack = (int *) yy_flex_alloc( new_size );
  1617.  
  1618.         else
  1619.             yy_start_stack = (int *) yy_flex_realloc(
  1620.                     (void *) yy_start_stack, new_size );
  1621.  
  1622.         if ( ! yy_start_stack )
  1623.             YY_FATAL_ERROR(
  1624.             "out of memory expanding start-condition stack" );
  1625.         }
  1626.  
  1627.     yy_start_stack[yy_start_stack_ptr++] = YY_START;
  1628.  
  1629.     BEGIN(new_state);
  1630.     }
  1631. #endif
  1632.  
  1633.  
  1634. #ifndef YY_NO_POP_STATE
  1635. static void yy_pop_state()
  1636.     {
  1637.     if ( --yy_start_stack_ptr < 0 )
  1638.         YY_FATAL_ERROR( "start-condition stack underflow" );
  1639.  
  1640.     BEGIN(yy_start_stack[yy_start_stack_ptr]);
  1641.     }
  1642. #endif
  1643.  
  1644.  
  1645. #ifndef YY_NO_TOP_STATE
  1646. static int yy_top_state()
  1647.     {
  1648.     return yy_start_stack[yy_start_stack_ptr - 1];
  1649.     }
  1650. #endif
  1651.  
  1652. #ifndef YY_EXIT_FAILURE
  1653. #define YY_EXIT_FAILURE 2
  1654. #endif
  1655.  
  1656. #ifdef YY_USE_PROTOS
  1657. static void yy_fatal_error( yyconst char msg[] )
  1658. #else
  1659. static void yy_fatal_error( msg )
  1660. char msg[];
  1661. #endif
  1662.     {
  1663.     (void) fprintf( stderr, "%s\n", msg );
  1664.     exit( YY_EXIT_FAILURE );
  1665.     }
  1666.  
  1667.  
  1668.  
  1669. /* Redefine yyless() so it works in section 3 code. */
  1670.  
  1671. #undef yyless
  1672. #define yyless(n) \
  1673.     do \
  1674.         { \
  1675.         /* Undo effects of setting up yytext. */ \
  1676.         yytext[yyleng] = yy_hold_char; \
  1677.         yy_c_buf_p = yytext + n - YY_MORE_ADJ; \
  1678.         yy_hold_char = *yy_c_buf_p; \
  1679.         *yy_c_buf_p = '\0'; \
  1680.         yyleng = n; \
  1681.         } \
  1682.     while ( 0 )
  1683.  
  1684.  
  1685. /* Internal utility routines. */
  1686.  
  1687. #ifndef yytext_ptr
  1688. #ifdef YY_USE_PROTOS
  1689. static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
  1690. #else
  1691. static void yy_flex_strncpy( s1, s2, n )
  1692. char *s1;
  1693. yyconst char *s2;
  1694. int n;
  1695. #endif
  1696.     {
  1697.     register int i;
  1698.     for ( i = 0; i < n; ++i )
  1699.         s1[i] = s2[i];
  1700.     }
  1701. #endif
  1702.  
  1703.  
  1704. #ifdef YY_USE_PROTOS
  1705. static void *yy_flex_alloc( yy_size_t size )
  1706. #else
  1707. static void *yy_flex_alloc( size )
  1708. yy_size_t size;
  1709. #endif
  1710.     {
  1711.     return (void *) malloc( size );
  1712.     }
  1713.  
  1714. #ifdef YY_USE_PROTOS
  1715. static void *yy_flex_realloc( void *ptr, yy_size_t size )
  1716. #else
  1717. static void *yy_flex_realloc( ptr, size )
  1718. void *ptr;
  1719. yy_size_t size;
  1720. #endif
  1721.     {
  1722.     /* The cast to (char *) in the following accommodates both
  1723.      * implementations that use char* generic pointers, and those
  1724.      * that use void* generic pointers.  It works with the latter
  1725.      * because both ANSI C and C++ allow castless assignment from
  1726.      * any pointer type to void*, and deal with argument conversions
  1727.      * as though doing an assignment.
  1728.      */
  1729.     return (void *) realloc( (char *) ptr, size );
  1730.     }
  1731.  
  1732. #ifdef YY_USE_PROTOS
  1733. static void yy_flex_free( void *ptr )
  1734. #else
  1735. static void yy_flex_free( ptr )
  1736. void *ptr;
  1737. #endif
  1738.     {
  1739.     free( ptr );
  1740.     }
  1741.  
  1742. #if YY_MAIN
  1743. int main()
  1744.     {
  1745.     yylex();
  1746.     return 0;
  1747.     }
  1748. #endif
  1749. #line 168 "fflow.l"
  1750.  
  1751.  
  1752. /*****
  1753. * Print the flowgraph to the given file. We follow up to depth levels
  1754. * deep. If this depth is reached, recursion might be happening. If this
  1755. * is the case, the program aborts with an appropriate message. The
  1756. * default value for depth is MAXDEPTH, defined to 64. 
  1757. * This routine is recursive.
  1758. *****/
  1759. static void 
  1760. print_flow_calls(FILE *file, flowInfo *calls, int depth)
  1761. {
  1762.     flowInfo *tmp;
  1763.     int i;
  1764.  
  1765.     /* return if we are cutoff_depth levels deep in the calltree */
  1766.     if(cutoff_depth && depth >= cutoff_depth)
  1767.         return;
  1768.  
  1769.     if(depth >= maxdepth) 
  1770.     {
  1771.         fprintf(stderr,"ERROR: I'm %i levels deep. This might indicate "
  1772.             "undetected recursion.\n", depth);
  1773.         if(calls->name) 
  1774.             fprintf(stderr, "Current function is %s in file %s%s\n",
  1775.                 calls->name, calls->path, calls->file);  
  1776.         fprintf(stderr,"If this is no recursion, increase maxdepth by "
  1777.                 "using -d\n"); 
  1778.         exit(9);
  1779.     } 
  1780.     for(tmp = calls; tmp != NULL; tmp = tmp->next)
  1781.     {
  1782.         if(tmp->parent || (skip_unknowns == 0 && tmp->Type != KNOWN)) 
  1783.         {
  1784.             fprintf(file,"%-5i",depth+1);
  1785.             for(i = 0 ; i < depth; i++)
  1786.                 fprintf(file," %s", sep_char);
  1787.             fprintf(file," %s -> %s, line %i ", sep_char, tmp->name,
  1788.                 tmp->defline);
  1789.             if(tmp->parent)
  1790.             {
  1791.                 if(complete_graph || 
  1792.                     tmp->parent->output_line == 0) 
  1793.                 {
  1794.                     if(full_names)
  1795.                         fprintf(file,"(%s", 
  1796.                             tmp->parent->path);
  1797.                     else
  1798.                         fprintf(file, "(");
  1799.                     fprintf(file, "%s, line %i)\n",
  1800.                         tmp->parent->file, 
  1801.                         tmp->parent->defline);
  1802.                     if(errno)
  1803.                     {
  1804.                         fprintf(stderr, "Write failed:"
  1805.                             " %s\n", ErrorString());
  1806.                         exit(6);
  1807.                     }
  1808.                     tmp->output_line = ++output_line;
  1809.                     if(!tmp->parent->recursive && 
  1810.                         tmp->parent->calls)
  1811.                         print_flow_calls(file, 
  1812.                             tmp->parent->calls, 
  1813.                             depth+1);
  1814.                 } 
  1815.                 else if(!complete_graph)
  1816.                 {
  1817.                     fprintf(file, "==>> line %i <<==\n", 
  1818.                         tmp->parent->output_line);
  1819.                     output_line++;
  1820.                 }
  1821.             } 
  1822.             else 
  1823.             {
  1824.                 fprintf(file, "(<unknown>)\n");
  1825.                 tmp->output_line = ++output_line;
  1826.             }
  1827.         }
  1828.     }
  1829. }
  1830.  
  1831. /*****
  1832. * Main flow graph printing routine
  1833. *****/
  1834. static void 
  1835. print_flow_graph(FILE *file, flowInfo *list)
  1836. {
  1837.     flowInfo *tmp, *start;
  1838.  
  1839.     if(start_at_program)
  1840.     {
  1841.         for(tmp=list; tmp!=NULL && tmp->Type!=PROGRAM; tmp=tmp->next);
  1842.         if(tmp == NULL)
  1843.         {
  1844.             fprintf(stderr,"\nCould not find PROGRAM anywhere, "
  1845.                 "I'm stymied\n");
  1846.             exit(10);
  1847.         }
  1848.         start = tmp;
  1849.     }    
  1850.     else
  1851.         if(start_at_named_function) 
  1852.         { 
  1853.             for(tmp = list; tmp != NULL && 
  1854. /*
  1855.                 strcasecmp(base_function_name, tmp->name); 
  1856. */
  1857. /* sad: on emx / gcc there is only strcmp under os/2 */
  1858.  
  1859.                 strcmp(base_function_name, tmp->name); 
  1860.                 tmp = tmp->next);
  1861.             if(tmp == NULL)
  1862.             {
  1863.                 fprintf(stderr,"\nCould not find function or "
  1864.                     "subroutine %s anywhere, "
  1865.                     "I'm stymied\n", base_function_name);
  1866.                 exit(11);
  1867.             }
  1868.             start = tmp;
  1869.         } 
  1870.         else
  1871.             start = list;
  1872.  
  1873.     if(!quiet) 
  1874.         printf("Writing to %s...\n", outfile); 
  1875.     fflush(stdout);
  1876.     fprintf(file, "%%\n%% Fortran flowgraph generated by fflow\n");
  1877.     fprintf(file, "%% args used: %s\n%%\n", cmd_line); 
  1878.     output_line = 5;
  1879.  
  1880.     if(start_at_named_function) 
  1881.     {
  1882.         fprintf(file, "\n%%\n%% Generated for %s\n%%\n", 
  1883.             base_function_name); 
  1884.         output_line += 4;
  1885.     }
  1886.     /* neat loop termination trick */
  1887.     for(tmp = start; tmp != NULL; 
  1888.         tmp=(ignore_unused_funcs ? NULL : tmp->next))
  1889.     {
  1890.         if(verbose)
  1891.             printf("Generating flowgraph for: %s\n", tmp->name);
  1892.         if(tmp->calls || !ignore_empty_funcs)
  1893.         {
  1894.             tmp->output_line = output_line++;
  1895.             switch(tmp->Type)
  1896.             {
  1897.                 case PROGRAM:
  1898.                     fprintf(file,"program");
  1899.                     break;
  1900.                 case FUNCTION:
  1901.                     fprintf(file,"function");
  1902.                     break;
  1903.                 case SUBROUTINE:
  1904.                     fprintf(file,"subroutine");
  1905.                     break;
  1906.                 default:    /* should not be reached */
  1907.                     fprintf(file,"(unknown type)");
  1908.             }
  1909.             if(full_names)
  1910.                 fprintf(file," %s (%s",tmp->name,tmp->path);
  1911.             else
  1912.                 fprintf(file," %s (", tmp->name);
  1913.             fprintf(file,"%s, line %i)\n\n",tmp->file,tmp->defline);
  1914.             output_line++;
  1915.             print_flow_calls(file, tmp->calls, 0);
  1916.             fprintf(file,"\n"); 
  1917.             output_line++;
  1918.             if(verbose)
  1919.                 fflush(stdout);
  1920.         }
  1921.     }
  1922. }
  1923.  
  1924. /*****
  1925. * Scan command line options
  1926. *****/
  1927. static int 
  1928. set_global_option(char *arg)
  1929.     switch(arg[0])
  1930.     {
  1931.         case 'c' :    /* generate a complete flowgraph */
  1932.             complete_graph = 1;
  1933.             break;
  1934.         case 'e' :    /* ignore empty functions */
  1935.             ignore_empty_funcs = 1;
  1936.             break;
  1937.         case 'f' :    /* use full names instead of filename only.*/
  1938.             full_names = 1 ;
  1939.             break;
  1940.         case 'h' :    /* help requested */
  1941.             printf(usage, progname, MAXDEPTH); 
  1942.             exit(2); 
  1943.         case 'i' :    /* don't print unresolved references */
  1944.             skip_unknowns = 1;
  1945.             break;
  1946.         case 'n' :    /* tell what subroutines are never invoked */
  1947.             never_invoked = 1;
  1948.             /* -n- will not generate a flowgraph */
  1949.             if(arg[1] != '\0' && arg[1] == '-')
  1950.             {
  1951.                 no_graph = 1;
  1952.                 return(1);
  1953.             }
  1954.             break;
  1955. #ifdef __MSDOS__
  1956.         case 'm' :    /* show memory usage under msdos */
  1957.             need_mem_info_for_msdos = 1;
  1958.             break;
  1959. #endif
  1960.         case 'p' :    /* start the flowgraph at PROGRAM */
  1961.             start_at_program = 1;
  1962.             break;
  1963.         case 'q' :     /* be really quiet */
  1964.             quiet = 1; 
  1965.             verbose = 0; 
  1966.         case 't' :    /* use a tabs instead of | */
  1967.             sep_char = "\t";
  1968.             break;
  1969.         case 'u' :    /* ignore unreferenced functions */
  1970.             ignore_unused_funcs = 1;
  1971.             break;
  1972.         case 'v' :     /* be verbose */
  1973.             verbose = 1; 
  1974.             break; 
  1975.         case 'E' :    /* an extension specification */
  1976.             SCAN_ARG("-E");
  1977.             if(num_extensions == MAXEXTS)
  1978.             {
  1979.                 fprintf(stderr, "Capacity exceeded, more than "
  1980.                     "%i extensions given on command line\n",
  1981.                     MAXEXTS);
  1982.                 fprintf(stderr,"Ignoring extension %s\n",arg+1);
  1983.             }
  1984.             else
  1985.             {
  1986.                 checked_malloc(ext_table[num_extensions], 
  1987.                     strlen(arg+1)+1, char);
  1988.                 strcpy(ext_table[num_extensions++], arg+1);
  1989. #ifdef __MSDOS__    /* dos returns uppercase when building a filelist */
  1990.                 upcase(ext_table[num_extensions-1]);
  1991. #endif
  1992.             }
  1993.             return(1);
  1994.         case 'I' :    /* a directory specification */
  1995.             SCAN_ARG("-I");
  1996.             if(num_dirs_to_visit == MAXDIRS)
  1997.             {
  1998.                 fprintf(stderr,"Capacity exceeded, more than %i"
  1999.                     " directories given on command line\n",
  2000.                     MAXDIRS);
  2001.                 fprintf(stderr,"Ignoring directory %s\n",arg+1);
  2002.             }
  2003.             else
  2004.             {
  2005.                 checked_malloc(dirs_to_visit[num_dirs_to_visit],
  2006.                     strlen(arg+1)+1, char);
  2007.                 strcpy(dirs_to_visit[num_dirs_to_visit++], 
  2008.                     arg+1); 
  2009.             }
  2010.             return(1);
  2011.         case 'd' : /* max. recursion depth */
  2012.             SCAN_ARG("-d");
  2013.             maxdepth = atoi(arg + 1);
  2014.             return(1);
  2015.         case 'l' : /* max. recursion depth */
  2016.             SCAN_ARG("-l");
  2017.             cutoff_depth = atoi(arg + 1);
  2018.             return(1);
  2019.         case 'o' :    /* name of the output file */
  2020.             SCAN_ARG("-o");
  2021.             outfile = arg + 1;
  2022.             return(1);
  2023.         case 's' :    /* start flowgraph at the given function name */
  2024.             start_at_named_function = 1;
  2025.             SCAN_ARG("-s");
  2026.             base_function_name = arg + 1;
  2027.             return(1); 
  2028.         case 'x' :    /* ignore the given file */
  2029.             SCAN_ARG("-x");
  2030.             if(num_ignore == MAXIGNORE)
  2031.             {
  2032.                 fprintf(stderr, "Capacity exceeded, more than "
  2033.                     "%i ignores given on command line\n",
  2034.                     MAXIGNORE);
  2035.                 fprintf(stderr, "Ignoring option -x%s\n",arg+1);
  2036.             }
  2037.             else
  2038.             {
  2039.                 checked_malloc(ignore_list[num_ignore], 
  2040.                     strlen(arg+1)+1, char);
  2041.                 strcpy(ignore_list[num_ignore++], arg+1);
  2042. #ifdef __MSDOS__    /* dos returns uppercase when building a filelist */
  2043.                 upcase(ignore_list[num_ignore-1]);
  2044. #endif
  2045.             }
  2046.             return(1);
  2047.         case '-' :    /* secondary options */
  2048.             if(!strcmp("help", arg+1))    /* help wanted */
  2049.             {
  2050.                 printf(usage, progname, MAXDEPTH); 
  2051.                 exit(2); 
  2052.             }
  2053.             if(!strcmp("version", arg+1))    /* show version id */
  2054.             {
  2055.                 print_version_id(progname, VERSION, "$Revision: 1.9 $");
  2056.                 exit(2);
  2057.             }        /* fall through */
  2058.         default:
  2059.             fprintf(stderr,"unknown option -%s\n", arg);
  2060.             exit(3);
  2061.     }
  2062.     return(0); 
  2063. }
  2064.  
  2065. /*****
  2066. * main for fflow
  2067. *****/
  2068. int 
  2069. main(int argc, char **argv)
  2070.     int i, narg; 
  2071.     char *arg; 
  2072.  
  2073.     /* set global default values */
  2074.     initialise(argv[0]);
  2075.  
  2076.     if(argc == 1)
  2077.     {
  2078.         fprintf(stderr, "%s: no files given\n",progname);
  2079.         printf(usage, progname, MAXDEPTH); 
  2080.         exit(4);
  2081.     }
  2082.  
  2083.     /* Default values */
  2084.     outfile = "stdout"; 
  2085.     sep_char = "|"; 
  2086.     maxdepth = MAXDEPTH; 
  2087.     cutoff_depth = 0;
  2088.  
  2089.     /* scan for any command line options and save a copy of it */
  2090.     arg = argv[narg = 1];
  2091.     while ( narg < argc && arg[0] == '-' )
  2092.     {
  2093.         if (arg[0] == '-')
  2094.         { 
  2095.             int num_opts = strlen(arg) ; 
  2096.             for(i = 1 ; i < num_opts ; i++ )
  2097.             if(set_global_option(++arg)) 
  2098.                 break;
  2099.         } 
  2100.         strcat(cmd_line, argv[narg]);
  2101.         strcat(cmd_line, " ");
  2102.         arg = argv[++narg];
  2103.     }
  2104.  
  2105.     /* if no directories or files are given, exit */
  2106.     if(num_dirs_to_visit == 0 && narg == argc) 
  2107.     { 
  2108.         fprintf(stderr,"no files given.\n"); 
  2109.         exit(4); 
  2110.     } 
  2111.  
  2112.     /* install signal handlers */
  2113.     install_sig_handlers();
  2114.  
  2115.     /* open the output file */
  2116.     if(!strcmp(outfile, "stdout"))
  2117.         output_file = stdout;
  2118.     else if((output_file = fopen(outfile, "w")) == NULL)
  2119.     {
  2120.         perror(outfile);
  2121.         exit(6);
  2122.     }
  2123.  
  2124.     /*
  2125.     * always use this extension of none is given and directories are to be
  2126.     * searched. 3 equals the size of .f\0 
  2127.     */
  2128.     if(num_dirs_to_visit && !num_extensions)
  2129.     {
  2130.         checked_malloc(ext_table[num_extensions], 3, char);
  2131. #ifdef __MSDOS__    /* msdos returns uppercase when building a filelist */
  2132.         ext_table[num_extensions++] = ".F";
  2133. #else
  2134.         ext_table[num_extensions++] = ".f";
  2135. #endif
  2136.     }
  2137.  
  2138.     /* when directories have been given on the cmdline, build a filelist */
  2139.     if(num_dirs_to_visit && verbose)
  2140.         printf("Scanning directories:\n");
  2141.  
  2142.     for(i = 0 ; i < num_dirs_to_visit; i++)
  2143.     {
  2144.         if(verbose)
  2145.             printf("%s\n", dirs_to_visit[i]); 
  2146.         build_file_list(&file_list, &num_files, dirs_to_visit[i],
  2147.             ext_table, num_extensions); 
  2148.     }
  2149.  
  2150.     /* see if we have files left on the command line */
  2151.     if(narg != argc)
  2152.     {
  2153.         for(i = narg ; i < argc ; i++)
  2154.         {
  2155.             checked_realloc(file_list, num_files+1, char*);
  2156.             checked_malloc(file_list[num_files], strlen(argv[i])+1,
  2157.                 char);
  2158.             sprintf(file_list[num_files++], "%s", argv[i]); 
  2159.         }
  2160.         if(verbose && argc-narg !=0)
  2161.             printf("%i files given on command line.\n", argc - narg); 
  2162.     }
  2163.  
  2164.     /* show settings if we have to be verbose */
  2165.     if(verbose)
  2166.         print_settings();
  2167.  
  2168.     if(!quiet)
  2169.     {
  2170.         printf("Total Files to scan: %i\n", num_files); 
  2171.         printf("File to write to: %s\n", outfile);
  2172.     }
  2173.     fflush(stdout);
  2174.  
  2175.     /* purge any non-matching output from yylex to /dev/null */
  2176.     yyout = fopen(YYOUT_DEVICE, "w+");
  2177.  
  2178.     /* scan the file list */
  2179.     for(i = 0; i < num_files; i++)
  2180.     {
  2181.         if ((num_ignore == 0 ? 1 : ignore_this_file(file_list[i]))) 
  2182.         {
  2183.             /* reset scanner for this file */
  2184.             if((yyin = reset_scanner(file_list[i])) == NULL)
  2185.                 continue;
  2186.             yylineno = 0;
  2187.             /* scan the file */
  2188.             yylex();
  2189.             /* 
  2190.             * flush the buffer of flex so we won't have 
  2191.             * any trailing stuff from the previous file 
  2192.             */
  2193.             YY_FLUSH_BUFFER; 
  2194.             /* close input file */
  2195.             fclose(yyin);
  2196.             /* report some statistics if we have to */
  2197.             if(verbose) 
  2198.                 print_file_stats(output_file, file_list[i], 
  2199.                 yylineno);
  2200.         }
  2201.     }
  2202.     fclose(yyout);
  2203.  
  2204.     /* this is the final flowgraph data */
  2205.     flow = global_flow.head;
  2206.  
  2207.     if(!quiet) 
  2208.         printf("Sorting...\n"); 
  2209.     fflush(stdout);
  2210.  
  2211.     /* Sort the flowgraph */
  2212.     flow = sortAll(flow); 
  2213.  
  2214.     /* print the flow graph if thus wanted */
  2215.     if(no_graph == 0)
  2216.         print_flow_graph(output_file, flow);
  2217.  
  2218.     /* print subroutines that are never invoked */
  2219.     if(never_invoked)
  2220.         print_unused_routines(output_file, flow);
  2221.  
  2222.     /* close the output file */
  2223.     if(!strcmp(outfile, "stdout"))
  2224.     {
  2225.         fflush(output_file);
  2226.         fclose(output_file); 
  2227.     }
  2228.     if(!quiet)
  2229.         printf("Done, total files scanned: %i\n", i);
  2230.  
  2231.     /* when wanted, print msdos memory usage summary */
  2232.     print_dos_memory_usage();
  2233.  
  2234.     return(0);
  2235. }
  2236.