source: tags/ms_r16q2/CORE/arb_pattern.cxx

Last change on this file was 12961, checked in by westram, 10 years ago
  • stuff leak in arb_shell_expand
File size: 2.4 KB
Line 
1#include "arb_pattern.h"
2#include "arb_core.h"
3#include "arb_strbuf.h"
4#include "arb_msg.h"
5
6#include <wordexp.h>
7
8
9/**
10 * Performs shell-like path expansion on @param str:
11 *  - Tilde-Expansion
12 *  - Environment variable substitution
13 *  - Command substitition
14 *  - Arithmetic expansion
15 *  - Wildcard expansion
16 *  - Quote removal
17 *
18 * The implementation uses wordexp (see man wordexp).
19 *
20 *  @return Expanded string (must be freed)
21 */
22char* arb_shell_expand(const char* str) {
23    char      *expanded = NULL;
24    wordexp_t  result;
25    GB_ERROR   error    = NULL;
26
27    switch (wordexp(str, &result, 0)) {
28        case 0:
29        break;
30    case WRDE_BADCHAR:
31        error = "Illegal character";
32        break;
33    case WRDE_BADVAL:
34        error = "Undefined variable referenced";
35        break; 
36    case WRDE_CMDSUB:
37        error = "Command substitution not allowed";
38        break;
39    case WRDE_NOSPACE:
40        error = "Out of memory";
41        break;
42    case WRDE_SYNTAX:
43        error = "Syntax error";
44        break;
45    default:
46        error = "Unknown error";
47    }
48
49    if (error) {
50        GB_export_errorf("Encountered error \"%s\" while expanding \"%s\"",
51                         error, str);
52        expanded = strdup(str);
53    }
54    else {
55        if (result.we_wordc == 0) {
56            expanded = strdup("");
57        }
58        else {
59            GBS_strstruct *out = GBS_stropen(strlen(str)+100);
60            GBS_strcat(out, result.we_wordv[0]);
61            for (unsigned int i = 1; i < result.we_wordc; i++) {
62                GBS_chrcat(out, ' ');
63                GBS_strcat(out, result.we_wordv[i]);
64            }
65
66            expanded = GBS_strclose(out);
67        }
68        wordfree(&result);
69    }
70    return expanded;
71}
72
73////////// UNIT TESTS ///////////
74
75#ifdef UNIT_TESTS
76
77#ifndef TEST_UNIT_H
78#include <test_unit.h>
79#endif
80
81void TEST_arb_shell_expand() {
82    char *res;
83
84    res = arb_shell_expand("");
85    TEST_REJECT(GB_have_error());
86    TEST_EXPECT_EQUAL(res, "");
87    free(res);
88
89    res = arb_shell_expand("test");
90    TEST_REJECT(GB_have_error());
91    TEST_EXPECT_EQUAL(res, "test");
92    free(res);
93
94    res = arb_shell_expand("$ARBHOME");
95    TEST_REJECT(GB_have_error());
96    TEST_EXPECT_EQUAL(res, getenv("ARBHOME"));
97    free(res);
98
99    res = arb_shell_expand("$ARBHOME&");
100    TEST_EXPECT(GB_have_error());
101    GB_await_error();
102    TEST_EXPECT_EQUAL(res, "$ARBHOME&");
103    free(res);
104   
105}
106
107
108
109#endif
Note: See TracBrowser for help on using the repository browser.