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

« back to all changes in this revision

Viewing changes to bin/trampoline/norm.c

  • Committer: William Grant
  • Date: 2010-02-23 08:48:09 UTC
  • mfrom: (1673 trunk)
  • mto: This revision was merged to the branch mainline in revision 1674.
  • Revision ID: grantw@unimelb.edu.au-20100223084809-du6dvsxrjhw15ytr
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
}