home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / emxtutor.zip / emxsrcd1.zip / emx / src / pmgdb / annotati.cc next >
C/C++ Source or Header  |  1996-08-04  |  8KB  |  277 lines

  1. /* annotati.cc
  2.    Copyright (c) 1996 Eberhard Mattes
  3.  
  4. This file is part of pmgdb.
  5.  
  6. pmgdb is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 2, or (at your option)
  9. any later version.
  10.  
  11. pmgdb is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with pmgdb; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 59 Temple Place - Suite 330,
  19. Boston, MA 02111-1307, USA.  */
  20.  
  21.  
  22. #include <os2.h>
  23. #include <string.h>
  24. #include <io.h>
  25. #include "annotati.h"
  26.  
  27.  
  28. struct annotation::node
  29. {
  30.   node *next;
  31.   char *str;
  32.   int len;
  33.   annotation::code c;
  34. };
  35.  
  36.  
  37. annotation::annotation ()
  38. {
  39.   buf = NULL; buf_size = 0; buf_in = buf_out = 0;
  40.   for (int i = 0; i < hash_size; ++i)
  41.     table[i] = NULL;
  42.   init (arg_begin, "arg-begin");
  43.   init (arg_end, "arg-end");
  44.   init (arg_name_end, "arg-name-end");
  45.   init (arg_value, "arg-value");
  46.   init (array_section_begin, "array-section-begin");
  47.   init (array_section_end, "array-section-end");
  48.   init (breakpoint, "breakpoint");
  49.   init (breakpoint_new, "breakpoint-new");
  50.   init (breakpoints_headers, "breakpoints-headers");
  51.   init (breakpoints_table, "breakpoints-table");
  52.   init (breakpoints_table_end, "breakpoints-table-end");
  53.   init (breakpoints_invalid, "breakpoints-invalid");
  54.   init (commands, "commands");
  55.   init (display_begin, "display-begin");
  56.   init (display_delete, "display-delete");
  57.   init (display_disable, "display-disable");
  58.   init (display_enable, "display-enable");
  59.   init (display_end, "display-end");
  60.   init (display_expression, "display-expression");
  61.   init (display_expression_end, "display-expression-end");
  62.   init (display_format, "display-format");
  63.   init (display_number_end, "display-number-end");
  64.   init (display_value, "display-value");
  65.   init (error_begin, "error-begin");
  66.   init (error, "error");
  67.   init (elt, "elt");
  68.   init (elt_rep, "elt-rep");
  69.   init (elt_rep_end, "elt-rep-end");
  70.   init (exec_file, "exec-file");
  71.   init (exec_file_invalid, "exec-file-invalid");
  72.   init (exited, "exited");
  73.   init (field, "field");
  74.   init (field_begin, "field-begin");
  75.   init (field_end, "field-end");
  76.   init (field_name_end, "field-name-end");
  77.   init (field_value, "field-value");
  78.   init (frame, "frame");
  79.   init (frame_args, "frame-args");
  80.   init (frame_begin, "frame-begin");
  81.   init (frame_end, "frame-end");
  82.   init (frame_function_name, "frame-function-name");
  83.   init (frame_source_begin, "frame-source-begin");
  84.   init (frame_source_end, "frame-source-end");
  85.   init (frame_source_file, "frame-source-file");
  86.   init (frame_source_file_end, "frame-source-file-end");
  87.   init (frame_source_line, "frame-source-line");
  88.   init (frames_invalid, "frames-invalid");
  89.   init (overload_choice, "overload-choice");
  90.   init (prompt, "prompt");
  91.   init (prompt_for_continue, "prompt-for-continue");
  92.   init (pre_commands, "pre-commands");
  93.   init (pre_overload_choice, "pre-overload-choice");
  94.   init (pre_prompt, "pre-prompt");
  95.   init (pre_prompt_for_continue, "pre-prompt-for-continue");
  96.   init (pre_query, "pre-query");
  97.   init (post_commands, "post-commands");
  98.   init (post_overload_choice, "post-overload-choice");
  99.   init (post_prompt, "post-prompt");
  100.   init (post_prompt_for_continue, "post-prompt-for-continue");
  101.   init (post_query, "post-query");
  102.   init (query, "query");
  103.   init (quit, "quit");
  104.   init (record, "record");
  105.   init (show_value, "show-value");
  106.   init (show_value_end, "show-value-end");
  107.   init (starting, "starting");
  108.   init (stopped, "stopped");
  109.   init (signalled, "signalled");
  110.   init (source, "source");
  111.   init (source_file, "source-file");
  112.   init (source_location, "source-location");
  113.   init (source_location_end, "source-location-end");
  114.   init (signal, "signal");
  115.   init (signal_handler_caller, "signal-handler-caller");
  116.   init (signal_name, "signal-name");
  117.   init (signal_name_end, "signal-name-end");
  118.   init (signal_string, "signal-string");
  119.   init (signal_string_end, "signal-string-end");
  120.   init (thread_add, "thread-add");
  121.   init (thread_disable, "thread-disable");
  122.   init (thread_enable, "thread-enable");
  123.   init (thread_end, "thread-end");
  124.   init (thread_switch, "thread-switch");
  125.   init (value_begin, "value-begin");
  126.   init (value_end, "value-end");
  127.   init (value_history_begin, "value-history-begin");
  128.   init (value_history_end, "value-history-end");
  129.   init (value_history_value, "value-history-value");
  130.   init (watchpoint, "watchpoint");
  131. }
  132.  
  133.  
  134. annotation::~annotation ()
  135. {
  136.   node *next;
  137.   for (int h = 0; h < hash_size; ++h)
  138.     for (node *p = table[h]; p != NULL; p = next)
  139.       {
  140.         next = p->next;
  141.         delete[] p->str;
  142.         delete p;
  143.       }
  144.   delete[] buf;
  145. }
  146.  
  147.  
  148. unsigned annotation::hash (const char *s, int len)
  149. {
  150.   unsigned h = 0;
  151.   for (int i = 0; i < len; ++i)
  152.     h = (h << 1) ^ (unsigned char)s[i];
  153.   return h % hash_size;
  154. }
  155.  
  156.  
  157. void annotation::init (code c, const char *s)
  158. {
  159.   int len = strlen (s);
  160.   unsigned h = hash (s, len);
  161.   node *n = new node;
  162.   n->c = c;
  163.   n->len = len;
  164.   n->str = new char[len + 1];
  165.   memcpy (n->str, s, len + 1);
  166.   n->next = table[h];
  167.   table[h] = n;
  168. }
  169.  
  170.  
  171. void annotation::start (int in_fd)
  172. {
  173.   fd = in_fd;
  174. }
  175.  
  176.  
  177. void annotation::parse (const char *s, int len)
  178. {
  179.   const char *args = (const char *)memchr (s, ' ', len);
  180.   int keyword_len = args == NULL ? len : args - s;
  181.   unsigned h = hash (s, keyword_len);
  182.   last_code = UNKNOWN; last_args = s; last_args_len = len;
  183.   const node *n;
  184.   for (n = table[h]; n != NULL; n = n->next)
  185.     if (n->len == keyword_len && memcmp (n->str, s, keyword_len) == 0)
  186.       break;
  187.   if (n != NULL)
  188.     {
  189.       last_code = n->c;
  190.       if (args != NULL)
  191.         {
  192.           last_args = args + 1;
  193.           last_args_len = len - (keyword_len + 1);
  194.         }
  195.       else
  196.         {
  197.           last_args = NULL;
  198.           last_args_len = 0;
  199.         }
  200.     }
  201. }
  202.  
  203.  
  204. bool annotation::fill ()
  205. {
  206.   if (buf_in == buf_out)
  207.     buf_in = buf_out = 0;
  208.   if (buf_in == buf_size)
  209.     {
  210.       buf_size += 512;
  211.       char *new_buf = new char [buf_size];
  212.       memcpy (new_buf, buf, buf_in);
  213.       delete[] buf;
  214.       buf = new_buf;
  215.     }
  216.   int n = read (fd, buf + buf_in, buf_size - buf_in);
  217.   if (n <= 0)
  218.     return false;
  219.   buf_in += n;
  220.   return true;
  221. }
  222.  
  223.  
  224. annotation::code annotation::get_next ()
  225. {
  226.   if (buf_in == buf_out && !fill ())
  227.     return READ_ERROR;
  228.   const char *nl;
  229.   int text_len = 0;
  230.   for (;;)
  231.     {
  232.       const char *start = buf + buf_out + text_len;
  233.       nl = (const char *)memchr (start, '\n', buf_in - (buf_out + text_len));
  234.       if (nl == NULL)
  235.         {
  236.           text_len = buf_in - buf_out;
  237.           break;
  238.         }
  239.       text_len += (nl - start);
  240.       int pos = nl - buf;
  241.  
  242.       if (pos + 1 >= buf_in && !fill ())
  243.         return READ_ERROR;
  244.       if (buf[pos+1] != 0x1a)
  245.         ++text_len;             // Beware of \n\n^Z^Z!
  246.       else
  247.         {
  248.           if (pos + 2 >= buf_in && !fill ())
  249.             return READ_ERROR;
  250.           if (buf[pos+2] != 0x1a)
  251.             ++text_len;         // Beware of \n^Z\n^Z^Z
  252.           else
  253.             break;              // Annotation found
  254.         }
  255.     }
  256.  
  257.   if (text_len != 0)
  258.     {
  259.       last_code = TEXT;
  260.       last_text = buf + buf_out; last_text_len = text_len;
  261.       last_args = NULL; last_args_len = 0;
  262.       buf_out += text_len;
  263.       return last_code;
  264.     }
  265.  
  266.   while ((nl = (const char *)memchr (buf + buf_out + 3, '\n',
  267.                                      buf_in - (buf_out + 3))) == NULL)
  268.     if (!fill ())
  269.       return READ_ERROR;
  270.   last_text = buf + buf_out + 3;
  271.   last_text_len = nl - last_text;
  272.   parse (last_text, last_text_len);
  273.   buf[buf_out + 3 + last_text_len] = 0;
  274.   buf_out = (nl + 1) - buf;
  275.   return last_code;
  276. }
  277.