1#!/usr/bin/perl
2#
3# generator.pl - derive various and sundry C++ code from the CDSA header files
4#
5# Usage:
6#	perl generator.pl input-directory output-directory
7#
8# Perry The Cynic, Fall 1999.
9#
10$ERR_H="cssmerr.h";
11$APPLE_ERR_H="cssmapple.h";
12
13$SOURCEDIR=$ARGV[0];						# directory with cdsa headers
14$TARGETDIR=$ARGV[1];						# where to put the output file
15@INPUTFILES=@ARGV[2 .. 9999];				# list of input files
16
17$TABLES="$TARGETDIR/errorcodes.gen";		# error name tables
18
19$tabs = "\t\t\t";	# argument indentation (noncritical)
20$warning = "This file was automatically generated. Do not edit on penalty of futility!";
21
22
23#
24# Parse CSSM error header and build table of all named codes
25#
26open(ERR, "$SOURCEDIR/$ERR_H") or die "Cannot open $ERR_H: $^E";
27open(APPLE_ERR, "$SOURCEDIR/$APPLE_ERR_H") or die "Cannot open $APPLE_ERR_H: $^E";
28$/=undef;	# big gulp mode
29$errors = <ERR> . <APPLE_ERR>;
30close(ERR); close(APPLE_ERR);
31
32@fullErrors = $errors =~ /^\s+CSSMERR_([A-Z_]+)/gm;
33@convertibles = $errors =~ /^\s+CSSM_ERRCODE_([A-Z_]+)\s*=\s*([0-9xXA-Fa-f]+)/gm;
34
35while ($name = shift @convertibles) {
36  $value = shift @convertibles or die;
37  $convErrors[hex $value] = $name;
38};
39
40
41#
42# Read Keychain-level headers for more error codes (errSecBlahBlah)
43#
44open(ERR, "cat " . join(" ", @INPUTFILES) . "|") or die "Cannot open error header files";
45$/=undef;	# still gulping
46$_ = <ERR>;
47@kcerrors = /err((?:Sec|Authorization)\w+)\s*=\s*-?\d+/gm;
48close(ERR);
49
50
51#
52# Now we will generate the error name tables.
53#
54open(OUT, ">$TABLES") or die "Cannot write $TABLES: $^E";
55select OUT;
56
57print <<HDR;
58//
59// CSSM error code tables.
60// $warning
61//
62static const Mapping errorList[] = {
63HDR
64foreach $name (@fullErrors) {
65  print "  { CSSMERR_$name, \"$name\" },\n";
66};
67foreach $err (@kcerrors) {
68  print "  { err$err, \"$err\" },\n";
69};
70print <<MID;
71};
72
73static const char * const convErrorList [] = {
74MID
75for ($n = 0; $n <= $#convErrors; $n++) {
76  if ($name = $convErrors[$n]) {
77    print "  \"$name\",\n";
78  } else {
79    print "  NULL,\n";
80  };
81};
82print "};\n";
83
84close(OUT);
85select(STDOUT);
86
87$nFull = $#fullErrors + 1;
88$nConv = $#convertibles + 1;
89print "$nFull errors available to error translation functions.\n";
90