Git fork
at reftables-rust 139 lines 2.9 kB view raw
1#define USE_THE_REPOSITORY_VARIABLE 2 3#include "git-compat-util.h" 4#include "alias.h" 5#include "config.h" 6#include "gettext.h" 7#include "strbuf.h" 8#include "string-list.h" 9 10struct config_alias_data { 11 const char *alias; 12 char *v; 13 struct string_list *list; 14}; 15 16static int config_alias_cb(const char *key, const char *value, 17 const struct config_context *ctx UNUSED, void *d) 18{ 19 struct config_alias_data *data = d; 20 const char *p; 21 22 if (!skip_prefix(key, "alias.", &p)) 23 return 0; 24 25 if (data->alias) { 26 if (!strcasecmp(p, data->alias)) { 27 FREE_AND_NULL(data->v); 28 return git_config_string(&data->v, 29 key, value); 30 } 31 } else if (data->list) { 32 string_list_append(data->list, p); 33 } 34 35 return 0; 36} 37 38char *alias_lookup(const char *alias) 39{ 40 struct config_alias_data data = { alias, NULL }; 41 42 read_early_config(the_repository, config_alias_cb, &data); 43 44 return data.v; 45} 46 47void list_aliases(struct string_list *list) 48{ 49 struct config_alias_data data = { NULL, NULL, list }; 50 51 read_early_config(the_repository, config_alias_cb, &data); 52} 53 54void quote_cmdline(struct strbuf *buf, const char **argv) 55{ 56 for (const char **argp = argv; *argp; argp++) { 57 if (argp != argv) 58 strbuf_addch(buf, ' '); 59 strbuf_addch(buf, '"'); 60 for (const char *p = *argp; *p; p++) { 61 const char c = *p; 62 63 if (c == '"' || c =='\\') 64 strbuf_addch(buf, '\\'); 65 strbuf_addch(buf, c); 66 } 67 strbuf_addch(buf, '"'); 68 } 69} 70 71#define SPLIT_CMDLINE_BAD_ENDING 1 72#define SPLIT_CMDLINE_UNCLOSED_QUOTE 2 73#define SPLIT_CMDLINE_ARGC_OVERFLOW 3 74static const char *split_cmdline_errors[] = { 75 N_("cmdline ends with \\"), 76 N_("unclosed quote"), 77 N_("too many arguments"), 78}; 79 80int split_cmdline(char *cmdline, const char ***argv) 81{ 82 size_t src, dst, count = 0, size = 16; 83 char quoted = 0; 84 85 ALLOC_ARRAY(*argv, size); 86 87 /* split alias_string */ 88 (*argv)[count++] = cmdline; 89 for (src = dst = 0; cmdline[src];) { 90 char c = cmdline[src]; 91 if (!quoted && isspace(c)) { 92 cmdline[dst++] = 0; 93 while (cmdline[++src] 94 && isspace(cmdline[src])) 95 ; /* skip */ 96 ALLOC_GROW(*argv, count + 1, size); 97 (*argv)[count++] = cmdline + dst; 98 } else if (!quoted && (c == '\'' || c == '"')) { 99 quoted = c; 100 src++; 101 } else if (c == quoted) { 102 quoted = 0; 103 src++; 104 } else { 105 if (c == '\\' && quoted != '\'') { 106 src++; 107 c = cmdline[src]; 108 if (!c) { 109 FREE_AND_NULL(*argv); 110 return -SPLIT_CMDLINE_BAD_ENDING; 111 } 112 } 113 cmdline[dst++] = c; 114 src++; 115 } 116 } 117 118 cmdline[dst] = 0; 119 120 if (quoted) { 121 FREE_AND_NULL(*argv); 122 return -SPLIT_CMDLINE_UNCLOSED_QUOTE; 123 } 124 125 if (count >= INT_MAX) { 126 FREE_AND_NULL(*argv); 127 return -SPLIT_CMDLINE_ARGC_OVERFLOW; 128 } 129 130 ALLOC_GROW(*argv, count + 1, size); 131 (*argv)[count] = NULL; 132 133 return count; 134} 135 136const char *split_cmdline_strerror(int split_cmdline_errno) 137{ 138 return split_cmdline_errors[-split_cmdline_errno - 1]; 139}