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

  1. /*    read.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. extern int line_number;
  14.  
  15. /*    process a line that looks like
  16.  *    target names: dependencies
  17.  */
  18. struct target *
  19. process_targetline( char *line, struct List *cmdlist )
  20. {
  21.     struct target *first_targ = NULL;
  22.     struct target *targ = NULL;
  23.     struct List *ownerlist = NULL;
  24.     char *delim, *nexttar;
  25.     char name[ MAXPATHNAME ];
  26.     char *expandlhs = NULL, *expandrhs = NULL;
  27.     long len;
  28.     int dbl_colon_flag = 0;
  29.  
  30.     struct depend *dep = NULL;
  31.     struct command *cmd = NULL;
  32.     char *next;
  33.  
  34.     if( !(expandlhs = (char *)malloc( Param.MaxLine )) ||
  35.         !(expandrhs = (char *)malloc( Param.MaxLine ))) goto death;
  36.  
  37.     while( isspace( *line )) line++;
  38.     delim = find_token( line + 1, ':' );
  39.     if( !delim ) goto death;
  40.     len = (long)(delim - line);
  41.     if( !len ) goto death;
  42.  
  43.     if( delim[1] == ':' ) {
  44.         dbl_colon_flag = 1;
  45.         delim++;
  46.     }
  47.  
  48.     memset( name, 0, sizeof( name ));
  49.     strncpy( name, line, (int)(delim - line));
  50.  
  51.     /* expand macros in targetnames */
  52.     if( expand_macros( expandlhs, name, Param.MaxLine )) goto death;
  53.     nexttar = expandlhs;
  54.  
  55.     /* for each target name left of the colon */
  56.     for(;;) {
  57.         dep = NULL;
  58.         cmd = NULL;
  59.         
  60.         nexttar = parse_str( name, nexttar, sizeof( name ));
  61.         if( !*name ) break; /* no more names */
  62.  
  63.         if( dbl_colon_flag) targ = NULL;
  64.         else targ = find_target( name );
  65.         if( !targ ) {
  66.             targ = new_target( name );
  67.             if( !targ )    goto death;
  68.             targ->line_number = line_number;
  69.         }
  70.         if( Global.builtin_flag ) targ->flags |= TF_BUILTIN;
  71.         if( dbl_colon_flag ) targ->flags |= TF_DBLCOLON;
  72.  
  73.         debugprintf( 5, ( "new target: %s\n", targ->name ) );
  74.  
  75.         if( !first_targ ) {
  76.             first_targ = targ;
  77.             first_targ->flags |= TF_OWNER;
  78.             ownerlist = &targ->commandlist;
  79.         }
  80.  
  81.         set_target_macros( name, NULL );
  82.  
  83.         /* find the dependencies */
  84.         next = delim + 1;
  85.         while( isspace( *next )) next++;
  86.  
  87.         /* expand macros in dependencies */
  88.         if( expand_macros( expandrhs, next, Param.MaxLine )) goto death;
  89.         next = expandrhs;
  90.  
  91.         /* for each dependency add to list */
  92.         for( ;; ) {
  93.             next = parse_str( name, next, sizeof( name ));
  94.             if( !*name ) break; /* no more names */
  95.  
  96.             if( *name == '.' ) {
  97.                 if( !stricmp( name+1, ONCE_TARGET )) {
  98.                     targ->flags |= TF_ONCE;
  99.                     continue;
  100.                 }
  101.                 else if( !stricmp( name+1, INVIS_TARGET )) {
  102.                     targ->flags |= TF_INVIS;
  103.                     continue;
  104.                 }
  105.                 else if( !stricmp( name+1, ALWAYS_TARGET )) {
  106.                     targ->flags |= TF_ALWAYS;
  107.                     continue;
  108.                 }
  109.                 else if( !stricmp( name+1, NEVER_TARGET )) {
  110.                     targ->flags |= TF_NEVER;
  111.                     continue;
  112.                 }
  113.             }
  114.  
  115.             /* first check if that dependency already exists */
  116.             for( dep = targ->dependlist.lh_Head; dep->node.ln_Succ;
  117.                 dep = dep->node.ln_Succ ) {
  118.                 if( !stricmp( dep->name, name )) break;
  119.             }
  120.  
  121.             if( !dep->node.ln_Succ ) { /* doesn't exist already */
  122.                 if(  dep = new_depend( name ))
  123.                     AddTail( &targ->dependlist, &dep->node );
  124.                 else goto death;
  125.             }
  126.             else {
  127.                 logprintf( "duplicate dependency %s for target %s\n",
  128.                     name, targ->name );
  129.             }
  130.         }
  131.         /* for each command add to list */
  132.         if( targ->flags & TF_OWNER ) {
  133.             delete_commandlist( &targ->commandlist );
  134.             attach_list( &targ->commandlist, cmdlist );
  135.         }
  136.         else targ->alternate = ownerlist;
  137.  
  138.         if( !stricmp( targ->name, DEFAULT_TARGET )) {
  139.             set_default_target( targ );
  140.         }
  141.         else if( !(targ->flags & TF_ADDED )) {
  142.             if( ((dep = targ->dependlist.lh_Head) &&
  143.                 strchr( dep->name, PATMATCH_CHAR )) ||
  144.                 strchr( targ->name, PATMATCH_CHAR )) {
  145.                 add_pattern_rule( targ );
  146.             }
  147.             else {
  148.                 targ->flags |= TF_ADDED;
  149.                 AddTail( &Global.targetlist, &targ->node );
  150.             }
  151.         }
  152.         targ = NULL;
  153.     } /* for */
  154.     set_target_macros( NULL, NULL ); /* delete $@ $* and $< */
  155.  
  156. death:
  157.     if( targ ) free( targ );
  158.     if( expandrhs ) free( expandrhs );
  159.     if( expandlhs ) free( expandlhs );
  160.     if( dbl_colon_flag ) {
  161.         logfile( "WARNING:  double colon rules do not work!\n" );
  162.     }
  163.     return( first_targ );
  164. }
  165.  
  166. /*    process a line that looks like
  167.  *    variable = value
  168.  */
  169. struct macro *
  170. process_macroline( char *line )
  171. {
  172.     struct macro *mac = NULL;
  173.     char *delim, *next;
  174.     char macroname[ MAX_MACRONAME ], *rhs;
  175.     char *expansion = NULL; /* dynamic */
  176.     long namelen, explen;
  177.     int do_expansion = 0;
  178.     int do_addition = 0;
  179.  
  180.     debugprintf( 5, ( "macroline %d: %s\n", line_number, line ) );
  181.  
  182.     while( isspace( *line )) line++; /* skip whitespace */
  183.  
  184.     delim = strchr( line, '=' ); /* cannot be escaped by backslash */
  185.     if( !delim ) goto death;
  186.     rhs = delim + 1;
  187.  
  188.     namelen = min( (long)(delim - line), sizeof(macroname)-1);
  189.     if( !namelen ) goto death;
  190.  
  191.     switch( *(delim-1)) {
  192.     case ':':
  193.         do_expansion = 1;
  194.         delim--;
  195.         namelen--;
  196.         break;
  197.     case '+':
  198.         do_addition = 1;
  199.         delim--;
  200.         namelen--;
  201.         break;
  202.     }
  203.  
  204.     next = line;
  205.     while( isspace( *next )) next++;
  206.     memset( macroname, 0, sizeof( macroname ));
  207.     for( int i = 0; next < delim && i < 79; i++ ) {
  208.         if( isspace( *next )) break;
  209.         macroname[ i ] = *next++;
  210.     }
  211.  
  212.     while( isspace( *rhs )) rhs++; /* skip whitespace */
  213.  
  214.     if( do_expansion && *rhs ) {
  215.         expansion = (char *)malloc( Param.MaxLine );
  216.         if( !expansion ) goto death;
  217.         if( expand_macros( expansion, rhs, Param.MaxLine )) goto death;
  218.             /* expand rhs */
  219.         rhs = expansion;
  220.     }
  221.  
  222.     if( mac = find_macro( macroname )) {
  223.         char *old = mac->expansion;
  224.  
  225.         mac->flags &= ~MF_SIMPLE;
  226.         if( do_addition && old ) {
  227.             if( mac->expansion = malloc(strlen( old ) + strlen( rhs ) + 1)) {
  228.                 strcpy( mac->expansion, old );
  229.                 strcat( mac->expansion, " " );
  230.                 strcat( mac->expansion, rhs );
  231.             }
  232.         }
  233.         else mac->expansion = strdup( rhs );
  234.         if( old ) free( old );
  235.     }
  236.     else mac = new_macro( macroname, rhs );
  237.  
  238.     if( mac ) {
  239.         if( do_expansion ) mac->flags |= MF_SIMPLE;
  240.         if( !(mac->flags & MF_ADDED )) {
  241.             mac->flags |= MF_ADDED;
  242.             AddTail( &Global.macrolist, &mac->node );
  243.         }
  244.         debugprintf( 5, ( "assigned macro [%s] = [%s]\n",
  245.             mac->name, mac->expansion ));
  246.     }
  247.     else {
  248.         debugprintf( 2, ("error assigning macro [%s]\n", macroname ) );
  249.     }
  250.  
  251.     if( expansion ) free( expansion );
  252.     return( mac );
  253. death:
  254.     if( expansion ) free( expansion );
  255.     if( mac ) free( mac );
  256.     return( NULL );
  257. }
  258.  
  259. /*    read in all rules and variables from this makefile
  260. */
  261. int
  262. input_makefile( const char *makefile )
  263. {
  264.     char *curline = NULL;
  265.     char *commandline = NULL;
  266.     FILE *infile = NULL;
  267.     int targetcount = 0, macrocount = 0;
  268.     int st;
  269.  
  270.     curline = (char *)malloc( Param.MaxLine );
  271.     commandline = (char *)malloc( Param.MaxLine );
  272.     if( !curline || !commandline ) goto death;
  273.  
  274.     infile = fopen( makefile, "r" );
  275.     if( !infile ) {
  276.         logprintf( "Cannot open %s\n", makefile );
  277.         goto death;
  278.     }
  279.  
  280.     debugprintf( 3,( "input Makefile: %s\n", makefile ));
  281.  
  282.     line_number = 0;
  283.     if( st = getline( curline, Param.MaxLine, infile )) goto death;
  284.     while( !st ) {
  285.         /* debugprintf( 5,( "getline %d: %s\n", line_number, curline )); */
  286.         if( strchr( curline, '=' )) {
  287.             macrocount++;
  288.             process_macroline( curline );
  289.  
  290.             st = getline( curline, Param.MaxLine, infile );
  291.         }
  292.         else if( isemptyline( curline )) {
  293.             st = getline( curline, Param.MaxLine, infile );
  294.         }
  295.         else {
  296.             struct List cmdList;
  297.             struct target *targ = NULL;
  298.             struct command *cmd = NULL;
  299.             char *delim;
  300.  
  301.             NewList( &cmdList );
  302.  
  303.             targetcount++;
  304.             *commandline = (char)0;
  305.  
  306.             delim = find_token( curline + 1, ':' );
  307.             if( delim ) {
  308.                 if( delim = find_token( delim + 1, ';' ) ) {
  309.                     *delim++ = (char)0;
  310.                     *commandline = '\t'; /* commandlines begin with a tab */
  311.                     strcpy( commandline + 1, delim );
  312.                 }
  313.             }
  314.  
  315.             if( st = ( *commandline ) ? 0 :
  316.                 getline( commandline, Param.MaxLine, infile )) break;
  317.             while( !st ) {
  318.                 if( *commandline != '\t' ) break;
  319.                 debugprintf( 5,("tabline %d: %s\n",line_number, commandline));
  320.                 delim = commandline;
  321.                 while( isspace( *delim )) delim++;
  322.                 if( *delim ) { /* line is not empty */
  323.                     if( cmd = new_command( delim ))
  324.                         AddTail( &cmdList, &cmd->node );
  325.                     else {
  326.                         logprintf( "Could not add command for target\n" ); 
  327.                         goto death;
  328.                     }
  329.                 }
  330.                 st = getline( commandline, Param.MaxLine, infile );
  331.             } /* while */
  332.  
  333.             debugprintf( 4, ("targetline %d is %s\n", line_number, curline));
  334.             targ = process_targetline( curline, &cmdList );
  335.             if( !targ ) {
  336.                 logprintf( "Error in Makefile before line %d: %s\n",
  337.                     line_number, curline );
  338.                 goto death;
  339.             }
  340.  
  341.             strcpy( curline, commandline );
  342.         } /* else */
  343.     } /* while */
  344.  
  345.     debugprintf( 2,( "targetcount = %d\nmacrocount = %d\n", targetcount,
  346.         macrocount ));
  347.  
  348. #if DEBUG
  349.     if( Param.debug && Param.verbosity >= 5 ) {
  350.         dump_all();
  351.     }
  352. #endif
  353.  
  354.     free( commandline );
  355.     free( curline );
  356.     fclose( infile );
  357.     return( 0 );
  358. death:
  359.     if( commandline ) free( commandline );
  360.     if( curline ) free( curline );
  361.     if( infile ) fclose( infile );
  362.     return( 1 );
  363. }
  364.