inf.c revision 123475
1123475Swpaul/* 2123475Swpaul * $Id: inf.c,v 1.3 2003/11/30 21:58:16 winter Exp $ 3123475Swpaul */ 4123475Swpaul 5123475Swpaul#include <sys/cdefs.h> 6123475Swpaul__FBSDID("$FreeBSD: head/usr.sbin/ndiscvt/inf.c 123475 2003-12-11 22:38:14Z wpaul $"); 7123475Swpaul 8123475Swpaul#include <stdio.h> 9123475Swpaul#include <stdlib.h> 10123475Swpaul#include <string.h> 11123475Swpaul#include <sys/types.h> 12123475Swpaul 13123475Swpaul#include <sys/queue.h> 14123475Swpaul 15123475Swpaul#include "inf.h" 16123475Swpaul 17123475Swpaulextern FILE *yyin; 18123475Swpaulint yyparse (void); 19123475Swpaul 20123475Swpaulconst char *words[W_MAX]; /* More than we'll need. */ 21123475Swpaulint idx; 22123475Swpaul 23123475Swpaulstatic struct section_head sh; 24123475Swpaulstatic struct reg_head rh; 25123475Swpaulstatic struct assign_head ah; 26123475Swpaul 27123475Swpaulstatic char *sstrdup (const char *); 28123475Swpaulstatic struct assign 29123475Swpaul *find_assign (const char *, const char *); 30123475Swpaulstatic struct section 31123475Swpaul *find_section (const char *); 32123475Swpaulstatic void dump_deviceids (void); 33123475Swpaulstatic void dump_pci_id (const char *); 34123475Swpaulstatic void dump_regvals (void); 35123475Swpaulstatic void dump_paramreg (const struct section *, const struct reg *); 36123475Swpaul 37123475Swpaulstatic FILE *ofp; 38123475Swpaul 39123475Swpaulint 40123475Swpaulinf_parse (FILE *fp, FILE *outfp) 41123475Swpaul{ 42123475Swpaul TAILQ_INIT(&sh); 43123475Swpaul TAILQ_INIT(&rh); 44123475Swpaul TAILQ_INIT(&ah); 45123475Swpaul 46123475Swpaul ofp = outfp; 47123475Swpaul yyin = fp; 48123475Swpaul yyparse(); 49123475Swpaul 50123475Swpaul dump_deviceids(); 51123475Swpaul dump_regvals(); 52123475Swpaul 53123475Swpaul return (0); 54123475Swpaul} 55123475Swpaul 56123475Swpaulvoid 57123475Swpaulsection_add (const char *s) 58123475Swpaul{ 59123475Swpaul struct section *sec; 60123475Swpaul 61123475Swpaul sec = malloc(sizeof(struct section)); 62123475Swpaul bzero(sec, sizeof(struct section)); 63123475Swpaul sec->name = s; 64123475Swpaul TAILQ_INSERT_TAIL(&sh, sec, link); 65123475Swpaul 66123475Swpaul return; 67123475Swpaul} 68123475Swpaul 69123475Swpaulstatic struct assign * 70123475Swpaulfind_assign (const char *s, const char *k) 71123475Swpaul{ 72123475Swpaul struct assign *assign; 73123475Swpaul char newkey[256]; 74123475Swpaul 75123475Swpaul /* Deal with string section lookups. */ 76123475Swpaul 77123475Swpaul if (k != NULL && k[0] == '%') { 78123475Swpaul bzero(newkey, sizeof(newkey)); 79123475Swpaul strncpy(newkey, k + 1, strlen(k) - 2); 80123475Swpaul k = newkey; 81123475Swpaul } 82123475Swpaul 83123475Swpaul TAILQ_FOREACH(assign, &ah, link) { 84123475Swpaul if (strcasecmp(assign->section->name, s) == 0) { 85123475Swpaul if (k == NULL) 86123475Swpaul return(assign); 87123475Swpaul else 88123475Swpaul if (strcasecmp(assign->key, k) == 0) 89123475Swpaul return(assign); 90123475Swpaul } 91123475Swpaul } 92123475Swpaul return(NULL); 93123475Swpaul} 94123475Swpaul 95123475Swpaulstatic const char * 96123475Swpaulstringcvt(const char *s) 97123475Swpaul{ 98123475Swpaul struct assign *manf; 99123475Swpaul 100123475Swpaul manf = find_assign("strings", s); 101123475Swpaul if (manf == NULL) 102123475Swpaul return(s); 103123475Swpaul return(manf->vals[0]); 104123475Swpaul} 105123475Swpaul 106123475Swpaulstruct section * 107123475Swpaulfind_section (const char *s) 108123475Swpaul{ 109123475Swpaul struct section *section; 110123475Swpaul 111123475Swpaul TAILQ_FOREACH(section, &sh, link) { 112123475Swpaul if (strcasecmp(section->name, s) == 0) 113123475Swpaul return(section); 114123475Swpaul } 115123475Swpaul return(NULL); 116123475Swpaul} 117123475Swpaul 118123475Swpaulstatic void 119123475Swpauldump_pci_id(const char *s) 120123475Swpaul{ 121123475Swpaul char *p; 122123475Swpaul char vidstr[7], didstr[7]; 123123475Swpaul 124123475Swpaul p = strcasestr(s, "VEN_"); 125123475Swpaul if (p == NULL) 126123475Swpaul return; 127123475Swpaul p += 4; 128123475Swpaul strcpy(vidstr, "0x"); 129123475Swpaul strncat(vidstr, p, 4); 130123475Swpaul p = strcasestr(s, "DEV_"); 131123475Swpaul if (p == NULL) 132123475Swpaul return; 133123475Swpaul p += 4; 134123475Swpaul strcpy(didstr, "0x"); 135123475Swpaul strncat(didstr, p, 4); 136123475Swpaul if (p == NULL) 137123475Swpaul return; 138123475Swpaul 139123475Swpaul fprintf(ofp, "\t\\\n\t{ %s, %s,", vidstr, didstr); 140123475Swpaul return; 141123475Swpaul} 142123475Swpaul 143123475Swpaulstatic void 144123475Swpauldump_deviceids() 145123475Swpaul{ 146123475Swpaul struct assign *manf, *dev; 147123475Swpaul struct section *sec; 148123475Swpaul struct assign *assign; 149123475Swpaul 150123475Swpaul /* Find manufacturer name */ 151123475Swpaul manf = find_assign("Manufacturer", NULL); 152123475Swpaul 153123475Swpaul /* Find manufacturer section */ 154123475Swpaul sec = find_section(manf->vals[0]); 155123475Swpaul 156123475Swpaul /* Emit start of device table */ 157123475Swpaul fprintf (ofp, "#define NDIS_DEV_TABLE"); 158123475Swpaul 159123475Swpaul /* 160123475Swpaul * Now run through all the device names listed 161123475Swpaul * in the manufacturer section and dump out the 162123475Swpaul * device descriptions and vendor/device IDs. 163123475Swpaul */ 164123475Swpaul 165123475Swpaul TAILQ_FOREACH(assign, &ah, link) { 166123475Swpaul if (assign->section == sec) { 167123475Swpaul dev = find_assign("strings", assign->key); 168123475Swpaul /* Emit device IDs. */ 169123475Swpaul if (strcasestr(assign->vals[1], "PCI") != NULL) 170123475Swpaul dump_pci_id(assign->vals[1]); 171123475Swpaul#ifdef notdef 172123475Swpaul else if (strcasestr(assign->vals[1], "PCMCIA") != NULL) 173123475Swpaul dump_pcmcia_id(assign->vals[1]); 174123475Swpaul#endif 175123475Swpaul /* Emit device description */ 176123475Swpaul fprintf (ofp, "\t\\\n\t\"%s\"", dev->vals[0]); 177123475Swpaul } 178123475Swpaul } 179123475Swpaul 180123475Swpaul /* Emit end of table */ 181123475Swpaul 182123475Swpaul fprintf(ofp, " },\n\n"); 183123475Swpaul} 184123475Swpaul 185123475Swpaulstatic void 186123475Swpauldump_addreg(const char *s) 187123475Swpaul{ 188123475Swpaul struct section *sec; 189123475Swpaul struct reg *reg; 190123475Swpaul 191123475Swpaul /* Find the addreg section */ 192123475Swpaul sec = find_section(s); 193123475Swpaul 194123475Swpaul /* Dump all the keys defined in it. */ 195123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 196123475Swpaul /* 197123475Swpaul * Keys with an empty subkey are very easy to parse, 198123475Swpaul * so just deal with them here. If a parameter key 199123475Swpaul * of the same name also exists, prefer that one and 200123475Swpaul * skip this one. 201123475Swpaul */ 202123475Swpaul if (reg->section == sec) { 203123475Swpaul if (reg->subkey == NULL) { 204123475Swpaul fprintf(ofp, "\n\t{ \"%s\",", reg->key); 205123475Swpaul fprintf(ofp,"\n\t\"%s \",", reg->key); 206123475Swpaul fprintf(ofp, "\n\t{ \"%s\" } },", 207123475Swpaul reg->value == NULL ? "" : 208123475Swpaul reg->value); 209123475Swpaul } else if (strcasestr(reg->subkey, 210123475Swpaul "Ndi\\params") != NULL && 211123475Swpaul strcasecmp(reg->key, "ParamDesc") == 0) 212123475Swpaul dump_paramreg(sec, reg); 213123475Swpaul } 214123475Swpaul } 215123475Swpaul 216123475Swpaul return; 217123475Swpaul} 218123475Swpaul 219123475Swpaulstatic void 220123475Swpauldump_enumreg(const struct section *s, const struct reg *r) 221123475Swpaul{ 222123475Swpaul struct reg *reg; 223123475Swpaul char enumkey[256]; 224123475Swpaul 225123475Swpaul sprintf(enumkey, "%s\\enum", r->subkey); 226123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 227123475Swpaul if (reg->section != s) 228123475Swpaul continue; 229123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, enumkey)) 230123475Swpaul continue; 231123475Swpaul fprintf(ofp, " [%s=%s]", reg->key, stringcvt(reg->value)); 232123475Swpaul } 233123475Swpaul return; 234123475Swpaul} 235123475Swpaul 236123475Swpaulstatic void 237123475Swpauldump_editreg(const struct section *s, const struct reg *r) 238123475Swpaul{ 239123475Swpaul struct reg *reg; 240123475Swpaul 241123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 242123475Swpaul if (reg->section != s) 243123475Swpaul continue; 244123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 245123475Swpaul continue; 246123475Swpaul if (strcasecmp(reg->key, "LimitText") == 0) 247123475Swpaul fprintf(ofp, " [maxchars=%s]", reg->value); 248123475Swpaul if (strcasecmp(reg->key, "Optional") == 0 && 249123475Swpaul strcmp(reg->value, "1") == 0) 250123475Swpaul fprintf(ofp, " [optional]"); 251123475Swpaul } 252123475Swpaul return; 253123475Swpaul} 254123475Swpaul 255123475Swpaul/* Use this for int too */ 256123475Swpaulstatic void 257123475Swpauldump_dwordreg(const struct section *s, const struct reg *r) 258123475Swpaul{ 259123475Swpaul struct reg *reg; 260123475Swpaul 261123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 262123475Swpaul if (reg->section != s) 263123475Swpaul continue; 264123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 265123475Swpaul continue; 266123475Swpaul if (strcasecmp(reg->key, "min") == 0) 267123475Swpaul fprintf(ofp, " [min=%s]", reg->value); 268123475Swpaul if (strcasecmp(reg->key, "max") == 0) 269123475Swpaul fprintf(ofp, " [max=%s]", reg->value); 270123475Swpaul } 271123475Swpaul return; 272123475Swpaul} 273123475Swpaul 274123475Swpaulstatic void 275123475Swpauldump_defaultinfo(const struct section *s, const struct reg *r) 276123475Swpaul{ 277123475Swpaul struct reg *reg; 278123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 279123475Swpaul if (reg->section != s) 280123475Swpaul continue; 281123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 282123475Swpaul continue; 283123475Swpaul if (strcasecmp(reg->key, "Default")) 284123475Swpaul continue; 285123475Swpaul fprintf(ofp, "\n\t{ \"%s\" } },", reg->value == NULL ? "" : 286123475Swpaul reg->value); 287123475Swpaul break; 288123475Swpaul } 289123475Swpaul return; 290123475Swpaul} 291123475Swpaul 292123475Swpaulstatic void 293123475Swpauldump_paramdesc(const struct section *s, const struct reg *r) 294123475Swpaul{ 295123475Swpaul struct reg *reg; 296123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 297123475Swpaul if (reg->section != s) 298123475Swpaul continue; 299123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 300123475Swpaul continue; 301123475Swpaul if (strcasecmp(reg->key, "ParamDesc")) 302123475Swpaul continue; 303123475Swpaul fprintf(ofp, "\n\t\"%s", stringcvt(r->value)); 304123475Swpaul break; 305123475Swpaul } 306123475Swpaul return; 307123475Swpaul} 308123475Swpaul 309123475Swpaulstatic void 310123475Swpauldump_typeinfo(const struct section *s, const struct reg *r) 311123475Swpaul{ 312123475Swpaul struct reg *reg; 313123475Swpaul TAILQ_FOREACH(reg, &rh, link) { 314123475Swpaul if (reg->section != s) 315123475Swpaul continue; 316123475Swpaul if (reg->subkey == NULL || strcasecmp(reg->subkey, r->subkey)) 317123475Swpaul continue; 318123475Swpaul if (strcasecmp(reg->key, "type")) 319123475Swpaul continue; 320123475Swpaul if (strcasecmp(reg->value, "dword") == 0 || 321123475Swpaul strcasecmp(reg->value, "int") == 0) 322123475Swpaul dump_dwordreg(s, r); 323123475Swpaul if (strcasecmp(reg->value, "enum") == 0) 324123475Swpaul dump_enumreg(s, r); 325123475Swpaul if (strcasecmp(reg->value, "edit") == 0) 326123475Swpaul dump_editreg(s, r); 327123475Swpaul } 328123475Swpaul return; 329123475Swpaul} 330123475Swpaul 331123475Swpaulstatic void 332123475Swpauldump_paramreg(const struct section *s, const struct reg *r) 333123475Swpaul{ 334123475Swpaul const char *keyname; 335123475Swpaul 336123475Swpaul keyname = r->subkey + strlen("Ndi\\params\\"); 337123475Swpaul fprintf(ofp, "\n\t{ \"%s\",", keyname); 338123475Swpaul dump_paramdesc(s, r); 339123475Swpaul dump_typeinfo(s, r); 340123475Swpaul fprintf(ofp, "\","); 341123475Swpaul dump_defaultinfo(s, r); 342123475Swpaul 343123475Swpaul return; 344123475Swpaul} 345123475Swpaul 346123475Swpaulstatic void 347123475Swpauldump_regvals(void) 348123475Swpaul{ 349123475Swpaul struct assign *manf, *dev, *dev_dup; 350123475Swpaul struct section *sec; 351123475Swpaul struct assign *assign; 352123475Swpaul struct assign_head tmp_ah; 353123475Swpaul char sname[256]; 354123475Swpaul int i; 355123475Swpaul 356123475Swpaul TAILQ_INIT(&tmp_ah); 357123475Swpaul 358123475Swpaul /* Find manufacturer name */ 359123475Swpaul manf = find_assign("Manufacturer", NULL); 360123475Swpaul 361123475Swpaul /* Find manufacturer section */ 362123475Swpaul sec = find_section(manf->vals[0]); 363123475Swpaul 364123475Swpaul /* Emit start of block */ 365123475Swpaul fprintf (ofp, "ndis_cfg ndis_regvals[] = {"); 366123475Swpaul 367123475Swpaul TAILQ_FOREACH(assign, &ah, link) { 368123475Swpaul /* Avoid repeating the same section. */ 369123475Swpaul i = 0; 370123475Swpaul TAILQ_FOREACH(dev_dup, &tmp_ah, link) 371123475Swpaul if (strcmp(dev_dup->vals[0], assign->vals[0]) == 0) { 372123475Swpaul i++; 373123475Swpaul break; 374123475Swpaul } 375123475Swpaul if (i) 376123475Swpaul continue; 377123475Swpaul dev_dup = malloc(sizeof(struct assign)); 378123475Swpaul bcopy((char *)assign, (char *)dev_dup, 379123475Swpaul sizeof(struct assign)); 380123475Swpaul TAILQ_INSERT_TAIL(&tmp_ah, dev_dup, link); 381123475Swpaul if (assign->section == sec) { 382123475Swpaul /* Ignore Windows 95-era data. */ 383123475Swpaul sprintf(sname, "%s.NT", assign->vals[0]); 384123475Swpaul /* Find all the AddReg sections. */ 385123475Swpaul dev = find_assign(sname, "AddReg"); 386123475Swpaul for (i = 0; i < W_MAX; i++) { 387123475Swpaul if (dev->vals[i] != NULL) 388123475Swpaul dump_addreg(dev->vals[i]); 389123475Swpaul } 390123475Swpaul } 391123475Swpaul } 392123475Swpaul 393123475Swpaul fprintf(ofp, "\n\t{ NULL, NULL, { 0 } }\n};\n\n"); 394123475Swpaul 395123475Swpaul return; 396123475Swpaul} 397123475Swpaul 398123475Swpaulvoid 399123475Swpaulassign_add (const char *a) 400123475Swpaul{ 401123475Swpaul struct assign *assign; 402123475Swpaul int i; 403123475Swpaul 404123475Swpaul assign = malloc(sizeof(struct assign)); 405123475Swpaul bzero(assign, sizeof(struct assign)); 406123475Swpaul assign->section = TAILQ_LAST(&sh, section_head); 407123475Swpaul assign->key = sstrdup(a); 408123475Swpaul for (i = 0; i < idx; i++) 409123475Swpaul assign->vals[(idx - 1) - i] = sstrdup(words[i]); 410123475Swpaul TAILQ_INSERT_TAIL(&ah, assign, link); 411123475Swpaul 412123475Swpaul clear_words(); 413123475Swpaul return; 414123475Swpaul} 415123475Swpaul 416123475Swpaulvoid 417123475Swpauldefine_add (const char *d __unused) 418123475Swpaul{ 419123475Swpaul#ifdef notdef 420123475Swpaul fprintf(stderr, "define \"%s\"\n", d); 421123475Swpaul#endif 422123475Swpaul return; 423123475Swpaul} 424123475Swpaul 425123475Swpaulstatic char * 426123475Swpaulsstrdup(const char *str) 427123475Swpaul{ 428123475Swpaul if (str != NULL && strlen(str)) 429123475Swpaul return (strdup(str)); 430123475Swpaul return (NULL); 431123475Swpaul} 432123475Swpaul 433123475Swpaulstatic int 434123475Swpaulsatoi (const char *nptr) 435123475Swpaul{ 436123475Swpaul if (nptr != NULL && strlen(nptr)) 437123475Swpaul return (atoi(nptr)); 438123475Swpaul return (0); 439123475Swpaul} 440123475Swpaul 441123475Swpaulvoid 442123475Swpaulregkey_add (const char *r) 443123475Swpaul{ 444123475Swpaul struct reg *reg; 445123475Swpaul 446123475Swpaul reg = malloc(sizeof(struct reg)); 447123475Swpaul bzero(reg, sizeof(struct reg)); 448123475Swpaul reg->section = TAILQ_LAST(&sh, section_head); 449123475Swpaul reg->root = sstrdup(r); 450123475Swpaul reg->subkey = sstrdup(words[3]); 451123475Swpaul reg->key = sstrdup(words[2]); 452123475Swpaul reg->flags = satoi(words[1]); 453123475Swpaul reg->value = sstrdup(words[0]); 454123475Swpaul TAILQ_INSERT_TAIL(&rh, reg, link); 455123475Swpaul 456123475Swpaul free(__DECONST(char *, r)); 457123475Swpaul clear_words(); 458123475Swpaul return; 459123475Swpaul} 460123475Swpaul 461123475Swpaulvoid 462123475Swpaulpush_word (const char *w) 463123475Swpaul{ 464123475Swpaul if (w && strlen(w)) 465123475Swpaul words[idx++] = w; 466123475Swpaul else 467123475Swpaul words[idx++] = NULL; 468123475Swpaul return; 469123475Swpaul} 470123475Swpaul 471123475Swpaulvoid 472123475Swpaulclear_words (void) 473123475Swpaul{ 474123475Swpaul int i; 475123475Swpaul 476123475Swpaul for (i = 0; i < idx; i++) { 477123475Swpaul if (words[i]) { 478123475Swpaul free(__DECONST(char *, words[i])); 479123475Swpaul } 480123475Swpaul } 481123475Swpaul idx = 0; 482123475Swpaul bzero(words, sizeof(words)); 483123475Swpaul return; 484123475Swpaul} 485