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.

377 lines
8.4 KiB

  1. // Copyright (c) 1999 Microsoft Corporation. All rights reserved.
  2. //
  3. // Helper functions for logging script parsing. Useful for debugging, but never turned on in released builds.
  4. //
  5. #error This file should never be used in released builds. // ��
  6. #include "stdinc.h"
  7. #include "englog.h"
  8. void LogToken(Lexer &l)
  9. {
  10. char msg[500] = "";
  11. char type[500] = "";
  12. char more[500] = "";
  13. switch (l)
  14. {
  15. case TOKEN_eof:
  16. if (l.error_num())
  17. {
  18. sprintf(msg, "%d(%d): error #%d - %s\n", l.line(), l.column(), l.error_num(), l.error_descr());
  19. OutputDebugString(msg);
  20. return;
  21. }
  22. strcpy(type, "end-of-file");
  23. break;
  24. case TOKEN_sub:
  25. strcpy(type, "sub");
  26. break;
  27. case TOKEN_dim:
  28. strcpy(type, "dim");
  29. break;
  30. case TOKEN_if:
  31. strcpy(type, "if");
  32. break;
  33. case TOKEN_then:
  34. strcpy(type, "then");
  35. break;
  36. case TOKEN_end:
  37. strcpy(type, "end");
  38. break;
  39. case TOKEN_elseif:
  40. strcpy(type, "elseif");
  41. break;
  42. case TOKEN_else:
  43. strcpy(type, "else");
  44. break;
  45. case TOKEN_set:
  46. strcpy(type, "set");
  47. break;
  48. case TOKEN_call:
  49. strcpy(type, "call");
  50. break;
  51. case TOKEN_lparen:
  52. strcpy(type, "(");
  53. break;
  54. case TOKEN_rparen:
  55. strcpy(type, ")");
  56. break;
  57. case TOKEN_comma:
  58. strcpy(type, ",");
  59. break;
  60. case TOKEN_op_minus:
  61. strcpy(type, "-");
  62. break;
  63. case TOKEN_op_not:
  64. strcpy(type, "not");
  65. break;
  66. case TOKEN_op_pow:
  67. strcpy(type, "^");
  68. break;
  69. case TOKEN_op_mult:
  70. strcpy(type, "*");
  71. break;
  72. case TOKEN_op_div:
  73. strcpy(type, "\\");
  74. break;
  75. case TOKEN_op_mod:
  76. strcpy(type, "mod");
  77. break;
  78. case TOKEN_op_plus:
  79. strcpy(type, "+");
  80. break;
  81. case TOKEN_op_lt:
  82. strcpy(type, "<");
  83. break;
  84. case TOKEN_op_leq:
  85. strcpy(type, "<=");
  86. break;
  87. case TOKEN_op_gt:
  88. strcpy(type, ">");
  89. break;
  90. case TOKEN_op_geq:
  91. strcpy(type, ">=");
  92. break;
  93. case TOKEN_op_eq:
  94. strcpy(type, "=");
  95. break;
  96. case TOKEN_op_neq:
  97. strcpy(type, "<>");
  98. break;
  99. case TOKEN_is:
  100. strcpy(type, "is");
  101. break;
  102. case TOKEN_and:
  103. strcpy(type, "and");
  104. break;
  105. case TOKEN_or:
  106. strcpy(type, "or");
  107. break;
  108. case TOKEN_linebreak:
  109. strcpy(type, "linebreak");
  110. break;
  111. case TOKEN_identifier:
  112. strcpy(type, "identifier");
  113. strcpy(more, l.identifier_name());
  114. break;
  115. case TOKEN_identifierdot:
  116. strcpy(type, "identifier.");
  117. strcpy(more, l.identifier_name());
  118. break;
  119. case TOKEN_stringliteral:
  120. strcpy(type, "string-literal");
  121. strcpy(more, l.stringliteral_text());
  122. break;
  123. case TOKEN_numericliteral:
  124. strcpy(type, "numeric-literal");
  125. _itoa(l.numericliteral_val(), more, 10);
  126. break;
  127. default:
  128. strcpy(type, "invalid token type!");
  129. break;
  130. }
  131. static const char format[] = "%d(%d): %s\n";
  132. static const char formatmore[] = "%d(%d): %s(%s)\n";
  133. sprintf(msg, *more ? formatmore : format, l.line(), l.column(), type, more);
  134. OutputDebugString(msg);
  135. }
  136. SmartRef::AString GetVarrefName(Script &script, VariableReferences::index ivarref)
  137. {
  138. VariableReference r = script.varrefs[ivarref];
  139. const char *pszKind;
  140. if (r.k == VariableReference::_global)
  141. pszKind = "G";
  142. else if (r.k == VariableReference::_local)
  143. pszKind = "L";
  144. bool fFirst = true;
  145. char namebuf[500] = "";
  146. for (ReferenceNames::index irname = r.irname; script.rnames[irname].istrIdentifier != -1; ++irname)
  147. {
  148. if (fFirst)
  149. fFirst = false;
  150. else
  151. strcat(namebuf, ".");
  152. strcat(namebuf, script.strings[script.rnames[irname].istrIdentifier]);
  153. }
  154. Variables::index islot = r.ivar;
  155. // check if it's a dispatch item
  156. if (r.k == VariableReference::_global)
  157. {
  158. DISPID dispid = script.globals[islot].dispid;
  159. if (dispid != DISPID_UNKNOWN)
  160. {
  161. pszKind = "D";
  162. islot = dispid; // show the dispid instead of the slot
  163. }
  164. }
  165. char buf[500];
  166. sprintf(buf, "{%s%d}%s", pszKind, islot, namebuf);
  167. return buf;
  168. }
  169. SmartRef::AString GetValueName(Script &script, Values::index ival)
  170. {
  171. const Value &v = script.vals[ival];
  172. char buf[500];
  173. if (v.k == Value::_numvalue)
  174. {
  175. sprintf(buf, "%d", v.inumvalue);
  176. }
  177. else if (v.k == Value::_strvalue)
  178. {
  179. sprintf(buf, "\"%s\"", script.strings[v.istrvalue]);
  180. }
  181. else
  182. {
  183. assert(v.k == Value::_varref);
  184. return GetVarrefName(script, v.ivarref);
  185. }
  186. return buf;
  187. }
  188. void Indent(int iNesting)
  189. {
  190. for (int i = 0; i < iNesting; ++i)
  191. OutputDebugString(" ");
  192. }
  193. // forward declaration due to mutual recursion with LogExpression
  194. void LogCall(Script &script, Calls::index icall);
  195. ExprBlocks::index LogExpression(Script &script, ExprBlocks::index _iexpr)
  196. {
  197. char msg[500] = "";
  198. bool fFirst = true;
  199. for (ExprBlocks::index iexpr = _iexpr; script.exprs[iexpr]; ++iexpr)
  200. {
  201. ExprBlock expr = script.exprs[iexpr];
  202. if (fFirst)
  203. fFirst = false;
  204. else
  205. OutputDebugString("|");
  206. if (expr.k == ExprBlock::_op)
  207. {
  208. bool fUnary = false;
  209. const char *pszOp = "";
  210. switch (expr.op)
  211. {
  212. case TOKEN_sub: fUnary = true; pszOp = "-"; break;
  213. case TOKEN_op_not: fUnary = true; pszOp = "not"; break;
  214. case TOKEN_op_minus: pszOp = "-"; break;
  215. case TOKEN_op_pow: pszOp = "^"; break;
  216. case TOKEN_op_mult: pszOp = "*"; break;
  217. case TOKEN_op_div: pszOp = "\\"; break;
  218. case TOKEN_op_mod: pszOp = "mod"; break;
  219. case TOKEN_op_plus: pszOp = "+"; break;
  220. case TOKEN_op_lt: pszOp = "<"; break;
  221. case TOKEN_op_leq: pszOp = "<="; break;
  222. case TOKEN_op_gt: pszOp = ">"; break;
  223. case TOKEN_op_geq: pszOp = ">="; break;
  224. case TOKEN_op_eq: pszOp = "="; break;
  225. case TOKEN_op_neq: pszOp = "<>"; break;
  226. case TOKEN_is: pszOp = "is"; break;
  227. case TOKEN_and: pszOp = "and"; break;
  228. case TOKEN_or: pszOp = "or"; break;
  229. default: assert(false); break;
  230. }
  231. if (fUnary)
  232. sprintf(msg, "%su", pszOp);
  233. else
  234. sprintf(msg, "%sb", pszOp);
  235. OutputDebugString(msg);
  236. }
  237. else if (expr.k == ExprBlock::_val)
  238. {
  239. SmartRef::AString astrVal = GetValueName(script, expr.ival);
  240. OutputDebugString(astrVal);
  241. }
  242. else
  243. {
  244. assert(expr.k == ExprBlock::_call);
  245. LogCall(script, expr.icall);
  246. }
  247. }
  248. return iexpr;
  249. }
  250. void LogCall(Script &script, Calls::index icall)
  251. {
  252. Call c = script.calls[icall];
  253. if (c.k == Call::_global)
  254. {
  255. OutputDebugString(script.strings[c.istrname]);
  256. }
  257. else
  258. {
  259. assert(c.k == Call::_dereferenced);
  260. SmartRef::AString astrCall = GetVarrefName(script, c.ivarref);
  261. OutputDebugString(astrCall);
  262. }
  263. OutputDebugString("(");
  264. bool fFirst = true;
  265. for (ExprBlocks::index iexpr = c.iexprParams; script.exprs[iexpr]; ++iexpr)
  266. {
  267. if (fFirst)
  268. fFirst = false;
  269. else
  270. OutputDebugString(", ");
  271. iexpr = LogExpression(script, iexpr);
  272. }
  273. OutputDebugString(")");
  274. }
  275. void LogStatements(Script &script, Statements::index istmt, int iNesting)
  276. {
  277. char msg[500] = "";
  278. for (; script.statements[istmt].k; ++istmt)
  279. {
  280. Statement s = script.statements[istmt];
  281. if (s.k == Statement::_asgn)
  282. {
  283. Assignment a = script.asgns[s.iasgn];
  284. SmartRef::AString astrLHS = GetVarrefName(script, a.ivarrefLHS);
  285. sprintf(msg, "%s = ", astrLHS);
  286. Indent(iNesting);
  287. OutputDebugString(msg);
  288. LogExpression(script, a.iexprRHS);
  289. OutputDebugString("\n");
  290. }
  291. else if (s.k == Statement::_if)
  292. {
  293. bool fFirst = true;
  294. for (IfBlocks::index iif = s.iif; script.ifs[iif].k != IfBlock::_end; ++iif)
  295. {
  296. Indent(iNesting);
  297. IfBlock ib = script.ifs[iif];
  298. if (fFirst)
  299. {
  300. assert(ib.k == IfBlock::_cond);
  301. OutputDebugString("if ");
  302. fFirst = false;
  303. }
  304. else
  305. {
  306. if (ib.k == IfBlock::_cond)
  307. OutputDebugString("elseif ");
  308. else if (ib.k == IfBlock::_else)
  309. OutputDebugString("else");
  310. }
  311. if (ib.k == IfBlock::_cond)
  312. {
  313. LogExpression(script, ib.iexprCondition);
  314. }
  315. OutputDebugString("\n");
  316. LogStatements(script, ib.istmtBlock, iNesting + 3);
  317. }
  318. istmt = s.istmtIfTail - 1; // -1 to offset the loop, which will increment it back
  319. }
  320. else if (s.k == Statement::_call)
  321. {
  322. Indent(iNesting);
  323. LogCall(script, s.icall);
  324. OutputDebugString("\n");
  325. }
  326. else
  327. {
  328. assert(false);
  329. Indent(iNesting);
  330. OutputDebugString(" Unknown statement type!\n");
  331. }
  332. }
  333. }
  334. void LogRoutine(Script &script, Routines::index irtn)
  335. {
  336. Routine r = script.routines[irtn];
  337. const char *pszName = script.strings[r.istrIdentifier];
  338. int cLocals = r.ivarNextLocal;
  339. char msg[500] = "";
  340. sprintf(msg, "@ Sub %s (%d locals)\n", pszName, cLocals);
  341. OutputDebugString(msg);
  342. LogStatements(script, r.istmtBody, 3);
  343. }