debug.l 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. /* -*-C-*-
  2. * Lexical scanner for command line parsing
  3. *
  4. * Copyright 1993 Eric Youngdale
  5. * 2000 Eric Pouech
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
  20. */
  21. %option noinput nounput always-interactive 8bit prefix="dbg_"
  22. %{
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <stdarg.h>
  26. #define YY_NO_UNISTD_H
  27. #include "debugger.h"
  28. #include "dbg.tab.h"
  29. #undef YY_INPUT
  30. static char** local_lexemes /* = NULL */;
  31. static int next_lexeme /* = 0 */;
  32. static int alloc_lexeme /* = 0 */;
  33. char* lexeme_alloc_size(int size)
  34. {
  35. assert(0 <= next_lexeme && next_lexeme < alloc_lexeme + 1);
  36. if (next_lexeme >= alloc_lexeme)
  37. {
  38. alloc_lexeme += 32;
  39. local_lexemes = dbg_heap_realloc(local_lexemes, alloc_lexeme * sizeof(local_lexemes[0]));
  40. assert(local_lexemes);
  41. }
  42. return local_lexemes[next_lexeme++] = HeapAlloc(GetProcessHeap(), 0, size + 1);
  43. }
  44. static char* lexeme_alloc(const char* lexeme)
  45. {
  46. char* ptr = lexeme_alloc_size(strlen(lexeme) + 1);
  47. return strcpy(ptr, lexeme);
  48. }
  49. void lexeme_flush(void)
  50. {
  51. while (--next_lexeme >= 0) HeapFree(GetProcessHeap(), 0, local_lexemes[next_lexeme]);
  52. next_lexeme = 0;
  53. }
  54. /* called with quoted string, unescape all elements inside the quotes */
  55. static char* unescape_string(const char* str)
  56. {
  57. size_t len = strlen(str) - 2;
  58. char* ret = lexeme_alloc_size(len + 1);
  59. char* dst = ret;
  60. const char* ptr;
  61. for (ptr = str + 1; ptr < str + 1 + len; ptr++)
  62. {
  63. if (*ptr == '\\')
  64. {
  65. switch (*++ptr)
  66. {
  67. case 't': *dst++ = '\t'; break;
  68. case 'r': *dst++ = '\r'; break;
  69. case 'n': *dst++ = '\n'; break;
  70. case '\\': *dst++ = '\\'; break;
  71. case '"': *dst++ = '"'; break;
  72. default: *dst++ = '\\'; *dst++ = *ptr; /* not handled, don't change */
  73. }
  74. }
  75. else
  76. *dst++ = *ptr;
  77. }
  78. *dst = '\0';
  79. return ret;
  80. }
  81. #define YY_INPUT(buf,result,max_size) \
  82. (result = input_lex_read_buffer(buf, max_size))
  83. static int syntax_error;
  84. %}
  85. OCTDIGIT [0-7]
  86. DIGIT [0-9]
  87. HEXDIGIT [0-9a-fA-F]
  88. FORMAT [ubcdgiswxa]
  89. IDENTIFIER [_a-zA-Z~?][_a-zA-Z0-9~?@]*
  90. SCOPED_IDENTIFIER [_a-zA-Z~?][_a-zA-Z0-9~?@]*"::"
  91. MODULE_IDENTIFIER [_a-zA-Z~?\*][_a-zA-Z0-9~?\*@]*"!"
  92. PATHNAME [\\/_a-zA-Z0-9\.~@][\\/\-_a-zA-Z0-9\.~@]*
  93. STRING \"(\\[^\n]|[^\\"\n])*\"
  94. %s FORMAT_EXPECTED
  95. %s INFO_CMD
  96. %s HELP_CMD
  97. %s BD_CMD
  98. %s LOCAL_CMD
  99. %s SHOW_CMD
  100. %s MODE_CMD
  101. %s MAINT_CMD
  102. %s NOCMD
  103. %s PATH_ACCEPTED
  104. %x PATH_EXPECTED
  105. %x ASTRING_EXPECTED
  106. %x AWORD_EXPECTED
  107. %x NOPROCESS
  108. %%
  109. /* set to special state when no process is loaded. */
  110. if (!dbg_num_processes() && YYSTATE == INITIAL) {BEGIN(NOPROCESS);}
  111. <<EOF>> { return tEOF; }
  112. <*>"#"[^\n]* /* Skip comments */
  113. <*>\n { BEGIN(INITIAL); syntax_error = 0; return tEOL; }
  114. /* Indicates end of command. Reset state. */
  115. "||" { return OP_LOR; }
  116. "&&" { return OP_LAND; }
  117. "==" { return OP_EQ; }
  118. "!=" { return OP_NE; }
  119. "<=" { return OP_LE; }
  120. ">=" { return OP_GE; }
  121. "<<" { return OP_SHL; }
  122. ">>" { return OP_SHR; }
  123. "->" { return OP_DRF; }
  124. "[" { return *yytext; }
  125. "]" { return *yytext; }
  126. "0x"{HEXDIGIT}+ { sscanf(yytext, "%I64x", &dbg_lval.integer); return tNUM; }
  127. {DIGIT}+ { sscanf(yytext, "%I64d", &dbg_lval.integer); return tNUM; }
  128. "'\\''" { dbg_lval.integer = '\''; return tNUM;}
  129. "'\\0"{OCTDIGIT}*"'" { sscanf(yytext + 3, "%I64o", &dbg_lval.integer); return tNUM;}
  130. "'\\x"{HEXDIGIT}+"'" { sscanf(yytext + 3, "%I64x", &dbg_lval.integer); return tNUM;}
  131. "'\\"[a-z]"'" { dbg_lval.integer = yytext[2] - 'a'; return tNUM;}
  132. "'"."'" { dbg_lval.integer = yytext[1]; return tNUM;}
  133. <FORMAT_EXPECTED>"/"{DIGIT}+{FORMAT} { char* last;
  134. dbg_lval.integer = strtol(yytext+1, &last, 0) << 8;
  135. dbg_lval.integer |= *last;
  136. return tFORMAT; }
  137. <FORMAT_EXPECTED>"/"{FORMAT} { dbg_lval.integer = (1 << 8) | yytext[1]; return tFORMAT; }
  138. <*>{STRING} { dbg_lval.string = unescape_string(yytext); return tSTRING;}
  139. <ASTRING_EXPECTED>[^\n]+ { char* p = yytext; while (*p == ' ' || *p == '\t') p++;
  140. dbg_lval.string = lexeme_alloc(p); return tSTRING; }
  141. <AWORD_EXPECTED>[^ \t\n]+ { char* p = yytext; while (*p == ' ' || *p == '\t') p++;
  142. dbg_lval.string = lexeme_alloc(p); return tSTRING; }
  143. <INITIAL,NOPROCESS>info|inf|in { BEGIN(INFO_CMD); return tINFO; }
  144. <INITIAL>up { BEGIN(NOCMD); return tUP; }
  145. <INITIAL>down|dow|do { BEGIN(NOCMD); return tDOWN; }
  146. <INITIAL,INFO_CMD>frame|fram|fra|fr { BEGIN(NOCMD); return tFRAME; }
  147. <INITIAL>list|lis|li|l { BEGIN(PATH_ACCEPTED); return tLIST; }
  148. <INITIAL>enable|enabl|enab|ena { BEGIN(BD_CMD); return tENABLE;}
  149. <INITIAL>disable|disabl|disab|disa|dis { BEGIN(BD_CMD); return tDISABLE; }
  150. <INITIAL>disassemble|disassembl|disassemb|disassem|disasse|disass|disas { BEGIN(NOCMD); return tDISASSEMBLE; }
  151. <INITIAL>locally|local { BEGIN(LOCAL_CMD); return tLOCAL; }
  152. <INITIAL,LOCAL_CMD>display|displa|displ|disp { BEGIN(FORMAT_EXPECTED); return tDISPLAY; }
  153. <INFO_CMD,BD_CMD>display|displa|displ|disp|dis|di|d { BEGIN(NOCMD); return tDISPLAY; }
  154. <INITIAL>undisplay|undispla|undispl|undisp|undis|undi|und { BEGIN(NOCMD); return tUNDISPLAY; }
  155. <INITIAL>delete|delet|dele|del { BEGIN(BD_CMD); return tDELETE; }
  156. <INITIAL>thread|threa|thre|thr|th { BEGIN(NOCMD); return tTHREAD; }
  157. <INITIAL,NOPROCESS>quit|qui|qu|q { BEGIN(NOCMD); return tQUIT; }
  158. <INITIAL>set|se { BEGIN(NOCMD); return tSET; }
  159. <INITIAL>x { BEGIN(FORMAT_EXPECTED); return tEXAM; }
  160. <INITIAL,NOPROCESS>help|hel|he|"?" { BEGIN(HELP_CMD); return tHELP; }
  161. <INITIAL,NOPROCESS>backtrace|backtrac|backtra|backt|back|bac|ba|bt { BEGIN(NOCMD); return tBACKTRACE; }
  162. <INITIAL,NOPROCESS>where|wher|whe { BEGIN(NOCMD); return tBACKTRACE; }
  163. <INITIAL>cont|con|co|c { BEGIN(NOCMD); return tCONT; }
  164. <INITIAL>pass|pas|pa { BEGIN(NOCMD); return tPASS; }
  165. <INITIAL>condition|conditio|conditi|condit|condi|cond { BEGIN(NOCMD); return tCOND; }
  166. <INITIAL>step|ste|st|s { BEGIN(NOCMD); return tSTEP; }
  167. <INITIAL>next|nex|ne|n { BEGIN(NOCMD); return tNEXT; }
  168. <INITIAL>stepi|si { BEGIN(NOCMD); return tSTEPI; }
  169. <INITIAL>nexti|ni { BEGIN(NOCMD); return tNEXTI; }
  170. <INITIAL>finish|finis|fini|fin|fi { BEGIN(NOCMD); return tFINISH; }
  171. <INITIAL>abort|abor|abo { BEGIN(NOCMD); return tABORT; }
  172. <INITIAL>print|prin|pri|pr|p { BEGIN(FORMAT_EXPECTED); return tPRINT; }
  173. <INITIAL>show|sho|sh { BEGIN(SHOW_CMD); return tSHOW; }
  174. <INITIAL,NOPROCESS>source|sourc|sour|src { BEGIN(PATH_EXPECTED); return tSOURCE; }
  175. <INITIAL>symbolfile|symbols|symbol|sf { BEGIN(PATH_EXPECTED); return tSYMBOLFILE; }
  176. <INITIAL,INFO_CMD,BD_CMD>break|brea|bre|br|b { BEGIN(PATH_ACCEPTED); return tBREAK; }
  177. <INITIAL,INFO_CMD,BD_CMD>hbreak|hbrea|hbre|hbr|hb { BEGIN(PATH_ACCEPTED); return tHBREAK; }
  178. <INITIAL>watch|watc|wat { BEGIN(NOCMD); return tWATCH; }
  179. <INITIAL>rwatch|rwatc|rwat { BEGIN(NOCMD); return tRWATCH; }
  180. <INITIAL>whatis|whati|what { BEGIN(NOCMD); return tWHATIS; }
  181. <INITIAL,NOPROCESS>run|ru|r { BEGIN(AWORD_EXPECTED); return tRUN;}
  182. <INITIAL>detach|detac|deta|det { BEGIN(NOCMD); return tDETACH; }
  183. <INITIAL>kill|kil|ki|k { BEGIN(NOCMD); return tKILL; }
  184. <INITIAL,NOPROCESS>maintenance|maint { BEGIN(MAINT_CMD); return tMAINTENANCE; }
  185. <INITIAL>minidump|mdmp { BEGIN(PATH_EXPECTED); return tMINIDUMP; }
  186. <INITIAL>echo { BEGIN(ASTRING_EXPECTED); return tECHO; }
  187. <NOPROCESS>attach|attac|atta|att { BEGIN(NOCMD); return tATTACH; }
  188. <INFO_CMD>share|shar|sha { return tSHARE; }
  189. <MAINT_CMD>module|modul|mod { BEGIN(ASTRING_EXPECTED); return tMODULE; }
  190. <INFO_CMD>locals|local|loca|loc { return tLOCAL; }
  191. <INFO_CMD>class|clas|cla { return tCLASS; }
  192. <INFO_CMD>process|proces|proce|proc { return tPROCESS; }
  193. <INFO_CMD>threads|thread|threa|thre|thr|th { return tTHREAD; }
  194. <INFO_CMD>exception|except|exc|ex { return tEXCEPTION; }
  195. <INFO_CMD>registers|regs|reg|re { return tREGS; }
  196. <INFO_CMD>allregs|allreg|allre { return tALLREGS; }
  197. <INFO_CMD>"all-registers"|"all-regs"|"all-reg"|"all-re" { return tALLREGS; }
  198. <INFO_CMD>segments|segment|segm|seg|se { return tSEGMENTS; }
  199. <INFO_CMD>stack|stac|sta|st { return tSTACK; }
  200. <INFO_CMD>symbol|symbo|symb|sym { BEGIN(ASTRING_EXPECTED); return tSYMBOL; }
  201. <INFO_CMD>maps|map { return tMAPS; }
  202. <INFO_CMD>window|windo|wind|win|wnd { return tWND; }
  203. <HELP_CMD>info|inf|in { return tINFO; }
  204. <MAINT_CMD>type { return tTYPE; }
  205. <INITIAL,SHOW_CMD>directories|directorie|directori|director|directo|direct|direc|direc|dir {
  206. BEGIN(PATH_EXPECTED); return tDIR; }
  207. char { return tCHAR; }
  208. short { return tSHORT; }
  209. int { return tINT; }
  210. long { return tLONG; }
  211. float { return tFLOAT; }
  212. double { return tDOUBLE; }
  213. unsigned { return tUNSIGNED; }
  214. signed { return tSIGNED; }
  215. struct { return tSTRUCT; }
  216. union { return tUNION; }
  217. enum { return tENUM; }
  218. all { return tALL; }
  219. {MODULE_IDENTIFIER}?{SCOPED_IDENTIFIER}*{IDENTIFIER} { dbg_lval.string = lexeme_alloc(yytext); return tIDENTIFIER; }
  220. "$"{IDENTIFIER} { dbg_lval.string = lexeme_alloc(yytext+1); return tINTVAR; }
  221. <PATH_EXPECTED,PATH_ACCEPTED>{PATHNAME} { dbg_lval.string = lexeme_alloc(yytext); return tPATH; }
  222. [-+<=>|&^()*/%:!~,\.] { return *yytext; }
  223. <*>[ \t\r]+ /* Eat up whitespace and DOS LF */
  224. <NOPROCESS>. { BEGIN(ASTRING_EXPECTED); yyless(0); return tNOPROCESS;}
  225. <*>. { if (syntax_error == 0) { syntax_error++; dbg_printf("Syntax Error (%s)\n", yytext); } }
  226. %%
  227. #ifndef dbg_wrap
  228. int dbg_wrap(void) { return 1; }
  229. #endif