resetting manifest requested domain to floor
[platform/upstream/ccache.git] / args.c
1 /*
2  * Copyright (C) 2002 Andrew Tridgell
3  *
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License as published by the Free
6  * Software Foundation; either version 3 of the License, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc., 51
16  * Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18
19 #include "ccache.h"
20
21 struct args *
22 args_init(int init_argc, char **init_args)
23 {
24         struct args *args;
25         int i;
26         args = (struct args *)x_malloc(sizeof(struct args));
27         args->argc = 0;
28         args->argv = (char **)x_malloc(sizeof(char *));
29         args->argv[0] = NULL;
30         for (i = 0; i < init_argc; i++) {
31                 args_add(args, init_args[i]);
32         }
33         return args;
34 }
35
36 struct args *
37 args_init_from_string(const char *command)
38 {
39         struct args *args;
40         char *p = x_strdup(command);
41         char *q = p;
42         char *word, *saveptr = NULL;
43
44         args = args_init(0, NULL);
45         while ((word = strtok_r(q, " \t\r\n", &saveptr))) {
46                 args_add(args, word);
47                 q = NULL;
48         }
49
50         free(p);
51         return args;
52 }
53
54 struct args *
55 args_copy(struct args *args)
56 {
57         return args_init(args->argc, args->argv);
58 }
59
60 void
61 args_free(struct args *args)
62 {
63         int i;
64         if (!args) return;
65         for (i = 0; i < args->argc; ++i) {
66                 if (args->argv[i]) {
67                         free(args->argv[i]);
68                 }
69         }
70         free(args->argv);
71         free(args);
72 }
73
74 void
75 args_add(struct args *args, const char *s)
76 {
77         args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char *));
78         args->argv[args->argc] = x_strdup(s);
79         args->argc++;
80         args->argv[args->argc] = NULL;
81 }
82
83 /* Add all arguments in to_append to args. */
84 void
85 args_extend(struct args *args, struct args *to_append)
86 {
87         int i;
88         for (i = 0; i < to_append->argc; i++) {
89                 args_add(args, to_append->argv[i]);
90         }
91 }
92
93 /* pop the last element off the args list */
94 void
95 args_pop(struct args *args, int n)
96 {
97         while (n--) {
98                 args->argc--;
99                 free(args->argv[args->argc]);
100                 args->argv[args->argc] = NULL;
101         }
102 }
103
104 /* set argument at given index */
105 void
106 args_set(struct args *args, int index, const char *value)
107 {
108         assert(index < args->argc);
109         free(args->argv[index]);
110         args->argv[index] = x_strdup(value);
111 }
112
113 /* remove the first element of the argument list */
114 void
115 args_remove_first(struct args *args)
116 {
117         free(args->argv[0]);
118         memmove(&args->argv[0], &args->argv[1], args->argc * sizeof(args->argv[0]));
119         args->argc--;
120 }
121
122 /* add an argument into the front of the argument list */
123 void
124 args_add_prefix(struct args *args, const char *s)
125 {
126         args->argv = (char**)x_realloc(args->argv, (args->argc + 2) * sizeof(char *));
127         memmove(&args->argv[1], &args->argv[0],
128                 (args->argc+1) * sizeof(args->argv[0]));
129         args->argv[0] = x_strdup(s);
130         args->argc++;
131 }
132
133 /* strip any arguments beginning with the specified prefix */
134 void
135 args_strip(struct args *args, const char *prefix)
136 {
137         int i;
138         for (i = 0; i < args->argc; ) {
139                 if (str_startswith(args->argv[i], prefix)) {
140                         free(args->argv[i]);
141                         memmove(&args->argv[i],
142                                 &args->argv[i+1],
143                                 (args->argc - i) * sizeof(args->argv[i]));
144                         args->argc--;
145                 } else {
146                         i++;
147                 }
148         }
149 }
150
151 /*
152  * Format args to a space-separated string. Does not quote spaces. Caller
153  * frees.
154  */
155 char *
156 args_to_string(struct args *args)
157 {
158         char *result;
159         char **p;
160         unsigned size = 0;
161         int pos;
162         for (p = args->argv; *p; p++) {
163                 size += strlen(*p) + 1;
164         }
165         result = x_malloc(size + 1);
166         pos = 0;
167         for (p = args->argv; *p; p++) {
168                 pos += sprintf(&result[pos], "%s ", *p);
169         }
170         result[pos - 1] = '\0';
171         return result;
172 }
173
174 /* Returns true if args1 equals args2, else false. */
175 bool
176 args_equal(struct args *args1, struct args *args2)
177 {
178         int i;
179         if (args1->argc != args2->argc) {
180                 return false;
181         }
182         for (i = 0; i < args1->argc; i++) {
183                 if (!str_eq(args1->argv[i], args2->argv[i])) {
184                         return false;
185                 }
186         }
187         return true;
188 }
189