source: trunk/CORE/arb_pattern.cxx

Last change on this file was 19339, checked in by westram, 2 years ago
  • reintegrates 'refactor' into 'trunk'
    • eliminates old interface of GBS_strstruct
    • add a few new unittests (editor-config string + some PT-SERVER-functions)
  • adds: log:branches/refactor@19300:19338
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 = NULp;
24    wordexp_t  result;
25    GB_ERROR   error    = NULp;
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 = ARB_strdup(str);
53    }
54    else {
55        if (result.we_wordc == 0) {
56            expanded = ARB_strdup("");
57        }
58        else {
59            GBS_strstruct out(strlen(str)+100);
60            out.cat(result.we_wordv[0]);
61            for (unsigned int i = 1; i < result.we_wordc; i++) {
62                out.put(' ');
63                out.cat(result.we_wordv[i]);
64            }
65
66            expanded = out.release();
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_CONTAINS(GB_incur_error(), "Illegal character");
101    TEST_EXPECT_EQUAL(res, "$ARBHOME&");
102    free(res);
103
104}
105TEST_PUBLISH(TEST_arb_shell_expand);
106
107#endif
Note: See TracBrowser for help on using the repository browser.