home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1999 mARCH / PCWK3A99.iso / Linux / DDD331 / DDD-3_1_.000 / DDD-3_1_ / ddd-3.1.1 / ddd / dbx-lookup.C < prev    next >
C/C++ Source or Header  |  1998-10-20  |  6KB  |  262 lines

  1. // $Id: dbx-lookup.C,v 1.36 1998/10/20 13:26:43 zeller Exp $ -*- C++ -*-
  2. // Lookup a DBX function
  3.  
  4. // Copyright (C) 1996-1998 Technische Universitaet Braunschweig, Germany.
  5. // Written by Andreas Zeller <zeller@ips.cs.tu-bs.de>.
  6. // 
  7. // This file is part of DDD.
  8. // 
  9. // DDD is free software; you can redistribute it and/or
  10. // modify it under the terms of the GNU General Public
  11. // License as published by the Free Software Foundation; either
  12. // version 2 of the License, or (at your option) any later version.
  13. // 
  14. // DDD is distributed in the hope that it will be useful,
  15. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  17. // See the GNU General Public License for more details.
  18. // 
  19. // You should have received a copy of the GNU General Public
  20. // License along with DDD -- see the file COPYING.
  21. // If not, write to the Free Software Foundation, Inc.,
  22. // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  23. // 
  24. // DDD is the data display debugger.
  25. // For details, see the DDD World-Wide-Web page, 
  26. // `http://www.cs.tu-bs.de/softech/ddd/',
  27. // or send a mail to the DDD developers <ddd@ips.cs.tu-bs.de>.
  28.  
  29. char dbx_lookup_rcsid[] = 
  30.     "$Id: dbx-lookup.C,v 1.36 1998/10/20 13:26:43 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "dbx-lookup.h"
  37.  
  38. #include "StringSA.h"
  39. #include "cook.h"
  40. #include "ddd.h"
  41. #include "post.h"
  42. #include "misc.h"
  43. #include "question.h"
  44. #include "regexps.h"
  45. #include "index.h"
  46. #include "string-fun.h"
  47. #include "GDBAgent.h"
  48. #include "SourceView.h"
  49.  
  50. #include <stdlib.h>
  51.  
  52. //-----------------------------------------------------------------------------
  53. // Lookup location of FUNC using DBX
  54. //-----------------------------------------------------------------------------
  55.  
  56. static StringStringAssoc pos_cache;
  57.  
  58. string dbx_lookup(const string& func_name, bool silent)
  59. {
  60.     // Protect against `1' or `' being looked up as function names
  61.     if (!func_name.contains(rxidentifier, 0))
  62.     return "";        // Bad function name
  63.  
  64.     if (pos_cache.has(func_name))
  65.     {
  66.     string pos = pos_cache[func_name];
  67.     if (silent || pos != "")
  68.         return pos;
  69.     }
  70.  
  71.     string reply;
  72.     switch (gdb->type())
  73.     {
  74.     case GDB:
  75.     case DBX:
  76.     case JDB:
  77.     case PYDB:
  78.     reply = gdb_question("list " + func_name, 0, true);
  79.     break;
  80.  
  81.     case XDB:
  82.     reply = gdb_question("v " + func_name, 0, true);
  83.     break;
  84.  
  85.     case PERL:
  86.     reply = gdb_question("l " + func_name, 0, true);
  87.     break;
  88.     }
  89.  
  90.     if (reply == NO_GDB_ANSWER)
  91.     {
  92.     // post_gdb_busy();
  93.     return "";
  94.     }
  95.  
  96.     string file = "";
  97.     int line    = 0;
  98.     switch (gdb->type())
  99.     {
  100.     case GDB:
  101.     case PYDB:    // XXX
  102.     {
  103.     file = reply.from('\"');
  104.     file = file.before('\"');
  105.     string line_s = reply.after("Line ");
  106.     line = atoi(line_s);
  107.     break;
  108.     }
  109.  
  110.     case DBX:
  111.     line = line_of_listing(reply, silent);
  112.     if (line > 0)
  113.     {
  114.         file = gdb_question("file");
  115.         strip_trailing_space(file);
  116.     }
  117.     break;
  118.  
  119.     case JDB:
  120.     case PERL:
  121.     line = line_of_listing(reply, silent);
  122.     file = source_view->line_of_cursor();
  123.     file = file.before(':');
  124.     break;
  125.  
  126.     case XDB:
  127.     {
  128. #if RUNTIME_REGEX
  129.     static regex rxcolons("[^:]*:[^:]*: *[0-9][0-9]*.*");
  130. #endif
  131.     if (reply.matches(rxcolons))
  132.     {
  133.         file = reply.before(':');
  134.         reply = reply.after(':'); // Skip file
  135.         reply = reply.after(':'); // Skip function
  136.         strip_leading_space(reply);
  137.         string line_s = reply.before(':');
  138.         line = atoi(line_s);
  139.     }
  140.     else
  141.     {
  142.         // post_gdb_message(reply);
  143.         return "";
  144.     }
  145.     break;
  146.     }
  147.     }
  148.  
  149.     string pos = "";
  150.     if (line > 0)
  151.     pos = file + ":" + itostring(line);
  152.  
  153.     pos_cache[func_name] = pos;
  154.     return pos;
  155. }
  156.  
  157. // Find path of source file SOURCE
  158. string dbx_path(const string& source)
  159. {
  160.     string path;
  161.     if (gdb->has_setenv_command() && gdb->has_edit_command())
  162.     {
  163.     // The DBX `file' command issues only the base name of the
  164.     // current file.  The `edit' command, however, invokes an
  165.     // editor with the entire path.  So, we misuse the `edit'
  166.     // command such that it reports the entire path.
  167.     gdb_question("setenv EDITOR \"echo\"");
  168.     path = gdb_question("edit " + source);
  169.     gdb_question(string("setenv EDITOR ") + 
  170.              quote(getenv("EDITOR") ? getenv("EDITOR") : "vi"));
  171.     }
  172.     else if (gdb->type() == DBX)
  173.     {
  174.     // We have DBX, but no `setenv' and no `edit' command.  Check
  175.     // whether the `file' command with no arguments provides the
  176.     // full path, as in AIX DBX 3.1.  This shouldn't affect other
  177.     // DBX variants as `file' will simply return the same thing
  178.     // already contained in source.
  179.     gdb_question("file " + source);
  180.     path = gdb_question("file");
  181.     }
  182.  
  183.     strip_leading_space(path);
  184.     if (!path.contains('/', 0) || path.contains(' '))
  185.     path = source;        // Sanity check
  186.  
  187.     strip_trailing_space(path);
  188.     return path;
  189. }
  190.  
  191. void clear_dbx_lookup_cache()
  192. {
  193.     static StringStringAssoc empty;
  194.     pos_cache = empty;
  195. }
  196.  
  197. int line_of_listing(string& listing, bool silent)
  198. {
  199.     string message;
  200.     while (listing != ""
  201.        && !listing.contains('>', 0) 
  202.        && !listing.contains('*', 1) 
  203.        && atoi(listing) == 0)
  204.     {
  205.     message += listing.through('\n');
  206.     listing = listing.after('\n');
  207.     }
  208.  
  209.     if (!silent)
  210.     post_gdb_message(message);
  211.  
  212.     int idx = -1;
  213.  
  214.     if (idx < 0 && gdb->type() == JDB)
  215.     {
  216.     // JDB issues `=>' in the listed line
  217.     int idx = listing.index("\t=> \t");
  218.     while (idx > 0 && listing[idx - 1] != '\n')
  219.         idx--;
  220.     }
  221.  
  222.     if (idx < 0 && gdb->type() == DBX)
  223.     {
  224.     // SGI DBX issues `*' in column 2 before the `list'ed line.
  225.     // Quite useful.
  226. #if RUNTIME_REGEX
  227.     static regex rxnlstar("\n.[*]");
  228. #endif
  229.     int idx = index(listing, rxnlstar, "\n");
  230.     if (idx < 0 && listing.contains('*', 1))
  231.         idx = 1;
  232.     }
  233.  
  234.     if (idx < 0 && gdb->type() == DBX)
  235.     {
  236.     // DEC and SGI DBX issue `>' in column 1 before the current
  237.     // execution line.  Quite useful.
  238.     int idx = listing.index("\n>");
  239.     if (idx < 0 && listing.contains('>', 0))
  240.         idx = 0;
  241.     }
  242.  
  243.     // Use the first number found.
  244.     int num_idx = listing.index(rxint, max(idx, 0));
  245.     int line = 0;
  246.     if (num_idx >= 0)
  247.     line = atoi(listing.chars() + num_idx);
  248.  
  249.     if (line == 0)
  250.     {
  251.     // Weird.  No source?
  252.     }
  253.     else if (idx < 0)
  254.     {
  255.     // No indicator found - 
  256.     // the position we are looking for is in the middle
  257.     line += (listing.freq('\n') + 1) / 2 - 1;
  258.     }
  259.  
  260.     return line;
  261. }
  262.