#
# boring setup
#
$hfile = ":include:auditdefs.h";
$rfile = "audit.r";
$cfile = "auditdefs.c";
$rid = 19600;

open(RFILE,">$rfile") || die;
open(HFILE,">$hfile") || die;
open(CFILE,">$cfile") || die;

#
# write initial junk
#
print RFILE <<'EOF';
resource 'STR#' (19600,purgeable) {{
EOF

print HFILE <<'EOF';
#ifndef AUDITDEFS_H
#define AUDITDEFS_H

EOF

print CFILE <<'EOF';
extern OSErr Audit(short auditType,...);
extern OSErr AuditFlush(Boolean force);

EOF

#
# finally, process the table
#
while(<>)
{
	if (/^#/) {next;}
	if (/^=/)
	{
		; # currently we don't do anything with the categories; they're just documentation for now
	}
	else
	{
		#
		# UINT4 crap...
		#
		s/UINT4/uLong/g;
		
		#
		# does this line want a flush?
		#
		if (s/^\+//) {$flush = "false";} # gentle flush
		elsif (s/^!//) {$flush = "true";} #hard flush
		else {$flush = "";}
		
		#
		# do basic split
		#
		chop;
		($name,$id,$cat,$fmt,$fnargs) = split(/\t/);
		if ($id > $maxID) {$maxID = $id;}
		
		#
		# write audit type to .h file, save prototype for later
		#
		print HFILE "#define kAudit$name $id //$cmnt\n";
		$proto .= "OSErr Audit$name($fnargs);\n";
		$cats .= "$cat,";
		
		#
		# remove type declarations from args
		#
		@fnargs = split(',',$fnargs);
		$auditArgs = "";
		foreach $fna (@fnargs)
		{
			$fna =~ s/ *$//;
			$fna =~ s/.* //;
			$auditArgs .= $fna . ',';
		}
		chop $auditArgs;	# remove trailing comma
		
		#
		# write function to .c file
		#
		if ($flush ne "")
		{
			print CFILE <<"EOF";

OSErr Audit$name($fnargs)
{
	OSErr err = Audit(kAudit$name,$auditArgs);
	if (!err) err = AuditFlush($flush);
	return err;
}
EOF
		}
		else
		{
			print CFILE <<"EOF";

OSErr Audit$name($fnargs)
{
	return Audit(kAudit$name,$auditArgs);
}
EOF
		}

		#
		# write format string to .r file
		#
		print RFILE qq|"$fmt\\n",\n|;
	}
}

#
# finish up
#
print HFILE "$proto\nextern short AuditCategories[];\n#define MaxAuditType $maxID\n\n#endif //AUDITDEFS_H\n";
print RFILE "}};\n";
chop $cats; print CFILE "short AuditCategories[] = {$cats};\n";
