~ubuntu-branches/ubuntu/breezy/pam/breezy

« back to all changes in this revision

Viewing changes to Linux-PAM/doc/specs/formatter/parse.y

  • Committer: Bazaar Package Importer
  • Author(s): Sam Hartman
  • Date: 2004-06-28 14:28:08 UTC
  • mfrom: (2.1.1 warty)
  • Revision ID: james.westby@ubuntu.com-20040628142808-adikk7vtfg3pzcjw
Tags: 0.76-22
* Add uploaders
* Document location of repository
* Fix options containing arguments in pam_unix, Closes: #254904

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
%{
 
3
#include <stdio.h>
 
4
#include <stdlib.h>
 
5
#include <string.h>
 
6
    
 
7
#define MAXLINE  1000
 
8
#define INDENT_STRING "  "
 
9
#define PAPER_WIDTH   74
 
10
 
 
11
    int indent=0;
 
12
    int line=1;
 
13
    char *last_label=NULL;
 
14
 
 
15
    extern void yyerror(const char *x);
 
16
    extern char *get_label(const char *label);
 
17
    extern void set_label(const char *label, const char *target);
 
18
    char *new_counter(const char *key);
 
19
 
 
20
#include "lex.yy.c"
 
21
 
 
22
%}
 
23
 
 
24
%union {
 
25
    int def;
 
26
    char *string;
 
27
}
 
28
 
 
29
%token NEW_COUNTER LABEL HASH CHAR NEWLINE NO_INDENT RIGHT
 
30
%type <string> stuff text
 
31
 
 
32
%start doc
 
33
 
 
34
%%
 
35
 
 
36
doc:
 
37
| doc NEWLINE {
 
38
    printf("\n");
 
39
    ++line;
 
40
}
 
41
| doc stuff NEWLINE {
 
42
    if (strlen($2) > (PAPER_WIDTH-(indent ? strlen(INDENT_STRING):0))) {
 
43
        yyerror("line too long");
 
44
    }
 
45
    printf("%s%s\n", indent ? INDENT_STRING:"", $2);
 
46
    free($2);
 
47
    indent = 1;
 
48
    ++line;
 
49
}
 
50
| doc stuff RIGHT stuff NEWLINE {
 
51
    char fixed[PAPER_WIDTH+1];
 
52
    int len;
 
53
 
 
54
    len = PAPER_WIDTH-(strlen($2)+strlen($4));
 
55
 
 
56
    if (len >= 0) {
 
57
        memset(fixed, ' ', len);
 
58
        fixed[len] = '\0';
 
59
    } else {
 
60
        yyerror("line too wide");
 
61
        fixed[0] = '\0';
 
62
    }
 
63
    printf("%s%s%s\n", $2, fixed, $4);
 
64
    free($2);
 
65
    free($4);
 
66
    indent = 1;
 
67
    ++line;
 
68
}
 
69
| doc stuff RIGHT stuff RIGHT stuff NEWLINE {
 
70
    char fixed[PAPER_WIDTH+1];
 
71
    int len, l;
 
72
 
 
73
    len = PAPER_WIDTH-(strlen($2)+strlen($4));
 
74
 
 
75
    if (len < 0) {
 
76
        len = 0;
 
77
        yyerror("line too wide");
 
78
    }
 
79
 
 
80
    l = len/2;
 
81
    memset(fixed, ' ', l);
 
82
    fixed[l] = '\0';
 
83
    printf("%s%s%s", $2, fixed, $4);
 
84
    free($2);
 
85
    free($4);
 
86
    
 
87
    l = (len+1)/2;
 
88
    memset(fixed, ' ', l);
 
89
    fixed[l] = '\0';
 
90
    printf("%s%s\n", fixed, $6);
 
91
    free($6);
 
92
 
 
93
    indent = 1;
 
94
    ++line;
 
95
}
 
96
| doc stuff RIGHT stuff RIGHT stuff NEWLINE {
 
97
    char fixed[PAPER_WIDTH+1];
 
98
    int len, l;
 
99
 
 
100
    len = PAPER_WIDTH-(strlen($2)+strlen($4));
 
101
 
 
102
    if (len < 0) {
 
103
        len = 0;
 
104
        yyerror("line too wide");
 
105
    }
 
106
 
 
107
    l = len/2;
 
108
    memset(fixed, ' ', l);
 
109
    fixed[l] = '\0';
 
110
    printf("%s%s%s", $2, fixed, $4);
 
111
    free($2);
 
112
    free($4);
 
113
    
 
114
    l = (len+1)/2;
 
115
    memset(fixed, ' ', l);
 
116
    fixed[l] = '\0';
 
117
    printf("%s%s\n", fixed, $6);
 
118
    free($6);
 
119
 
 
120
    indent = 1;
 
121
    ++line;
 
122
}
 
123
;
 
124
 
 
125
stuff: {
 
126
    $$ = strdup("");
 
127
}
 
128
| stuff text {
 
129
    $$ = malloc(strlen($1)+strlen($2)+1);
 
130
    sprintf($$,"%s%s", $1, $2);
 
131
    free($1);
 
132
    free($2);
 
133
}
 
134
;
 
135
 
 
136
text: CHAR {
 
137
    $$ = strdup(yytext);
 
138
}
 
139
| text CHAR {
 
140
    $$ = malloc(strlen($1)+2);
 
141
    sprintf($$,"%s%s", $1, yytext);
 
142
    free($1);
 
143
}
 
144
| NO_INDENT {
 
145
    $$ = strdup("");
 
146
    indent = 0;
 
147
}
 
148
| HASH {
 
149
    $$ = strdup("#");
 
150
}
 
151
| LABEL {
 
152
    if (($$ = get_label(yytext)) == NULL) {
 
153
        set_label(yytext, last_label);
 
154
        $$ = strdup("");
 
155
    }
 
156
}
 
157
| NEW_COUNTER {
 
158
    $$ = new_counter(yytext);
 
159
}
 
160
;
 
161
 
 
162
%%
 
163
 
 
164
typedef struct node_s {
 
165
    struct node_s *left, *right;
 
166
    const char *key;
 
167
    char *value;
 
168
} *node_t;
 
169
 
 
170
node_t label_root = NULL;
 
171
node_t counter_root = NULL;
 
172
 
 
173
const char *find_key(node_t root, const char *key)
 
174
{
 
175
    while (root) {
 
176
        int cmp = strcmp(key, root->key);
 
177
 
 
178
        if (cmp > 0) {
 
179
            root = root->right;
 
180
        } else if (cmp) {
 
181
            root = root->left;
 
182
        } else {
 
183
            return root->value;
 
184
        }
 
185
    }
 
186
    return NULL;
 
187
}
 
188
 
 
189
node_t set_key(node_t root, const char *key, const char *value)
 
190
{
 
191
    if (root) {
 
192
        int cmp = strcmp(key, root->key);
 
193
        if (cmp > 0) {
 
194
            root->right = set_key(root->right, key, value);
 
195
        } else if (cmp) {
 
196
            root->left = set_key(root->left, key, value);
 
197
        } else {
 
198
            free(root->value);
 
199
            root->value = strdup(value);
 
200
        }
 
201
    } else {
 
202
        root = malloc(sizeof(struct node_s));
 
203
        root->right = root->left = NULL;
 
204
        root->key = strdup(key);
 
205
        root->value = strdup(value);
 
206
    }
 
207
    return root;
 
208
}
 
209
 
 
210
void yyerror(const char *x)
 
211
{
 
212
    fprintf(stderr, "line %d: %s\n", line, x);
 
213
}
 
214
 
 
215
char *get_label(const char *label)
 
216
{
 
217
    const char *found = find_key(label_root, label);
 
218
 
 
219
    if (found) {
 
220
        return strdup(found);
 
221
    }
 
222
    return NULL;
 
223
}
 
224
 
 
225
void set_label(const char *label, const char *target)
 
226
{
 
227
    if (target == NULL) {
 
228
        yyerror("no hanging value for label");
 
229
        target = "<??>";
 
230
    }
 
231
    label_root = set_key(label_root, label, target);
 
232
}
 
233
 
 
234
char *new_counter(const char *key)
 
235
{
 
236
    int i=0, j, ndollars = 0;
 
237
    const char *old;
 
238
    char *new;
 
239
 
 
240
    if (key[i++] != '#') {
 
241
        yyerror("bad index");
 
242
        return strdup("<???>");
 
243
    }
 
244
 
 
245
    while (key[i] == '$') {
 
246
        ++ndollars;
 
247
        ++i;
 
248
    }
 
249
 
 
250
    key += i;
 
251
    old = find_key(counter_root, key);
 
252
    new = malloc(20*ndollars);
 
253
 
 
254
    if (old) {
 
255
        for (j=0; ndollars > 1 && old[j]; ) {
 
256
            if (old[j++] == '.' && --ndollars <= 0) {
 
257
                break;
 
258
            }
 
259
        }
 
260
        if (j) {
 
261
            strncpy(new, old, j);
 
262
        }
 
263
        if (old[j]) {
 
264
            i = atoi(old+j);
 
265
        } else {
 
266
            new[j++] = '.';
 
267
            i = 0;
 
268
        }
 
269
    } else {
 
270
        j=0;
 
271
        while (--ndollars > 0) {
 
272
            new[j++] = '0';
 
273
            new[j++] = '.';
 
274
        }
 
275
        i = 0;
 
276
    }
 
277
    new[j] = '\0';
 
278
    sprintf(new+j, "%d", ++i);
 
279
 
 
280
    counter_root = set_key(counter_root, key, new);
 
281
    
 
282
    if (last_label) {
 
283
        free(last_label);
 
284
    }
 
285
    last_label = strdup(new);
 
286
 
 
287
    return new;
 
288
}
 
289
 
 
290
main()
 
291
{
 
292
    yyparse();
 
293
}