⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 variable.c

📁 Boost provides free peer-reviewed portable C++ source libraries. We emphasize libraries that work
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1993, 2000 Christopher Seiwald. * * This file is part of Jam - see jam.c for Copyright information. *//*  This file is ALSO: *  Copyright 2001-2004 David Abrahams. *  Copyright 2005 Reece H. Dunn. *  Copyright 2005 Rene Rivera. *  Distributed under the Boost Software License, Version 1.0. *  (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) */# include "jam.h"# include "lists.h"# include "parse.h"# include "variable.h"# include "expand.h"# include "hash.h"# include "filesys.h"# include "newstr.h"# include "strings.h"# include "pathsys.h"# include <stdlib.h># include <stdio.h>/* * variable.c - handle jam multi-element variables * * External routines: * *	var_defines() - load a bunch of variable=value settings *	var_string() - expand a string with variables in it *	var_get() - get value of a user defined symbol *	var_set() - set a variable in jam's user defined symbol table *	var_swap() - swap a variable's value with the given one *	var_done() - free variable tables * * Internal routines: * *	var_enter() - make new var symbol table entry, returning var ptr *	var_dump() - dump a variable to stdout * * 04/13/94 (seiwald) - added shorthand L0 for null list pointer * 08/23/94 (seiwald) - Support for '+=' (append to variable) * 01/22/95 (seiwald) - split environment variables at blanks or :'s * 05/10/95 (seiwald) - split path variables at SPLITPATH (not :) * 09/11/00 (seiwald) - defunct var_list() removed */static struct hash *varhash = 0;/* * VARIABLE - a user defined multi-value variable */typedef struct _variable VARIABLE ;struct _variable {	char	*symbol;	LIST	*value;} ;static VARIABLE *var_enter( char *symbol );static void var_dump( char *symbol, LIST *value, char *what );/* * var_hash_swap() - swap all variable settings with those passed * * Used to implement separate settings spaces for modules */void var_hash_swap( struct hash** new_vars ){    struct hash* old = varhash;    varhash = *new_vars;    *new_vars = old;}/* * var_defines() - load a bunch of variable=value settings * * If preprocess is false, take the value verbatim. * * Otherwise, if the variable value is enclosed in quotes, strip the * quotes. * * Otherwise, if variable name ends in PATH, split value at :'s. * * Otherwise, split the value at blanks. */voidvar_defines( char *const* e, int preprocess ){    string buf[1];    string_new( buf );	for( ; *e; e++ )	{	    char *val;# ifdef OS_MAC	    /* On the mac (MPW), the var=val is actually var\0val */	    /* Think different. */		    if( ( val = strchr( *e, '=' ) ) || ( val = *e + strlen( *e ) ) )# else	    if( val = strchr( *e, '=' ) )# endif	    {		LIST *l = L0;		char *pp, *p;# ifdef OPT_NO_EXTERNAL_VARIABLE_SPLIT                char split = '\0';# else# ifdef OS_MAC		char split = ',';# else		char split = ' ';# endif# endif                size_t len = strlen(val + 1);                int quoted = val[1] == '"' && val[len] == '"' && len > 1;                                if ( quoted && preprocess )                {                    string_append_range( buf, val + 2, val + len );                    l = list_new( l, newstr( buf->value ) );                    string_truncate( buf, 0 );                }                else                {                    /* Split *PATH at :'s, not spaces */                    if( val - 4 >= *e )                    {                        if( !strncmp( val - 4, "PATH", 4 ) ||                            !strncmp( val - 4, "Path", 4 ) ||                            !strncmp( val - 4, "path", 4 ) )			    split = SPLITPATH;                    }                    /* Do the split */                    for(                        pp = val + 1;                        preprocess && (p = strchr( pp, split )) != 0;                        pp = p + 1 )                    {                        string_append_range( buf, pp, p );                        l = list_new( l, newstr( buf->value ) );                        string_truncate( buf, 0 );                    }                    l = list_new( l, newstr( pp ) );                }		/* Get name */                string_append_range( buf, *e, val );		var_set( buf->value, l, VAR_SET );                string_truncate( buf, 0 );	    }	}        string_free( buf );}/* * var_string() - expand a string with variables in it * * Copies in to out; doesn't modify targets & sources. */intvar_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++;                *out++ = *in++;            }            #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)                {                    /*  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;                    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 */                    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            else            {                *out++ = *in++;            }        }        /* Add zero to 'out' so that 'lastword' is correctly zero-terminated. */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -