~azzar1/unity/add-show-desktop-key

1079 by William Grant
Merge setup-refactor branch. This completely breaks existing installations;
1
#include <assert.h>
2
#include <string.h>
3
#include <stdlib.h>
4
#include <stdio.h>
5
#include <unistd.h>
6
#include "norm.h"
7
8
#define SKP()               \
9
    do {                    \
10
        s++;                \
11
    } while (0)
12
13
#define CPY()               \
14
    do {                    \
15
        *d++ = *s++;        \
16
    } while (0)
17
18
#define MRK()               \
19
    do {                    \
20
        PUSH();             \
21
    } while (0)
22
23
#define BKP()               \
24
    do {                    \
25
        POP();              \
26
    } while (0)
27
28
#define BKP2()              \
29
    do {                    \
30
        POP();              \
31
        POP();              \
32
    } while (0)
33
34
#define PUSH()              \
35
    do {                    \
36
        stk[top++] = d;     \
37
    } while (0)
38
39
#define POP()               \
40
    do {                    \
41
        if (top == 0)       \
42
        {                   \
43
            dest[0] = '\0'; \
44
            return -1;      \
45
        }                   \
46
        d = stk[--top];     \
47
    } while (0)
48
49
/*
50
 * Normalize the unix pathname in src eliminating . and .. sequences
51
 * to yield an absolute path. Returns 0 on success, and -1 on error.
52
 */
53
int norm(char* dest, int len, const char* src)
54
{
55
    const char* s = src;
56
    char* d = dest;
57
    char* stk[256];
58
    int top = 0;
59
    enum { L0, L1, L2, L3, L4 } state = L0;
60
    assert(strlen(src) <= len);
61
62
    while (*s)
63
    {
64
        char c = *s;
65
        enum { slash, dot, other } cls;
66
        switch (c)
67
        {
68
            case '/':
69
            {
70
                cls = slash;
71
                break;
72
            }
73
            case '.':
74
            {
75
                cls = dot;
76
                break;
77
            }
78
            default:
79
            {
80
                cls = other;
81
            }
82
        }
83
        switch (state)
84
        {
85
            case L0:
86
            {
87
                switch (cls)
88
                {
89
                    case slash:
90
                    {
91
                        CPY();
92
                        state = L1;
93
                        break;
94
                    }
95
                    case dot:
96
                    case other:
97
                    {
98
                        dest[0] = '\0';
99
                        return -1;
100
                    }
101
                }
102
                break;
103
            }
104
            case L1:
105
            {
106
                switch (cls)
107
                {
108
                    case slash:
109
                    {
110
                        SKP();
111
                        break;
112
                    }
113
                    case dot:
114
                    {
115
                        MRK();
116
                        CPY();
117
                        state = L2;
118
                        break;
119
                    }
120
                    case other:
121
                    {
122
                        MRK();
123
                        CPY();
124
                        state = L4;
125
                        break;
126
                    }
127
                }
128
                break;
129
            }
130
            case L2:
131
            {
132
                switch (cls)
133
                {
134
                    case slash:
135
                    {
136
                        BKP();
137
                        state = L1;
138
                        break;
139
                    }
140
                    case dot:
141
                    {
142
                        CPY();
143
                        state = L3;
144
                        break;
145
                    }
146
                    case other:
147
                    {
148
                        CPY();
149
                        state = L4;
150
                        break;
151
                    }
152
                }
153
                break;
154
            }
155
            case L3:
156
            {
157
                switch (cls)
158
                {
159
                    case slash:
160
                    {
161
                        BKP2();
162
                        state = L1;
163
                        break;
164
                    }
165
                    case dot:
166
                    case other:
167
                    {
168
                        CPY();
169
                        state = L4;
170
                        break;
171
                    }
172
                }
173
                break;
174
            }
175
            case L4:
176
            {
177
                switch (cls)
178
                {
179
                    case slash:
180
                    {
181
                        CPY();
182
                        state = L1;
183
                        break;
184
                    }
185
                    case dot:
186
                    case other:
187
                    {
188
                        CPY();
189
                        break;
190
                    }
191
                }
192
                break;
193
            }
194
        }
195
    }
196
    *d = '\0';
197
    return 0;
198
}