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 / annotation.C < prev    next >
C/C++ Source or Header  |  1998-10-23  |  6KB  |  239 lines

  1. // $Id: annotation.C,v 1.5 1998/10/23 20:30:21 zeller Exp $ -*- C++ -*-
  2. // Create an edge annotation
  3.  
  4. // Copyright (C) 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 annotation_rcsid[] = 
  30.     "$Id: annotation.C,v 1.5 1998/10/23 20:30:21 zeller Exp $";
  31.  
  32. #ifdef __GNUG__
  33. #pragma implementation
  34. #endif
  35.  
  36. #include "annotation.h"
  37.  
  38. #include "ddd.h"
  39. #include "GDBAgent.h"
  40. #include "cook.h"
  41. #include "isid.h"
  42.  
  43. // Remove leading S from A
  44. static void strip_leading(string& a, const string& s)
  45. {
  46.     if (a.length() > s.length() && a.contains(s, 0))
  47.     a = a.from(int(s.length()));
  48. }
  49.  
  50. static bool my_equal(char c1, char c2)
  51. {
  52.     if (is_perl_prefix(c1) && is_perl_prefix(c2))
  53.     return true;
  54.     else
  55.     return c1 == c2;
  56. }
  57.  
  58. // Return 1st occurrence of B in A
  59. static int my_index(const string& a, const string& b)
  60. {
  61.     if (gdb->program_language() != LANGUAGE_PERL)
  62.     return a.index(b);
  63.  
  64.     // Compare with all Perl prefix keys considered equal
  65.     for (int i = 0; i < int(a.length()) - int(b.length()) + 1; i++)
  66.     {
  67.     int j;
  68.     for (j = 0; j < int(b.length()) && my_equal(a[i + j], b[j]); j++)
  69.         ;
  70.     if (j >= int(b.length()))
  71.         return i;
  72.     }
  73.  
  74.     return -1;
  75. }
  76.  
  77. // In A, substitute 1st occurrence of S1 by S2
  78. static bool _sub1(string& a, const string& s1, const string& s2)
  79. {
  80.     int index = my_index(a, s1);
  81.     if (index >= 0)
  82.     {
  83.     a = a.before(index) + s2 + a.from(index + int(s1.length()));
  84.     return true;
  85.     }
  86.  
  87.     return false;
  88. }
  89.  
  90. static string c_prefix(string& expr)
  91. {
  92.     if (gdb->program_language() != LANGUAGE_C)
  93.     return "";
  94.  
  95.     string prefix;
  96.  
  97.     while (expr.contains('*', 0) || expr.contains('&', 0))
  98.     {
  99.     prefix += expr[0];
  100.     expr = expr.after(0);
  101.     }
  102.  
  103.     return prefix;
  104. }
  105.  
  106. static string perl_prefix(string& expr)
  107. {
  108.     if (gdb->program_language() != LANGUAGE_PERL)
  109.     return "";
  110.  
  111.     string prefix;
  112.  
  113.     while (expr != "" && is_perl_prefix(expr[0]))
  114.     {
  115.     prefix += expr[0];
  116.     expr = expr.after(0);
  117.     }
  118.  
  119.     return prefix;
  120. }
  121.  
  122. static bool sub1(string& a, string s1, string s2)
  123. {
  124.     string prefix = c_prefix(s1);
  125.  
  126.     for (int depth = 2; depth >= 0; depth--)
  127.     {
  128.     for (int p = 0; p < 2; p++)
  129.     {
  130.         string open  = replicate("([{"[p], depth);
  131.         string close = replicate(")]}"[p], depth);
  132.  
  133.         if (_sub1(a, prefix + open + s1 + close, s2))
  134.         return true;
  135.  
  136.         if (_sub1(a, open + prefix + s1 + close, s2))
  137.         return true;
  138.     }
  139.     }
  140.  
  141.     return false;
  142. }
  143.  
  144. // Normalize pointers: In C, `A->B' becomes `(*A).B'.
  145. static void normalize_pointers(string& expr)
  146. {
  147.     if (gdb->program_language() == LANGUAGE_C)
  148.     {
  149.     string prefix = c_prefix(expr);
  150.     while (expr.contains("->"))
  151.         expr = "(*" + expr.before("->") + ")." + expr.after("->");
  152.  
  153.     expr = prefix + expr;
  154.     }
  155.     else if (gdb->program_language() == LANGUAGE_PERL)
  156.     {
  157.     // Re-insert optional arrows between brackets subscripts
  158.     int i;
  159.     for (i = 0; i < 3; i++)
  160.     {
  161.         for (int j = 0; j < 3; j++)
  162.         {
  163.         string open  = "([{"[j];
  164.         string close = ")]}"[i];
  165.         expr.gsub(close + open, close + "->" + open);
  166.         }
  167.     }
  168.  
  169.     // Replace $A->[B] by ${$A}[B]
  170.     string prefix = perl_prefix(expr);
  171.     while (expr.contains("->"))
  172.         expr = "{$" + expr.before("->") + "}" + expr.after("->");
  173.  
  174.     // Replace $$A by ${$A}
  175.     for (i = prefix.length() - 1; i > 0; i--)
  176.         expr = string("{") + prefix[i] + expr + "}";
  177.     if (prefix.length() > 0)
  178.         expr.prepend(prefix[0]);
  179.     }
  180. }
  181.  
  182. static string _annotation(string from, string to)
  183. {
  184.     string annotation = to;
  185.     sub1(annotation, from, "()");
  186.  
  187.     if (annotation == to)
  188.     {
  189.     string to0 = to;
  190.  
  191.     // No suitable annotation found -- try normalized
  192.     normalize_pointers(from);
  193.     normalize_pointers(to);
  194.  
  195.     annotation = to;
  196.     sub1(annotation, from, "()");
  197.     if (annotation == to)
  198.         annotation = to0;
  199.     }
  200.  
  201.     return annotation;
  202. }
  203.  
  204. // Return an annotation for an edge from FROM to TO
  205. string annotation(string from, string to)
  206. {
  207.     string annotation = _annotation(from, to);
  208.     if (annotation == to)
  209.     return "";        // Nothing found
  210.  
  211.     // Strip surrounding braces
  212.     for (int i = 0; i < 3; i++)
  213.     {
  214.     string open  = "([{"[i];
  215.     string close = ")]}"[i];
  216.  
  217.     while (annotation.contains(open + "()" + close))
  218.         annotation.gsub(open + "()" + close, string("()"));
  219.  
  220.     while (annotation.length() > 2 && 
  221.            annotation.contains(open, 0) && annotation.contains(close, -1))
  222.     {
  223.         annotation = unquote(annotation);
  224.     }
  225.     }
  226.  
  227.     if (gdb->program_language() == LANGUAGE_C)
  228.     {
  229.     // Display pointers using the base name only
  230.     strip_leading(annotation, "*().");
  231.     strip_leading(annotation, "()->");
  232.     }
  233.  
  234.     // Omit the source name from any other expressions
  235.     strip_leading(annotation, "()");
  236.  
  237.     return annotation;
  238. }
  239.