/* * Copyright 1993, 1995 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. */ /* * command.c - maintain lists of commands * * 01/20/00 (seiwald) - Upgraded from K&R to ANSI C * 09/08/00 (seiwald) - bulletproof PIECEMEAL size computation */ # include "jam.h" # include "lists.h" # include "parse.h" # include "variable.h" # include "rules.h" # include "tmpfile.h" # include "expand.h" # include "command.h" static int cmd_string( const char *in, char *out, int outsize, LOL *lol, ARGFILE **args); /* * cmd_new() - return a new CMD or 0 if too many args */ CMD * cmd_new( RULE *rule, LIST *targets, LIST *sources, LIST *shell ) { CMD *cmd = (CMD *)malloc( sizeof( CMD ) ); cmd->rule = rule; cmd->shell = shell; cmd->next = 0; cmd->argfiles = 0; lol_init( &cmd->args ); lol_add( &cmd->args, targets ); lol_add( &cmd->args, sources ); /* Bail if the result won't fit in MAXLINE */ /* We don't free targets/sources/shell if bailing. */ if( cmd_string( rule->actions, cmd->buf, MAXLINE, &cmd->args, &cmd->argfiles ) < 0 ) { cmd_free( cmd ); return 0; } return cmd; } /* * cmd_free() - free a CMD */ void cmd_free( CMD *cmd ) { lol_free( &cmd->args ); list_free( cmd->shell ); while( cmd->argfiles ) { ARGFILE *t; t = cmd->argfiles; cmd->argfiles = t->next; tmp_release( t->file ); free( t ); } free( (char *)cmd ); } /* * cmd_string() - expand a string with variables in it, handling * the magic 'expand to file' prefix. Based on var_string(). * * Copies in to out; doesn't modify targets & sources. * * Adds files created into the args linked list. The caller is * responsible for deletion, even in failure conditions. * */ #define MAX_TMPFILES 10 static int cmd_string( const char *in, char *out, int outsize, LOL *lol, ARGFILE **args) { char *out0 = out; char *oute = out + outsize - 1; ARGFILE *argfiles[MAX_TMPFILES]; int i; for( i = 0; i < MAX_TMPFILES; ++i) argfiles[i] = 0; while( *in ) { char *lastword; int dollar = 0; int fileargs = 0; int tmpfile = -1; /* Copy white space */ while( isspace( *in ) ) { if( out >= oute ) return -1; *out++ = *in++; } lastword = out; /* Copy non-white space, watching for variables & magic flags */ /* The magic flag characters are a bit ugly, in the hope that * no one else will choose sequences that ugly. */ while( *in && !isspace( *in ) ) { if( out >= oute ) return -1; if( in[0] == '$' && in[1] == '(' ) dollar++; else if( !dollar && !fileargs && in[0] == '@' ) { /* If a magic flag is encountered, advance lastword. */ /* Any characters before the magic flag are not used * in variable expansion. */ if( in[1] == '^' || ( in[1] == '#' && isdigit( in[2] ) ) ) { fileargs = 1; lastword = out; if( in[1] == '#' ) tmpfile = in[2] - '0'; } } *out++ = *in++; } /* If we saw the magic prefix, expand the following expression * to a file, one entry per line and add the filename to the * output if it hasn't previously been added. * OTHERWISE * If a variable encountered, expand it and and embed the * space-separated members of the list in the output. */ if( fileargs ) { LIST *l; ARGFILE *a; int copy_file = 0; if( tmpfile >= 0 && argfiles[ tmpfile ] ) a = argfiles[tmpfile]; else { a = malloc( sizeof( ARGFILE ) ); a->next = *args; a->file = tmp_new( 0 ); if( !a->file ) { /* display message and die: any alternative? */ free( a ); printf( "jam: Could not create temporary file\n" ); exit( EXITBAD ); } if( tmpfile >= 0 ) argfiles[ tmpfile ] = a; copy_file = 1; } *args = a; /* +2 to skip over the magic flag, plus the file number */ l = var_expand( L0, lastword + 2 + ( tmpfile >= 0 ? 1 : 0 ), out, lol, 0 ); out = lastword; for( ; l; l = list_next( l ) ) { tmp_write( a->file, l->string, strlen( l->string ) ); tmp_write( a->file, "\n", 1 ); } if( !tmp_flush( a->file ) ) { printf( "jam: I/O error on temporary file\n"); exit( EXITBAD ); } /* Only copy the filename the first time we reference it */ if( copy_file ) { int so = strlen( a->file->name ); if( out + so > oute ) return -1; memcpy( out, a->file->name, so ); out += so; *out++ = ' '; } if( tmpfile < 0 ) tmp_close( a->file ); } else if( dollar ) { LIST *l; l = var_expand( L0, lastword, out, lol, 0 ); out = lastword; for( ; l; l = list_next( l ) ) { int so = strlen( l->string ); if( out + so >= oute ) return -1; strcpy( out, l->string ); out += so; *out++ = ' '; } list_free( l ); } } if( out >= oute ) return -1; for( i = 0; i < MAX_TMPFILES; ++i ) if( argfiles[ i ] ) tmp_close( argfiles[ i ]->file ); *out++ = '\0'; return out - out0; }
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#3 | 2632 | Jan Mikkelsen |
- Added support for expression expansion to a temporary file in actions. There are two forms: the "one-shot" syntax of "@^" and the numbered form or "@#n", where n is a digit 0 through 9. - Removed unnecessary #include of command.h in make.c |
||
#2 | 2631 | Jan Mikkelsen |
Integrate changes from mainline in preparation for adding my changes (at last). |
||
#1 | 1723 | Jan Mikkelsen | Integrate Jam 2.4 | ||
//guest/perforce_software/jam/src/command.c | |||||
#3 | 486 | Perforce staff |
Jam 2.3. See RELNOTES for a list of changes from 2.2.x. Just about every source file was touched when jam got ANSI-fied. |
||
#2 | 76 | Laura Wingerd |
Integrate command-block-too-long fix, plus minor doc updates. Jam/MR release level is now 2.2.5. (change 72, change 73, change 74, change 75) |
||
#1 | 2 | laura | Add Jam/MR 2.2 source |