int var_string( char *in, char *out, int outsize, LOL *lol ) { char *out0 = out; char *oute = out + outsize - 1; while( *in ) { char *lastword; int dollar = 0; /* Copy white space */ while( isspace( *in ) ) { if( out >= oute ) return -1; *out++ = *in++; } lastword = out; /* Copy non-white space, watching for variables */ while( *in && !isspace( *in ) ) { if( out >= oute ) return -1; if( in[0] == '$' && in[1] == '(' ) dollar++; #ifdef OPT_AT_FILES else if ( in[0] == '@' && in[1] == '(' ) { int depth = 1; char *ine = in + 2; char *split = 0; /* Scan the content of the response file @() section. */ while( *ine && depth > 0 ) { switch( *ine ) { case '(': ++depth; break; case ')': --depth; break; case ':': if( depth == 1 && ine[1] == 'E' && ine[2] == '=' ) { split = ine; } break; } ++ine; } if (!split) { printf( "no file specified!\n" ); exit( EXITBAD ); } if ( depth == 0 ) { string file_name_v; int file_name_l = 0; const char * file_name_s = 0; /* expand the temporary file name var inline */ #if 0 string_copy(&file_name_v,"$("); string_append_range(&file_name_v,in+2,split); string_push_back(&file_name_v,')'); #else string_new(&file_name_v); string_append_range(&file_name_v,in+2,split); #endif file_name_l = var_string(file_name_v.value,out,oute-out+1,lol); string_free(&file_name_v); if ( file_name_l < 0 ) return -1; file_name_s = out; /* for stdout/stderr we will create a temp file and generate a command that outputs the content as needed. */ if ( strcmp( "STDOUT", out ) == 0 || strcmp( "STDERR", out ) == 0 ) { int err_redir = strcmp( "STDERR", out ) == 0; out[0] = '\0'; file_name_s = path_tmpfile(); file_name_l = strlen(file_name_s); #ifdef OS_NT if ( (out+7+file_name_l+(err_redir?5:0)) >= oute ) return -1; sprintf( out,"type \"%s\"%s", file_name_s, err_redir ? " 1>&2" : "" ); #else if ( (out+6+file_name_l+(err_redir?5:0)) >= oute ) return -1; sprintf( out,"cat \"%s\"%s", file_name_s, err_redir ? " 1>&2" : "" ); #endif /* we also make sure that the temp files created by this get nuked eventually. */ file_remove_atexit( file_name_s ); } /* expand the file value into the file reference */ if ( !globs.noexec ) var_string_to_file( split+3, ine-split-4, file_name_s, lol ); /* continue on with the expansion */ out += strlen(out); } /* and continue with the parsing just past the @() reference */ in = ine; } #endif *out++ = *in++; } /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */ if (out >= oute) return -1; /* Don't increment, intentionally. */ *out= '\0'; /* If a variable encountered, expand it and and embed the */ /* space-separated members of the list in the output. */ if( dollar ) { LIST *l; l = var_expand( L0, lastword, out, lol, 0 ); out = lastword; while ( l ) { int so = strlen( l->string ); if( out + so >= oute ) return -1; strcpy( out, l->string ); out += so; l = list_next( l ); if ( l ) *out++ = ' '; } list_free( l ); } } if( out >= oute ) return -1; *out++ = '\0'; return out - out0; }
int var_string( const char * in, char * out, int outsize, LOL * lol ) { char * out0 = out; char * oute = out + outsize - 1; while ( *in ) { char * lastword; int dollar = 0; /* Copy white space. */ while ( isspace( *in ) ) { if ( out >= oute ) return -1; *out++ = *in++; } lastword = out; /* Copy non-white space, watching for variables. */ while ( *in && !isspace( *in ) ) { if ( out >= oute ) return -1; if ( ( in[ 0 ] == '$' ) && ( in[ 1 ] == '(' ) ) { ++dollar; *out++ = *in++; } #ifdef OPT_AT_FILES else if ( ( in[ 0 ] == '@' ) && ( in[ 1 ] == '(' ) ) { int depth = 1; const char * ine = in + 2; const char * split = 0; /* Scan the content of the response file @() section. */ while ( *ine && ( depth > 0 ) ) { switch ( *ine ) { case '(': ++depth; break; case ')': --depth; break; case ':': if ( ( depth == 1 ) && ( ine[ 1 ] == 'E' ) && ( ine[ 2 ] == '=' ) ) split = ine; break; } ++ine; } if ( !split ) { /* the @() reference doesn't match the @(foo:E=bar) format. hence we leave it alone by copying directly to output. */ int l = 0; if ( out + 2 >= oute ) return -1; *( out++ ) = '@'; *( out++ ) = '('; l = var_string( in + 2, out, oute - out, lol ); if ( l < 0 ) return -1; out += l; if ( out + 1 >= oute ) return -1; *( out++ ) = ')'; } else if ( depth == 0 ) { string file_name_v; OBJECT * file_name = 0; int file_name_l = 0; const char * file_name_s = 0; /* Expand the temporary file name var inline. */ #if 0 string_copy( &file_name_v, "$(" ); string_append_range( &file_name_v, in + 2, split ); string_push_back( &file_name_v, ')' ); #else string_new( &file_name_v ); string_append_range( &file_name_v, in + 2, split ); #endif file_name_l = var_string( file_name_v.value, out, oute - out + 1, lol ); string_free( &file_name_v ); if ( file_name_l < 0 ) return -1; file_name_s = out; /* For stdout/stderr we will create a temp file and generate * a command that outputs the content as needed. */ if ( ( strcmp( "STDOUT", out ) == 0 ) || ( strcmp( "STDERR", out ) == 0 ) ) { int err_redir = strcmp( "STDERR", out ) == 0; out[ 0 ] = '\0'; file_name = path_tmpfile(); file_name_s = object_str(file_name); file_name_l = strlen(file_name_s); #ifdef OS_NT if ( ( out + 7 + file_name_l + ( err_redir ? 5 : 0 ) ) >= oute ) return -1; sprintf( out,"type \"%s\"%s", file_name_s, err_redir ? " 1>&2" : "" ); #else if ( ( out + 6 + file_name_l + ( err_redir ? 5 : 0 ) ) >= oute ) return -1; sprintf( out,"cat \"%s\"%s", file_name_s, err_redir ? " 1>&2" : "" ); #endif /* We also make sure that the temp files created by this * get nuked eventually. */ file_remove_atexit( file_name ); } /* Expand the file value into the file reference. */ var_string_to_file( split + 3, ine - split - 4, file_name_s, lol ); if ( file_name ) { object_free( file_name ); } /* Continue on with the expansion. */ out += strlen( out ); } /* And continue with the parsing just past the @() reference. */ in = ine; } #endif else { *out++ = *in++; } } /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */ if ( out >= oute ) return -1; /* Do not increment, intentionally. */ *out = '\0'; /* If a variable encountered, expand it and and embed the * space-separated members of the list in the output. */ if ( dollar ) { LIST * l = var_expand( L0, lastword, out, lol, 0 ); LIST * saved = l; out = lastword; while ( l ) { int so = strlen( object_str( l->value ) ); if ( out + so >= oute ) return -1; strcpy( out, object_str( l->value ) ); out += so; l = list_next( l ); if ( l ) *out++ = ' '; } list_free( saved ); } } if ( out >= oute ) return -1; *out++ = '\0'; return out - out0; }