home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d5xx / d523 / bmake.lha / BMake / source.lzh / input.c < prev    next >
C/C++ Source or Header  |  1991-07-28  |  5KB  |  206 lines

  1. /*    input.c
  2.  *    (c) Copyright 1991 by Ben Eng, All Rights Reserved
  3.  *
  4.  */
  5.  
  6. #include <ctype.h>
  7. #include <clib/exec_protos.h>
  8.  
  9. #include "make.h"
  10. #include "depend.h"
  11. #include "cond.h"
  12.  
  13. int line_number;
  14.  
  15. struct List Mstack =
  16. {
  17.     (struct Node *)&Mstack.lh_Tail,    /* lh_Head */
  18.     (struct Node *)NULL,            /* lh_Tail */
  19.     (struct Node *)&Mstack.lh_Head,    /* lh_TailPred */
  20.     (UBYTE)NT_USER,
  21.     (UBYTE)0
  22. };
  23.  
  24. static int
  25. drctv_include( char *string, struct List *stack )
  26. {
  27.     int retval = 0;
  28.     int saved_line_number, state;
  29.     while( isspace( *string )) string++;
  30.     if( *string ) {
  31.         saved_line_number = line_number;
  32.         retval = input_makefile( string );
  33.         line_number = saved_line_number;
  34.     }
  35.     return( retval );
  36. }
  37.  
  38. static int
  39. drctv_pragma( char *string, struct List *stack )
  40. {
  41.     int i, arguments, retval = 1;
  42.     char **argv = NULL;
  43.  
  44.     while( isspace( *string )) string++;
  45.     if( arguments = count_args( string ) + 1) {
  46.         if( argv = (char **)malloc( (arguments + 1) * sizeof(char *)) ) {
  47.             for( i = 1; i < arguments; i++ ) {
  48.                 argv[ i ] = find_word( string, i );
  49.             }
  50.             argv[ 0 ] = version_string + 7; /* kludge */
  51.             argv[ arguments ] = NULL;
  52.             retval = parse_parameters( arguments, argv );
  53.             free( argv );
  54.         }
  55.     }
  56.     debugprintf( 3,( "Pragma(%d,%s)\n", arguments, string ));
  57.     return( retval );
  58. }
  59.  
  60. static int
  61. drctv_phony( char *string, struct List *stack )
  62. {
  63.     char name[ MAXPATHNAME ];
  64.     char *expansion = NULL;
  65.     char *nexttar = string;
  66.     struct target *targ;
  67.  
  68.     if( !(expansion = (char *)malloc( Param.MaxLine ))) goto death;
  69.  
  70.     while( isspace( *nexttar )) nexttar++;
  71.     if( *nexttar != ':' ) {
  72.         logfile( "WARNING: missing colon in .PHONY\n" );
  73.     }
  74.     else nexttar++;
  75.  
  76.     *expansion = (char)0;
  77.     /* expand macros in rhs */
  78.     if( *nexttar && expand_macros( expansion, nexttar, Param.MaxLine ))
  79.         goto death;
  80.     nexttar = expansion;
  81.  
  82.     for( ; ; ) {
  83.         nexttar = parse_str( name, nexttar, MAXPATHNAME );
  84.         if( !*name ) break;
  85.         if( targ = find_target( name )) {
  86.             targ->flags |= TF_PHONY;
  87.             debugprintf(4, ( "Marking %s as phony target\n", name ));
  88.         }
  89.         else {
  90.             logprintf( "Unknown phony target %s\n", name );
  91.             goto death;
  92.         }
  93.     }
  94.     free( expansion );
  95.     return( 0 );
  96. death:
  97.     if( expansion ) free( expansion );
  98.     return( 1 );
  99. }
  100.  
  101. static int
  102. drctv_suffixes( char *string, struct List *stack )
  103. {
  104.     char suf[ MAXSUFFIX ];
  105.     char *expansion = NULL;
  106.     char *nexttar = string;
  107.  
  108.     if( !(expansion = (char *)malloc( Param.MaxLine ))) goto death;
  109.  
  110.     while( isspace( *nexttar )) nexttar++;
  111.     if( *nexttar != ':' ) {
  112.         logfile( "WARNING: missing colon in .SUFFIXES\n" );
  113.     }
  114.     else nexttar++;
  115.  
  116.     *expansion = (char)0;
  117.     /* expand macros in rhs */
  118.     if( *nexttar && expand_macros( expansion, nexttar, Param.MaxLine ))
  119.         goto death;
  120.     nexttar = expansion;
  121.  
  122.     for( ; ; ) {
  123.         while( isspace( *nexttar )) nexttar++;
  124.         if( *nexttar != '.' ) {
  125.             if( *nexttar ) {
  126.                 logprintf( "bad suffix rule [%s] on line %d\n%s\n",
  127.                     nexttar, line_number, string );
  128.             }
  129.             break;
  130.         }
  131.         nexttar = parse_strtok( suf, ++nexttar, sizeof(suf)-1, isnotsuf );
  132.         if( !*suf ) break;
  133.         add_suffix_targets( suf );
  134.     }
  135.     free( expansion );
  136.     return( 0 );
  137. death:
  138.     if( expansion ) free( expansion );
  139.     return( 1 );
  140. }
  141.  
  142. /* keep it sorted for binary search */
  143. #define MAX_MDRCTVS 7
  144. static struct drctvs darray[ MAX_MDRCTVS ] = {
  145.     { ".INCLUDE", drctv_include },
  146.     { ".PHONY",    drctv_phony },
  147.     { ".SUFFIXES", drctv_suffixes },
  148.     { "else",    drctv_else    },
  149.     { "endif",    drctv_endif    },
  150.     { "if",        drctv_if    },
  151.     { "pragma",    drctv_pragma }
  152. };
  153.  
  154. /*    get a non-comment line
  155.  */
  156. static int
  157. get_ncline( char *buf, int sz, FILE *in )
  158. {
  159.     char *inbuf, *cptr;
  160.     int total, len;
  161.  
  162.     do {
  163.         if( feof( in )) return( 1 );
  164.         if( !fgets( buf, sz, in )) return( 1);
  165.         line_number++;
  166.         total = strlen( buf );
  167.         inbuf = buf;
  168.         while( cptr = strrchr( inbuf, '\\' ) ){
  169.             if( cptr[1] != '\n' ) break;
  170.             total -= 2; /* subtract backslash newline */
  171.             inbuf = cptr;
  172.             if( total >= sz ) break;
  173.             if( feof( in )) return( 1 );
  174.             if( !fgets( inbuf, sz - total, in )) return( 1 );
  175.             line_number++;
  176.             total += strlen( inbuf );
  177.         }
  178.     } while( *buf == '#' );
  179.     strip_trailspace( buf );
  180.     return( 0 );
  181. }
  182.  
  183. /*    get the next valid line from a Makefile
  184.  */
  185. int
  186. getline( char *buf, int sz, FILE *in )
  187. {
  188.     struct drctvs *found = NULL;
  189.     int st, state = 0;
  190.     do {
  191.         if( state && !found )
  192.             debugprintf( 4, ("skipped[state=%d] %s\n", state, buf ));
  193.         st = get_ncline( buf, sz, in );
  194.         if( !st ) {
  195.             if( found = find_drctvs( darray, MAX_MDRCTVS, buf )) {
  196.                 if( st = (*found->call)( buf + strlen( found->directive),
  197.                     &Mstack )) clear_stack( &Mstack );
  198.             }
  199.         }
  200.         state = get_directive_state( &Mstack );
  201.     } while( !st && (state == STATE_IF_F || state == STATE_EL_T || found ));
  202.  
  203.     return( st );
  204. }
  205.  
  206.