Ejemplo n.º 1
0
// Don't test printing code to thoroughly because it will change a lot
void test_print_functions() {
	char*  output_ptr = NULL;
	size_t output_len = 0;
	FILE* output = NULL;
	
	node_p module = node_alloc(NT_MODULE);
	module->module.filename = str_from_c("tokenizer_test.c/test_print_functions");
	module->module.source = str_from_c("x = \n1 + y\n\"next\nline\"");
	
	tokenize(module->module.source, &module->tokens, stderr);
	st_check_int(module->tokens.len, 12);
	
	output = open_memstream(&output_ptr, &output_len);
		token_print(output, &module->tokens.ptr[10], TP_SOURCE);
	fclose(output);
	st_check_str(output_ptr, "\"next\nline\"");
	
	output = open_memstream(&output_ptr, &output_len);
		token_print(output, &module->tokens.ptr[10], TP_DUMP);
	fclose(output);
	st_check_not_null( strstr(output_ptr, "\"next\nline\"") );
	
	output = open_memstream(&output_ptr, &output_len);
		token_print(output, &module->tokens.ptr[10], TP_INLINE_DUMP);
	fclose(output);
	st_check_not_null( strstr(output_ptr, "\"next\\nline\"") );
}
Ejemplo n.º 2
0
void
cook_search_list(const opcode_context_ty *ocp, string_list_ty  *slp)
{
    string_ty        *s;
    id_ty            *idp;

    /*
     * make sure the variable exists
     */
    trace(("cook_search_list()\n{\n"));
    idp = opcode_context_id_search(ocp, id_search_list);
    if (!idp)
    {
        string_list_constructor(slp);
        s = str_from_c(".");
        string_list_append(slp, s);
        str_free(s);
        opcode_context_id_assign
        (
            (opcode_context_ty *)ocp,
            id_search_list,
            id_variable_new(slp),
            0
        );
        string_list_destructor(slp);
    }

    /*
     * extract its string value
     */
    id_variable_query(idp, slp);

    /*
     * make sure the search list isn't empty
     * make sure the search list has "." as the first element
     */
    if
    (
        !slp->nstrings
    ||
        slp->string[0]->str_length != 1
    ||
        slp->string[0]->str_text[0] != '.'
    )
    {
        s = str_from_c(".");
        string_list_prepend(slp, s);
        str_free(s);
        opcode_context_id_assign
        (
            (opcode_context_ty *)ocp,
            id_search_list,
            id_variable_new(slp),
            0
        );
    }
    trace(("}\n"));
}
Ejemplo n.º 3
0
bool get_subdirectories(
			std::vector<std::string> &list,
			const std::string &path )
{
#ifdef SFML_SYSTEM_WINDOWS
	std::string temp = path + "*";

	struct _finddata_t t;
	intptr_t srch = _findfirst( temp.c_str(), &t );

	if  ( srch < 0 )
		return false;

	do
	{
		std::string what;
		str_from_c( what, t.name );

		if ( ( what.compare( "." ) == 0 ) || ( what.compare( ".." ) == 0 ) )
			continue;

		if ( t.attrib & _A_SUBDIR )
			list.push_back( what );

	} while ( _findnext( srch, &t ) == 0 );
	_findclose( srch );

#else

	DIR *dir;
	struct dirent *ent;
	if ( (dir = opendir( path.c_str() )) == NULL )
		return false;

	while ((ent = readdir( dir )) != NULL )
	{
		std::string name;
		str_from_c( name, ent->d_name );

		if (( name.compare( "." ) == 0 )
				|| ( name.compare( ".." ) == 0 ))
			continue;

		struct stat st;
		stat( (path + name).c_str(), &st );

		if ( S_ISDIR( st.st_mode ) )
			list.push_back( name );
	}
	closedir( dir );

#endif

	return true;
}
Ejemplo n.º 4
0
static blob_list_ty *
ifndef(blob_list_ty *blp, string_list_ty *ref)
{
    blob_ty         *arg;
    blob_list_ty    *result;
    blob_ty         *bp;

    arg = blp->list[0];
    result = ifdef(blp, ref);
    bp = blob_alloc(str_from_c("[not"), arg->file_name, arg->line_number);
    blob_list_prepend(result, bp);
    bp = blob_alloc(str_from_c("]"), arg->file_name, arg->line_number);
    blob_list_append(result, bp);
    return result;
}
Ejemplo n.º 5
0
void
str_initialize(void)
{
    str_hash_ty     j;

    hash_modulus = 1 << 8; /* MUST be a power of 2 */
    hash_mask = hash_modulus - 1;
    hash_load = 0;
    hash_table = mem_alloc(hash_modulus * sizeof(string_ty *));
    for (j = 0; j < hash_modulus; ++j)
	    hash_table[j] = 0;

    str_true = str_from_c("1");
    str_false = str_from_c("");
}
Ejemplo n.º 6
0
stmt_ty *
stmt_if_alloc(blob_list_ty *condition, stmt_ty *then_clause,
    stmt_ty *else_clause)
{
    stmt_if_ty      *result;
    blob_list_ty    *c2;
    table_ty        *tp;

    trace(("stmt_if_alloc()\n{\n"));
    result = (stmt_if_ty *)stmt_alloc(&method);

    assert(condition->length >= 1);
    for (tp = table; tp < ENDOF(table); ++tp)
    {
        if (!tp->fast)
            tp->fast = str_from_c(tp->name);
        if (str_equal(condition->list[0]->text, tp->fast))
            break;
    }
    assert(tp < ENDOF(table));
    if (tp >= ENDOF(table))
        tp = &table[0];
    c2 = tp->rewrite(condition, &result->ref);
    blob_list_free(condition);

    result->condition = c2;
    result->then_clause = then_clause;
    result->else_clause = else_clause;

    stmt_variable_merge((stmt_ty *)result, then_clause);
    if (else_clause)
        stmt_variable_merge((stmt_ty *)result, else_clause);
    trace(("}\n"));
    return (stmt_ty *)result;
}
Ejemplo n.º 7
0
void
fp_find_flush(void)
{
    static string_ty *dot;
    fp_subdir_ty    *sdp;

    if (!option_test(OPTION_FINGERPRINT_WRITE))
    {
        trace(("no fp write\n"));
        return;
    }

    /*
     * Write out all of the known subdirectories, except dot.
     */
    trace(("fp_find_flush()\n{\n"));
    need_to_write_dot = 0;
    if (subdir_stp)
        symtab_walk(subdir_stp, subdir_walk, 0);

    /*
     * Do dot last, so we catch all of the `cache_in_dot's.
     */
    if (!dot)
        dot = str_from_c(".");
    sdp = fp_find_subdir(dot, 0);
    if (need_to_write_dot)
        sdp->dirty = 1;
    fp_subdir_write(sdp, &need_to_write_dot);
    trace(("}\n"));
}
Ejemplo n.º 8
0
void
lex_open(char *s)
{
    trace(("lex_open()\n{\n"));
    assert(!input);
    blob_error_notify(notify);
    if (s)
    {
        string_ty       *filename;

        filename = str_from_c(s);
        input = input_file_text_open(filename);
        str_free(filename);
    }
    else
    {
        input = input_file_text_open((string_ty *) 0);
    }
    line_number = 1;
    bol = 1;
    first = 1;
    colon_special = 1;
    error_count = 0;
    trace(("}\n"));
}
Ejemplo n.º 9
0
void
fp_tweak(void)
{
    static string_ty *dot;

    if (!dot)
        dot = str_from_c(".");
    fp_subdir_tweak(fp_find_subdir(dot, 1));
}
Ejemplo n.º 10
0
std::string clean_path( const std::string &path, bool add_trailing_slash )
{
	std::string retval = path;

	if ( retval.empty() )
		return retval;

#ifdef SFML_SYSTEM_WINDOWS
	// substitute systemroot leading %SYSTEMROOT%
	if (( retval.size() >= 12 )
		&& ( retval.compare( 0, 12, "%SYSTEMROOT%" ) == 0 ))
	{
		std::string sysroot;
		str_from_c( sysroot, getenv( "SystemRoot" ) );
		retval.replace( 0, 12, sysroot );
	}
	else if (( retval.size() >= 14 )
		&& ( retval.compare( 0, 14, "%PROGRAMFILES%" ) == 0 ))
	{
		std::string pf;
		str_from_c( pf, getenv( "ProgramFiles" ) );
		retval.replace( 0, 14, pf );
	}

#endif

	// substitute home dir for leading ~
	if (( retval.size() >= 1 ) && ( retval.compare( 0, 1, "~" ) == 0 ))
		retval.replace( 0, 1, get_home_dir() );

	// substitute home dir for leading $HOME
	if (( retval.size() >= 5 ) && ( retval.compare( 0, 5, "$HOME" ) == 0 ))
		retval.replace( 0, 5, get_home_dir() );

	if (( add_trailing_slash )
#ifdef SFML_SYSTEM_WINDOWS
			&& (retval[retval.size()-1] != '\\')
#endif
			&& (retval[retval.size()-1] != '/')
			&& (directory_exists(retval)) )
		retval += '/';

	return retval;
}
Ejemplo n.º 11
0
int
main(int argc, char **argv)
{
    string_ty       *s;
    string_list_ty  sl;
    size_t          j;

    arglex_init(argc, argv, argtab);
    str_initialize();
    switch (arglex())
    {
    case arglex_token_help:
        help((char *)0, usage);
        exit(0);

    case arglex_token_version:
        version();
        exit(0);

    default:
        break;
    }

    string_list_constructor(&sl);
    while (arglex_token != arglex_token_eoln)
    {
        switch (arglex_token)
        {
        default:
            generic_argument(usage);
            continue;

        case arglex_token_warning:
            warning++;
            break;

        case arglex_token_string:
            s = str_from_c(arglex_value.alv_string);
            string_list_append_unique(&sl, s);
            str_free(s);
            break;
        }
        arglex();
    }

    if (!sl.nstrings)
    {
        error_intl(0, i18n("no files named"));
        usage();
    }

    for (j = 0; j < sl.nstrings; ++j)
        file_check(sl.string[j]);
    exit(0);
    return 0;
}
Ejemplo n.º 12
0
static int
interpret(string_list_ty *result, const string_list_ty *arg,
    const expr_position_ty *pp, const struct opcode_context_ty *ocp)
{
    string_ty       *s;
    size_t          j;
    struct passwd   *pw;

    trace(("home\n"));
    (void)ocp;
    if (arg->nstrings < 2)
    {
        const char      *cp;

        cp = home_directory();
        assert(cp);
        s = str_from_c(cp);
        string_list_append(result, s);
        str_free(s);
        return 0;
    }
    for (j = 1; j < arg->nstrings; ++j)
    {
        s = arg->string[j];
        pw = getpwnam(s->str_text);
        if (!pw)
        {
            sub_context_ty  *scp;

            scp = sub_context_new();
            sub_var_set_string(scp, "Name", s);
            error_with_position(pp, scp, i18n("user \"$name\" unknown"));
            sub_context_delete(scp);
            return -1;
        }
        s = str_from_c(pw->pw_dir);
        string_list_append(result, s);
        str_free(s);
    }
    return 0;
}
Ejemplo n.º 13
0
fp_subdir_ty *
fp_find_subdir(string_ty *dirname, int ok_to_read)
{
    fp_subdir_ty    *sdp;

    /*
     * Most of the time, we have already polled this one before,
     * so do a quick lookup and see.
     */
    trace(("fp_find_subdir(dirname = \"%s\")\n{\n", dirname->str_text));
    if (!subdir_stp)
    {
        static string_ty *dot;

        subdir_stp = symtab_alloc(10);
        subdir_stp->reap = subdir_reap;

        /*
         * Read dot (the current directory) immediately.
         * This primes the cache with all the things that were
         * found to be read-only on previous runs.
         */
        if (!dot)
            dot = str_from_c(".");
        sdp = fp_subdir_new(dot);
        symtab_assign(subdir_stp, dot, sdp);
        fp_subdir_read(sdp);
    }
    sdp = symtab_query(subdir_stp, dirname);
    if (!sdp)
    {
        /*
         * It's a new one, we must allocate it.
         */
        sdp = fp_subdir_new(dirname);
        symtab_assign(subdir_stp, dirname, sdp);
    }

    if (ok_to_read && sdp->need_to_read)
    {
        /*
         * Read in the cache file from the directory,
         * if it exists.  This causes a number of
         * fp_find_update calls (see below), one for
         * each entry.
         */
        fp_subdir_read(sdp);
    }

    trace(("return %08lX;\n", (long)sdp));
    trace(("}\n"));
    return sdp;
}
Ejemplo n.º 14
0
static void
set_command_line_goals(void)
{
    string_ty       *name;
    opcode_context_ty *ocp;

    name = str_from_c("command-line-goals");
    ocp = opcode_context_new(0, 0);
    opcode_context_id_assign(ocp, name, id_variable_new(&option.o_target), 0);
    opcode_context_delete(ocp);
    str_free(name);
}
Ejemplo n.º 15
0
void
builtin_initialize(void)
{
    builtin_ty      **fpp;
    string_ty       *s;

    for (fpp = func; fpp < ENDOF(func); ++fpp)
    {
        s = str_from_c((*fpp)->name);
        symtab_assign(id_global_stp(), s, id_builtin_new(*fpp));
        str_free(s);
    }
}
Ejemplo n.º 16
0
graph_walk_status_ty
graph_walk(graph_ty *gp)
{
    int             nproc;
    string_ty       *key;
    string_ty       *s;
    id_ty           *idp;
    string_list_ty  wl;
    opcode_context_ty *ocp;

    /*
     * see if the jobs variable is set
     */
    key = str_from_c("parallel_jobs");
    ocp = opcode_context_new(0, 0);
    idp = opcode_context_id_search(ocp, key);

    /*
     * extract the number of jobs
     */
    nproc = 1;
    if (idp)
    {
        id_variable_query(idp, &wl);
        if (wl.nstrings == 1)
        {
            nproc = atoi(wl.string[0]->str_text);
            if (nproc < 1)
                nproc = 1;
        }
        string_list_destructor(&wl);
    }

    /*
     * Set the jobs variable to precisely reflect what we are going
     * to do, should the recipes use it in some way.
     */
    string_list_constructor(&wl);
    s = str_format("%d", nproc);
    string_list_append(&wl, s);
    str_free(s);
    opcode_context_id_assign(ocp, key, id_variable_new(&wl), 0);
    string_list_destructor(&wl);
    str_free(key);
    opcode_context_delete(ocp);

    /*
     * walk the graph
     */
    return graph_walk_inner(gp, graph_recipe_run, nproc);
}
Ejemplo n.º 17
0
static blob_list_ty *
ifdef(blob_list_ty *blp, string_list_ty *ref)
{
    blob_ty         *bp;
    blob_list_ty    *result;
    size_t          j;

    bp = blp->list[0];
    result = blob_list_alloc();
    blob_list_append
    (
        result,
        blob_alloc(str_from_c("[defined"), bp->file_name, bp->line_number)
    );
    for (j = 1; j < blp->length; ++j)
        variable_rename(blp->list[j], result, ref, VAREN_QUOTE_SPACES);
    blob_list_append
    (
        result,
        blob_alloc(str_from_c("]"), bp->file_name, bp->line_number)
    );
    return result;
}
Ejemplo n.º 18
0
static void
subdir_walk(symtab_ty *stp, string_ty *key, void *data, void *aux)
{
    fp_subdir_ty    *sdp;
    static string_ty *dot;

    trace(("subdir_walk(key = \"%s\")\n{\n", key->str_text));
    (void)stp;
    (void)key;
    (void)aux;
    if (!dot)
        dot = str_from_c(".");
    sdp = data;
    if (!str_equal(sdp->path, dot))
        fp_subdir_write(sdp, &need_to_write_dot);
    trace(("}\n"));
}
Ejemplo n.º 19
0
string_ty *
str_field(string_ty *s, int sep, int fldnum)
{
    char        *cp;
    char        *ep;

    cp = s->str_text;
    while (fldnum > 0)
    {
	ep = strchr(cp, sep);
	if (!ep)
    	    return 0;
	cp = ep + 1;
	--fldnum;
    }
    ep = strchr(cp, sep);
    if (ep)
	return str_n_from_c(cp, ep - cp);
    return str_from_c(cp);
}
Ejemplo n.º 20
0
static int
echo_command(string_list_ty *wlp)
{
    static string_ty *echo;
    string_ty       *tmp;
    char            *cp;

    if (!echo)
        echo = str_from_c("echo");
    if (wlp->nstrings < 1 || !str_equal(wlp->string[0], echo))
        return 0;
    tmp = wl2str(wlp, 0, wlp->nstrings - 1, (char *)0);
    for (cp = tmp->str_text; *cp; ++cp)
    {
        if (strchr("^|>", *cp))
        {
            str_free(tmp);
            return 0;
        }
    }
    str_free(tmp);
    return 1;
}
Ejemplo n.º 21
0
static int
mtime_interpret(string_list_ty *result, const string_list_ty *args,
    const struct expr_position_ty *pp, const struct opcode_context_ty *ocp)
{
    size_t          j;

    trace(("mtime\n"));
    (void)pp;
    assert(result);
    assert(args);
    assert(args->nstrings);
    for (j = 1; j < args->nstrings; j++)
    {
        time_t          mtime;
        long            depth;

        depth = 32767;
        mtime = cook_mtime_newest(ocp, args->string[j], &depth, depth);
        if (mtime < 0)
            return -1;
        if (mtime == 0)
            string_list_append(result, str_false);
        else
        {
            struct tm       *tm;
            char            buffer[1000];
            string_ty       *s;

            tm = localtime(&mtime);
            strftime(buffer, sizeof(buffer), "%Y%m%d%H%M%S", tm);
            s = str_from_c(buffer);
            string_list_append(result, s);
            str_free(s);
        }
    }
    return 0;
}
Ejemplo n.º 22
0
void test_samples() {
	for(size_t i = 0; i < sizeof(samples) / sizeof(samples[0]); i++) {
		char* code = samples[i].code;
		//printf("test: %s\n", code);
		
		token_list_t tokens = { 0 };
		tokenize(str_from_c(code), &tokens, stderr);
		
		st_check_int(tokens.len, samples[i].tokens_len);
		for(size_t j = 0; j < samples[i].tokens_len; j++) {
			token_p actual_token = &tokens.ptr[j];
			token_p expected_token = &samples[i].tokens_ptr[j];
			
			st_check_msg(actual_token->type == expected_token->type, "got %s, expected %s",
				token_type_name(actual_token->type), token_type_name(expected_token->type));
			st_check_int(actual_token->source.len, expected_token->source.len);
			st_check_strn(actual_token->source.ptr, expected_token->source.ptr, expected_token->source.len);
			if (actual_token->type == T_INT) {
				st_check(actual_token->int_val == expected_token->int_val);
			} else if (actual_token->type == T_ERROR) {
				// Check that an error message is present, exact content doesn't matter, will change anyway
				st_check(actual_token->str_val.len > 0);
				st_check_not_null(actual_token->str_val.ptr);
			} else if (expected_token->str_val.ptr != NULL) {
				st_check_int(actual_token->str_val.len, expected_token->str_val.len);
				st_check_strn(actual_token->str_val.ptr, expected_token->str_val.ptr, expected_token->str_val.len);
			} else {
				st_check_null(actual_token->str_val.ptr);
				st_check_int(actual_token->str_val.len, 0);
			}
		}
		
		for(size_t j = 0; j < tokens.len; j++)
			token_cleanup(&tokens.ptr[j]);
		list_destroy(&tokens);
	}
}
Ejemplo n.º 23
0
static int
reserved(string_ty *s)
{
    typedef struct table_ty table_ty;
    struct table_ty
    {
        char            *name;
        int             token;
    };

    static table_ty table[] =
    {
        { "override", OVERRIDE },
        { "include", INCLUDE2 },
        { "-include", INCLUDE3 },
        { ".include", INCLUDE },
        { "vpath", VPATH },
        { "VPATH", VPATH2 },
        { "ifdef", IF },
        { "ifndef", IF },
        { "ifeq", IF },
        { "ifneq", IF },
        { "else", ELSE },
        { "endif", ENDIF },
        { "endef", ENDDEF },
        { "define", DEFINE },
        { "export", EXPORT },
        { "unexport", UNEXPORT },
    };

    static symtab_ty *symtab;
    int             *data;
    string_ty       *name;
    char            *cp;

    if (!symtab)
    {
        table_ty        *tp;

        symtab = symtab_alloc(SIZEOF(table));
        for (tp = table; tp < ENDOF(table); ++tp)
        {
            name = str_from_c(tp->name);
            symtab_assign(symtab, name, &tp->token);
            str_free(name);
        }
    }

    cp = strchr(s->str_text, '(');
    if (cp)
    {
        name = str_n_from_c(s->str_text, cp - s->str_text);
        data = symtab_query(symtab, name);
        str_free(name);
    }
    else
        data = symtab_query(symtab, s);
    if (data)
        return *data;
    return 0;
}
Ejemplo n.º 24
0
static opcode_status_ty
execute(const opcode_ty *op, opcode_context_ty *icp)
{
    opcode_status_ty status;
    const opcode_setenv_append_ty *this;
    string_list_ty  *name;
    string_list_ty  *value;
    string_ty       *s;
    char            *tmp;

    trace(("opcode_setenv_append::execute()\n{\n"));
    status = opcode_status_success;
    this = (const opcode_setenv_append_ty *)op;

    value = opcode_context_string_list_pop(icp);
    name = opcode_context_string_list_pop(icp);

    switch (name->nstrings)
    {
    case 0:
        error_with_position
        (
            &this->pos,
            0,
            i18n("lefthand side of assignment is empty")
        );
        status = opcode_status_error;
        break;

    case 1:
        /*
         * If the environment variable is already set, prepend
         * its existing value to the value list the user gave us.
         */
        tmp = getenv(name->string[0]->str_text);
        if (tmp)
        {
            string_ty       *tmp2;

            tmp2 = str_from_c(tmp);
            string_list_prepend(value, tmp2);
            str_free(tmp2);
        }
        s = wl2str(value, 0, value->nstrings, " ");
        env_set(name->string[0]->str_text, s->str_text);
        str_free(s);
        break;

    default:
        error_with_position
        (
            &this->pos,
            0,
            i18n("lefthand side of assignment is more than one word")
        );
        status = opcode_status_error;
        break;
    }

    string_list_delete(name);
    string_list_delete(value);
    trace(("return %s;\n", opcode_status_name(status)));
    trace(("}\n"));
    return status;
}
Ejemplo n.º 25
0
bool get_basename_from_extension(
			std::vector<std::string> &list,
			const std::string &path,
			const std::string &extension,
			bool strip_extension )
{
#ifdef SFML_SYSTEM_WINDOWS
	std::string temp = path + "*" + extension;

	struct _finddata_t t;
	intptr_t srch = _findfirst( temp.c_str(), &t );

	if  ( srch < 0 )
		return false;

	do
	{
		std::string what;
		str_from_c( what, t.name );

		// I don't know why but the search filespec we are using
		// "path/*.ext"seems to also match "path/*.ext*"... so we
		// do the tail comparison below on purpose to catch this...
#else
	DIR *dir;
	struct dirent *ent;

	if ( (dir = opendir( path.c_str() )) == NULL )
		return false;

	while ((ent = readdir( dir )) != NULL )
	{
		std::string what;
		str_from_c( what, ent->d_name );
#endif

		if ( ( what.compare( "." ) == 0 ) || ( what.compare( ".." ) == 0 ) )
			continue;

		if ( tail_compare( what, extension ) )
		{
			if ( strip_extension && ( what.size() > extension.size() ))
			{
				std::string bname = what.substr( 0,
					what.size() - extension.size() );

				// don't add duplicates if we are stripping extension
				// example: if there is both foo.zip and foo.7z
				//
				if ( list.empty() || ( bname.compare( list.back() ) != 0 ))
					list.push_back( bname );
			}
			else
				list.push_back( what );

		}
#ifdef SFML_SYSTEM_WINDOWS
	} while ( _findnext( srch, &t ) == 0 );
	_findclose( srch );
#else
	}
	closedir( dir );
#endif

	std::sort( list.begin(), list.end() );
	return !(list.empty());
}
Ejemplo n.º 26
0
int
main(int argc, char **argv)
{
    int             retval;

    /*
     * Some versions of cron(8) and at(1) set SIGCHLD to SIG_IGN.
     * This is kinda dumb, because it breaks assumprions made in
     * libc (like pclose, for instance).  It also blows away most
     * of Cook's process handling.  We explicitly set the SIGCHLD
     * signal handling to SIG_DFL to make sure this signal does what
     * we expect no matter how we are invoked.
     */
#ifdef SIGCHLD
    signal(SIGCHLD, SIG_DFL);
#else
    signal(SIGCLD, SIG_DFL);
#endif

    /*
     * initialize things
     * (order is critical here)
     */
    progname_set(argv[0]);
    str_initialize();
    id_initialize();
    lex_initialize();

    /*
     * parse the COOK environment variable
     */
    arglex_init_from_env(argv[0], argtab);
    argparse(OPTION_LEVEL_ENVIRONMENT);

    /*
     * parse the command line
     */
    arglex_init(argc, argv, argtab);
    argparse(OPTION_LEVEL_COMMAND_LINE);

    option_tidy_up();

    log_open();

    /*
     * turn on progress stars if they asked for them
     */
    if (option_test(OPTION_STAR))
        star_enable();

    /*
     * If we were asked to update the fingerprints, do it here.
     * We don't actually ant to read in the cookbook.
     */
    if (option.fingerprint_update)
    {
        fp_tweak();
        quit(0);
    }

    /*
     * read in the cook book
     *
     * If there are #include-cooked directives,
     * we may need to do it more than once.
     */
    if (!option.o_book)
        fatal_intl(0, i18n("no book found"));
    for (;;)
    {
        int             status;
        size_t          j;

        builtin_initialize();

        /*
         * instanciate the command line variable assignments
         */
        for (j = 0; j < option.o_vardef.nstrings; ++j)
        {
            char            *s;
            char            *cp;
            string_ty       *name;
            string_ty       *value;
            string_list_ty  wl;
            opcode_context_ty *ocp;

            s = option.o_vardef.string[j]->str_text;
            cp = strchr(s, '=');
            assert(cp);
            if (!cp)
                continue;
            name = str_n_from_c(s, cp - s);
            value = str_from_c(cp + 1);
            str2wl(&wl, value, (char *)0, 0);
            str_free(value);
            ocp = opcode_context_new(0, 0);
            opcode_context_id_assign(ocp, name, id_variable_new(&wl), 0);
            opcode_context_delete(ocp);
            str_free(name);
            string_list_destructor(&wl);
        }

        set_command_line_goals();

        parse(option.o_book);
        status = cook_auto_required();
        if (status < 0)
            quit(1);
        if (!status)
            break;
        id_reset();
        cook_reset();
    }

    /*
     * work out what to cook.
     * If no targets have been given, use the first explicit recipe.
     */
    set_command_line_goals();
    if (!option.o_target.nstrings)
        cook_find_default(&option.o_target);
    assert(option.o_target.nstrings);

    /*
     * cook the target
     */
    if (option.pairs)
        retval = cook_pairs(&option.o_target);
    else if (option.script)
        retval = cook_script(&option.o_target);
    else if (option.web)
        retval = cook_web(&option.o_target);
    else
        retval = cook(&option.o_target);

#ifdef DEBUG
    fflush_slowly_report();
#endif

    quit(retval);
    /*NOTREACHED*/
    return 0;
}
Ejemplo n.º 27
0
static void
argparse(option_level_ty level)
{
    option_number_ty type;
    string_ty       *s;
    sub_context_ty  *scp;
    int             fingerprint_update;

    type = -1;
    fingerprint_update = 0;
    switch (arglex())
    {
    case arglex_token_help:
        if (level != OPTION_LEVEL_COMMAND_LINE)
        {
          not_in_env:
            scp = sub_context_new();
            sub_var_set(scp, "Name", "%s", arglex_value.alv_string);
            fatal_intl(scp, i18n("may not use $name in environment variable"));
            /* NOTREACHED */
        }
        help((char *)0, usage);
        quit(0);

    case arglex_token_version:
        if (level != OPTION_LEVEL_COMMAND_LINE)
            goto not_in_env;
        version();
        quit(0);

    default:
        break;
    }
    while (arglex_token != arglex_token_eoln)
    {
        switch (arglex_token)
        {
        default:
            generic_argument(usage);
            continue;

        case arglex_token_include:
            if (arglex() != arglex_token_string)
            {
                arg_needs_string(arglex_token_include, usage);
                /* NOTREACHED */
            }
            s = str_from_c(arglex_value.alv_string);
            string_list_append_unique(&option.o_search_path, s);
            str_free(s);
            break;

        case arglex_token_reason:
            type = OPTION_REASON;
          normal_on:
            if (option_already(type, level))
            {
              too_many:
                arg_duplicate_cur(usage);
                /* NOTREACHED */
            }
            option_set(type, level, 1);
            break;

        case arglex_token_reason_not:
            type = OPTION_REASON;
          normal_off:
            if (option_already(type, level))
                goto too_many;
            option_set(type, level, 0);
            break;

        case arglex_token_cascade:
            type = OPTION_CASCADE;
            goto normal_on;

        case arglex_token_cascade_not:
            type = OPTION_CASCADE;
            goto normal_off;

        case arglex_token_disassemble:
            type = OPTION_DISASSEMBLE;
            goto normal_on;

        case arglex_token_disassemble_not:
            type = OPTION_DISASSEMBLE;
            goto normal_off;

        case arglex_token_tty:
            type = OPTION_TERMINAL;
            goto normal_on;

        case arglex_token_tty_not:
            type = OPTION_TERMINAL;
            goto normal_off;

        case arglex_token_precious:
            type = OPTION_PRECIOUS;
            goto normal_on;

        case arglex_token_precious_not:
            type = OPTION_PRECIOUS;
            goto normal_off;

        case arglex_token_log:
            if (option_already(OPTION_LOGGING, level))
                goto too_many;
            option_set(OPTION_LOGGING, level, 1);
            if (arglex() != arglex_token_string)
                continue;
            if (option.o_logfile)
                str_free(option.o_logfile);
            option.o_logfile = str_from_c(arglex_value.alv_string);
            break;

        case arglex_token_log_not:
            type = OPTION_LOGGING;
            goto normal_off;

        case arglex_token_book:
            if (option_already(OPTION_BOOK, level))
                goto too_many;
            option_set(OPTION_BOOK, level, 1);
            if (arglex() != arglex_token_string)
                continue;
            if (option.o_book)
                str_free(option.o_book);
            option.o_book = str_from_c(arglex_value.alv_string);
            break;

        case arglex_token_book_not:
            type = OPTION_BOOK;
            goto normal_off;

        case arglex_token_include_cooked:
            type = OPTION_INCLUDE_COOKED;
            goto normal_on;

        case arglex_token_include_cooked_not:
            type = OPTION_INCLUDE_COOKED;
            goto normal_off;

        case arglex_token_include_cooked_warning:
            type = OPTION_INCLUDE_COOKED_WARNING;
            goto normal_on;

        case arglex_token_include_cooked_warning_not:
            type = OPTION_INCLUDE_COOKED_WARNING;
            goto normal_off;

        case arglex_token_silent:
            type = OPTION_SILENT;
            goto normal_on;

        case arglex_token_silent_not:
            type = OPTION_SILENT;
            goto normal_off;

        case arglex_token_tell_position:
            type = OPTION_TELL_POSITION;
            goto normal_on;

        case arglex_token_tell_position_not:
            type = OPTION_TELL_POSITION;
            goto normal_off;

        case arglex_token_metering:
            type = OPTION_METER;
            goto normal_on;

        case arglex_token_metering_not:
            type = OPTION_METER;
            goto normal_off;

        case arglex_token_touch:
            type = OPTION_TOUCH;
            goto normal_on;

        case arglex_token_touch_not:
            type = OPTION_TOUCH;
            goto normal_off;

        case arglex_token_action:
            type = OPTION_ACTION;
            goto normal_on;

        case arglex_token_action_not:
            type = OPTION_ACTION;
            goto normal_off;

        case arglex_token_persevere:
            type = OPTION_PERSEVERE;
            goto normal_on;

        case arglex_token_persevere_not:
            type = OPTION_PERSEVERE;
            goto normal_off;

        case arglex_token_errok:
            type = OPTION_ERROK;
            goto normal_on;

        case arglex_token_errok_not:
            type = OPTION_ERROK;
            goto normal_off;

        case arglex_token_force:
            type = OPTION_FORCE;
            goto normal_on;

        case arglex_token_force_not:
            type = OPTION_FORCE;
            goto normal_off;

        case arglex_token_fingerprint:
            type = OPTION_FINGERPRINT;
            goto normal_on;

        case arglex_token_fingerprint_not:
            type = OPTION_FINGERPRINT;
            goto normal_off;

        case arglex_token_fingerprint_update:
            if (level != OPTION_LEVEL_COMMAND_LINE)
                goto not_in_env;
            if (option.fingerprint_update)
                goto too_many;
            option.fingerprint_update++;
            break;

        case arglex_token_pairs:
            if (level != OPTION_LEVEL_COMMAND_LINE)
                goto not_in_env;
            if (option.pairs)
                goto too_many;
            option.pairs++;
            break;

        case arglex_token_script:
            if (level != OPTION_LEVEL_COMMAND_LINE)
                goto not_in_env;
            if (option.script)
                goto too_many;
            option.script++;
            break;

        case arglex_token_web:
            if (level != OPTION_LEVEL_COMMAND_LINE)
                goto not_in_env;
            if (option.web)
                goto too_many;
            option.web++;
            break;

        case arglex_token_string:
            if (level != OPTION_LEVEL_COMMAND_LINE)
            {
                if (strchr(arglex_value.alv_string, '='))
                {
                    fatal_intl
                    (
                        0,
                        i18n("may not assign variables in environment variable")
                    );
                }
                else
                {
                    fatal_intl
                    (
                        0,
                        i18n("may not name targets in environment variable")
                    );
                }
            }
            else
            {
                char            *cp;

                cp = strchr(arglex_value.alv_string, '=');
                if (!cp)
                {
                    s = str_from_c(arglex_value.alv_string);
                    string_list_append(&option.o_target, s);
                    str_free(s);
                }
                else
                {
                    s = str_from_c(arglex_value.alv_string);
                    string_list_append(&option.o_vardef, s);
                    str_free(s);
                }
            }
            break;

        case arglex_token_star:
            type = OPTION_STAR;
            goto normal_on;

        case arglex_token_star_not:
            type = OPTION_STAR;
            goto normal_off;

        case arglex_token_strip_dot:
            type = OPTION_STRIP_DOT;
            goto normal_on;

        case arglex_token_strip_dot_not:
            type = OPTION_STRIP_DOT;
            goto normal_off;

        case arglex_token_update:
            type = OPTION_UPDATE;
            goto normal_on;

        case arglex_token_update_not:
            type = OPTION_UPDATE;
            goto normal_off;

        case arglex_token_parallel:
            if (arglex() != arglex_token_number)
            {
                s = str_from_c("parallel_jobs=4");
                string_list_append(&option.o_vardef, s);
                str_free(s);
                continue;
            }
            s = str_format("parallel_jobs=%d", (int)arglex_value.alv_number);
            string_list_append(&option.o_vardef, s);
            str_free(s);
            break;

        case arglex_token_parallel_not:
            s = str_from_c("parallel_jobs=1");
            string_list_append(&option.o_vardef, s);
            str_free(s);
            break;

        case arglex_token_shallow:
            type = OPTION_SHALLOW;
            goto normal_on;

        case arglex_token_shallow_not:
            type = OPTION_SHALLOW;
            goto normal_off;
        }
        arglex();
    }
}
Ejemplo n.º 28
0
arglex_token_ty
arglex(void)
{
    arglex_table_ty *tp;
    int             j;
    arglex_table_ty *hit[20];
    int             nhit;
    char            *arg;
    static char     *pushback[3];
    static int      pushback_depth;

    trace(("arglex()\n{\n"));
    if (pushback_depth)
    {
        /*
         * the second half of a "-foo=bar" style argument.
         */
        arg = pushback[--pushback_depth];
    }
    else
    {
        if (argc <= 0)
        {
            arglex_token = arglex_token_eoln;
            arg = "";
            goto done;
        }
        arg = argv[0];
        argc--;
        argv++;

        /*
         * See if it looks like a GNU "-foo=bar" option.
         * Split it at the '=' to make it something the
         * rest of the code understands.
         */
        if (arg[0] == '-' && arg[1] != '=')
        {
            char           *eqp;

            eqp = strchr(arg, '=');
            if (eqp)
            {
                pushback[pushback_depth++] = eqp + 1;
                *eqp = 0;
            }
        }

        /*
         * Turn the GNU-style leading "--"
         * into "-" if necessary.
         */
        if (arg[0] == '-' && arg[1] == '-' && arg[2] && !is_a_number(arg + 1))
            ++arg;
    }

    /*
     * see if it is a number
     */
    if (is_a_number(arg))
    {
        arglex_token = arglex_token_number;
        goto done;
    }

    /*
     * scan the tables to see what it matches
     */
    nhit = 0;
    partial = 0;
    for (tp = table; tp < ENDOF(table); tp++)
    {
        if (arglex_compare(tp->name, arg))
            hit[nhit++] = tp;
    }
    if (utable)
    {
        for (tp = utable; tp->name; tp++)
        {
            if (arglex_compare(tp->name, arg))
                hit[nhit++] = tp;
        }
    }

    /*
     * deal with unknown or ambiguous options
     */
    switch (nhit)
    {
    case 0:
        /*
         * not found in the tables
         */
        if (*arg == '-')
            arglex_token = arglex_token_option;
        else
            arglex_token = arglex_token_string;
        break;

    case 1:
        if (partial)
            pushback[pushback_depth++] = (char *)partial;
        arg = hit[0]->name;
        arglex_token = hit[0]->token;
        break;

    default:
    {
        string_ty      *s1;
        string_ty      *s2;
        sub_context_ty *scp;

        s1 = str_from_c(hit[0]->name);
        for (j = 1; j < nhit; ++j)
        {
            s2 = str_format("%s, %s", s1->str_text, hit[j]->name);
            str_free(s1);
            s1 = s2;
        }
        scp = sub_context_new();
        sub_var_set_charstar(scp, "Name", arg);
        sub_var_set_string(scp, "Guess", s1);
        fatal_intl(scp, i18n("option \"$name\" ambiguous ($guess)"));
        /* NOTREACHED */
    }
    }

    /*
     * here for all exits
     */
  done:
    arglex_value.alv_string = arg;
    trace(("return %d; /* \"%s\" */\n", arglex_token, arg));
    trace(("}\n"));
    return arglex_token;
}
Ejemplo n.º 29
0
static blob_list_ty *
ifeq(blob_list_ty *blp, string_list_ty *ref)
{
    blob_ty         *arg;
    blob_ty         *bp;
    blob_list_ty    *result;
    string_ty       *s;
    string_ty       *s2;
    char            *cp;
    size_t          j;

    /*
     * allocate the result list
     */
    trace(("ifeq()\n{\n"));
    result = blob_list_alloc();

    /*
     * make sure we were given enough arguments
     */
    if (blp->length < 2)
    {
        arg = blp->list[0];
        blob_list_append
        (
            result,
            blob_alloc(str_from_c("0"), arg->file_name, arg->line_number)
        );
        trace(("}\n"));
        return result;
    }

    /*
     * turn the list of arguments into a single string
     */
    arg = blp->list[1];
    s = str_copy(blp->list[1]->text);
    for (j = 2; j < blp->length; ++j)
    {
        s2 = str_format("%s %s", s->str_text, blp->list[j]->text->str_text);
        str_free(s);
        s = s2;
    }
    bp = blob_alloc(s, arg->file_name, arg->line_number);

    /*
     * rename the variables
     * and reform to be a single string, again.
     */
    variable_rename(bp, result, ref, VAREN_NO_QUOQUO);
    blob_free(bp);
    s = result->length ? str_copy(result->list[0]->text) : str_from_c("0");
    for (j = 1; j < result->length; ++j)
    {
        s2 = str_format("%s %s", s->str_text, result->list[j]->text->str_text);
        str_free(s);
        s = s2;
    }
    blob_list_free(result);

    /*
     * construct the result
     */
    result = blob_list_alloc();
    switch (s->str_text[0])
    {
    case '(':
        /*
         * ifeq (xxx,yyy)
         */
        if (s->str_length < 3)
            goto useless;
        cp = strchr(s->str_text, ',');
        if (cp == 0 || s->str_text[s->str_length - 1] != ')')
            goto useless;

        blob_list_append
        (
            result,
            blob_alloc(str_from_c("[in"), arg->file_name, arg->line_number)
        );

        s2 = str_n_from_c(s->str_text + 1, cp - s->str_text - 1);
        if (s2->str_length == 0)
            s2 = str_from_c("\"\"");
        bp = blob_alloc(s2, arg->file_name, arg->line_number);
        blob_list_append(result, bp);

        s2 = str_n_from_c(cp + 1, s->str_text + s->str_length - cp - 2);
        if (s2->str_length == 0)
            s2 = str_from_c("\"\"");
        bp = blob_alloc(s2, arg->file_name, arg->line_number);
        blob_list_append(result, bp);

        blob_list_append
        (
            result,
            blob_alloc(str_from_c("]"), arg->file_name, arg->line_number)
        );
        break;

    case '\'':
    case '"':
        /*
         * ifeq "xxx" "yyy"
         */
        if (s->str_length < 5)
            goto useless;
        cp = strchr(s->str_text + 1, s->str_text[0]);
        if
        (
            !cp
        ||
            cp[1] != ' '
        ||
            cp[2] != s->str_text[0]
        ||
            s->str_text[s->str_length - 1] != s->str_text[0]
        )
            goto useless;

        blob_list_append
        (
            result,
            blob_alloc(str_from_c("[in"), arg->file_name, arg->line_number)
        );

        s2 = str_n_from_c(s->str_text + 1, cp - s->str_text - 1);
        if (s2->str_length == 0)
            s2 = str_from_c("\"\"");
        bp = blob_alloc(s2, arg->file_name, arg->line_number);
        blob_list_append(result, bp);

        s2 = str_n_from_c(cp + 3, s->str_text + s->str_length - cp - 4);
        if (s2->str_length == 0)
            s2 = str_from_c("\"\"");
        bp = blob_alloc(s2, arg->file_name, arg->line_number);
        blob_list_append(result, bp);

        blob_list_append
        (
            result,
            blob_alloc(str_from_c("]"), arg->file_name, arg->line_number)
        );
        break;

    default:
        /*
         * We were given some useless thing, just rename the
         * variables and copy it through.
         */
        useless:
        bp = blob_alloc(str_copy(s), arg->file_name, arg->line_number);
        blob_list_append(result, bp);
        break;
    }
    str_free(s);
    trace(("}\n"));
    return result;
}
Ejemplo n.º 30
0
string_ty *
flatten(string_ty *filename)
{
    string_list_ty  sl;
    static string_ty *root;
    static string_ty *dot;
    static string_ty *dotdot;
    size_t          pos;
    size_t          start;
    size_t          j;
    string_ty       *s;

    /*
     * Create some things we are going to need.
     */
    if (!root)
    {
        root = str_from_c("");
        dot = str_from_c(".");
        dotdot = str_from_c("..");
    }

    /*
     * leading slash is special
     */
    pos = 0;
    string_list_constructor(&sl);
    if (filename->str_text[0] == '/')
    {
        ++pos;
        string_list_append(&sl, root);
    }

    /*
     * Break it into slash-separaed words.
     */
    for (;;)
    {
        while (pos < filename->str_length && filename->str_text[pos] == '/')
            ++pos;
        if (pos >= filename->str_length)
            break;
        start = pos;
        for (;;)
        {
            ++pos;
            if (pos >= filename->str_length || filename->str_text[pos] == '/')
                break;
        }

        /*
         * remember each word (except ".")
         */
        s = str_n_from_c(filename->str_text + start, pos - start);
        if (!str_equal(s, dot))
            string_list_append(&sl, s);
        str_free(s);
    }

    /*
     * Try as hard as possible to chuck out redundant stuff.
     */
    for (;;)
    {
        int             changed = 0;

        /*
         * "/.." -> "/"
         */
        if
        (
            sl.nstrings >= 2
        &&
            str_equal(sl.string[0], root)
        &&
            str_equal(sl.string[1], dotdot)
        )
        {
            string_list_remove_nth(&sl, 1);
            ++changed;
        }

        /*
         * "name/.." -> ""
         */
        for (j = 0; j + 1 < sl.nstrings; ++j)
        {
            if (str_equal(sl.string[j], root))
                continue;
            if (str_equal(sl.string[j], dotdot))
                continue;
            if (!str_equal(sl.string[j + 1], dotdot))
                continue;
            string_list_remove_nth(&sl, j);
            string_list_remove_nth(&sl, j);
            ++changed;
            --j;
        }

        /*
         * loop if anything changed,
         * bail if we can't find more to do
         */
        if (!changed)
            break;
    }

    /*
     * reassemble the "cleaned" path
     */
    s = wl2str_respect_empty(&sl, 0, sl.nstrings, "/", 1);
    string_list_destructor(&sl);
    return s;
}