source: tags/arb_5.2/AISC/aisc_var_ref.c

Last change on this file was 5968, checked in by westram, 15 years ago
  • new flag -w to aisc_mkpt (add include wrapper)
  • uniform style for several include wrappers
  • removed duplicated includes
  • removed useless nt_concatenate.hxx
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.0 KB
Line 
1#include <stdio.h>
2#include <stdlib.h>
3#include <string.h>
4/* #include <malloc.h> */
5#include "aisc.h"
6
7static AD *aisc_match(AD * var, char *varid, char *varct) {
8    if (varid) {
9        if (strcmp(var->key, varid)) {
10            return 0;
11        }
12    }
13    if (varct) {
14        if (var->sub) {
15            return 0;
16        }
17        if (strcmp(var->val, varct)) {
18            return 0;
19        }
20    }
21    return var;
22}
23#define NEXT_ITEM(se,extended) if (extended) {  \
24        if (se->next_item) se = se->next_item;  \
25        else se=se->first_item->next_line;      \
26    }else{                                      \
27        se = se->next_item;                     \
28    }
29
30AD *aisc_find_var_hier(AD * cursor, char *str, int next, int extended, int goup) {
31    char *slash;
32    AD   *found;
33   
34    if (*str == '/') {
35        cursor = 0;
36        str++;
37    }
38    slash = strchr(str, '/');
39    found = 0;
40    while (slash) {
41        *(slash++) = 0;
42        found = aisc_find_var(cursor, str, next, extended, goup);
43        if (!found)
44            return 0;
45        if (!found->sub) {
46            return 0;
47        }
48        cursor = found->sub;
49        goup = 0;
50        extended = 1;
51        str = slash;
52        slash = strchr(str, '/');
53        next = 0;
54    }
55    found = aisc_find_var(cursor, str, next, extended, goup);
56    return found;
57
58}
59
60AD *aisc_find_var(AD * cursor, char *str, int next, int extended, int goup) {
61    /* if next = 1 search next entry
62     * else search all
63     * if extended != 0 search in parallel sentences,
64     * if goup search whole upper hierarchy
65     */
66    AD             *se, *line;
67    AD             *found;
68    char           *varid, *varct;
69    char           *pp, *buf;
70    found = 0;
71
72    if (cursor) {
73        line = cursor;
74    } else {
75        line = gl->root;
76    }
77
78    pp = strchr(str, '.');
79    if (!pp) {
80        varid = strdup(str);
81        varct = 0;
82    } else {
83        buf = strdup(str);
84        pp = strchr(buf, '.');
85        *(pp++) = 0;
86        if ((!strcmp(buf, "*")) || (!buf[0])) {
87            varid = 0;
88        } else {
89            varid = strdup(buf);
90        }
91        if ((!strcmp(pp, "*")) || (!pp[0])) {
92            varct = 0;
93        } else {
94            varct = strdup(pp);
95        }
96        free(buf);
97    }
98    while (line && !found) {
99        if (next) {
100            NEXT_ITEM(line, extended);
101        } else {
102            if (extended) {
103                line = line->first_item->first_line;
104            } else {
105                line = line->first_item;
106            }
107        }
108        for (se = line; se;) {
109            if ( (found = aisc_match(se, varid, varct))) {
110                break;
111            }
112            NEXT_ITEM(se, extended);
113        }
114        if (goup) {
115            line = line->first_item->first_line->father;
116        } else {
117            line = 0;
118        }
119    }
120    if (varid)
121        free(varid);
122    if (varct)
123        free(varct);
124    return found;
125}
126
127
128char           *
129get_var_string(char *var)
130/* Berechnet zu einem Ausdruch der Form $(IDENT:fdg|"sdfg") das Ergebnis */
131{
132    AD             *cur;
133    char           *doppelpunkt;
134    char           *bar;
135    char           *nextdp;
136    char           *finds;
137    int             len;
138    int             findl;
139    int             replacel;
140    int             offset;
141    int             use_path;
142    char           *in, *buf1, *buf2;
143
144
145
146    READ_SPACES(var);
147    use_path = 0;
148    while (var[0] == '&') {
149        use_path++;
150        var++;
151        READ_SPACES(var);
152    }
153    doppelpunkt = strchr(var, ':');
154    if (doppelpunkt)
155        *(doppelpunkt++) = 0;
156    bar = strchr(var, '|');
157    if (bar)
158        *(bar++) = 0;
159    in = read_hash_local(var,0);
160    if (in) {
161        in = strdup(in);
162    } else {
163        cur = aisc_find_var_hier(gl->cursor, var, 0, 0, 1);
164        if (!cur) {
165            if (!bar) {
166                if (gl->pc->command == IF) {
167                    return 0;
168                }
169                /* fprintf(stderr, "%s: ", var); */
170                printf_error("Ident '%s' not found", var);
171                return 0;
172            }
173            return strdup(bar);
174        }
175        if (use_path) {
176            in = strdup(cur->key);
177            if (use_path == 1) {
178            } else {
179                while (cur->first_item->first_line->father) {
180                    cur = cur->first_item->first_line->father;
181                    len = strlen(in) + strlen(cur->key);
182                    buf1 = (char *) calloc(sizeof(char), len + 2);
183                    sprintf(buf1, "%s/%s", cur->key, in);
184                    free(in);
185                    in = buf1;
186                }
187
188            }
189        } else {
190            if (cur->sub) {
191                printf_error("Ident '%s' is a hierarchical type", var);
192                return 0;
193            } else {
194                if (cur->val) {
195                    in = strdup(cur->val);
196                }else{
197                    in = strdup("");
198                }
199            }
200        }
201    }
202    if (!doppelpunkt)
203        return in;
204    len = strlen(in);
205    while (doppelpunkt) {
206        nextdp = strchr(doppelpunkt, ':');
207        if (nextdp)
208            *(nextdp++) = 0;
209        if (!doppelpunkt[0]) {
210            print_error("Ident replacement is missing an '='");
211            return 0;
212        }
213
214        bar = strchr(doppelpunkt+1, '=');
215        if (bar) {
216            *(bar++) = 0;
217        } else {
218            print_error("Ident replacement is missing an '='");
219            return 0;
220        }
221        findl = strlen(doppelpunkt);
222        replacel = strlen(bar);
223        for (finds = strstr(in, doppelpunkt); finds; finds = strstr(buf2, doppelpunkt)) {
224            len += replacel - findl;
225            buf1 = (char *) calloc(sizeof(char), len + 1);
226            offset = finds - in;
227            memcpy(buf1, in, offset);
228            memcpy(buf1 + offset, bar, replacel);
229            buf2 = buf1 + offset + replacel;
230            memcpy(buf2, in + offset + findl, len - replacel - offset);
231            free(in);
232            in = buf1;
233            buf2 = in + offset + replacel;
234        }
235        doppelpunkt = nextdp;
236    }
237    return in;
238}
Note: See TracBrowser for help on using the repository browser.