示例#1
0
t_dlist	*tokenizer(char *line, t_lnv *envlist)
{
  t_dlist	*list;
  t_dlist	*cur;
  int		i;
  char		*exp;

  i = 0;
  if (line == NULL || !line[(i)])
    return (NULL);
  list = NULL;
  if ((exp = expand_variables(line, envlist)) == NULL)
    return (NULL);
  while ((exp[i]))
    {
      skipspace(exp, &i);
      if (exp[i])
  	{
  	  if (((list = add_dlist_elem(list)) == NULL)	 ||
  	      ((cur = goto_last_dlist(list)) == NULL)	 ||
  	      ((cur->data = get_next_token(exp, &i)) == NULL))
  	    return (NULL);
  	}
    }
  gbgc_free(NULL, exp);
  return (list);
}
std::string filename_map::expand_variables(it & begin, it end, bool close) const {
	
	std::string result;
	result.reserve(size_t(end - begin));
	
	while(begin != end) {
		
		// Flush everything before the next bracket
		it pos = begin;
		while(pos != end && *pos != '{' && *pos != '}') {
			pos++;
		}
		result.append(begin, pos);
		begin = pos;
		
		if(pos == end) {
			// No more variables or escape sequences
			break;
		}
		
		begin++;
		
		if(close && *pos == '}') {
			// Current context closed
			break;
		}
		
		if(!close && *pos == '}') {
			// literal '}' character
			result.push_back('}');
			continue;
		}
		
		// '{{' escape sequence
		if(begin != end && *begin == '{') {
			result.push_back('{');
			begin++;
			continue;
		}
		
		// Recursively expand variables until we reach the end of this context
		result.append(lookup(expand_variables(begin, end, true)));
	}
	
	return result;
}
std::string filename_map::convert(std::string input) const {
	
	// Convert paths to lower-case if requested
	if(lowercase) {
		std::transform(input.begin(), input.end(), input.begin(), ::tolower);
	}
	
	// Don't expand variables if requested
	if(!expand) {
		return input;
	}
	
	it begin = input.begin();
	std::string expanded = expand_variables(begin, input.end());
	
	return shorten_path(expanded);
}
示例#4
0
/*
 * @brief minimal realization of wordexp according to IEEE standard
 * shall perform word expansion as described in the Shell
 * expansion of ´$NAME´ or ´${NAME}´
 * expansion of ´*´ and ´?´
 * @param words: pointer to a string containing one or more words to be expanded
 * but here only one word supported
 */
int 
wordexp(const char *words, wordexp_t *we, int flags)
{	
	int     i;
	int     error;	
	char   *words_expanded;
#ifdef HAVE_API_WIN32_BASE
	glob_t  pglob;
#endif

	assert(we != NULL);
	assert(words != NULL);
 
	/* expansion of ´$NAME´ or ´${NAME}´ */
	words_expanded=expand_variables(words);

#ifdef HAVE_API_WIN32_BASE
	/* expansion of ´*´, ´?´ */
	error=glob(words_expanded, 0, NULL, &pglob);
	if (!error)
	{
		/* copy the content of struct of glob into struct of wordexp */
		we->we_wordc = pglob.gl_pathc;
		we->we_offs = pglob.gl_offs;
		we->we_wordv = malloc(we->we_wordc * sizeof(char*));
		for (i=0; i<we->we_wordc; i++)
		{
			we->we_wordv[i] = strdup(pglob.gl_pathv[i]);
		}		
		globfree(&pglob);
		free(words_expanded);
	}
	else
	{
#endif
		we->we_wordc = 1;		
		we->we_wordv = malloc(sizeof(char*));	
		we->we_wordv[0] = words_expanded;
#ifdef HAVE_API_WIN32_BASE
	}
#endif


	return error;	
}
示例#5
0
static int configure_via_resource(LPWSTR basename, LPWSTR exepath, LPWSTR exep,
	LPWSTR *prefix_args, int *prefix_args_len,
	int *is_git_command, LPWSTR *working_directory, int *full_path,
	int *skip_arguments, int *allocate_console, int *show_console,
	int *append_quote_to_cmdline)
{
	int i, id, minimal_search_path, needs_a_console, no_hide, wargc;
	int append_quote;
	LPWSTR *wargv;
	WCHAR *app_id;

#define BUFSIZE 65536
	static WCHAR buf[BUFSIZE];
	LPWSTR buf2 = buf;
	int len;

	for (id = 0; ; id++) {
		minimal_search_path = 0;
		needs_a_console = 0;
		no_hide = 0;
		append_quote = 0;
		app_id = NULL;
		len = LoadString(NULL, id, buf, BUFSIZE);

		if (!len) {
			if (!id)
				return 0; /* no resources found */

			fwprintf(stderr, L"Need a valid command-line; "
				L"Edit the string resources accordingly\n");
			exit(1);
		}

		if (len >= BUFSIZE) {
			fwprintf(stderr,
				L"Could not read resource (too large)\n");
			exit(1);
		}

		for (;;) {
			if (strip_prefix(buf, &len, L"MINIMAL_PATH=1 "))
				minimal_search_path = 1;
			else if (strip_prefix(buf, &len, L"ALLOC_CONSOLE=1 "))
				needs_a_console = 1;
			else if (strip_prefix(buf, &len, L"SHOW_CONSOLE=1 "))
				no_hide = 1;
			else if (strip_prefix(buf, &len, L"APPEND_QUOTE=1 "))
				append_quote = 1;
			else if (strip_prefix(buf, &len, L"APP_ID=")) {
				LPWSTR space = wcschr(buf, L' ');
				size_t app_id_len = space - buf;
				if (!space) {
					len -= 7;
					memmove(buf, buf + 7,
							len * sizeof(WCHAR));
					break;
				}
				app_id = wcsdup(buf);
				app_id[app_id_len] = L'\0';
				len -= app_id_len + 1;
				memmove(buf, buf + app_id_len + 1,
						len * sizeof(WCHAR));
			}
			else
				break;
		}

		buf[len] = L'\0';

		if (!id)
			SetEnvironmentVariable(L"EXEPATH", exepath);

		buf2 = expand_variables(buf, BUFSIZE);

		extract_first_arg(buf2, exepath, exep);

		if (_waccess(exep, 0) != -1)
			break;
		fwprintf(stderr,
			L"Skipping command-line '%s'\n('%s' not found)\n",
			buf2, exep);
		if (app_id)
			free(app_id);
	}

	*prefix_args = buf2;
	*prefix_args_len = wcslen(buf2);

	*is_git_command = 0;
	wargv = CommandLineToArgvW(GetCommandLine(), &wargc);
	for (i = 1; i < wargc; i++) {
		if (!wcscmp(L"--no-cd", wargv[i]))
			*working_directory = NULL;
		else if (!wcscmp(L"--cd-to-home", wargv[i]))
			*working_directory = (LPWSTR) 1;
		else if (!wcsncmp(L"--cd=", wargv[i], 5))
			*working_directory = wcsdup(wargv[i] + 5);
		else if (!wcscmp(L"--minimal-search-path", wargv[i]))
			minimal_search_path = 1;
		else if (!wcscmp(L"--no-minimal-search-path", wargv[i]))
			minimal_search_path = 0;
		else if (!wcscmp(L"--needs-console", wargv[i]))
			needs_a_console = 1;
		else if (!wcscmp(L"--no-needs-console", wargv[i]))
			needs_a_console = 0;
		else if (!wcscmp(L"--hide", wargv[i]))
			no_hide = 0;
		else if (!wcscmp(L"--no-hide", wargv[i]))
			no_hide = 1;
		else if (!wcscmp(L"--append-quote", wargv[i]))
			append_quote = 1;
		else if (!wcscmp(L"--no-append-quote", wargv[i]))
			append_quote = -1;
		else if (!wcsncmp(L"--command=", wargv[i], 10)) {
			LPWSTR expanded;

			wargv[i] += 10;
			expanded = expand_variables(wargv[i], wcslen(wargv[i]));
			if (expanded == wargv[i])
				expanded = wcsdup(expanded);

			extract_first_arg(expanded, exepath, exep);

			*prefix_args = expanded;
			*prefix_args_len = wcslen(*prefix_args);
			*skip_arguments = i;
			break;
		}
		else if (!wcsncmp(L"--app-id=", wargv[i], 9)) {
			free(app_id);
			app_id = wcsdup(wargv[i] + 9);
		}
		else
			break;
		*skip_arguments = i;
	}
	if (minimal_search_path)
		*full_path = 0;
	if (needs_a_console)
		*allocate_console = 1;
	if (no_hide)
		*show_console = 1;
	if (append_quote)
		*append_quote_to_cmdline = append_quote == 1;
	if (app_id)
		set_app_id(app_id);
	LocalFree(wargv);

	return 1;
}
示例#6
0
/// Expand all environment variables in the string *ptr.
///
/// This function is slow, fragile and complicated. There are lots of little corner cases, like
/// $$foo should do a double expansion, $foo$bar should not double expand bar, etc. Also, it's easy
/// to accidentally leak memory on array out of bounds errors an various other situations. All in
/// all, this function should be rewritten, split out into multiple logical units and carefully
/// tested. After that, it can probably be optimized to do fewer memory allocations, fewer string
/// scans and overall just less work. But until that happens, don't edit it unless you know exactly
/// what you are doing, and do proper testing afterwards.
///
/// This function operates on strings backwards, starting at last_idx.
///
/// Note: last_idx is considered to be where it previously finished procesisng. This means it
/// actually starts operating on last_idx-1. As such, to process a string fully, pass string.size()
/// as last_idx instead of string.size()-1.
static bool expand_variables(const wcstring &instr, std::vector<completion_t> *out, size_t last_idx,
                             parse_error_list_t *errors) {
    const size_t insize = instr.size();

    // last_idx may be 1 past the end of the string, but no further.
    assert(last_idx <= insize && "Invalid last_idx");
    if (last_idx == 0) {
        append_completion(out, instr);
        return true;
    }

    // Locate the last VARIABLE_EXPAND or VARIABLE_EXPAND_SINGLE
    bool is_single = false;
    size_t varexp_char_idx = last_idx;
    while (varexp_char_idx--) {
        const wchar_t c = instr.at(varexp_char_idx);
        if (c == VARIABLE_EXPAND || c == VARIABLE_EXPAND_SINGLE) {
            is_single = (c == VARIABLE_EXPAND_SINGLE);
            break;
        }
    }
    if (varexp_char_idx >= instr.size()) {
        // No variable expand char, we're done.
        append_completion(out, instr);
        return true;
    }

    // Get the variable name.
    const size_t var_name_start = varexp_char_idx + 1;
    size_t var_name_stop = var_name_start;
    while (var_name_stop < insize) {
        const wchar_t nc = instr.at(var_name_stop);
        if (nc == VARIABLE_EXPAND_EMPTY) {
            var_name_stop++;
            break;
        }
        if (!valid_var_name_char(nc)) break;
        var_name_stop++;
    }
    assert(var_name_stop >= var_name_start && "Bogus variable name indexes");
    const size_t var_name_len = var_name_stop - var_name_start;

    // It's an error if the name is empty.
    if (var_name_len == 0) {
        if (errors) {
            parse_util_expand_variable_error(instr, 0 /* global_token_pos */, varexp_char_idx,
                                             errors);
        }
        return false;
    }

    // Get the variable name as a string, then try to get the variable from env.
    const wcstring var_name(instr, var_name_start, var_name_len);
    // Do a dirty hack to make sliced history fast (#4650). We expand from either a variable, or a
    // history_t. Note that "history" is read only in env.cpp so it's safe to special-case it in
    // this way (it cannot be shadowed, etc).
    history_t *history = nullptr;
    maybe_t<env_var_t> var{};
    if (var_name == L"history") {
        // We do this only on the main thread, matching env.cpp.
        if (is_main_thread()) {
            history = reader_get_history();
        }
    } else if (var_name != wcstring{VARIABLE_EXPAND_EMPTY}) {
        var = env_get(var_name);
    }

    // Parse out any following slice.
    // Record the end of the variable name and any following slice.
    size_t var_name_and_slice_stop = var_name_stop;
    bool all_values = true;
    const size_t slice_start = var_name_stop;
    // List of indexes, and parallel array of source positions of each index in the variable list.
    std::vector<long> var_idx_list;
    std::vector<size_t> var_pos_list;
    if (slice_start < insize && instr.at(slice_start) == L'[') {
        all_values = false;
        const wchar_t *in = instr.c_str();
        wchar_t *slice_end;
        // If a variable is missing, behave as though we have one value, so that $var[1] always
        // works.
        size_t effective_val_count = 1;
        if (var) {
            effective_val_count = var->as_list().size();
        } else if (history) {
            effective_val_count = history->size();
        }
        size_t bad_pos = parse_slice(in + slice_start, &slice_end, var_idx_list, var_pos_list,
                                     effective_val_count);
        if (bad_pos != 0) {
            append_syntax_error(errors, slice_start + bad_pos, L"Invalid index value");
            return false;
        }
        var_name_and_slice_stop = (slice_end - in);
    }

    if (!var && !history) {
        // Expanding a non-existent variable.
        if (!is_single) {
            // Normal expansions of missing variables successfully expand to nothing.
            return true;
        } else {
            // Expansion to single argument.
            // Replace the variable name and slice with VARIABLE_EXPAND_EMPTY.
            wcstring res(instr, 0, varexp_char_idx);
            if (!res.empty() && res.back() == VARIABLE_EXPAND_SINGLE) {
                res.push_back(VARIABLE_EXPAND_EMPTY);
            }
            res.append(instr, var_name_and_slice_stop, wcstring::npos);
            return expand_variables(res, out, varexp_char_idx, errors);
        }
    }

    // Ok, we have a variable or a history. Let's expand it.
    // Start by respecting the sliced elements.
    assert((var || history) && "Should have variable or history here");
    wcstring_list_t var_item_list;
    if (all_values) {
        if (history) {
            history->get_history(var_item_list);
        } else {
            var->to_list(var_item_list);
        }
    } else {
        // We have to respect the slice.
        if (history) {
            // Ask history to map indexes to item strings.
            // Note this may have missing entries for out-of-bounds.
            auto item_map = history->items_at_indexes(var_idx_list);
            for (long item_index : var_idx_list) {
                auto iter = item_map.find(item_index);
                if (iter != item_map.end()) {
                    var_item_list.push_back(iter->second);
                }
            }
        } else {
            const wcstring_list_t &all_var_items = var->as_list();
            for (long item_index : var_idx_list) {
                // Check that we are within array bounds. If not, skip the element. Note:
                // Negative indices (`echo $foo[-1]`) are already converted to positive ones
                // here, So tmp < 1 means it's definitely not in.
                // Note we are 1-based.
                if (item_index >= 1 && size_t(item_index) <= all_var_items.size()) {
                    var_item_list.push_back(all_var_items.at(item_index - 1));
                }
            }
        }
    }

    if (is_single) {
        wcstring res(instr, 0, varexp_char_idx);
        if (!res.empty()) {
            if (res.back() != VARIABLE_EXPAND_SINGLE) {
                res.push_back(INTERNAL_SEPARATOR);
            } else if (var_item_list.empty() || var_item_list.front().empty()) {
                // First expansion is empty, but we need to recursively expand.
                res.push_back(VARIABLE_EXPAND_EMPTY);
            }
        }

        // Append all entries in var_item_list, separated by spaces.
        // Remove the last space.
        if (!var_item_list.empty()) {
            for (const wcstring &item : var_item_list) {
                res.append(item);
                res.push_back(L' ');
            }
            res.pop_back();
        }
        res.append(instr, var_name_and_slice_stop, wcstring::npos);
        return expand_variables(res, out, varexp_char_idx, errors);
    } else {
        // Normal cartesian-product expansion.
        for (const wcstring &item : var_item_list) {
            if (varexp_char_idx == 0 && var_name_and_slice_stop == insize) {
                append_completion(out, item);
            } else {
                wcstring new_in(instr, 0, varexp_char_idx);
                if (!new_in.empty()) {
                    if (new_in.back() != VARIABLE_EXPAND) {
                        new_in.push_back(INTERNAL_SEPARATOR);
                    } else if (item.empty()) {
                        new_in.push_back(VARIABLE_EXPAND_EMPTY);
                    }
                }
                new_in.append(item);
                new_in.append(instr, var_name_and_slice_stop, wcstring::npos);
                if (!expand_variables(new_in, out, varexp_char_idx, errors)) {
                    return false;
                }
            }
        }
    }
    return true;
}
示例#7
0
文件: boxes.c 项目: DINKIN/nip2
/* Make the insides of an about box.
 */
static void
about_build( iDialog *idlg, GtkWidget *work )
{	
	/* Translators: translate this to a credit for you, and it'll appear in
	 * the About box.
	 */
	char *translator_credits = _( "translator_credits" );

	GtkWidget *hb;
	GtkWidget *lab;
	char txt[MAX_DIALOG_TEXT];
	char txt2[MAX_DIALOG_TEXT];
	VipsBuf buf = VIPS_BUF_STATIC( txt );
	GtkWidget *image;

	im_snprintf( txt2, MAX_DIALOG_TEXT, _( "About %s." ), PACKAGE );
	vips_buf_appendf( &buf, "<b><big>%s</big></b>\n\n", txt2 );
	im_snprintf( txt2, MAX_DIALOG_TEXT, 
		_( "%s is an image processing package." ), PACKAGE );
	vips_buf_appendf( &buf, "%s\n\n", txt2 );

	im_snprintf( txt2, MAX_DIALOG_TEXT, 
		_( "%s comes with ABSOLUTELY NO WARRANTY. This is "
		"free software and you are welcome to redistribute "
		"it under certain conditions, see http://www.gnu.org." ), 
		PACKAGE );
	vips_buf_appendf( &buf, "%s\n\n", txt2 );

	im_snprintf( txt2, MAX_DIALOG_TEXT, _( NIP_COPYRIGHT ), PACKAGE );
	vips_buf_appendf( &buf, "%s\n\n", txt2 );

{
	char buf1[FILENAME_MAX];
	char buf2[FILENAME_MAX];

	im_snprintf( buf1, FILENAME_MAX, "%s" G_DIR_SEPARATOR_S "start",
		get_savedir() );
	expand_variables( buf1, buf2 );
        nativeize_path( buf2 );
	escape_markup( buf2, buf1, FILENAME_MAX );
	vips_buf_appendf( &buf, "<b>%s:</b> %s\n", 
		_( "Personal start folder" ), buf1 );
}

	vips_buf_appendf( &buf, "<b>%s:</b> %s\n", 
		_( "Homepage" ), VIPS_HOMEPAGE );
	escape_markup( im_version_string(), txt2, MAX_DIALOG_TEXT );
	vips_buf_appendf( &buf, "<b>%s:</b> %s\n", 
		_( "Linked to VIPS" ), txt2 );
	escape_markup( IM_VERSION_STRING, txt2, MAX_DIALOG_TEXT );
	vips_buf_appendf( &buf, "<b>%s:</b> %s\n", 
		_( "Built against VIPS" ), txt2 );
	escape_markup( PACKAGE, txt2, MAX_DIALOG_TEXT );
	vips_buf_appendf( &buf, "<b>$PACKAGE:</b> %s\n", txt2 );
	escape_markup( VERSION, txt2, MAX_DIALOG_TEXT );
	vips_buf_appendf( &buf, "<b>$VERSION:</b> %s\n", txt2 );
	escape_markup( NN( g_getenv( "VIPSHOME" ) ), txt2, MAX_DIALOG_TEXT );
	vips_buf_appendf( &buf, "<b>$VIPSHOME:</b> %s\n", txt2 );
	escape_markup( NN( g_getenv( "HOME" ) ), txt2, MAX_DIALOG_TEXT );
	vips_buf_appendf( &buf, "<b>$HOME:</b> %s\n", txt2 );
	escape_markup( NN( g_getenv( "SAVEDIR" ) ), txt2, MAX_DIALOG_TEXT );
	vips_buf_appendf( &buf, "<b>$SAVEDIR:</b> %s\n", txt2 );
	escape_markup( PATH_TMP, txt2, MAX_DIALOG_TEXT );
	vips_buf_appendf( &buf, "<b>%s:</b> %s\n", 
		_( "Temp files in" ), txt2 );
	if( strcmp( translator_credits, "translator_credits" ) != 0 ) {
		vips_buf_appendf( &buf, "\n" ); 
		vips_buf_appends( &buf, translator_credits );
	}

	vips_buf_appendf( &buf, "\n" ); 

	mainw_find_disc( &buf );
	/* Expands to (eg.) "14GB free in /pics/tmp" */
        vips_buf_appendf( &buf, _( " in \"%s\"" ), PATH_TMP );
        vips_buf_appends( &buf, "\n" );

        vips_buf_appendf( &buf, 
		_( "%d cells in heap, %d cells free, %d cells maximum" ),
                reduce_context->heap->ncells, 
		reduce_context->heap->nfree, 
		reduce_context->heap->max_fn( reduce_context->heap ) );
        vips_buf_appends( &buf, "\n" );

        vips_buf_appendf( &buf, _( "%d vips calls cached by nip2" ), 
		cache_history_size );
        vips_buf_appends( &buf, "\n" );

        vips_buf_appendf( &buf, _( "%d vips operations cached by libvips" ), 
		vips_cache_get_size() );
        vips_buf_appends( &buf, "\n" );

        vips_buf_appendf( &buf, _( "using %d threads" ), im_concurrency_get() );
        vips_buf_appends( &buf, "\n" );

        vips_buf_appendf( &buf, _( "%d pixel buffers in vips" ), 
		vips_tracked_get_allocs() );
        vips_buf_appends( &buf, "\n" );

	vips_buf_append_size( &buf, vips_tracked_get_mem() );
        vips_buf_appendf( &buf, _( " of ram in pixel buffers" ) ); 
        vips_buf_appends( &buf, "\n" );

	vips_buf_append_size( &buf, vips_tracked_get_mem_highwater() );
        vips_buf_appendf( &buf, _( " of ram highwater mark" ) ); 
        vips_buf_appends( &buf, "\n" );

	hb = gtk_hbox_new( FALSE, 0 );
	gtk_container_border_width( GTK_CONTAINER( hb ), 10 );
	gtk_container_add( GTK_CONTAINER( work ), hb );
	gtk_widget_show( hb );

	image = image_new_from_file( 
		"$VIPSHOME/share/$PACKAGE/data/vips-128.png" );
        gtk_box_pack_start( GTK_BOX( hb ), image, FALSE, FALSE, 2 );
	gtk_widget_show( image );

	lab = gtk_label_new( "" );
	gtk_label_set_markup( GTK_LABEL( lab ), vips_buf_all( &buf ) );
        gtk_label_set_justify( GTK_LABEL( lab ), GTK_JUSTIFY_LEFT );
        gtk_label_set_selectable( GTK_LABEL( lab ), TRUE );
	gtk_label_set_line_wrap( GTK_LABEL( lab ), TRUE );
        gtk_box_pack_start( GTK_BOX( hb ), lab, FALSE, FALSE, 2 );
	gtk_widget_show( lab );
}