home *** CD-ROM | disk | FTP | other *** search
/ Amiga Elysian Archive / AmigaElysianArchive.iso / prog / c / bmake15.lzh / input.c < prev    next >
C/C++ Source or Header  |  1991-09-19  |  5KB  |  221 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 )))
  69.         goto death;
  70.  
  71.     while( isspace( *nexttar )) nexttar++;
  72.     if( *nexttar != ':' ) {
  73.         logfile( "WARNING: missing colon in .PHONY\n" );
  74.     }
  75.     else nexttar++;
  76.  
  77.     *expansion = (char)0;
  78.     /* expand macros in rhs */
  79.     if( *nexttar && expand_macros( expansion, nexttar, Param.MaxLine ))
  80.         goto death;
  81.     nexttar = expansion;
  82.  
  83.     for( ; ; ) {
  84.         nexttar = parse_str( name, nexttar, MAXPATHNAME );
  85.         if( !*name )
  86.             break;
  87.         if( targ = find_target( name )) {
  88.             targ->flags |= TF_PHONY;
  89.             debugprintf(4, ( "Marking %s as phony target\n", name ));
  90.         }
  91.         else {
  92.             logprintf( "Unknown phony target %s\n", name );
  93.             goto death;
  94.         }
  95.     }
  96.     free( expansion );
  97.     return( 0 );
  98. death:
  99.     if( expansion )
  100.         free( expansion );
  101.     return( 1 );
  102. }
  103.  
  104. static int
  105. drctv_suffixes( char *string, struct List *stack )
  106. {
  107.     char suf[ MAXSUFFIX ];
  108.     char *expansion = NULL;
  109.     char *nexttar = string;
  110.  
  111.     if( !(expansion = (char *)malloc( Param.MaxLine )))
  112.         goto death;
  113.  
  114.     while( isspace( *nexttar ))
  115.         nexttar++;
  116.     if( *nexttar != ':' ) {
  117.         logfile( "WARNING: missing colon in .SUFFIXES\n" );
  118.     }
  119.     else nexttar++;
  120.  
  121.     *expansion = (char)0;
  122.     /* expand macros in rhs */
  123.     if( *nexttar && expand_macros( expansion, nexttar, Param.MaxLine ))
  124.         goto death;
  125.     nexttar = expansion;
  126.  
  127.     for( ; ; ) {
  128.         while( isspace( *nexttar )) nexttar++;
  129.         if( *nexttar != '.' ) {
  130.             if( *nexttar ) {
  131.                 logprintf( "bad suffix rule [%s] on line %d\n%s\n",
  132.                     nexttar, line_number, string );
  133.             }
  134.             break;
  135.         }
  136.         nexttar = parse_strtok( suf, ++nexttar, sizeof(suf)-1, isnotsuf );
  137.         if( !*suf )
  138.             break;
  139.         add_suffix_targets( suf );
  140.     }
  141.     free( expansion );
  142.     return( 0 );
  143. death:
  144.     if( expansion )
  145.         free( expansion );
  146.     return( 1 );
  147. }
  148.  
  149. /* keep it sorted for binary search */
  150. #define MAX_MDRCTVS 7
  151. static struct drctvs darray[ MAX_MDRCTVS ] = {
  152.     { ".INCLUDE", drctv_include },
  153.     { ".PHONY",    drctv_phony },
  154.     { ".SUFFIXES", drctv_suffixes },
  155.     { "else",    drctv_else    },
  156.     { "endif",    drctv_endif    },
  157.     { "if",        drctv_if    },
  158.     { "pragma",    drctv_pragma }
  159. };
  160.  
  161. /*    get a non-comment line
  162.  */
  163. static int
  164. get_ncline( char *buf, int sz, FILE *in )
  165. {
  166.     char *inbuf, *cptr;
  167.     int total, len;
  168.  
  169.     do {
  170.         if( feof( in ))
  171.             return( 1 );
  172.         if( !fgets( buf, sz, in ))
  173.             return( 1);
  174.         line_number++;
  175.         total = strlen( buf );
  176.         inbuf = buf;
  177.         while( cptr = strrchr( inbuf, '\\' ) ){
  178.             if( cptr[1] != '\n' )
  179.                 break;
  180.             total -= 2; /* subtract backslash newline */
  181.             inbuf = cptr;
  182.             if( total >= sz )
  183.                 break;
  184.             if( feof( in ))
  185.                 return( 1 );
  186.             if( !fgets( inbuf, sz - total, in ))
  187.                 return( 1 );
  188.             line_number++;
  189.             total += strlen( inbuf );
  190.         }
  191.     } while( *buf == '#' );
  192.     strip_trailspace( buf );
  193.     return( 0 );
  194. }
  195.  
  196. /*    get the next valid line from a Makefile
  197.  */
  198. int
  199. getline( char *buf, int sz, FILE *in )
  200. {
  201.     struct drctvs *found = NULL;
  202.     int st, state = 0;
  203.     do {
  204.         if( state && !found )
  205.             debugprintf( 4, ("skipped[state=%d] %s\n", state, buf ));
  206.         st = get_ncline( buf, sz, in );
  207.         if( !st ) {
  208.             if( found = find_drctvs( darray, MAX_MDRCTVS, buf )) {
  209.                 if( st = (*found->call)( buf + strlen( found->directive),
  210.                     &Mstack )) {
  211.                     clear_stack( &Mstack );
  212.                 }
  213.             }
  214.         }
  215.         state = get_directive_state( &Mstack );
  216.     } while( !st && (state == STATE_IF_F || state == STATE_EL_T || found ));
  217.  
  218.     return( st );
  219. }
  220.  
  221.