Code: Select all
001a Some long text here
\t03af Subfield of 001a
\t040d And another subfield
00c4 New field
Entries are sorted.
I'm trying to get that string out, given the hex value.
(If you're curious, this is the pci-id database, which I'd like to parse so toybox lspci can output text. But this parser would also apply to the usb id database. Of course, this means any code I use must be PD/CC0/other permissive license that does not stipulate preservation of the copyright notice; I intend to indicate the source, but Rob's policy is to not require a notice if you copy from toybox.)
What I have is buggy and segfaults at line 38 (if curr[match] != id[match]), but I don't know why:
Code: Select all
/* Test of reading the PCI-id database
* Written in 2013 and released under CC0, Isaac Dunham
*/
#define _XOPEN_SOURCE 600
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
int get_db_entry(int fd, char *buf, ssize_t bufsiz, char *id, char *string, char *subfield)
{
int overboard;
off_t offset = 0;
int bytes, match;
char *curr, *eol;
errno = 0;
while (!errno)
{
overboard = 0;
bytes = read(fd, buf, bufsiz);
curr = buf; eol = buf;
if (string || overboard)
printf("Something's wrong! string is %s, overboard is %d\n",string, overboard);
while (!string && !overboard) {
/* Yes, this is where this should be.
* If we aren't in a "subfield" any longer,
* we cannot match the device within its class.
*/
if (subfield && curr[0]++ !=subfield[0])
string=id;
for (match=0; match<4;) {
if (curr[match] != id[match]) {
eol=strstr(eol, "\n");
break;
} else {
match++; printf("Match: %d\n", match);
}
}
printf("string loop: match: %d curr: %jd eol: %jd\n", match, curr-buf, eol-buf);
if (match == 4) {
string = curr[match + 3];
return string;
} else if ( eol && eol != buf) {
curr=++eol;
}
if (((curr - buf) > (bytes - 8)) || (eol == buf)) {
overboard = (buf + bytes) - curr;
}
} //answer or overboard
overboard = 0 - overboard;
offset = lseek(fd, overboard, SEEK_CUR);
printf("Read loop: off: %jd curr_off: %d eol_off: %d overboard: %d\n", (intmax_t)offset, curr-buf, eol-buf, overboard );
} //errno
}
int main(int argc, char *argv[])
{
int fd = open("/usr/share/misc/pci.ids", O_RDONLY);
char *class = "168c", *dev = "001c", *sub = "\t";
char *clnam = NULL;
char *buff = calloc(1, 4104);
get_db_entry(fd, buff, 4096, class, clnam, 0);
}