Skip to content
Snippets Groups Projects
Select Git revision
  • pu
  • passt default
  • master
  • todo
  • next
  • maint
  • v2.8.0-rc1
  • v2.8.0-rc0
  • v2.7.2
  • v2.7.1
  • v2.7.0
  • v2.6.5
  • v2.7.0-rc3
  • v2.7.0-rc2
  • v2.7.0-rc1
  • v2.7.0-rc0
  • v2.6.4
  • v2.6.3
  • v2.6.2
  • v2.6.1
  • v2.3.10
  • v2.5.4
  • v2.4.10
  • v2.6.0
  • v2.6.0-rc3
  • v2.5.3
26 results

argv-array.c

Blame
    • Jeff King's avatar
      b992657e
      argv-array: add detach function · b992657e
      Jeff King authored
      
      The usual pattern for an argv array is to initialize it,
      push in some strings, and then clear it when done. Very
      occasionally, though, we must do other exotic things with
      the memory, like freeing the list but keeping the strings.
      Let's provide a detach function so that callers can make use
      of our API to build up the array, and then take ownership of
      it.
      
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
      b992657e
      History
      argv-array: add detach function
      Jeff King authored
      
      The usual pattern for an argv array is to initialize it,
      push in some strings, and then clear it when done. Very
      occasionally, though, we must do other exotic things with
      the memory, like freeing the list but keeping the strings.
      Let's provide a detach function so that callers can make use
      of our API to build up the array, and then take ownership of
      it.
      
      Signed-off-by: default avatarJeff King <peff@peff.net>
      Signed-off-by: default avatarJunio C Hamano <gitster@pobox.com>
    argv-array.c 1.74 KiB
    #include "cache.h"
    #include "argv-array.h"
    #include "strbuf.h"
    
    const char *empty_argv[] = { NULL };
    
    void argv_array_init(struct argv_array *array)
    {
    	array->argv = empty_argv;
    	array->argc = 0;
    	array->alloc = 0;
    }
    
    static void argv_array_push_nodup(struct argv_array *array, const char *value)
    {
    	if (array->argv == empty_argv)
    		array->argv = NULL;
    
    	ALLOC_GROW(array->argv, array->argc + 2, array->alloc);
    	array->argv[array->argc++] = value;
    	array->argv[array->argc] = NULL;
    }
    
    void argv_array_push(struct argv_array *array, const char *value)
    {
    	argv_array_push_nodup(array, xstrdup(value));
    }
    
    void argv_array_pushf(struct argv_array *array, const char *fmt, ...)
    {
    	va_list ap;
    	struct strbuf v = STRBUF_INIT;
    
    	va_start(ap, fmt);
    	strbuf_vaddf(&v, fmt, ap);
    	va_end(ap);
    
    	argv_array_push_nodup(array, strbuf_detach(&v, NULL));
    }
    
    void argv_array_pushl(struct argv_array *array, ...)
    {
    	va_list ap;
    	const char *arg;
    
    	va_start(ap, array);
    	while((arg = va_arg(ap, const char *)))
    		argv_array_push(array, arg);
    	va_end(ap);
    }
    
    void argv_array_pushv(struct argv_array *array, const char **argv)
    {
    	for (; *argv; argv++)
    		argv_array_push(array, *argv);
    }
    
    void argv_array_pop(struct argv_array *array)
    {
    	if (!array->argc)
    		return;
    	free((char *)array->argv[array->argc - 1]);
    	array->argv[array->argc - 1] = NULL;
    	array->argc--;
    }
    
    void argv_array_clear(struct argv_array *array)
    {
    	if (array->argv != empty_argv) {
    		int i;
    		for (i = 0; i < array->argc; i++)
    			free((char *)array->argv[i]);
    		free(array->argv);
    	}
    	argv_array_init(array);
    }
    
    const char **argv_array_detach(struct argv_array *array)
    {
    	if (array->argv == empty_argv)
    		return xcalloc(1, sizeof(const char *));
    	else {
    		const char **ret = array->argv;
    		argv_array_init(array);
    		return ret;
    	}
    }