home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 529b.lha / BMake_v1.1 / read.c < prev    next >
C/C++ Source or Header  |  1991-07-02  |  8KB  |  347 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.             /* first check if that dependency already exists */
  96.             for( dep = targ->dependlist.lh_Head; dep->node.ln_Succ;
  97.                 dep = dep->node.ln_Succ ) {
  98.                 if( !strcmp( dep->name, name )) break;
  99.             }
  100.  
  101.             if( !dep->node.ln_Succ ) { /* doesn't exist already */
  102.                 if(  dep = new_depend( name ))
  103.                     AddTail( &targ->dependlist, &dep->node );
  104.                 else goto death;
  105.             }
  106.             else {
  107.                 logprintf( "duplicate dependency %s for target %s\n",
  108.                     name, targ->name );
  109.             }
  110.         }
  111.         /* for each command add to list */
  112.         if( targ->flags & TF_OWNER ) {
  113.             delete_commandlist( &targ->commandlist );
  114.             attach_list( &targ->commandlist, cmdlist );
  115.         }
  116.         else targ->alternate = ownerlist;
  117.  
  118.         if( !strcmp( targ->name, DEFAULT_TARGET )) {
  119.             set_default_target( targ );
  120.         }
  121.         else if( !(targ->flags & TF_ADDED )) {
  122.             if( ((dep = targ->dependlist.lh_Head) &&
  123.                 strchr( dep->name, PATMATCH_CHAR )) ||
  124.                 strchr( targ->name, PATMATCH_CHAR )) {
  125.                 add_pattern_rule( targ );
  126.             }
  127.             else {
  128.                 targ->flags |= TF_ADDED;
  129.                 AddTail( &Global.targetlist, &targ->node );
  130.             }
  131.         }
  132.         targ = NULL;
  133.     } /* for */
  134.     set_target_macros( NULL, NULL ); /* delete $@ $* and $< */
  135.  
  136. death:
  137.     if( targ ) free( targ );
  138.     if( expandrhs ) free( expandrhs );
  139.     if( expandlhs ) free( expandlhs );
  140.     if( dbl_colon_flag ) {
  141.         logfile( "WARNING:  double colon rules do not work!\n" );
  142.     }
  143.     return( first_targ );
  144. }
  145.  
  146. /*    process a line that looks like
  147.  *    variable = value
  148.  */
  149. struct macro *
  150. process_macroline( char *line )
  151. {
  152.     struct macro *mac = NULL;
  153.     char *delim, *next;
  154.     char macroname[ MAX_MACRONAME ], *rhs;
  155.     char *expansion = NULL; /* dynamic */
  156.     long namelen, explen;
  157.     int do_expansion = 0;
  158.     int do_addition = 0;
  159.  
  160.     debugprintf( 5, ( "macroline %d: %s\n", line_number, line ) );
  161.  
  162.     while( isspace( *line )) line++; /* skip whitespace */
  163.  
  164.     delim = strchr( line, '=' ); /* cannot be escaped by backslash */
  165.     if( !delim ) goto death;
  166.     rhs = delim + 1;
  167.  
  168.     namelen = min( (long)(delim - line), sizeof(macroname)-1);
  169.     if( !namelen ) goto death;
  170.  
  171.     switch( *(delim-1)) {
  172.     case ':':
  173.         do_expansion = 1;
  174.         delim--;
  175.         namelen--;
  176.         break;
  177.     case '+':
  178.         do_addition = 1;
  179.         delim--;
  180.         namelen--;
  181.         break;
  182.     }
  183.  
  184.     next = line;
  185.     while( isspace( *next )) next++;
  186.     memset( macroname, 0, sizeof( macroname ));
  187.     for( int i = 0; next < delim && i < 79; i++ ) {
  188.         if( isspace( *next )) break;
  189.         macroname[ i ] = *next++;
  190.     }
  191.  
  192.     while( isspace( *rhs )) rhs++; /* skip whitespace */
  193.  
  194.     if( do_expansion && *rhs ) {
  195.         expansion = (char *)malloc( Param.MaxLine );
  196.         if( !expansion ) goto death;
  197.         if( expand_macros( expansion, rhs, Param.MaxLine )) goto death;
  198.             /* expand rhs */
  199.         rhs = expansion;
  200.     }
  201.  
  202.     if( mac = find_macro( macroname )) {
  203.         char *old = mac->expansion;
  204.  
  205.         if( do_addition && old ) {
  206.             if( mac->expansion = malloc(strlen( old ) + strlen( rhs ) + 1)) {
  207.                 strcpy( mac->expansion, old );
  208.                 strcat( mac->expansion, " " );
  209.                 strcat( mac->expansion, rhs );
  210.             }
  211.         }
  212.         else mac->expansion = strdup( rhs );
  213.         if( old ) free( old );
  214.     }
  215.     else mac = new_macro( macroname, rhs );
  216.  
  217.     if( mac ) {
  218.         if( do_expansion ) mac->flags |= MF_SIMPLE;
  219.         if( !(mac->flags & MF_ADDED )) {
  220.             mac->flags |= MF_ADDED;
  221.             AddTail( &Global.macrolist, &mac->node );
  222.         }
  223.         debugprintf( 5, ( "assigned macro [%s] = [%s]\n",
  224.             mac->name, mac->expansion ));
  225.     }
  226.     else {
  227.         debugprintf( 2, ("error assigning macro [%s]\n", macroname ) );
  228.     }
  229.  
  230.     if( expansion ) free( expansion );
  231.     return( mac );
  232. death:
  233.     if( expansion ) free( expansion );
  234.     if( mac ) free( mac );
  235.     return( NULL );
  236. }
  237.  
  238. /*    read in all rules and variables from this makefile
  239. */
  240. int
  241. input_makefile( const char *makefile )
  242. {
  243.     char *curline = NULL;
  244.     char *commandline = NULL;
  245.     FILE *infile = NULL;
  246.     int targetcount = 0, macrocount = 0;
  247.     int st;
  248.  
  249.     curline = (char *)malloc( Param.MaxLine );
  250.     commandline = (char *)malloc( Param.MaxLine );
  251.     if( !curline || !commandline ) goto death;
  252.  
  253.     infile = fopen( makefile, "r" );
  254.     if( !infile ) {
  255.         logprintf( "Cannot open %s\n", makefile );
  256.         goto death;
  257.     }
  258.  
  259.     debugprintf( 3,( "input Makefile: %s\n", makefile ));
  260.  
  261.     line_number = 0;
  262.     if( st = getline( curline, Param.MaxLine, infile )) goto death;
  263.     while( !st ) {
  264.         /* debugprintf( 5,( "getline %d: %s\n", line_number, curline )); */
  265.         if( strchr( curline, '=' )) {
  266.             macrocount++;
  267.             process_macroline( curline );
  268.  
  269.             st = getline( curline, Param.MaxLine, infile );
  270.         }
  271.         else if( isemptyline( curline )) {
  272.             st = getline( curline, Param.MaxLine, infile );
  273.         }
  274.         else {
  275.             struct List cmdList;
  276.             struct target *targ = NULL;
  277.             struct command *cmd = NULL;
  278.             char *delim;
  279.  
  280.             NewList( &cmdList );
  281.  
  282.             targetcount++;
  283.             *commandline = (char)0;
  284.  
  285.             delim = find_token( curline + 1, ':' );
  286.             if( delim ) {
  287.                 if( delim = find_token( delim + 1, ';' ) ) {
  288.                     *delim++ = (char)0;
  289.                     *commandline = '\t'; /* commandlines begin with a tab */
  290.                     strcpy( commandline + 1, delim );
  291.                 }
  292.             }
  293.  
  294.             if( st = ( *commandline ) ? 0 :
  295.                 getline( commandline, Param.MaxLine, infile )) break;
  296.             while( !st ) {
  297.                 if( *commandline != '\t' ) break;
  298.                 debugprintf( 5,("tabline %d: %s\n",line_number, commandline));
  299.                 delim = commandline;
  300.                 while( isspace( *delim )) delim++;
  301.                 if( *delim ) { /* line is not empty */
  302.                     if( cmd = new_command( delim ))
  303.                         AddTail( &cmdList, &cmd->node );
  304.                     else {
  305.                         printf( "Could not add command for target\n" ); 
  306.                         goto death;
  307.                     }
  308.                 }
  309.                 st = getline( commandline, Param.MaxLine, infile );
  310.             } /* while */
  311.  
  312.             debugprintf( 4, ("targetline %d is %s\n", line_number, curline));
  313.             targ = process_targetline( curline, &cmdList );
  314.             if( !targ ) {
  315.                 logprintf( "Error in Makefile before line %d: %s\n",
  316.                     line_number, curline );
  317.                 goto death;
  318.             }
  319.  
  320.             strcpy( curline, commandline );
  321.         } /* else */
  322.     } /* while */
  323.  
  324.     debugprintf( 2,( "targetcount = %d\nmacrocount = %d\n", targetcount,
  325.         macrocount ));
  326.  
  327. #if DEBUG
  328.     if( Param.debug && Param.verbosity >= 5 ) {
  329.         dump_all();
  330.     }
  331. #endif
  332.     if( get_directive_state( &Mstack )) {
  333.         logfile( "Missing endif directive in conditional\n" );
  334.         goto death;
  335.     }
  336.  
  337.     free( commandline );
  338.     free( curline );
  339.     fclose( infile );
  340.     return( 0 );
  341. death:
  342.     if( commandline ) free( commandline );
  343.     if( curline ) free( curline );
  344.     if( infile ) fclose( infile );
  345.     return( 1 );
  346. }
  347.