]>
git.saurik.com Git - apple/security.git/blob - lib/generateErrStrings.pl
   3 # Copyright (c) 2003-2004 Apple Computer, Inc. All Rights Reserved. 
   5 # @APPLE_LICENSE_HEADER_START@ 
   7 # This file contains Original Code and/or Modifications of Original Code 
   8 # as defined in and that are subject to the Apple Public Source License 
   9 # Version 2.0 (the 'License'). You may not use this file except in 
  10 # compliance with the License. Please obtain a copy of the License at 
  11 # http://www.opensource.apple.com/apsl/ and read it before using this 
  14 # The Original Code and all software distributed under the License are 
  15 # distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
  16 # EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
  17 # INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 
  18 # FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
  19 # Please see the License for the specific language governing rights and 
  20 # limitations under the License. 
  22 # @APPLE_LICENSE_HEADER_END@ 
  24 # generateErrStrings.pl - create error strings files from the Security header files 
  28 #       perl generateErrStrings.pl <GENDEBUGSTRS?> <NAME_OF_STRINGS_FILE> <input files> 
  30 #       Currently supported files are SecBase.h, SecureTransport.h,cssmapple.h, 
  31 #       cssmerr.h and Authorization.h. These are used by: 
  33 #               void cssmPerror(const char *how, CSSM_RETURN error); 
  35 #       which is in SecBase.cpp. 
  37 # Paths of input files: 
  39 #       ./libsecurity_authorization/lib/Authorization.h 
  40 #       ./libsecurity_cssm/lib/cssmapple.h 
  41 #       ./libsecurity_cssm/lib/cssmerr.h 
  42 #       ./libsecurity_keychain/lib/SecBase.h 
  43 #       ./libsecurity_ssl/lib/SecureTransport.h 
  47 #       perl generateErrStrings.pl "YES" "SecErrorMessages.strings" Authorization.h SecBase.h \ 
  48 #               cssmapple.h cssmerr.h SecureTransport.h 
  50 # Input to script: header file(s) containing enum declarations 
  51 # Output: C++ program with one cout statement per decl 
  53 # The input headers are scanned for enums containing error numbers and 
  54 # optional comments. Only certain prefixes for the identifiers in the 
  55 # enums are considered, to avoid non-error message type defines. See 
  56 # the line in the file with CSSM_ERRCODE for acceptable prefixes. 
  58 # There are three styles of comments that this script parses: 
  60 #       Style A [see /System/Library/Frameworks/Security.framework/Headers/SecBase.h]: 
  62 #               errSSLProtocol                          = -9800,        /* SSL protocol error */ 
  64 #       Style B [see /System/Library/Frameworks/Security.framework/Headers/cssmapple.h]: 
  66 #               /* a code signature match failed */ 
  67 #               CSSMERR_CSP_APPLE_SIGNATURE_MISMATCH = CSSM_CSP_PRIVATE_ERROR + 2, 
  69 #       Style C [see /System/Library/Frameworks/Security.framework/Headers/cssmerr.h]: 
  71 #               CSSM_CSSM_BASE_CSSM_ERROR = 
  72 #                       CSSM_CSSM_BASE_ERROR + CSSM_ERRORCODE_COMMON_EXTENT + 0x10, 
  73 #               CSSMERR_CSSM_SCOPE_NOT_SUPPORTED =                              CSSM_CSSM_BASE_CSSM_ERROR + 1, 
  75 # Style A has the comment after the comment. Style has the comment before the value, 
  76 # and Style C has no comment. In cases where both Style A and B apply, the 
  77 # comment at the end of the line is used. 
  79 # The final output after the generated Objective-C++ program is run looks like: 
  81 #               /* errSSLProtocol */ 
  82 #               "-9800" = "SSL protocol error"; 
  84 #               /* errSSLNegotiation */ 
  85 #               "-9801" = "Cipher Suite negotiation failure"; 
  87 # The appropriate byte order marker for UTF-16 is written to the start of the file. 
  88 # Note that the list of errors must be numerically unique across all input files,  
  89 # or the strings file will be invalid. Comments in "Style B" may span multiple lines. 
  90 # C++ style comments are not supported. Double quotes in a comment are hardened with 
  93 # The English versions of the error messages can be seen with: 
  95 #       cat /System/Library/Frameworks/Security.framework/Resources/English.lproj/SecErrorMessages.strings 
  97 # find -H -X -x . -name "*.h" -print0 2>/dev/null | xargs -0 grep -ri err 
  98 # ----------------------------------------------------------------------------------- 
 101 #       - what should I make PROGNAME? 
 102 #       - should I use a special call to make the temp file in the .mm file? 
 108 die "Usage:  $0 <gendebug> <tmpdir> <.strings file> <list of headers>\n" if ($#ARGV < 3); 
 110 $GENDEBUGSTRINGS=$ARGV[0];                      # If "YES", include all strings & don't localize  
 111 $TMPDIR=$ARGV[1];                                       # temporary directory for program compile, link, run 
 112 $TARGETSTR=$ARGV[2];                            # path of .strings file, e.g.  
 113                                                                         #       ${DERIVED_SRC}/English.lproj/SecErrorMessages.strings 
 114 @INPUTFILES=@ARGV[3 .. 9999];           # list of input files 
 116 $#INPUTFILES = $#ARGV - 3;                      # truncate to actual number of files 
 118 print "gend: $GENDEBUGSTRINGS, tmpdir: $TMPDIR, targetstr: $TARGETSTR\n"; 
 119 $PROGNAME="${TMPDIR}/generateErrStrings.mm"; 
 120 open PROGRAM
,"> $PROGNAME"  or die "can't open $PROGNAME: $!"; 
 123 printAdditionalIncludes
(); 
 124 printInputIncludes
(); 
 127 # ----------------------------------------------------------------------------------- 
 128 # Parse error headers and build array of all relevant lines 
 129 open(ERR
, "cat " . join(" ", @INPUTFILES) . "|") or die "Cannot open error header files"; 
 130 $/="\};";       #We set the section termination string - very important 
 133 # ----------------------------------------------------------------------------------- 
 144 # ----------------------------------------------------------------------------------- 
 146 # ----------------------------------------------------------------------------------- 
 150         # 3: Read input, process each line, output it. 
 151         while ( $line = <ERR
>) 
 153                 ($enum) = ($line =~ /\n\s*enum\s*{\s*([^}]*)};/); 
 154                 while ($enum ne '')     #basic filter for badly formed enums 
 156                         #Drop leading whitespace 
 158         #       print "A:", $enum,"\n"; 
 159                         ($leadingcomment) = ($enum =~ m
%^(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\
*+/)|(//.*)%); 
 160                         if ($leadingcomment ne '') 
 162                                 $enum = substr($enum, length($leadingcomment)); 
 163                                 $leadingcomment = substr($leadingcomment, 2);           # drop leading "/*" 
 164                                 $leadingcomment = substr($leadingcomment, 0, -2);       # drop trailing "*/" 
 165                                 $leadingcomment = cleanupComment
($leadingcomment); 
 167                         next if ($enum eq '');  #basic filter for badly formed enums 
 169                         # Check for C++ style comments at start of line 
 170                         if ($enum =~ /\s*(\/\
/)/) 
 172                                 #Drop everything before the end of line 
 173                                 $enum =~ s/[^\n]*[\n]*//; 
 176                         ($identifier) = ($enum =~ /\s*([_A-Za-z][_A-Za-z0-9]*)/); 
 178 #                       print "identifier: ", $identifier,"\n" if ($identifier ne ''); 
 180                         #Drop everything before the comma 
 183                         # Now look for trailing comment. We only consider them 
 184                         # trailing if they come before the end of the line 
 185                         ($trailingcomment) = ($enum =~ /^[ \t]*\/\
*((.)*)?\
*\
//); 
 186                 #       ($trailingcomment) = ($enum =~ m%^(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|(//.*)%); 
 187                         $trailingcomment = cleanupComment
($trailingcomment); 
 189                         #Drop everything before the end of line 
 190                         $enum =~ s/[^\n]*[\n]*//; 
 191         #       print "B:", $enum,"\n"; 
 192         #       print "lc:$leadingcomment, id:$identifier, tc:$trailingcomment\n"; 
 193         #       print "===========================================\n"; 
 195                         writecomment
($leadingcomment, $identifier, $trailingcomment); 
 202         # Leading comment, id, trailing comment 
 203         # To aid localizers, we will not output a line with no comment 
 206         #       tmp << "/* errAuthorizationSuccess */\n\"" << errAuthorizationSuccess  
 207         #               << "\" = \"The operation completed successfully.\"\n" << endl; 
 209         my($mylc,$myid,$mytc) = @_; 
 210         if ($myid =~ /(CSSM_ERRCODE|CSSMERR_|errSec|errCS|errAuth|errSSL)[_A-Za-z][_A-Za-z0-9]*/) 
 214                 {       $errormessage = $mytc; } 
 216                 {       $errormessage = $mylc; } 
 217                 elsif ($GENDEBUGSTRINGS eq "YES") 
 218                 {       $errormessage = $myid; } 
 220                 if ($errormessage ne '') 
 222                         print "\ttmp << \"/* ", $myid, " */\\n\\\"\" << "; 
 223                         print $myid, " << \"\\\" = \\\""; 
 224                         print $errormessage, "\\\";\\n\" << endl;\n"; 
 230 sub printAdditionalIncludes
 
 232         #This uses the "here" construct to dump out lines verbatim 
 233         print <<"AdditionalIncludes"; 
 237 #include <CoreFoundation/CoreFoundation.h> 
 238 #include <Foundation/Foundation.h> 
 244 sub printInputIncludes
 
 246         #Now "#include" each of the input files 
 247         print "\n#include \"$_\"" foreach @INPUTFILES; 
 253         #Output the main part of the program using the "here" construct 
 254         print <<"MAINPROGRAM"; 
 256 void writeStrings(const char *stringsFileName); 
 257 void createStringsTemp(); 
 259 int main (int argc, char * const argv[]) 
 261         const char *stringsFileName = NULL; 
 264                 stringsFileName = argv[1]; 
 267                 stringsFileName = "SecErrorMessages.strings"; 
 271         cout << "Strings file to create: " << stringsFileName << endl; 
 273         writeStrings(stringsFileName); 
 276 void writeStrings(const char *stringsFileName) 
 278         NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 
 279         NSFileHandle *fh = [NSFileHandle fileHandleForReadingAtPath:@"generateErrStrings.tmp"]; 
 280         NSData *rawstrings = [fh readDataToEndOfFile]; 
 281         UInt32 encoding = CFStringConvertEncodingToNSStringEncoding (kCFStringEncodingUTF8); 
 282         NSString *instring = [[NSString alloc] initWithData:rawstrings encoding:(NSStringEncoding)encoding]; 
 286                 NSString *path = [NSString stringWithUTF8String:stringsFileName]; 
 287                 NSFileManager *fm = [NSFileManager defaultManager]; 
 288                 if ([fm fileExistsAtPath:path]) 
 289                         [fm removeFileAtPath:path handler:nil]; 
 290                 BOOL bx = [fm createFileAtPath:path contents:nil attributes:nil]; 
 291                 NSFileHandle *fs = [NSFileHandle fileHandleForWritingAtPath:path]; 
 292                 [fs writeData:[instring dataUsingEncoding:NSUnicodeStringEncoding]]; 
 298 void createStringsTemp() 
 300         ofstream tmp("generateErrStrings.tmp") ;  
 307         my $comment = shift @_; 
 308 #       print "A:",$comment,"\n"; 
 311                 $comment =~ s/\s\s+/ /g;        # Squeeze multiple spaces to one 
 312                 $comment =~ s/^\s+//;           # Drop leading whitespace 
 313                 $comment =~ s/\s+$//;           # Drop trailing whitespace 
 314                 $comment =~ s/[\"]/\\\\\\"/g;   # Replace double quotes with \" (backslash is sextupled to make it through regex and printf) 
 316 #       print "B:",$comment,"\n"; 
 322         print " tmp.close();\n"; 
 326 sub compileLinkAndRun
 
 328         $status = system( <<"MAINPROGRAM"); 
 329 (cd ${TMPDIR} ; /usr/bin/cc -x objective-c++  -pipe -Wno-trigraphs -fpascal-strings -fasm-blocks -g -O0 -Wreturn-type -fmessage-length=0 -F$ENV{'BUILT_PRODUCTS_DIR'} -I$ENV{'BUILT_PRODUCTS_DIR'}/SecurityPieces/Headers -I$ENV{'BUILT_PRODUCTS_DIR'}/SecurityPieces/PrivateHeaders -c generateErrStrings.mm -o generateErrStrings.o) 
 331         die "$compile exited funny: $?" unless $status == 0; 
 333         $status = system( <<"LINKERSTEP"); 
 334 (cd ${TMPDIR} ; /usr/bin/g++ -o generateErrStrings generateErrStrings.o -framework Foundation ) 
 336         die "$linker exited funny: $?" unless $status == 0; 
 338         $status = system( <<"RUNSTEP"); 
 339 (cd ${TMPDIR} ; ./generateErrStrings $TARGETSTR ) 
 341         die "$built program exited funny: $?" unless $status == 0;