Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2 | mjames | 1 | /* $Id: lx_support.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $ |
2 | * |
||
3 | * $Log: lx_support.c,v $ |
||
4 | * Revision 1.1.1.1 2003/11/04 23:34:57 mjames |
||
5 | * Imported into local repositrory |
||
6 | * |
||
7 | * Revision 1.8 2002/09/09 10:29:56 mjames |
||
8 | * Moved pin remapping function to pin ident editing function from |
||
9 | * sorting pin name routine. |
||
10 | * |
||
11 | * Revision 1.7 2002/01/16 11:22:45 mjames |
||
12 | * database.h header file is read in first as it undefined DLL stuff irrelevant |
||
13 | * to HPUX |
||
14 | * |
||
15 | * Revision 1.6 2002/01/15 12:34:12 mjames |
||
16 | * DLL declarations put in |
||
17 | * |
||
18 | * Revision 1.5 2001/12/13 22:14:25 mjames |
||
19 | * Corrected nested command handlers to allow variable passing without corruption. |
||
20 | * |
||
21 | * Revision 1.4 2001/10/31 22:20:08 mjames |
||
22 | * Tidying up problematical comments caused by CVS |
||
23 | * 'intelligent' comment guessing |
||
24 | * |
||
25 | * |
||
26 | */ |
||
27 | #include "lx_support.h" |
||
28 | |||
29 | #include "acf_yacc.h" |
||
30 | #include "cmdexec.h" |
||
31 | #include "cmdlog.h" |
||
32 | #include "cmdparse.h" |
||
33 | #include "cmdutil.h" |
||
34 | #include "database.h" |
||
35 | #include "expression.h" |
||
36 | #include "generic.h" |
||
37 | #include "vertcl_main.h" |
||
38 | |||
39 | #include <stdio.h> |
||
40 | #include <stdlib.h> |
||
41 | #include <string.h> |
||
42 | |||
43 | /* purpose to queue lex tokens until all have been used on a line or in a statement */ |
||
44 | |||
45 | int yyval; /* propose to confuse LEX ... */ |
||
46 | int yy_nArgs; |
||
47 | char **yy_Args; |
||
48 | |||
49 | #ident \ |
||
50 | "@(#)$Header: c:\\cygwin\\cvsroot/Vert03/vertlib/lx_support.c,v 1.1.1.1 2003/11/04 23:34:57 mjames Exp $" |
||
51 | |||
52 | __declspec(dllexport) struct str *lx_first = NULL; |
||
53 | __declspec(dllexport) struct str *lx_last = NULL; |
||
54 | |||
55 | /* the Args values are for the current argc/argv context */ |
||
56 | void expand_string (char *source, char *dest, int nArgs, char *Args[]) |
||
57 | { |
||
58 | char num_buff[LINELEN]; |
||
59 | |||
60 | char *Ptr = source; |
||
61 | char *Optr = dest; |
||
62 | generic_info_t **chip_generics = NULL; |
||
63 | |||
64 | /* printf("IN ='%s'\n",source); */ |
||
65 | |||
66 | if (!source || !dest) |
||
67 | return; |
||
68 | |||
69 | dest[0] = 0; |
||
70 | while (*Ptr && (Optr - dest) < LINELEN - 1) |
||
71 | { |
||
72 | if (*Ptr == '\\') |
||
73 | { |
||
74 | Ptr++; |
||
75 | if (*Ptr) |
||
76 | { |
||
77 | *Optr++ = *Ptr++; |
||
78 | *Optr = 0; |
||
79 | }; |
||
80 | continue; |
||
81 | }; |
||
82 | |||
83 | if (*Ptr == '$') |
||
84 | { /* variable expansion */ |
||
85 | |||
86 | /* pattern 1 : $n - lookup argv[n] */ |
||
87 | if (Ptr[1] >= '0' && Ptr[1] <= '9') |
||
88 | { |
||
89 | int n = Ptr[1] - '0'; |
||
90 | if (n < nArgs) |
||
91 | { |
||
92 | /* space to place new word ? */ |
||
93 | if ((Optr + strlen (Args[n]) - dest) < LINELEN) |
||
94 | { |
||
95 | strcpy (Optr, Args[n]); |
||
96 | Optr += strlen (Args[n]); |
||
97 | *Optr = 0; |
||
98 | }; |
||
99 | |||
100 | Ptr += 2; |
||
101 | continue; |
||
102 | } |
||
103 | } |
||
104 | /* pattern 2 : look up a generic SYSVAR */ |
||
105 | else if (Ptr[1] == '(') |
||
106 | { |
||
107 | char var_name[WORDWIDTH], *env_val; |
||
108 | int c = 0; |
||
109 | generic_info_t generic[1]; |
||
110 | generic_type_t gen_type; |
||
111 | Ptr += 2; /* skip '$(' */ |
||
112 | var_name[0] = '\0'; |
||
113 | while (*Ptr && *Ptr != ')') |
||
114 | { |
||
115 | if (c < WORDWIDTH - 1) |
||
116 | { |
||
117 | var_name[c++] = *Ptr; |
||
118 | var_name[c] = '\0'; |
||
119 | } |
||
120 | Ptr++; |
||
121 | } |
||
122 | if (*Ptr) |
||
123 | Ptr++; |
||
124 | /* now lookup result */ |
||
125 | |||
126 | env_val = NULL; |
||
127 | /* try generic lookup first */ |
||
128 | |||
129 | gen_type = |
||
130 | get_generic_value (&global_generics, var_name, generic); |
||
131 | if (!gen_type) |
||
132 | gen_type = get_generic_value ( |
||
133 | &partition_generics, var_name, generic); |
||
134 | /* accept a string */ |
||
135 | if (gen_type == IS_STRING || gen_type == IS_ENV_VAL) |
||
136 | { |
||
137 | if (generic->expr) |
||
138 | env_val = generic->expr->left.s; |
||
139 | }; |
||
140 | if (gen_type == IS_INTEGER) |
||
141 | { |
||
142 | if (generic->expr) |
||
143 | { |
||
144 | sprintf ( |
||
145 | num_buff, |
||
146 | "%d", |
||
147 | eval_expression ( |
||
148 | generic->expr, chip_generics)); |
||
149 | env_val = num_buff; |
||
150 | } |
||
151 | } |
||
152 | if (gen_type == TO) |
||
153 | { |
||
154 | if (generic->expr) |
||
155 | { |
||
156 | sprintf ( |
||
157 | num_buff, |
||
158 | "%d TO %d", |
||
159 | eval_expression ( |
||
160 | generic->expr->left.e, chip_generics), |
||
161 | eval_expression ( |
||
162 | generic->expr->right.e, |
||
163 | chip_generics)); |
||
164 | env_val = num_buff; |
||
165 | } |
||
166 | } |
||
167 | if (gen_type == DOWNTO) |
||
168 | { |
||
169 | if (generic->expr) |
||
170 | { |
||
171 | sprintf ( |
||
172 | num_buff, |
||
173 | "%d DOWNTO %d", |
||
174 | eval_expression ( |
||
175 | generic->expr->left.e, chip_generics), |
||
176 | eval_expression ( |
||
177 | generic->expr->right.e, |
||
178 | chip_generics)); |
||
179 | env_val = num_buff; |
||
180 | } |
||
181 | } |
||
182 | |||
183 | /* try OS environment variables */ |
||
184 | if (!env_val) |
||
185 | env_val = getenv (var_name); |
||
186 | if (env_val && (Optr + strlen (env_val) - dest) < LINELEN) |
||
187 | { |
||
188 | strcpy (Optr, env_val); |
||
189 | Optr += strlen (env_val); |
||
190 | *Optr = 0; |
||
191 | continue; |
||
192 | }; |
||
193 | if ((Optr + strlen (var_name) - dest) < LINELEN) |
||
194 | { |
||
195 | sprintf (Optr, "$(%s)", var_name); |
||
196 | Optr += strlen (var_name) + 3; |
||
197 | *Optr = 0; |
||
198 | } |
||
199 | } |
||
200 | } |
||
201 | if (*Ptr != '\r' && *Ptr != '\n') |
||
202 | { |
||
203 | *Optr++ = *Ptr; |
||
204 | *Optr = 0; |
||
205 | } |
||
206 | Ptr++; |
||
207 | } |
||
208 | /* printf("OUT='%s'\n",dest); */ |
||
209 | } |
||
210 | |||
211 | char *make_string (char *token, struct str **pfirst, struct str **plast) |
||
212 | { |
||
213 | char *t; |
||
214 | struct str *s; |
||
215 | int l; |
||
216 | char workbuff[LINELEN]; |
||
217 | /* perform checks in the right order 18-02-2000 */ |
||
218 | if (!token) |
||
219 | return NULL; |
||
220 | l = strlen (token); |
||
221 | s = calloc (1, sizeof (struct str)); |
||
222 | if (!s) |
||
223 | return NULL; |
||
224 | |||
225 | /* eliminate quotes from the string : |
||
226 | * !! ASSUMES string is in Read/Write memory */ |
||
227 | if (l >= 2 && token[0] == '\"' && token[l - 1] == '\"') |
||
228 | { |
||
229 | strncpy (token, token + 1, l - 2); /* chuck quotes off string */ |
||
230 | token[l - 2] = '\0'; /* null terminate */ |
||
231 | } |
||
232 | |||
233 | /* the values yy_nArgs and yy_Args were filled |
||
234 | in just before calling yyparse */ |
||
235 | expand_string (token, workbuff, yy_nArgs, yy_Args); |
||
236 | l = strlen (workbuff); |
||
237 | |||
238 | t = malloc (l + 1); |
||
239 | if (!t) |
||
240 | return NULL; |
||
241 | |||
242 | strcpy (t, workbuff); /* copy string , join to structure */ |
||
243 | s->dat = t; |
||
244 | s->next = NULL; |
||
245 | |||
246 | if (!*pfirst) |
||
247 | *pfirst = s; |
||
248 | |||
249 | if (*plast) |
||
250 | (*plast)->next = s; |
||
251 | |||
252 | *plast = s; |
||
253 | /* printf("MADE\n"); */ |
||
254 | |||
255 | return (t); /* pointer to the string that can be later tidily freed */ |
||
256 | } |
||
257 | |||
258 | void free_strings (struct str **pfirst, struct str **plast) |
||
259 | { |
||
260 | struct str *s, *t; |
||
261 | s = *pfirst; |
||
262 | while (s) /* run down the list, freeing entries */ |
||
263 | { |
||
264 | if (s->dat) |
||
265 | free (s->dat); |
||
266 | t = s; |
||
267 | s = s->next; |
||
268 | free (t); |
||
269 | } |
||
270 | *pfirst = NULL; |
||
271 | *plast = NULL; |
||
272 | } |
||
273 | |||
274 | /* called from YACC to deallocate memory structures cleanly */ |
||
275 | void free_lex_strings (void) |
||
276 | { |
||
277 | free_strings (&lx_first, &lx_last); |
||
278 | }; |
||
279 | |||
280 | #define to_lower(c) ((c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c) |
||
281 | |||
282 | int streq (char *s1, char *s2) |
||
283 | { |
||
284 | while (*s1 != '\0') |
||
285 | { |
||
286 | if (to_lower (*s2) != to_lower (*s1)) |
||
287 | return (0); |
||
288 | s1++; |
||
289 | s2++; |
||
290 | } |
||
291 | return (*s2 == '\0'); |
||
292 | } |
||
293 | |||
294 | int strneq (char *s1, char *s2, int n) |
||
295 | { |
||
296 | while (n && *s1 != '\0') |
||
297 | { |
||
298 | if (to_lower (*s2) != to_lower (*s1)) |
||
299 | return (0); |
||
300 | s1++; |
||
301 | s2++; |
||
302 | --n; |
||
303 | } |
||
304 | return (n == 0 || *s2 == '\0'); |
||
305 | } |