Go to most recent revision | 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 | } |