/* ultra stupid program cause I cant right perl/awk/sed/bash */
#include <stdio.h>
#include <strings.h>
#include <unistd.h>
#include <stdlib.h>

#define MAX_MAP 1000

struct mapping {
    char *name;
    char *module;
};

struct mapping map[MAX_MAP];

static void trim( char *s ) {
    char *f, *l, *p, *q;

    if (!(*s))
	return;
    
    for (f=s; *f && isspace(*f); f++) ;

    if (!*f) {
	*s = '\0';
	return;
    }
    
    for (l=f+strlen(f)-1; isspace(*l) ; l--)
    *l = '\0';
	
    q = s, p = f;
    while (*p)
	*q++ = *p++;
    
    *q = '\0';
}

void readmap( int *mi, struct mapping *map, FILE *f ) {
    char cur[250];
    char *name, *module, *n, *split, *end;

    
    /* read in the wonderous mapping files */
    while (1) {
	end = fgets(cur, 100, f);
	if (!end)
	    break;
	
	if (*cur) {
	    cur[strlen(cur)-1] = 0; /* blow lf */
	    split = strrchr(cur, '|');
	    if (!split)
		continue;

	    module = split+1;
	    name   = cur;
	    cur[split-cur-1] = 0;
	    trim(module);
	    trim(name);
	    n=module;
	    /* look for a space or a "string", whichever is first */
	    while (*n) {
		for (split = n; *split &&
			 *split != '"' && *split != ' ';split++);
		if (!*split)
		    break;
		if (*split == '"') {
		    n=split+1;
		    for (split++; *split && *split != '"'; split++);
		}

		if (!*split)
		    break;
		
		*split = 0;
		map[*mi].name   = strdup(name);
		map[*mi].module = strdup(n);
		trim(map[*mi].module);
		(*mi)++;
		n=split+1;
	    }
	    /* get the last one now */
	    if (*n) {
		map[*mi].name   = strdup(name);
		map[*mi].module = strdup(n);
		trim(map[*mi].module);
		(*mi)++;
	    }
	}
    }
}



int main() {

    FILE *mapscsi, *mapeth, *mapvideo;
    char cur[250], next[250], tmpstr[250];
    int  mi, done, seen, i, len, done2, first;
    char *end;
    char *quote;
    char *strp, *strq;
    char *name, *mapped;
    
    if ((mapscsi=fopen("map-scsi.lst", "r"))==NULL) {
	fprintf(stderr,"Cant find scsi mapping file\n");
	exit(1);
    }
    
    if ((mapeth=fopen("map-eth.lst", "r"))==NULL) {
	fprintf(stderr,"Cant find eth mapping file\n");
	exit(1);
    }

    if ((mapvideo=fopen("map-video.lst", "r"))==NULL) {
	fprintf(stderr,"Cant find video mapping file\n");
	exit(1);
    }

    mi = 0;
    readmap(&mi, map, mapscsi);
    readmap(&mi, map, mapeth);
    readmap(&mi, map, mapvideo);
    
    done = 0;
    seen = 0;
    end = fgets(cur, 100, stdin);
    if (!end)
	done = 1;
    while (!done) {
	end = fgets(next, 100, stdin);
	if (!end) {
	    fputs(cur, stdout);
	    break;
	}

	/* see if this is start of the pci_module_maps */
	if (!strcmp(cur, "struct pci_module_map scsi_pci_ids[] = {\n")) {
	    seen = 1;
	    fputs(cur, stdout);
	    strcpy(cur,next);
	    continue;
	}

	/* seen if current line needs any mapping */
	/* we have to have seen the start above   */
	/* and current line needs to have a '"'   */
	/* character on it.                       */
	if (seen && (quote=strchr(cur, '\"'))) {
	    /* get name */
	    end = strrchr(cur, '\"');
	    name = malloc(end-quote+5);
	    memcpy(name, quote+1, end-quote-1);
	    name[end-quote-1] = 0;

	    /* find a mapping */
	    first = 1;
	    i=0;
	    while ( 1 ) {
		for (; i<mi && strcmp(name, map[i].name); i++);

		if (i>=mi) {
		    if (!first) 
			break;
		    else
			mapped = "UNKNOWN";
		} else {
		    mapped = map[i].module;
		}
		
		first = 0;
		
		/* insert into current string */
		strp = strrchr(cur, ')');
		memcpy(tmpstr, cur, (strp-cur)+1);
		tmpstr[(strp-cur)+1] = 0;
		strcat(tmpstr, ", ( \"");
		strcat(tmpstr, mapped);
		strcat(tmpstr, "\" )");
		strcat(tmpstr, strp+1);
		fputs(tmpstr, stdout);
		i++;
	    }

	    /* move on */
	    free(name);
	    strcpy(cur,next);
	    continue;
	}

		 
	    
	/* ok, is it end of a pci_module_map */
	if (!strcmp(next,"};\n") && seen) {
	    if (strrchr(cur, ',') == (cur+strlen(cur)-1)) {
		cur[strlen(cur)-2] = '\n';
		cur[strlen(cur)-1] = 0;
	    }
	    fputs(cur, stdout);
	    strcpy(cur,next);
	    continue;
	}

	/* otherwise just print it */
	fputs(cur, stdout);
	strcpy(cur,next);
    }
}

	    
	
