1#!/bin/sh
2#
3#  ascq_tbl.sh - Translate SCSI t10.org's "asc-num.txt" file of
4#                SCSI Additional Sense Code & Qualifiers (ASC/ASCQ's)
5#                into something useful in C, creating "ascq_tbl.c" file.
6#
7#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*#
8
9PREF_INFILE="t10.org/asc-num.txt"	# From SCSI t10.org
10PREF_OUTFILE="ascq_tbl.c"
11
12#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*#
13
14xlate_ascq() {
15	cat | awk '
16	BEGIN {
17		DQ = "\042";
18		OUTFILE = "'"${PREF_OUTFILE}"'";
19		TRUE = 1;
20		FALSE = 0;
21		#debug = TRUE;
22
23		#  read and discard all lines up to and including the one that begins
24		#  with the "magic token" of "-------  --------------  ---"...
25		headers_gone = FALSE;
26		while (!headers_gone) {
27			if (getline <= 0)
28				exit 1;
29			header_line[++hdrs] = $0;
30			if (debug)
31				printf("header_line[%d] = :%s:\n", ++hdrs, $0);
32			if ($0 ~ /^-------  --------------  ---/) {
33				headers_gone = TRUE;
34			}
35		}
36		outcount = 0;
37	}
38
39	(NF > 1) {
40		++outcount;
41		if (debug)
42			printf( "DBG: %s\n", $0 );
43		ASC[outcount] = substr($0,1,2);
44		ASCQ[outcount] = substr($0,5,2);
45		devtypes = substr($0,10,14);
46		gsub(/ /, ".", devtypes);
47		DESCRIP[outcount] = substr($0,26);
48
49		if (!(devtypes in DevTypesVoodoo)) {
50			DevTypesVoodoo[devtypes] = ++voodoo;
51			DevTypesIdx[voodoo] = devtypes;
52		}
53		DEVTYPES[outcount] = DevTypesVoodoo[devtypes];
54
55		#  Handle 0xNN exception stuff...
56		if (ASCQ[outcount] == "NN" || ASCQ[outcount] == "nn")
57			ASCQ[outcount] = "FF";
58	}
59
60	END {
61		printf("#ifndef SCSI_ASCQ_TBL_C_INCLUDED\n") > OUTFILE;
62		printf("#define SCSI_ASCQ_TBL_C_INCLUDED\n") >> OUTFILE;
63
64		printf("\n/* AuToMaGiCaLlY generated from: %s'"${FIN}"'%s\n", DQ, DQ) >> OUTFILE;
65		printf(" *******************************************************************************\n") >> OUTFILE;
66		for (i=1; i<=hdrs; i++) {
67			printf(" * %s\n", header_line[i]) >> OUTFILE;
68		}
69		printf(" */\n") >> OUTFILE;
70
71		printf("\n") >> OUTFILE;
72		for (i=1; i<=voodoo; i++) {
73			printf("static char SenseDevTypes%03d[] = %s%s%s;\n", i, DQ, DevTypesIdx[i], DQ) >> OUTFILE;
74		}
75
76		printf("\nstatic ASCQ_Table_t ASCQ_Table[] = {\n") >> OUTFILE;
77		for (i=1; i<=outcount; i++) {
78			printf("  {\n") >> OUTFILE;
79			printf("    0x%s, 0x%s,\n", ASC[i], ASCQ[i]) >> OUTFILE;
80			printf("    SenseDevTypes%03d,\n", DEVTYPES[i]) >> OUTFILE;
81			printf("    %s%s%s\n", DQ, DESCRIP[i], DQ) >> OUTFILE;
82			printf("  },\n") >> OUTFILE;
83		}
84		printf( "};\n\n" ) >> OUTFILE;
85
86		printf( "static int ASCQ_TableSize = %d;\n\n", outcount ) >> OUTFILE;
87		printf( "Total of %d ASC/ASCQ records generated\n", outcount );
88		printf("\n#endif\n") >> OUTFILE;
89		close(OUTFILE);
90	}'
91	return
92}
93
94#*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*#
95
96# main()
97if [ $# -lt 1 ]; then
98	echo "INFO: No input filename supplied - using: $PREF_INFILE" >&2
99	FIN=$PREF_INFILE
100else
101	FIN="$1"
102	if [ "$FIN" != "$PREF_INFILE" ]; then
103		echo "INFO: Ok, I'll try chewing on '$FIN' for SCSI ASC/ASCQ combos..." >&2
104	fi
105	shift
106fi
107
108cat $FIN | xlate_ascq
109exit 0
110