/[soft]/ldetect/trunk/names.c
ViewVC logotype

Contents of /ldetect/trunk/names.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1357 - (show annotations) (download)
Tue May 17 09:21:22 2011 UTC (10 years, 1 month ago) by dmorgan
File MIME type: text/plain
File size: 25427 byte(s)
Import  ldetect
1 /*****************************************************************************/
2 /*
3 * names.c -- USB name database manipulation routines
4 *
5 * Copyright (C) 1999, 2000 Thomas Sailer (sailer@ife.ee.ethz.ch)
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 *
21 *
22 */
23
24 /*****************************************************************************/
25
26 #include <sys/types.h>
27 #include <sys/stat.h>
28 #include <fcntl.h>
29 #include <dirent.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <stdio.h>
35 #include <ctype.h>
36
37 #ifdef HAVE_CONFIG_H
38 #include "config.h"
39 #endif
40
41 #ifdef HAVE_LIBZ
42 #include <zlib.h>
43 #define usb_file gzFile
44 #define usb_fopen(path, mode) gzopen(path, mode)
45 #define usb_fgets(s, size, stream) gzgets(stream, s, size)
46 #define usb_close(f) gzclose(f)
47 #else
48 #define usb_file FILE*
49 #define usb_fopen(path, mode) fopen(path, mode)
50 #define usb_fgets(s, size, stream) fgets(s, size, stream)
51 #define usb_close(f) fclose(f)
52 #endif
53
54 #include "names.h"
55
56
57 /* ---------------------------------------------------------------------- */
58
59 struct vendor {
60 struct vendor *next;
61 uint16_t vendorid;
62 char name[1];
63 };
64
65 struct product {
66 struct product *next;
67 uint16_t vendorid, productid;
68 char name[1];
69 };
70
71 struct class {
72 struct class *next;
73 uint8_t classid;
74 char name[1];
75 };
76
77 struct subclass {
78 struct subclass *next;
79 uint8_t classid, subclassid;
80 char name[1];
81 };
82
83 struct protocol {
84 struct protocol *next;
85 uint8_t classid, subclassid, protocolid;
86 char name[1];
87 };
88
89 struct audioterminal {
90 struct audioterminal *next;
91 uint16_t termt;
92 char name[1];
93 };
94
95 struct videoterminal {
96 struct videoterminal *next;
97 uint16_t termt;
98 char name[1];
99 };
100
101 struct genericstrtable {
102 struct genericstrtable *next;
103 unsigned int num;
104 char name[1];
105 };
106
107 /* ---------------------------------------------------------------------- */
108
109 #define HASH1 0x10
110 #define HASH2 0x02
111 #define HASHSZ 16
112
113 static unsigned int hashnum(unsigned int num)
114 {
115 unsigned int mask1 = HASH1 << 27, mask2 = HASH2 << 27;
116
117 for (; mask1 >= HASH1; mask1 >>= 1, mask2 >>= 1)
118 if (num & mask1)
119 num ^= mask2;
120 return num & (HASHSZ-1);
121 }
122
123 /* ---------------------------------------------------------------------- */
124
125 static struct vendor *vendors[HASHSZ] = { NULL, };
126 static struct product *products[HASHSZ] = { NULL, };
127 static struct class *classes[HASHSZ] = { NULL, };
128 static struct subclass *subclasses[HASHSZ] = { NULL, };
129 static struct protocol *protocols[HASHSZ] = { NULL, };
130 static struct audioterminal *audioterminals[HASHSZ] = { NULL, };
131 static struct videoterminal *videoterminals[HASHSZ] = { NULL, };
132 static struct genericstrtable *hiddescriptors[HASHSZ] = { NULL, };
133 static struct genericstrtable *reports[HASHSZ] = { NULL, };
134 static struct genericstrtable *huts[HASHSZ] = { NULL, };
135 static struct genericstrtable *biass[HASHSZ] = { NULL, };
136 static struct genericstrtable *physdess[HASHSZ] = { NULL, };
137 static struct genericstrtable *hutus[HASHSZ] = { NULL, };
138 static struct genericstrtable *langids[HASHSZ] = { NULL, };
139 static struct genericstrtable *countrycodes[HASHSZ] = { NULL, };
140
141 static int init_done = 0;
142
143 /* ---------------------------------------------------------------------- */
144
145 static const char *names_genericstrtable(struct genericstrtable *t[HASHSZ], unsigned int index)
146 {
147 struct genericstrtable *h;
148
149 for (h = t[hashnum(index)]; h; h = h->next)
150 if (h->num == index)
151 return h->name;
152 return NULL;
153 }
154
155 const char *names_hid(uint8_t hidd)
156 {
157 return names_genericstrtable(hiddescriptors, hidd);
158 }
159
160 const char *names_reporttag(uint8_t rt)
161 {
162 return names_genericstrtable(reports, rt);
163 }
164
165 const char *names_huts(unsigned int data)
166 {
167 return names_genericstrtable(huts, data);
168 }
169
170 const char *names_hutus(unsigned int data)
171 {
172 return names_genericstrtable(hutus, data);
173 }
174
175 const char *names_langid(uint16_t langid)
176 {
177 return names_genericstrtable(langids, langid);
178 }
179
180 const char *names_physdes(uint8_t ph)
181 {
182 return names_genericstrtable(physdess, ph);
183 }
184
185 const char *names_bias(uint8_t b)
186 {
187 return names_genericstrtable(biass, b);
188 }
189
190 const char *names_countrycode(unsigned int countrycode)
191 {
192 return names_genericstrtable(countrycodes, countrycode);
193 }
194
195 const char *names_vendor(uint16_t vendorid)
196 {
197 struct vendor *v;
198
199 v = vendors[hashnum(vendorid)];
200 for (; v; v = v->next)
201 if (v->vendorid == vendorid)
202 return v->name;
203 return NULL;
204 }
205
206 const char *names_product(uint16_t vendorid, uint16_t productid)
207 {
208 struct product *p;
209
210 p = products[hashnum((vendorid << 16) | productid)];
211 for (; p; p = p->next)
212 if (p->vendorid == vendorid && p->productid == productid)
213 return p->name;
214 return NULL;
215 }
216
217 const char *names_class(uint8_t classid)
218 {
219 struct class *c;
220
221 c = classes[hashnum(classid)];
222 for (; c; c = c->next)
223 if (c->classid == classid)
224 return c->name;
225 return NULL;
226 }
227
228 const char *names_subclass(uint8_t classid, uint8_t subclassid)
229 {
230 struct subclass *s;
231
232 s = subclasses[hashnum((classid << 8) | subclassid)];
233 for (; s; s = s->next)
234 if (s->classid == classid && s->subclassid == subclassid)
235 return s->name;
236 return NULL;
237 }
238
239 const char *names_protocol(uint8_t classid, uint8_t subclassid, uint8_t protocolid)
240 {
241 struct protocol *p;
242
243 p = protocols[hashnum((classid << 16) | (subclassid << 8) | protocolid)];
244 for (; p; p = p->next)
245 if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
246 return p->name;
247 return NULL;
248 }
249
250 const char *names_audioterminal(uint16_t termt)
251 {
252 struct audioterminal *at;
253
254 at = audioterminals[hashnum(termt)];
255 for (; at; at = at->next)
256 if (at->termt == termt)
257 return at->name;
258 return NULL;
259 }
260
261 const char *names_videoterminal(uint16_t termt)
262 {
263 struct videoterminal *vt;
264
265 vt = videoterminals[hashnum(termt)];
266 for (; vt; vt = vt->next)
267 if (vt->termt == termt)
268 return vt->name;
269 return NULL;
270 }
271
272 /* ---------------------------------------------------------------------- */
273
274 static int new_vendor(const char *name, uint16_t vendorid)
275 {
276 struct vendor *v;
277 unsigned int h = hashnum(vendorid);
278
279 v = vendors[h];
280 for (; v; v = v->next)
281 if (v->vendorid == vendorid)
282 return -1;
283 v = malloc(sizeof(struct vendor) + strlen(name));
284 if (!v)
285 return -1;
286 strcpy(v->name, name);
287 v->vendorid = vendorid;
288 v->next = vendors[h];
289 vendors[h] = v;
290 return 0;
291 }
292
293 static int new_product(const char *name, uint16_t vendorid, uint16_t productid)
294 {
295 struct product *p;
296 unsigned int h = hashnum((vendorid << 16) | productid);
297
298 p = products[h];
299 for (; p; p = p->next)
300 if (p->vendorid == vendorid && p->productid == productid)
301 return -1;
302 p = malloc(sizeof(struct product) + strlen(name));
303 if (!p)
304 return -1;
305 strcpy(p->name, name);
306 p->vendorid = vendorid;
307 p->productid = productid;
308 p->next = products[h];
309 products[h] = p;
310 return 0;
311 }
312
313 static int new_class(const char *name, uint8_t classid)
314 {
315 struct class *c;
316 unsigned int h = hashnum(classid);
317
318 c = classes[h];
319 for (; c; c = c->next)
320 if (c->classid == classid)
321 return -1;
322 c = malloc(sizeof(struct class) + strlen(name));
323 if (!c)
324 return -1;
325 strcpy(c->name, name);
326 c->classid = classid;
327 c->next = classes[h];
328 classes[h] = c;
329 return 0;
330 }
331
332 static int new_subclass(const char *name, uint8_t classid, uint8_t subclassid)
333 {
334 struct subclass *s;
335 unsigned int h = hashnum((classid << 8) | subclassid);
336
337 s = subclasses[h];
338 for (; s; s = s->next)
339 if (s->classid == classid && s->subclassid == subclassid)
340 return -1;
341 s = malloc(sizeof(struct subclass) + strlen(name));
342 if (!s)
343 return -1;
344 strcpy(s->name, name);
345 s->classid = classid;
346 s->subclassid = subclassid;
347 s->next = subclasses[h];
348 subclasses[h] = s;
349 return 0;
350 }
351
352 static int new_protocol(const char *name, uint8_t classid, uint8_t subclassid, uint8_t protocolid)
353 {
354 struct protocol *p;
355 unsigned int h = hashnum((classid << 16) | (subclassid << 8) | protocolid);
356
357 p = protocols[h];
358 for (; p; p = p->next)
359 if (p->classid == classid && p->subclassid == subclassid && p->protocolid == protocolid)
360 return -1;
361 p = malloc(sizeof(struct protocol) + strlen(name));
362 if (!p)
363 return -1;
364 strcpy(p->name, name);
365 p->classid = classid;
366 p->subclassid = subclassid;
367 p->protocolid = protocolid;
368 p->next = protocols[h];
369 protocols[h] = p;
370 return 0;
371 }
372
373 static int new_audioterminal(const char *name, uint16_t termt)
374 {
375 struct audioterminal *at;
376 unsigned int h = hashnum(termt);
377
378 at = audioterminals[h];
379 for (; at; at = at->next)
380 if (at->termt == termt)
381 return -1;
382 at = malloc(sizeof(struct audioterminal) + strlen(name));
383 if (!at)
384 return -1;
385 strcpy(at->name, name);
386 at->termt = termt;
387 at->next = audioterminals[h];
388 audioterminals[h] = at;
389 return 0;
390 }
391
392 static int new_videoterminal(const char *name, uint16_t termt)
393 {
394 struct videoterminal *vt;
395 unsigned int h = hashnum(termt);
396
397 vt = videoterminals[h];
398 for (; vt; vt = vt->next)
399 if (vt->termt == termt)
400 return -1;
401 vt = malloc(sizeof(struct videoterminal) + strlen(name));
402 if (!vt)
403 return -1;
404 strcpy(vt->name, name);
405 vt->termt = termt;
406 vt->next = videoterminals[h];
407 videoterminals[h] = vt;
408 return 0;
409 }
410
411 static int new_genericstrtable(struct genericstrtable *t[HASHSZ], const char *name, unsigned int index)
412 {
413 struct genericstrtable *g;
414 unsigned int h = hashnum(index);
415
416 for (g = t[h]; g; g = g->next)
417 if (g->num == index)
418 return -1;
419 g = malloc(sizeof(struct genericstrtable) + strlen(name));
420 if (!g)
421 return -1;
422 strcpy(g->name, name);
423 g->num = index;
424 g->next = t[h];
425 t[h] = g;
426 return 0;
427 }
428
429 static int new_hid(const char *name, uint8_t hidd)
430 {
431 return new_genericstrtable(hiddescriptors, name, hidd);
432 }
433
434 static int new_reporttag(const char *name, uint8_t rt)
435 {
436 return new_genericstrtable(reports, name, rt);
437 }
438
439 static int new_huts(const char *name, unsigned int data)
440 {
441 return new_genericstrtable(huts, name, data);
442 }
443
444 static int new_hutus(const char *name, unsigned int data)
445 {
446 return new_genericstrtable(hutus, name, data);
447 }
448
449 static int new_langid(const char *name, uint16_t langid)
450 {
451 return new_genericstrtable(langids, name, langid);
452 }
453
454 static int new_physdes(const char *name, uint8_t ph)
455 {
456 return new_genericstrtable(physdess, name, ph);
457 }
458 static int new_bias(const char *name, uint8_t b)
459 {
460 return new_genericstrtable(biass, name, b);
461 }
462
463 static int new_countrycode(const char *name, unsigned int countrycode)
464 {
465 return new_genericstrtable(countrycodes, name, countrycode);
466 }
467
468 /* ---------------------------------------------------------------------- */
469
470 #define DBG(x)
471
472 static void parse(usb_file f)
473 {
474 char buf[512], *cp;
475 unsigned int linectr = 0;
476 int lastvendor = -1, lastclass = -1, lastsubclass = -1, lasthut=-1, lastlang=-1;
477 unsigned int u;
478
479 while (usb_fgets(buf, sizeof(buf), f)) {
480 linectr++;
481 /* remove line ends */
482 if ((cp = strchr(buf, 13)))
483 *cp = 0;
484 if ((cp = strchr(buf, 10)))
485 *cp = 0;
486 if (buf[0] == '#' || !buf[0])
487 continue;
488 cp = buf;
489 if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && buf[3] == 'S' && buf[4] == 'D' &&
490 buf[5] == 'E' && buf[6] == 'S' && /*isspace(buf[7])*/ buf[7] == ' ') {
491 cp = buf + 8;
492 while (isspace(*cp))
493 cp++;
494 if (!isxdigit(*cp)) {
495 fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
496 continue;
497 }
498 u = strtoul(cp, &cp, 16);
499 while (isspace(*cp))
500 cp++;
501 if (!*cp) {
502 fprintf(stderr, "Invalid Physdes type at line %u\n", linectr);
503 continue;
504 }
505 if (new_physdes(cp, u))
506 fprintf(stderr, "Duplicate Physdes type spec at line %u terminal type %04x %s\n", linectr, u, cp);
507 DBG(printf("line %5u physdes type %02x %s\n", linectr, u, cp));
508 continue;
509
510 }
511 if (buf[0] == 'P' && buf[1] == 'H' && buf[2] == 'Y' && /*isspace(buf[3])*/ buf[3] == ' ') {
512 cp = buf + 4;
513 while (isspace(*cp))
514 cp++;
515 if (!isxdigit(*cp)) {
516 fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
517 continue;
518 }
519 u = strtoul(cp, &cp, 16);
520 while (isspace(*cp))
521 cp++;
522 if (!*cp) {
523 fprintf(stderr, "Invalid PHY type at line %u\n", linectr);
524 continue;
525 }
526 if (new_physdes(cp, u))
527 fprintf(stderr, "Duplicate PHY type spec at line %u terminal type %04x %s\n", linectr, u, cp);
528 DBG(printf("line %5u PHY type %02x %s\n", linectr, u, cp));
529 continue;
530
531 }
532 if (buf[0] == 'B' && buf[1] == 'I' && buf[2] == 'A' && buf[3] == 'S' && /*isspace(buf[4])*/ buf[4] == ' ') {
533 cp = buf + 5;
534 while (isspace(*cp))
535 cp++;
536 if (!isxdigit(*cp)) {
537 fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
538 continue;
539 }
540 u = strtoul(cp, &cp, 16);
541 while (isspace(*cp))
542 cp++;
543 if (!*cp) {
544 fprintf(stderr, "Invalid BIAS type at line %u\n", linectr);
545 continue;
546 }
547 if (new_bias(cp, u))
548 fprintf(stderr, "Duplicate BIAS type spec at line %u terminal type %04x %s\n", linectr, u, cp);
549 DBG(printf("line %5u BIAS type %02x %s\n", linectr, u, cp));
550 continue;
551
552 }
553 if (buf[0] == 'L' && /*isspace(buf[1])*/ buf[1] == ' ') {
554 cp = buf+2;
555 while (isspace(*cp))
556 cp++;
557 if (!isxdigit(*cp)) {
558 fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
559 continue;
560 }
561 u = strtoul(cp, &cp, 16);
562 while (isspace(*cp))
563 cp++;
564 if (!*cp) {
565 fprintf(stderr, "Invalid LANGID spec at line %u\n", linectr);
566 continue;
567 }
568 if (new_langid(cp, u))
569 fprintf(stderr, "Duplicate LANGID spec at line %u language-id %04x %s\n", linectr, u, cp);
570 DBG(printf("line %5u LANGID %02x %s\n", linectr, u, cp));
571 lasthut = lastclass = lastvendor = lastsubclass = -1;
572 lastlang = u;
573 continue;
574 }
575 if (buf[0] == 'C' && /*isspace(buf[1])*/ buf[1] == ' ') {
576 /* class spec */
577 cp = buf+2;
578 while (isspace(*cp))
579 cp++;
580 if (!isxdigit(*cp)) {
581 fprintf(stderr, "Invalid class spec at line %u\n", linectr);
582 continue;
583 }
584 u = strtoul(cp, &cp, 16);
585 while (isspace(*cp))
586 cp++;
587 if (!*cp) {
588 fprintf(stderr, "Invalid class spec at line %u\n", linectr);
589 continue;
590 }
591 if (new_class(cp, u))
592 fprintf(stderr, "Duplicate class spec at line %u class %04x %s\n", linectr, u, cp);
593 DBG(printf("line %5u class %02x %s\n", linectr, u, cp));
594 lasthut = lastlang = lastvendor = lastsubclass = -1;
595 lastclass = u;
596 continue;
597 }
598 if (buf[0] == 'A' && buf[1] == 'T' && isspace(buf[2])) {
599 /* audio terminal type spec */
600 cp = buf+3;
601 while (isspace(*cp))
602 cp++;
603 if (!isxdigit(*cp)) {
604 fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
605 continue;
606 }
607 u = strtoul(cp, &cp, 16);
608 while (isspace(*cp))
609 cp++;
610 if (!*cp) {
611 fprintf(stderr, "Invalid audio terminal type at line %u\n", linectr);
612 continue;
613 }
614 if (new_audioterminal(cp, u))
615 fprintf(stderr, "Duplicate audio terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp);
616 DBG(printf("line %5u audio terminal type %02x %s\n", linectr, u, cp));
617 continue;
618 }
619 if (buf[0] == 'V' && buf[1] == 'T' && isspace(buf[2])) {
620 /* video terminal type spec */
621 cp = buf+3;
622 while (isspace(*cp))
623 cp++;
624 if (!isxdigit(*cp)) {
625 fprintf(stderr, "Invalid video terminal type at line %u\n", linectr);
626 continue;
627 }
628 u = strtoul(cp, &cp, 16);
629 while (isspace(*cp))
630 cp++;
631 if (!*cp) {
632 fprintf(stderr, "Invalid video terminal type at line %u\n", linectr);
633 continue;
634 }
635 if (new_videoterminal(cp, u))
636 fprintf(stderr, "Duplicate video terminal type spec at line %u terminal type %04x %s\n", linectr, u, cp);
637 DBG(printf("line %5u video terminal type %02x %s\n", linectr, u, cp));
638 continue;
639 }
640 if (buf[0] == 'H' && buf[1] == 'C' && buf[2] == 'C' && isspace(buf[3])) {
641 /* HID Descriptor bCountryCode */
642 cp = buf+3;
643 while (isspace(*cp))
644 cp++;
645 if (!isxdigit(*cp)) {
646 fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
647 continue;
648 }
649 u = strtoul(cp, &cp, 10);
650 while (isspace(*cp))
651 cp++;
652 if (!*cp) {
653 fprintf(stderr, "Invalid HID country code at line %u\n", linectr);
654 continue;
655 }
656 if (new_countrycode(cp, u))
657 fprintf(stderr, "Duplicate HID country code at line %u country %02u %s\n", linectr, u, cp);
658 DBG(printf("line %5u keyboard country code %02u %s\n", linectr, u, cp));
659 continue;
660 }
661 if (isxdigit(*cp)) {
662 /* vendor */
663 u = strtoul(cp, &cp, 16);
664 while (isspace(*cp))
665 cp++;
666 if (!*cp) {
667 fprintf(stderr, "Invalid vendor spec at line %u\n", linectr);
668 continue;
669 }
670 if (new_vendor(cp, u))
671 fprintf(stderr, "Duplicate vendor spec at line %u vendor %04x %s\n", linectr, u, cp);
672 DBG(printf("line %5u vendor %04x %s\n", linectr, u, cp));
673 lastvendor = u;
674 lasthut = lastlang = lastclass = lastsubclass = -1;
675 continue;
676 }
677 if (buf[0] == '\t' && isxdigit(buf[1])) {
678 /* product or subclass spec */
679 u = strtoul(buf+1, &cp, 16);
680 while (isspace(*cp))
681 cp++;
682 if (!*cp) {
683 fprintf(stderr, "Invalid product/subclass spec at line %u\n", linectr);
684 continue;
685 }
686 if (lastvendor != -1) {
687 if (new_product(cp, lastvendor, u))
688 fprintf(stderr, "Duplicate product spec at line %u product %04x:%04x %s\n", linectr, lastvendor, u, cp);
689 DBG(printf("line %5u product %04x:%04x %s\n", linectr, lastvendor, u, cp));
690 continue;
691 }
692 if (lastclass != -1) {
693 if (new_subclass(cp, lastclass, u))
694 fprintf(stderr, "Duplicate subclass spec at line %u class %02x:%02x %s\n", linectr, lastclass, u, cp);
695 DBG(printf("line %5u subclass %02x:%02x %s\n", linectr, lastclass, u, cp));
696 lastsubclass = u;
697 continue;
698 }
699 if (lasthut != -1) {
700 if (new_hutus(cp, (lasthut << 16)+u))
701 fprintf(stderr, "Duplicate HUT Usage Spec at line %u\n", linectr);
702 continue;
703 }
704 if (lastlang != -1) {
705 if (new_langid(cp, lastlang+(u<<10)))
706 fprintf(stderr, "Duplicate LANGID Usage Spec at line %u\n", linectr);
707 continue;
708 }
709 fprintf(stderr, "Product/Subclass spec without prior Vendor/Class spec at line %u\n", linectr);
710 continue;
711 }
712 if (buf[0] == '\t' && buf[1] == '\t' && isxdigit(buf[2])) {
713 /* protocol spec */
714 u = strtoul(buf+2, &cp, 16);
715 while (isspace(*cp))
716 cp++;
717 if (!*cp) {
718 fprintf(stderr, "Invalid protocol spec at line %u\n", linectr);
719 continue;
720 }
721 if (lastclass != -1 && lastsubclass != -1) {
722 if (new_protocol(cp, lastclass, lastsubclass, u))
723 fprintf(stderr, "Duplicate protocol spec at line %u class %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp);
724 DBG(printf("line %5u protocol %02x:%02x:%02x %s\n", linectr, lastclass, lastsubclass, u, cp));
725 continue;
726 }
727 fprintf(stderr, "Protocol spec without prior Class and Subclass spec at line %u\n", linectr);
728 continue;
729 }
730 if (buf[0] == 'H' && buf[1] == 'I' && buf[2] == 'D' && /*isspace(buf[3])*/ buf[3] == ' ') {
731 cp = buf + 4;
732 while (isspace(*cp))
733 cp++;
734 if (!isxdigit(*cp)) {
735 fprintf(stderr, "Invalid HID type at line %u\n", linectr);
736 continue;
737 }
738 u = strtoul(cp, &cp, 16);
739 while (isspace(*cp))
740 cp++;
741 if (!*cp) {
742 fprintf(stderr, "Invalid HID type at line %u\n", linectr);
743 continue;
744 }
745 if (new_hid(cp, u))
746 fprintf(stderr, "Duplicate HID type spec at line %u terminal type %04x %s\n", linectr, u, cp);
747 DBG(printf("line %5u HID type %02x %s\n", linectr, u, cp));
748 continue;
749
750 }
751 if (buf[0] == 'H' && buf[1] == 'U' && buf[2] == 'T' && /*isspace(buf[3])*/ buf[3] == ' ') {
752 cp = buf + 4;
753 while (isspace(*cp))
754 cp++;
755 if (!isxdigit(*cp)) {
756 fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
757 continue;
758 }
759 u = strtoul(cp, &cp, 16);
760 while (isspace(*cp))
761 cp++;
762 if (!*cp) {
763 fprintf(stderr, "Invalid HUT type at line %u\n", linectr);
764 continue;
765 }
766 if (new_huts(cp, u))
767 fprintf(stderr, "Duplicate HUT type spec at line %u terminal type %04x %s\n", linectr, u, cp);
768 lastlang = lastclass = lastvendor = lastsubclass = -1;
769 lasthut = u;
770 DBG(printf("line %5u HUT type %02x %s\n", linectr, u, cp));
771 continue;
772
773 }
774 if (buf[0] == 'R' && buf[1] == ' ') {
775 cp = buf + 2;
776 while (isspace(*cp))
777 cp++;
778 if (!isxdigit(*cp)) {
779 fprintf(stderr, "Invalid Report type at line %u\n", linectr);
780 continue;
781 }
782 u = strtoul(cp, &cp, 16);
783 while (isspace(*cp))
784 cp++;
785 if (!*cp) {
786 fprintf(stderr, "Invalid Report type at line %u\n", linectr);
787 continue;
788 }
789 if (new_reporttag(cp, u))
790 fprintf(stderr, "Duplicate Report type spec at line %u terminal type %04x %s\n", linectr, u, cp);
791 DBG(printf("line %5u Report type %02x %s\n", linectr, u, cp));
792 continue;
793
794 }
795 fprintf(stderr, "Unknown line at line %u\n", linectr);
796 }
797 }
798
799 /* ---------------------------------------------------------------------- */
800
801 int names_init(char *n)
802 {
803 usb_file f;
804 if(init_done)
805 return 0;
806 init_done = 1;
807 if (!(f = usb_fopen(n, "r"))) {
808 return errno;
809 }
810 parse(f);
811 usb_close(f);
812 return 0;
813 }

Properties

Name Value
svn:eol-style native

  ViewVC Help
Powered by ViewVC 1.1.28