Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 lines
12 KiB

  1. #Copyright (c) 1992-2000 Microsoft Corporation
  2. #
  3. #Module Name:
  4. #
  5. # gnbugcds.pl
  6. #
  7. #Abstract:
  8. #
  9. # WinDbg Extension Api
  10. #
  11. #Environment:
  12. #
  13. # User Mode.
  14. #
  15. #Revision History:
  16. #
  17. # Kshitix K. Sharma (kksharma)
  18. #
  19. #
  20. # Parse bugcodes.txt file to generate C-relevant info for bugcheck codes
  21. #
  22. # Expected format of a bugcheck description:
  23. #
  24. # BUGCHECK
  25. # <bugcheck name> (<numericvalue>)
  26. # optional - <multiline description string about bugcheck>
  27. # optional - PARAMETERS <parameters description as follows>
  28. # Param [1|2|3|4] - <string>
  29. # OR
  30. # Param [1|2|3|4]
  31. # VALUES:
  32. # [<value> : <Rest of parameter description>]*
  33. # END_VALUES <required only in case of nesting>
  34. #DESCRIPTION
  35. #<additional description string>
  36. #
  37. sub emit_file_header;
  38. sub emit_bugcheck_info;
  39. sub emit_param_info;
  40. sub next_line;
  41. sub is_new_bugcheck;
  42. sub is_bugcheck_description;
  43. #
  44. # main
  45. #
  46. $NumLine = 0;
  47. @BugCheckList = {};
  48. @FullParamDesc = {"", "", "", ""};
  49. $ParamValueRec = {
  50. VALUE => 0,
  51. PARAMID => -1,
  52. PARAM1DESC => "",
  53. PARAM2DESC => "",
  54. PARAM3DESC => "",
  55. PARAM4DESC => "",
  56. };
  57. @ParamValueRecList = {};
  58. while ($arg = shift) {
  59. if ($arg eq "-o") {
  60. $OutFileName = shift;
  61. } elsif ($arg eq "-i") {
  62. $BugCheckTxtFile = shift;
  63. } else {
  64. $BugCheckTxtFile = $arg;
  65. }
  66. }
  67. die "Cannot open file $BugCheckTxtFile\n" if !open(BUGC_FILE, $BugCheckTxtFile);
  68. emit_file_header();
  69. while (is_new_bugcheck() || next_line ) {
  70. $line = $_ if !is_new_bugcheck();
  71. if (is_new_bugcheck()) {
  72. emit_bugcheck_info;
  73. }
  74. } continue {
  75. close BUGC_FILE if eof;
  76. }
  77. # emit a list of APIS for quick reference
  78. print OUT_FILE "BUGDESC_APIREFS g_BugDescApiRefs[] = {\n";
  79. for $i(1..$#BugCheckList) {
  80. printf (OUT_FILE " { %30s, &BugCheck%s},\n", $BugCheckList[ $i ], $BugCheckList[ $i ]);
  81. }
  82. print OUT_FILE "};\n";
  83. print OUT_FILE "ULONG g_NumBugDescApiRefs = sizeof(g_BugDescApiRefs) / sizeof(BUGDESC_APIREFS);\n";
  84. #
  85. # Subroutines
  86. #
  87. sub is_new_bugcheck {
  88. if ($line =~ /^BUGCHECK$/) {
  89. next_line;
  90. }
  91. if ($line =~ /^([A-Z][A-Z_0-9]+)\s*\((.*)\)$/) {
  92. return 1;
  93. }
  94. return 0;
  95. }
  96. sub is_bugcheck_description {
  97. if ($line =~ /^DESCRIPTION\s*$/) {
  98. return 1;
  99. }
  100. return 0;
  101. }
  102. sub emit_file_header {
  103. die "Cannot open file $OutFileName\n" if !open(OUT_FILE, ">" . $OutFileName);
  104. print OUT_FILE "//-------------------------------------".
  105. "--------------------------------------\n";
  106. print OUT_FILE "//\n";
  107. print OUT_FILE "// IMPORTANT: This file is automatically generated.\n";
  108. print OUT_FILE "// Do not edit by hand.\n";
  109. print OUT_FILE "//\n";
  110. print OUT_FILE "// Generated from $BugCheckTxtFile " . localtime() . "\n";
  111. print OUT_FILE "//\n";
  112. print OUT_FILE "//-------------------------------------".
  113. "--------------------------------------\n\n";
  114. print OUT_FILE "#include \"precomp.h\"\n";
  115. print OUT_FILE "\n\n";
  116. }
  117. sub emit_bugcheck_header {
  118. print OUT_FILE "//\n";
  119. print OUT_FILE "// DescriptionRoutine for $_[0] ($_[1])\n";
  120. print OUT_FILE "//\n";
  121. print OUT_FILE "void\nBugCheck$_[0] ( \n";
  122. print OUT_FILE " PBUGCHECK_ANALYSIS pBugCheck\n";
  123. print OUT_FILE " )\n";
  124. print OUT_FILE "{\n";
  125. print OUT_FILE " ULONG Value = $_[0];\n";
  126. print OUT_FILE " PCHAR BugName = \"$_[0]\";\n";
  127. print OUT_FILE " PCHAR Description = NULL, ParamDesc[4] = {0};\n\n";
  128. }
  129. sub init_param_array {
  130. for $i (0..3) {
  131. if ($FullParamDesc[ $i ] =~ /.*".+".*/) { # Non NULL values only
  132. print OUT_FILE "$_[0]$FullParamDesc[ $i ];\n";
  133. }
  134. }
  135. $FullParamDesc[ 0 ] = "";
  136. $FullParamDesc[ 1 ] = "";
  137. $FullParamDesc[ 2 ] = "";
  138. $FullParamDesc[ 3 ] = "";
  139. }
  140. sub begin_first_value {
  141. # $_[0] -> Argument index
  142. # $_[1] -> Argument value
  143. print OUT_FILE "$_[2]if (pBugCheck->Args[ $_[0] ] == $_[1]) {\n";
  144. }
  145. sub begin_intermediate_value {
  146. # $_[0] -> Argument index
  147. # $_[1] -> Argument value
  148. # $_[2] -> Indent
  149. init_param_array($_[2]);
  150. print OUT_FILE "$_[2]} else if (pBugCheck->Args[ $_[0] ] == $_[1]) {\n";
  151. }
  152. sub begin_intermediate_value_parent {
  153. # $_[0] -> Argument index
  154. # $_[1] -> Argument value
  155. # $_[2] -> Indent
  156. print OUT_FILE "$_[2]} else if (pBugCheck->Args[ $_[0] ] == $_[1]) {\n";
  157. }
  158. sub begin_default_value {
  159. # $_[0] -> Argument index
  160. # $_[1] -> Indent
  161. init_param_array($_[1]);
  162. print OUT_FILE "$_[1]} else {\n";
  163. }
  164. sub begin_default_value_parent {
  165. # $_[0] -> Argument index
  166. # $_[1] -> Indent
  167. print OUT_FILE "$_[1]} else {\n";
  168. }
  169. sub end_value {
  170. # $_[0] -> Indent
  171. init_param_array($_[0]);
  172. print OUT_FILE "$_[0]}\n";
  173. }
  174. sub emit_bugcheck_end {
  175. print OUT_FILE " pBugCheck->Code = Value;\n";
  176. print OUT_FILE " pBugCheck->szName = BugName;\n";
  177. print OUT_FILE " pBugCheck->szDescription = Description;\n";
  178. print OUT_FILE " pBugCheck->szParamsDesc[0] = ParamDesc[0];\n";
  179. print OUT_FILE " pBugCheck->szParamsDesc[1] = ParamDesc[1];\n";
  180. print OUT_FILE " pBugCheck->szParamsDesc[2] = ParamDesc[2];\n";
  181. print OUT_FILE " pBugCheck->szParamsDesc[3] = ParamDesc[3];\n";
  182. print OUT_FILE "\n}\n\n";
  183. }
  184. #
  185. # Match the folowing here
  186. # <BugName> (<num>)
  187. # <description>
  188. # <parameters> - done by emit_param_info
  189. # <more description>
  190. #
  191. sub emit_bugcheck_info {
  192. die "No name Info on line $NumLine\n" if !($BugNameLine = $line) ;
  193. if (($Name,$Value) = $BugNameLine =~ /^([A-Z][A-Z_0-9]+)\s*\((.*)\)$/) {
  194. emit_bugcheck_header ( $Name, $Value );
  195. push (@BugCheckList, $Name);
  196. $FullDesc = " Description = ";
  197. $DescPrinted = 0;
  198. while (next_line && (!is_new_bugcheck()) && ($line !~ /^\s*PARAMETERS\s*.*$/)) {
  199. if ($line !~ /^\s*$/) {
  200. ($Desc) = $line =~ /^(.*)\s*$/;
  201. if ($DescPrinted) {
  202. $FullDesc = $FullDesc . "\n\t";
  203. }
  204. ($Desc) =~ s/([\\"])/\\$1/g ;
  205. $FullDesc = $FullDesc . "\"$Desc\\n\"";
  206. $DescPrinted++;
  207. }
  208. }
  209. $MoreDesc = 0;
  210. if ($line =~ /^\s*PARAMETERS\s*.*$/) {
  211. ($line) = $line =~ /^\s*PARAMETERS\s*(.*)$/;
  212. if (!$line) {
  213. next_line;
  214. }
  215. $MoreDesc = emit_param_info;
  216. }
  217. if ($MoreDesc) {
  218. # BugCheck description string following parameter description
  219. while (next_line && (!is_new_bugcheck())) {
  220. if ($line !~ /^\s*$/) {
  221. ($Desc) = $line =~ /^(.*)\s*$/;
  222. if ($DescPrinted) {
  223. $FullDesc = $FullDesc . "\n\t";
  224. }
  225. ($Desc) =~ s/([\\"])/\\$1/g ;
  226. $FullDesc = $FullDesc . "\"$Desc\\n\"";
  227. $DescPrinted++;
  228. }
  229. }
  230. }
  231. if (!$DescPrinted) { $FullDesc = $FullDesc . "\"\"";}
  232. print OUT_FILE $FullDesc . ";\n";
  233. emit_bugcheck_end ;
  234. } else {
  235. print "Bad name Info on line $NumLine - $BugNameLine\n"
  236. }
  237. }
  238. sub emit_param_info {
  239. @FullParamDesc = {"", "", "", ""};
  240. $ParamValueDefined = -1;
  241. $IsFirstValue = 1;
  242. @ParamValueRecList = {};
  243. $Level = 0;
  244. $MovedLevelUp = 0;
  245. $FullParamDesc[ 0 ] = "";
  246. $FullParamDesc[ 1 ] = "";
  247. $FullParamDesc[ 2 ] = "";
  248. $FullParamDesc[ 3 ] = "";
  249. while (!is_new_bugcheck() && !is_bugcheck_description() && $line) {
  250. if ($line !~ /^\s*$/) {
  251. ($ParamPrefix, $ParamId, $ParamDesc) = $line =~ /^\s*(\w*)\s*([1234])\s*-\s*(.*)$/;
  252. if ($ParamId && ($ParamPrefix == "" || $ParamPrefix == "Param" || $ParamPrefix == "Arg" ||
  253. $ParamPrefix == "Parameter" || $ParamPrefix == "Argument")) {
  254. ($ParamDesc) =~ s/([\\"])/\\$1/g ;
  255. $ParamId--; # 0 based index
  256. $FullParamDesc[ $ParamId ] = " ParamDesc[ $ParamId ] = \"$ParamDesc\"";
  257. $LastParamId = $ParamId;
  258. } elsif ($line =~ /^\s*VALUES\s*:?\s*$/) {
  259. # emit the parameter description we have so far since the folowing
  260. # ones would be relevant to specific values only.
  261. # code path will automatically remember these if they are not defined later
  262. init_param_array(" " x ($Level * 4));
  263. $ParamValueDefined = $LastParamId;
  264. $IsFirstValue = 1;
  265. $ParamValueRec = {
  266. VALUE => 0,
  267. PARAMID => $LastParamId,
  268. PARAM1DESC => $FullParamDesc[ 0 ],
  269. PARAM2DESC => $FullParamDesc[ 1 ],
  270. PARAM3DESC => $FullParamDesc[ 2 ],
  271. PARAM4DESC => $FullParamDesc[ 3 ],
  272. };
  273. push (@ParamValueRecList, ($ParamValueRec));
  274. $Level = $#ParamValueRecList;
  275. } elsif ($line =~ /^\s*END_VALUES\s*$/) {
  276. $Level = $#ParamValueRecList;
  277. end_value(" " x ($Level * 4));
  278. $IsFirstValue = 0;
  279. $MovedLevelUp = 1;
  280. # restore what we had whe we saw VALUES clause
  281. $LastParamId = $ParamValueRecList[$Level-1]{PARAMID};
  282. $FullParamDesc[ 0 ] = $ParamValueRecList[$Level-1]{PARAM1DESC};
  283. $FullParamDesc[ 1 ] = $ParamValueRecList[$Level-1]{PARAM2DESC};
  284. $FullParamDesc[ 2 ] = $ParamValueRecList[$Level-1]{PARAM3DESC};
  285. $FullParamDesc[ 3 ] = $ParamValueRecList[$Level-1]{PARAM4DESC};
  286. if ($Level) {
  287. pop( @ParamValueRecList );
  288. } else {
  289. die "No preivious VALUE clause for END_VALUES on line $NumLine\n";
  290. }
  291. $ParamValueDefined = $LastParamId;
  292. $Level = $#ParamValueRecList;
  293. if ($Level == 0) {
  294. $ParamValueDefined = -1;
  295. }
  296. } elsif (($ParamValueDefined != -1) &&
  297. ((($Value) = $line =~ /^\s*(default)\s*:.*$/) ||
  298. (($Value) = $line =~ /^\s*(0?x?[0-9A-Fa-f]*)\s*:.*$/))) {
  299. #matched "<Value> : <text>"
  300. if ($Value !~ /0x.*/) {
  301. # prepend 0x
  302. $Value = "0x" . $Value;
  303. }
  304. if ($Value =~ /default/ ) {
  305. begin_default_value( $Value, " " x ($Level * 4));
  306. } elsif ($IsFirstValue) {
  307. $IsFirstValue = 0;
  308. begin_first_value($ParamValueDefined, $Value, " " x ($Level * 4));
  309. } elsif ($MovedLevelUp) {
  310. $MovedLevelUp = 0;
  311. begin_intermediate_value_parent($ParamValueDefined, $Value, " " x ($Level * 4));
  312. } else {
  313. begin_intermediate_value($ParamValueDefined, $Value, " " x ($Level * 4));
  314. }
  315. $ParamDesc = $FullParamDesc[ $ParamValueDefined ];
  316. if (($Desc) = $line =~ /^\s*0?x?[0-9A-Fa-f]*\s*:\s*(.*)$/) {
  317. ($Desc) =~ s/([\\"])/\\$1/g ;
  318. $FullParamDesc[ $ParamValueDefined ] = " ParamDesc[ $ParamValueDefined ] = \"$Desc\"";
  319. } else {
  320. $FullParamDesc[ $ParamValueDefined ] = $ParamDesc;
  321. }
  322. } else {
  323. ($line) = $line =~ /^\s*(.*)$/;
  324. ($line) =~ s/([\\"])/\\$1/g ; #"/# escape chars
  325. $temp = "\\n\"";
  326. $FullParamDesc[ $LastParamId ] = $FullParamDesc[ $LastParamId ] . "\n \"\\n$line\"";
  327. }
  328. }
  329. # print OUT_FILE "// FINISED UP----" . $line;
  330. $line = next_line;
  331. }
  332. if ($ParamValueDefined != -1) {
  333. end_value(" " x (4));
  334. } else {
  335. init_param_array("");
  336. }
  337. $MoreDesc = is_bugcheck_description();
  338. return $MoreDesc;
  339. }
  340. sub next_line {
  341. $line = <BUGC_FILE>;
  342. $NumLine++;
  343. while ($line =~ /\s*\%.*$/) {
  344. # Skip commented lines - ones which beging with %
  345. $line = <BUGC_FILE>;
  346. $NumLine++;
  347. }
  348. return $line;
  349. }