mkerr.pl 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723
  1. #!/usr/local/bin/perl -w
  2. my $config = "crypto/err/openssl.ec";
  3. my $debug = 0;
  4. my $rebuild = 0;
  5. my $static = 1;
  6. my $recurse = 0;
  7. my $reindex = 0;
  8. my $dowrite = 0;
  9. my $staticloader = "";
  10. my $pack_errcode;
  11. my $load_errcode;
  12. while (@ARGV) {
  13. my $arg = $ARGV[0];
  14. if($arg eq "-conf") {
  15. shift @ARGV;
  16. $config = shift @ARGV;
  17. } elsif($arg eq "-debug") {
  18. $debug = 1;
  19. shift @ARGV;
  20. } elsif($arg eq "-rebuild") {
  21. $rebuild = 1;
  22. shift @ARGV;
  23. } elsif($arg eq "-recurse") {
  24. $recurse = 1;
  25. shift @ARGV;
  26. } elsif($arg eq "-reindex") {
  27. $reindex = 1;
  28. shift @ARGV;
  29. } elsif($arg eq "-nostatic") {
  30. $static = 0;
  31. shift @ARGV;
  32. } elsif($arg eq "-staticloader") {
  33. $staticloader = "static ";
  34. shift @ARGV;
  35. } elsif($arg eq "-write") {
  36. $dowrite = 1;
  37. shift @ARGV;
  38. } else {
  39. last;
  40. }
  41. }
  42. if($recurse) {
  43. @source = ( <crypto/*.c>, <crypto/*/*.c>, <ssl/*.c>,
  44. <fips/*.c>, <fips/*/*.c>);
  45. } else {
  46. @source = @ARGV;
  47. }
  48. # Read in the config file
  49. open(IN, "<$config") || die "Can't open config file $config";
  50. # Parse config file
  51. while(<IN>)
  52. {
  53. if(/^L\s+(\S+)\s+(\S+)\s+(\S+)/) {
  54. $hinc{$1} = $2;
  55. $libinc{$2} = $1;
  56. $cskip{$3} = $1;
  57. if($3 ne "NONE") {
  58. $csrc{$1} = $3;
  59. $fmax{$1} = 99;
  60. $rmax{$1} = 99;
  61. $fassigned{$1} = ":";
  62. $rassigned{$1} = ":";
  63. $fnew{$1} = 0;
  64. $rnew{$1} = 0;
  65. }
  66. } elsif (/^F\s+(\S+)/) {
  67. # Add extra function with $1
  68. } elsif (/^R\s+(\S+)\s+(\S+)/) {
  69. $rextra{$1} = $2;
  70. $rcodes{$1} = $2;
  71. }
  72. }
  73. close IN;
  74. # Scan each header file in turn and make a list of error codes
  75. # and function names
  76. while (($hdr, $lib) = each %libinc)
  77. {
  78. next if($hdr eq "NONE");
  79. print STDERR "Scanning header file $hdr\n" if $debug;
  80. my $line = "", $def= "", $linenr = 0, $gotfile = 0;
  81. if (open(IN, "<$hdr")) {
  82. $gotfile = 1;
  83. while(<IN>) {
  84. $linenr++;
  85. print STDERR "line: $linenr\r" if $debug;
  86. last if(/BEGIN\s+ERROR\s+CODES/);
  87. if ($line ne '') {
  88. $_ = $line . $_;
  89. $line = '';
  90. }
  91. if (/\\$/) {
  92. $line = $_;
  93. next;
  94. }
  95. if(/\/\*/) {
  96. if (not /\*\//) { # multiline comment...
  97. $line = $_; # ... just accumulate
  98. next;
  99. } else {
  100. s/\/\*.*?\*\///gs; # wipe it
  101. }
  102. }
  103. if ($cpp) {
  104. $cpp++ if /^#\s*if/;
  105. $cpp-- if /^#\s*endif/;
  106. next;
  107. }
  108. $cpp = 1 if /^#.*ifdef.*cplusplus/; # skip "C" declaration
  109. next if (/^\#/); # skip preprocessor directives
  110. s/{[^{}]*}//gs; # ignore {} blocks
  111. if (/\{|\/\*/) { # Add a } so editor works...
  112. $line = $_;
  113. } else {
  114. $def .= $_;
  115. }
  116. }
  117. }
  118. print STDERR " \r" if $debug;
  119. $defnr = 0;
  120. # Delete any DECLARE_ macros
  121. $def =~ s/DECLARE_\w+\([\w,\s]+\)//gs;
  122. foreach (split /;/, $def) {
  123. $defnr++;
  124. print STDERR "def: $defnr\r" if $debug;
  125. # The goal is to collect function names from function declarations.
  126. s/^[\n\s]*//g;
  127. s/[\n\s]*$//g;
  128. # Skip over recognized non-function declarations
  129. next if(/typedef\W/ or /DECLARE_STACK_OF/ or /TYPEDEF_.*_OF/);
  130. # Remove STACK_OF(foo)
  131. s/STACK_OF\(\w+\)/void/;
  132. # Reduce argument lists to empty ()
  133. # fold round brackets recursively: (t(*v)(t),t) -> (t{}{},t) -> {}
  134. while(/\(.*\)/s) {
  135. s/\([^\(\)]+\)/\{\}/gs;
  136. s/\(\s*\*\s*(\w+)\s*\{\}\s*\)/$1/gs; #(*f{}) -> f
  137. }
  138. # pretend as we didn't use curly braces: {} -> ()
  139. s/\{\}/\(\)/gs;
  140. if (/(\w+)\s*\(\).*/s) { # first token prior [first] () is
  141. my $name = $1; # a function name!
  142. $name =~ tr/[a-z]/[A-Z]/;
  143. $ftrans{$name} = $1;
  144. } elsif (/[\(\)]/ and not (/=/)) {
  145. print STDERR "Header $hdr: cannot parse: $_;\n";
  146. }
  147. }
  148. print STDERR " \r" if $debug;
  149. next if $reindex;
  150. # Scan function and reason codes and store them: keep a note of the
  151. # maximum code used.
  152. if ($gotfile) {
  153. while(<IN>) {
  154. if(/^\#\s*define\s+(\S+)\s+(\S+)/) {
  155. $name = $1;
  156. $code = $2;
  157. next if $name =~ /^${lib}err/;
  158. unless($name =~ /^${lib}_([RF])_(\w+)$/) {
  159. print STDERR "Invalid error code $name\n";
  160. next;
  161. }
  162. if($1 eq "R") {
  163. $rcodes{$name} = $code;
  164. if ($rassigned{$lib} =~ /:$code:/) {
  165. print STDERR "!! ERROR: $lib reason code $code assigned twice\n";
  166. }
  167. $rassigned{$lib} .= "$code:";
  168. if(!(exists $rextra{$name}) &&
  169. ($code > $rmax{$lib}) ) {
  170. $rmax{$lib} = $code;
  171. }
  172. } else {
  173. if ($fassigned{$lib} =~ /:$code:/) {
  174. print STDERR "!! ERROR: $lib function code $code assigned twice\n";
  175. }
  176. $fassigned{$lib} .= "$code:";
  177. if($code > $fmax{$lib}) {
  178. $fmax{$lib} = $code;
  179. }
  180. $fcodes{$name} = $code;
  181. }
  182. }
  183. }
  184. }
  185. if ($debug) {
  186. if (defined($fmax{$lib})) {
  187. print STDERR "Max function code fmax" . "{" . "$lib" . "} = $fmax{$lib}\n";
  188. $fassigned{$lib} =~ m/^:(.*):$/;
  189. @fassigned = sort {$a <=> $b} split(":", $1);
  190. print STDERR " @fassigned\n";
  191. }
  192. if (defined($rmax{$lib})) {
  193. print STDERR "Max reason code rmax" . "{" . "$lib" . "} = $rmax{$lib}\n";
  194. $rassigned{$lib} =~ m/^:(.*):$/;
  195. @rassigned = sort {$a <=> $b} split(":", $1);
  196. print STDERR " @rassigned\n";
  197. }
  198. }
  199. if ($lib eq "SSL") {
  200. if ($rmax{$lib} >= 1000) {
  201. print STDERR "!! ERROR: SSL error codes 1000+ are reserved for alerts.\n";
  202. print STDERR "!! Any new alerts must be added to $config.\n";
  203. print STDERR "\n";
  204. }
  205. }
  206. close IN;
  207. }
  208. # Scan each C source file and look for function and reason codes
  209. # This is done by looking for strings that "look like" function or
  210. # reason codes: basically anything consisting of all upper case and
  211. # numerics which has _F_ or _R_ in it and which has the name of an
  212. # error library at the start. This seems to work fine except for the
  213. # oddly named structure BIO_F_CTX which needs to be ignored.
  214. # If a code doesn't exist in list compiled from headers then mark it
  215. # with the value "X" as a place holder to give it a value later.
  216. # Store all function and reason codes found in %ufcodes and %urcodes
  217. # so all those unreferenced can be printed out.
  218. foreach $file (@source) {
  219. # Don't parse the error source file.
  220. next if exists $cskip{$file};
  221. print STDERR "File loaded: ".$file."\r" if $debug;
  222. open(IN, "<$file") || die "Can't open source file $file\n";
  223. while(<IN>) {
  224. if(/(([A-Z0-9]+)_F_([A-Z0-9_]+))/) {
  225. next unless exists $csrc{$2};
  226. next if($1 eq "BIO_F_BUFFER_CTX");
  227. $ufcodes{$1} = 1;
  228. if(!exists $fcodes{$1}) {
  229. $fcodes{$1} = "X";
  230. $fnew{$2}++;
  231. }
  232. $notrans{$1} = 1 unless exists $ftrans{$3};
  233. }
  234. if(/(([A-Z0-9]+)_R_[A-Z0-9_]+)/) {
  235. next unless exists $csrc{$2};
  236. $urcodes{$1} = 1;
  237. if(!exists $rcodes{$1}) {
  238. $rcodes{$1} = "X";
  239. $rnew{$2}++;
  240. }
  241. }
  242. }
  243. close IN;
  244. }
  245. print STDERR " \n" if $debug;
  246. # Now process each library in turn.
  247. foreach $lib (keys %csrc)
  248. {
  249. my $hfile = $hinc{$lib};
  250. my $cfile = $csrc{$lib};
  251. if(!$fnew{$lib} && !$rnew{$lib}) {
  252. print STDERR "$lib:\t\tNo new error codes\n";
  253. next unless $rebuild;
  254. } else {
  255. print STDERR "$lib:\t\t$fnew{$lib} New Functions,";
  256. print STDERR " $rnew{$lib} New Reasons.\n";
  257. next unless $dowrite;
  258. }
  259. # If we get here then we have some new error codes so we
  260. # need to rebuild the header file and C file.
  261. # Make a sorted list of error and reason codes for later use.
  262. my @function = sort grep(/^${lib}_/,keys %fcodes);
  263. my @reasons = sort grep(/^${lib}_/,keys %rcodes);
  264. # Rewrite the header file
  265. if (open(IN, "<$hfile")) {
  266. # Copy across the old file
  267. while(<IN>) {
  268. push @out, $_;
  269. last if (/BEGIN ERROR CODES/);
  270. }
  271. close IN;
  272. } else {
  273. push @out,
  274. "/* ====================================================================\n",
  275. " * Copyright (c) 2001-2011 The OpenSSL Project. All rights reserved.\n",
  276. " *\n",
  277. " * Redistribution and use in source and binary forms, with or without\n",
  278. " * modification, are permitted provided that the following conditions\n",
  279. " * are met:\n",
  280. " *\n",
  281. " * 1. Redistributions of source code must retain the above copyright\n",
  282. " * notice, this list of conditions and the following disclaimer. \n",
  283. " *\n",
  284. " * 2. Redistributions in binary form must reproduce the above copyright\n",
  285. " * notice, this list of conditions and the following disclaimer in\n",
  286. " * the documentation and/or other materials provided with the\n",
  287. " * distribution.\n",
  288. " *\n",
  289. " * 3. All advertising materials mentioning features or use of this\n",
  290. " * software must display the following acknowledgment:\n",
  291. " * \"This product includes software developed by the OpenSSL Project\n",
  292. " * for use in the OpenSSL Toolkit. (http://www.openssl.org/)\"\n",
  293. " *\n",
  294. " * 4. The names \"OpenSSL Toolkit\" and \"OpenSSL Project\" must not be used to\n",
  295. " * endorse or promote products derived from this software without\n",
  296. " * prior written permission. For written permission, please contact\n",
  297. " * openssl-core\@openssl.org.\n",
  298. " *\n",
  299. " * 5. Products derived from this software may not be called \"OpenSSL\"\n",
  300. " * nor may \"OpenSSL\" appear in their names without prior written\n",
  301. " * permission of the OpenSSL Project.\n",
  302. " *\n",
  303. " * 6. Redistributions of any form whatsoever must retain the following\n",
  304. " * acknowledgment:\n",
  305. " * \"This product includes software developed by the OpenSSL Project\n",
  306. " * for use in the OpenSSL Toolkit (http://www.openssl.org/)\"\n",
  307. " *\n",
  308. " * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY\n",
  309. " * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n",
  310. " * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n",
  311. " * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR\n",
  312. " * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n",
  313. " * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n",
  314. " * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\n",
  315. " * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n",
  316. " * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,\n",
  317. " * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n",
  318. " * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED\n",
  319. " * OF THE POSSIBILITY OF SUCH DAMAGE.\n",
  320. " * ====================================================================\n",
  321. " *\n",
  322. " * This product includes cryptographic software written by Eric Young\n",
  323. " * (eay\@cryptsoft.com). This product includes software written by Tim\n",
  324. " * Hudson (tjh\@cryptsoft.com).\n",
  325. " *\n",
  326. " */\n",
  327. "\n",
  328. "#ifndef HEADER_${lib}_ERR_H\n",
  329. "#define HEADER_${lib}_ERR_H\n",
  330. "\n",
  331. "/* BEGIN ERROR CODES */\n";
  332. }
  333. open (OUT, ">$hfile") || die "Can't Open File $hfile for writing\n";
  334. print OUT @out;
  335. undef @out;
  336. print OUT <<"EOF";
  337. /*
  338. * The following lines are auto generated by the script mkerr.pl. Any changes
  339. * made after this point may be overwritten when the script is next run.
  340. */
  341. EOF
  342. if($static) {
  343. print OUT <<"EOF";
  344. ${staticloader}void ERR_load_${lib}_strings(void);
  345. EOF
  346. } else {
  347. print OUT <<"EOF";
  348. ${staticloader}void ERR_load_${lib}_strings(void);
  349. ${staticloader}void ERR_unload_${lib}_strings(void);
  350. ${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line);
  351. # define ${lib}err(f,r) ERR_${lib}_error((f),(r),__FILE__,__LINE__)
  352. EOF
  353. }
  354. print OUT <<"EOF";
  355. /* Error codes for the $lib functions. */
  356. /* Function codes. */
  357. EOF
  358. foreach $i (@function) {
  359. $z=48 - length($i);
  360. if($fcodes{$i} eq "X") {
  361. $fassigned{$lib} =~ m/^:([^:]*):/;
  362. $findcode = $1;
  363. if (!defined($findcode)) {
  364. $findcode = $fmax{$lib};
  365. }
  366. while ($fassigned{$lib} =~ m/:$findcode:/) {
  367. $findcode++;
  368. }
  369. $fcodes{$i} = $findcode;
  370. $fassigned{$lib} .= "$findcode:";
  371. print STDERR "New Function code $i\n" if $debug;
  372. }
  373. printf OUT "# define $i%s $fcodes{$i}\n"," " x $z;
  374. }
  375. print OUT "\n/* Reason codes. */\n";
  376. foreach $i (@reasons) {
  377. $z=48 - length($i);
  378. if($rcodes{$i} eq "X") {
  379. $rassigned{$lib} =~ m/^:([^:]*):/;
  380. $findcode = $1;
  381. if (!defined($findcode)) {
  382. $findcode = $rmax{$lib};
  383. }
  384. while ($rassigned{$lib} =~ m/:$findcode:/) {
  385. $findcode++;
  386. }
  387. $rcodes{$i} = $findcode;
  388. $rassigned{$lib} .= "$findcode:";
  389. print STDERR "New Reason code $i\n" if $debug;
  390. }
  391. printf OUT "# define $i%s $rcodes{$i}\n"," " x $z;
  392. }
  393. print OUT <<"EOF";
  394. #ifdef __cplusplus
  395. }
  396. #endif
  397. #endif
  398. EOF
  399. close OUT;
  400. # Rewrite the C source file containing the error details.
  401. # First, read any existing reason string definitions:
  402. my %err_reason_strings;
  403. if (open(IN,"<$cfile")) {
  404. my $line = "";
  405. while (<IN>) {
  406. chomp;
  407. $_ = $line . $_;
  408. $line = "";
  409. if (/{ERR_REASON\(/) {
  410. if (/\b(${lib}_R_\w*)\b.*\"(.*)\"/) {
  411. $err_reason_strings{$1} = $2;
  412. } else {
  413. $line = $_;
  414. }
  415. }
  416. }
  417. close(IN);
  418. }
  419. my $hincf;
  420. if($static) {
  421. $hfile =~ /([^\/]+)$/;
  422. $hincf = "<openssl/$1>";
  423. } else {
  424. $hincf = "\"$hfile\"";
  425. }
  426. # If static we know the error code at compile time so use it
  427. # in error definitions.
  428. if ($static)
  429. {
  430. $pack_errcode = "ERR_LIB_${lib}";
  431. $load_errcode = "0";
  432. }
  433. else
  434. {
  435. $pack_errcode = "0";
  436. $load_errcode = "ERR_LIB_${lib}";
  437. }
  438. open (OUT,">$cfile") || die "Can't open $cfile for writing";
  439. print OUT <<"EOF";
  440. /* $cfile */
  441. /* ====================================================================
  442. * Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
  443. *
  444. * Redistribution and use in source and binary forms, with or without
  445. * modification, are permitted provided that the following conditions
  446. * are met:
  447. *
  448. * 1. Redistributions of source code must retain the above copyright
  449. * notice, this list of conditions and the following disclaimer.
  450. *
  451. * 2. Redistributions in binary form must reproduce the above copyright
  452. * notice, this list of conditions and the following disclaimer in
  453. * the documentation and/or other materials provided with the
  454. * distribution.
  455. *
  456. * 3. All advertising materials mentioning features or use of this
  457. * software must display the following acknowledgment:
  458. * "This product includes software developed by the OpenSSL Project
  459. * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
  460. *
  461. * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
  462. * endorse or promote products derived from this software without
  463. * prior written permission. For written permission, please contact
  464. * openssl-core\@OpenSSL.org.
  465. *
  466. * 5. Products derived from this software may not be called "OpenSSL"
  467. * nor may "OpenSSL" appear in their names without prior written
  468. * permission of the OpenSSL Project.
  469. *
  470. * 6. Redistributions of any form whatsoever must retain the following
  471. * acknowledgment:
  472. * "This product includes software developed by the OpenSSL Project
  473. * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
  474. *
  475. * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
  476. * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  477. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  478. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
  479. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  480. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  481. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  482. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  483. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  484. * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  485. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  486. * OF THE POSSIBILITY OF SUCH DAMAGE.
  487. * ====================================================================
  488. *
  489. * This product includes cryptographic software written by Eric Young
  490. * (eay\@cryptsoft.com). This product includes software written by Tim
  491. * Hudson (tjh\@cryptsoft.com).
  492. *
  493. */
  494. /*
  495. * NOTE: this file was auto generated by the mkerr.pl script: any changes
  496. * made to it will be overwritten when the script next updates this file,
  497. * only reason strings will be preserved.
  498. */
  499. #include <stdio.h>
  500. #include <openssl/err.h>
  501. #include $hincf
  502. /* BEGIN ERROR CODES */
  503. #ifndef OPENSSL_NO_ERR
  504. # define ERR_FUNC(func) ERR_PACK($pack_errcode,func,0)
  505. # define ERR_REASON(reason) ERR_PACK($pack_errcode,0,reason)
  506. static ERR_STRING_DATA ${lib}_str_functs[] = {
  507. EOF
  508. # Add each function code: if a function name is found then use it.
  509. foreach $i (@function) {
  510. my $fn;
  511. $i =~ /^${lib}_F_(\S+)$/;
  512. $fn = $1;
  513. if(exists $ftrans{$fn}) {
  514. $fn = $ftrans{$fn};
  515. }
  516. # print OUT "{ERR_PACK($pack_errcode,$i,0),\t\"$fn\"},\n";
  517. if(length($i) + length($fn) > 58) {
  518. print OUT " {ERR_FUNC($i),\n \"$fn\"},\n";
  519. } else {
  520. print OUT " {ERR_FUNC($i), \"$fn\"},\n";
  521. }
  522. }
  523. print OUT <<"EOF";
  524. {0, NULL}
  525. };
  526. static ERR_STRING_DATA ${lib}_str_reasons[] = {
  527. EOF
  528. # Add each reason code.
  529. foreach $i (@reasons) {
  530. my $rn;
  531. my $rstr = "ERR_REASON($i)";
  532. if (exists $err_reason_strings{$i}) {
  533. $rn = $err_reason_strings{$i};
  534. } else {
  535. $i =~ /^${lib}_R_(\S+)$/;
  536. $rn = $1;
  537. $rn =~ tr/_[A-Z]/ [a-z]/;
  538. }
  539. if(length($i) + length($rn) > 56) {
  540. print OUT " {${rstr},\n \"$rn\"},\n";
  541. } else {
  542. print OUT " {${rstr}, \"$rn\"},\n";
  543. }
  544. }
  545. if($static) {
  546. print OUT <<"EOF";
  547. {0, NULL}
  548. };
  549. #endif
  550. ${staticloader}void ERR_load_${lib}_strings(void)
  551. {
  552. #ifndef OPENSSL_NO_ERR
  553. if (ERR_func_error_string(${lib}_str_functs[0].error) == NULL) {
  554. ERR_load_strings($load_errcode, ${lib}_str_functs);
  555. ERR_load_strings($load_errcode, ${lib}_str_reasons);
  556. }
  557. #endif
  558. }
  559. EOF
  560. } else {
  561. print OUT <<"EOF";
  562. {0, NULL}
  563. };
  564. #endif
  565. #ifdef ${lib}_LIB_NAME
  566. static ERR_STRING_DATA ${lib}_lib_name[] = {
  567. {0, ${lib}_LIB_NAME},
  568. {0, NULL}
  569. };
  570. #endif
  571. static int ${lib}_lib_error_code = 0;
  572. static int ${lib}_error_init = 1;
  573. ${staticloader}void ERR_load_${lib}_strings(void)
  574. {
  575. if (${lib}_lib_error_code == 0)
  576. ${lib}_lib_error_code = ERR_get_next_error_library();
  577. if (${lib}_error_init) {
  578. ${lib}_error_init = 0;
  579. #ifndef OPENSSL_NO_ERR
  580. ERR_load_strings(${lib}_lib_error_code, ${lib}_str_functs);
  581. ERR_load_strings(${lib}_lib_error_code, ${lib}_str_reasons);
  582. #endif
  583. #ifdef ${lib}_LIB_NAME
  584. ${lib}_lib_name->error = ERR_PACK(${lib}_lib_error_code, 0, 0);
  585. ERR_load_strings(0, ${lib}_lib_name);
  586. #endif
  587. }
  588. }
  589. ${staticloader}void ERR_unload_${lib}_strings(void)
  590. {
  591. if (${lib}_error_init == 0) {
  592. #ifndef OPENSSL_NO_ERR
  593. ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_functs);
  594. ERR_unload_strings(${lib}_lib_error_code, ${lib}_str_reasons);
  595. #endif
  596. #ifdef ${lib}_LIB_NAME
  597. ERR_unload_strings(0, ${lib}_lib_name);
  598. #endif
  599. ${lib}_error_init = 1;
  600. }
  601. }
  602. ${staticloader}void ERR_${lib}_error(int function, int reason, char *file, int line)
  603. {
  604. if (${lib}_lib_error_code == 0)
  605. ${lib}_lib_error_code = ERR_get_next_error_library();
  606. ERR_PUT_error(${lib}_lib_error_code, function, reason, file, line);
  607. }
  608. EOF
  609. }
  610. close OUT;
  611. undef %err_reason_strings;
  612. }
  613. if($debug && %notrans) {
  614. print STDERR "The following function codes were not translated:\n";
  615. foreach(sort keys %notrans)
  616. {
  617. print STDERR "$_\n";
  618. }
  619. }
  620. # Make a list of unreferenced function and reason codes
  621. foreach (keys %fcodes) {
  622. push (@funref, $_) unless exists $ufcodes{$_};
  623. }
  624. foreach (keys %rcodes) {
  625. push (@runref, $_) unless exists $urcodes{$_};
  626. }
  627. if($debug && @funref) {
  628. print STDERR "The following function codes were not referenced:\n";
  629. foreach(sort @funref)
  630. {
  631. print STDERR "$_\n";
  632. }
  633. }
  634. if($debug && @runref) {
  635. print STDERR "The following reason codes were not referenced:\n";
  636. foreach(sort @runref)
  637. {
  638. print STDERR "$_\n";
  639. }
  640. }