This source file includes following definitions.
- pmix_argv_append
- pmix_argv_append_nosize
- pmix_argv_prepend_nosize
- pmix_argv_append_unique_idx
- pmix_argv_append_unique_nosize
- pmix_argv_free
- pmix_argv_split_inter
- pmix_argv_split
- pmix_argv_split_with_empty
- pmix_argv_count
- pmix_argv_join
- pmix_argv_join_range
- pmix_argv_len
- pmix_argv_copy
- pmix_argv_delete
- pmix_argv_insert
- pmix_argv_insert_element
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include <src/include/pmix_config.h>
26
27
28 #ifdef HAVE_STDLIB_H
29 #include <stdlib.h>
30 #endif
31 #ifdef HAVE_STRING_H
32 #include <string.h>
33 #endif
34
35 #include "src/util/argv.h"
36
37 #define ARGSIZE 128
38
39
40
41
42
43 pmix_status_t pmix_argv_append(int *argc, char ***argv, const char *arg)
44 {
45 pmix_status_t rc;
46
47
48 if (PMIX_SUCCESS != (rc = pmix_argv_append_nosize(argv, arg))) {
49 return rc;
50 }
51
52 *argc = pmix_argv_count(*argv);
53
54 return PMIX_SUCCESS;
55 }
56
57 pmix_status_t pmix_argv_append_nosize(char ***argv, const char *arg)
58 {
59 int argc;
60
61
62
63 if (NULL == *argv) {
64 *argv = (char**) malloc(2 * sizeof(char *));
65 if (NULL == *argv) {
66 return PMIX_ERR_OUT_OF_RESOURCE;
67 }
68 argc = 0;
69 (*argv)[0] = NULL;
70 (*argv)[1] = NULL;
71 }
72
73
74 else {
75
76 argc = pmix_argv_count(*argv);
77
78 *argv = (char**) realloc(*argv, (argc + 2) * sizeof(char *));
79 if (NULL == *argv) {
80 return PMIX_ERR_OUT_OF_RESOURCE;
81 }
82 }
83
84
85
86 (*argv)[argc] = strdup(arg);
87 if (NULL == (*argv)[argc]) {
88 return PMIX_ERR_OUT_OF_RESOURCE;
89 }
90
91 argc = argc + 1;
92 (*argv)[argc] = NULL;
93
94 return PMIX_SUCCESS;
95 }
96
97 pmix_status_t pmix_argv_prepend_nosize(char ***argv, const char *arg)
98 {
99 int argc;
100 int i;
101
102
103
104 if (NULL == *argv) {
105 *argv = (char**) malloc(2 * sizeof(char *));
106 if (NULL == *argv) {
107 return PMIX_ERR_OUT_OF_RESOURCE;
108 }
109 (*argv)[0] = strdup(arg);
110 (*argv)[1] = NULL;
111 } else {
112
113 argc = pmix_argv_count(*argv);
114
115 *argv = (char**) realloc(*argv, (argc + 2) * sizeof(char *));
116 if (NULL == *argv) {
117 return PMIX_ERR_OUT_OF_RESOURCE;
118 }
119 (*argv)[argc+1] = NULL;
120
121
122 for (i=argc; 0 < i; i--) {
123 (*argv)[i] = (*argv)[i-1];
124 }
125 (*argv)[0] = strdup(arg);
126 }
127
128 return PMIX_SUCCESS;
129 }
130
131 pmix_status_t pmix_argv_append_unique_idx(int *idx, char ***argv, const char *arg)
132 {
133 int i;
134 pmix_status_t rc;
135
136
137
138
139 if (NULL == *argv) {
140 goto add;
141 }
142
143 for (i=0; NULL != (*argv)[i]; i++) {
144 if (0 == strcmp(arg, (*argv)[i])) {
145
146 *idx = i;
147 return PMIX_SUCCESS;
148 }
149 }
150 add:
151 if (PMIX_SUCCESS != (rc = pmix_argv_append_nosize(argv, arg))) {
152 return rc;
153 }
154 *idx = pmix_argv_count(*argv)-1;
155
156 return PMIX_SUCCESS;
157 }
158
159 pmix_status_t pmix_argv_append_unique_nosize(char ***argv, const char *arg)
160 {
161 int i;
162
163
164
165
166 if (NULL == *argv) {
167 return pmix_argv_append_nosize(argv, arg);
168 }
169
170
171 for (i=0; NULL != (*argv)[i]; i++) {
172 if (0 == strcmp(arg, (*argv)[i])) {
173
174 return PMIX_SUCCESS;
175 }
176 }
177
178
179 return pmix_argv_append_nosize(argv, arg);
180 }
181
182
183
184
185 void pmix_argv_free(char **argv)
186 {
187 char **p;
188
189 if (NULL == argv)
190 return;
191
192 for (p = argv; NULL != *p; ++p) {
193 free(*p);
194 }
195
196 free(argv);
197 }
198
199
200
201
202
203 static char **pmix_argv_split_inter(const char *src_string, int delimiter,
204 int include_empty)
205 {
206 char arg[ARGSIZE];
207 char **argv = NULL;
208 const char *p;
209 char *argtemp;
210 int argc = 0;
211 size_t arglen;
212
213 while (src_string && *src_string) {
214 p = src_string;
215 arglen = 0;
216
217 while (('\0' != *p) && (*p != delimiter)) {
218 ++p;
219 ++arglen;
220 }
221
222
223
224 if (src_string == p) {
225 if (include_empty) {
226 arg[0] = '\0';
227 if (PMIX_SUCCESS != pmix_argv_append(&argc, &argv, arg))
228 return NULL;
229 }
230 }
231
232
233
234 else if ('\0' == *p) {
235 if (PMIX_SUCCESS != pmix_argv_append(&argc, &argv, src_string))
236 return NULL;
237 src_string = p;
238 continue;
239 }
240
241
242
243 else if (arglen > (ARGSIZE - 1)) {
244 argtemp = (char*) malloc(arglen + 1);
245 if (NULL == argtemp)
246 return NULL;
247
248 pmix_strncpy(argtemp, src_string, arglen);
249 argtemp[arglen] = '\0';
250
251 if (PMIX_SUCCESS != pmix_argv_append(&argc, &argv, argtemp)) {
252 free(argtemp);
253 return NULL;
254 }
255
256 free(argtemp);
257 }
258
259
260
261 else {
262 pmix_strncpy(arg, src_string, arglen);
263 arg[arglen] = '\0';
264
265 if (PMIX_SUCCESS != pmix_argv_append(&argc, &argv, arg))
266 return NULL;
267 }
268
269 src_string = p + 1;
270 }
271
272
273
274 return argv;
275 }
276
277 char **pmix_argv_split(const char *src_string, int delimiter)
278 {
279 return pmix_argv_split_inter(src_string, delimiter, 0);
280 }
281
282 char **pmix_argv_split_with_empty(const char *src_string, int delimiter)
283 {
284 return pmix_argv_split_inter(src_string, delimiter, 1);
285 }
286
287
288
289
290 int pmix_argv_count(char **argv)
291 {
292 char **p;
293 int i;
294
295 if (NULL == argv)
296 return 0;
297
298 for (i = 0, p = argv; *p; i++, p++)
299 continue;
300
301 return i;
302 }
303
304
305
306
307
308
309 char *pmix_argv_join(char **argv, int delimiter)
310 {
311 char **p;
312 char *pp;
313 char *str;
314 size_t str_len = 0;
315 size_t i;
316
317
318
319 if (NULL == argv || NULL == argv[0]) {
320 return strdup("");
321 }
322
323
324
325
326 for (p = argv; *p; ++p) {
327 str_len += strlen(*p) + 1;
328 }
329
330
331
332 if (NULL == (str = (char*) malloc(str_len)))
333 return NULL;
334
335
336
337 str[--str_len] = '\0';
338 p = argv;
339 pp = *p;
340
341 for (i = 0; i < str_len; ++i) {
342 if ('\0' == *pp) {
343
344
345
346
347 str[i] = (char) delimiter;
348 ++p;
349 pp = *p;
350 } else {
351 str[i] = *pp++;
352 }
353 }
354
355
356
357 return str;
358 }
359
360
361
362
363
364
365 char *pmix_argv_join_range(char **argv, size_t start, size_t end, int delimiter)
366 {
367 char **p;
368 char *pp;
369 char *str;
370 size_t str_len = 0;
371 size_t i;
372
373
374
375 if (NULL == argv || NULL == argv[0] || (int)start > pmix_argv_count(argv)) {
376 return strdup("");
377 }
378
379
380
381
382 for (p = &argv[start], i=start; *p && i < end; ++p, ++i) {
383 str_len += strlen(*p) + 1;
384 }
385
386
387
388 if (NULL == (str = (char*) malloc(str_len)))
389 return NULL;
390
391
392
393 str[--str_len] = '\0';
394 p = &argv[start];
395 pp = *p;
396
397 for (i = 0; i < str_len; ++i) {
398 if ('\0' == *pp) {
399
400
401
402
403 str[i] = (char) delimiter;
404 ++p;
405 pp = *p;
406 } else {
407 str[i] = *pp++;
408 }
409 }
410
411
412
413 return str;
414 }
415
416
417
418
419
420 size_t pmix_argv_len(char **argv)
421 {
422 char **p;
423 size_t length;
424
425 if (NULL == argv)
426 return (size_t) 0;
427
428 length = sizeof(char *);
429
430 for (p = argv; *p; ++p) {
431 length += strlen(*p) + 1 + sizeof(char *);
432 }
433
434 return length;
435 }
436
437
438
439
440
441 char **pmix_argv_copy(char **argv)
442 {
443 char **dupv = NULL;
444 int dupc = 0;
445
446 if (NULL == argv)
447 return NULL;
448
449
450
451 dupv = (char**) malloc(sizeof(char*));
452 dupv[0] = NULL;
453
454 while (NULL != *argv) {
455 if (PMIX_SUCCESS != pmix_argv_append(&dupc, &dupv, *argv)) {
456 pmix_argv_free(dupv);
457 return NULL;
458 }
459
460 ++argv;
461 }
462
463
464
465 return dupv;
466 }
467
468
469 pmix_status_t pmix_argv_delete(int *argc, char ***argv, int start, int num_to_delete)
470 {
471 int i;
472 int count;
473 int suffix_count;
474 char **tmp;
475
476
477 if (NULL == argv || NULL == *argv || 0 == num_to_delete) {
478 return PMIX_SUCCESS;
479 }
480 count = pmix_argv_count(*argv);
481 if (start > count) {
482 return PMIX_SUCCESS;
483 } else if (start < 0 || num_to_delete < 0) {
484 return PMIX_ERR_BAD_PARAM;
485 }
486
487
488
489
490 suffix_count = count - (start + num_to_delete);
491 if (suffix_count < 0) {
492 suffix_count = 0;
493 }
494
495
496
497 for (i = start; i < count && i < start + num_to_delete; ++i) {
498 free((*argv)[i]);
499 }
500
501
502
503 for (i = start; i < start + suffix_count; ++i) {
504 (*argv)[i] = (*argv)[i + num_to_delete];
505 }
506
507
508
509 (*argv)[i] = NULL;
510
511
512 tmp = (char**)realloc(*argv, sizeof(char*) * (i + 1));
513 if (NULL != tmp) *argv = tmp;
514
515
516 (*argc) -= num_to_delete;
517
518 return PMIX_SUCCESS;
519 }
520
521
522 pmix_status_t pmix_argv_insert(char ***target, int start, char **source)
523 {
524 int i, source_count, target_count;
525 int suffix_count;
526
527
528
529 if (NULL == target || NULL == *target || start < 0) {
530 return PMIX_ERR_BAD_PARAM;
531 } else if (NULL == source) {
532 return PMIX_SUCCESS;
533 }
534
535
536
537 target_count = pmix_argv_count(*target);
538 source_count = pmix_argv_count(source);
539 if (start > target_count) {
540 for (i = 0; i < source_count; ++i) {
541 pmix_argv_append(&target_count, target, source[i]);
542 }
543 }
544
545
546
547 else {
548
549
550
551 *target = (char**) realloc(*target,
552 sizeof(char *) * (target_count + source_count + 1));
553
554
555
556 suffix_count = target_count - start;
557 for (i = suffix_count - 1; i >= 0; --i) {
558 (*target)[start + source_count + i] =
559 (*target)[start + i];
560 }
561 (*target)[start + suffix_count + source_count] = NULL;
562
563
564
565 for (i = start; i < start + source_count; ++i) {
566 (*target)[i] = strdup(source[i - start]);
567 }
568 }
569
570
571
572 return PMIX_SUCCESS;
573 }
574
575 pmix_status_t pmix_argv_insert_element(char ***target, int location, char *source)
576 {
577 int i, target_count;
578 int suffix_count;
579
580
581
582 if (NULL == target || NULL == *target || location < 0) {
583 return PMIX_ERR_BAD_PARAM;
584 } else if (NULL == source) {
585 return PMIX_SUCCESS;
586 }
587
588
589 target_count = pmix_argv_count(*target);
590 if (location > target_count) {
591 pmix_argv_append(&target_count, target, source);
592 return PMIX_SUCCESS;
593 }
594
595
596 *target = (char**) realloc(*target,
597 sizeof(char*) * (target_count + 2));
598
599
600 suffix_count = target_count - location;
601 for (i = suffix_count - 1; i >= 0; --i) {
602 (*target)[location + 1 + i] =
603 (*target)[location + i];
604 }
605 (*target)[location + suffix_count + 1] = NULL;
606
607
608 (*target)[location] = strdup(source);
609
610
611 return PMIX_SUCCESS;
612 }