Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Parser/C++/syn/link_map.cc
    1| // Synopsis C++ Parser: LinkMap.cc source file
    2| // Implementation of the LinkMap class
    3| 
    4| // $Id: link_map.cc,v 1.6 2003/01/27 06:53:37 chalky Exp $
    5| //
    6| // This file is a part of Synopsis.
    7| // Copyright (C) 2000-2002 Stephen Davies
    8| // Copyright (C) 2000, 2001 Stefan Seefeld
    9| //
   10| // Synopsis is free software; you can redistribute it and/or modify it
   11| // under the terms of the GNU General Public License as published by
   12| // the Free Software Foundation; either version 2 of the License, or
   13| // (at your option) any later version.
   14| //
   15| // This program is distributed in the hope that it will be useful,
   16| // but WITHOUT ANY WARRANTY; without even the implied warranty of
   17| // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   18| // General Public License for more details.
   19| //
   20| // You should have received a copy of the GNU General Public License
   21| // along with this program; if not, write to the Free Software
   22| // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   23| // 02111-1307, USA.
   24| 
   25| // $Log: link_map.cc,v $
   26| // Revision 1.6  2003/01/27 06:53:37  chalky
   27| // Added macro support for C++.
   28| //
   29| // Revision 1.5  2002/12/12 17:25:34  chalky
   30| // Implemented Include support for C++ parser. A few other minor fixes.
   31| //
   32| // Revision 1.4  2002/11/17 12:11:43  chalky
   33| // Reformatted all files with astyle --style=ansi, renamed fakegc.hh
   34| //
   35| // Revision 1.3  2002/10/25 08:57:47  chalky
   36| // Clear the link map (stores where expanded macros are for syntax highlighted
   37| // files) after parsing
   38| //
   39| // Revision 1.2  2001/05/06 20:15:03  stefan
   40| // fixes to get std compliant; replaced some pass-by-value by pass-by-const-ref; bug fixes;
   41| //
   42| // Revision 1.1  2001/03/16 04:42:00  chalky
   43| // SXR parses expressions, handles differences from macro expansions. Some work
   44| // on function call resolution.
   45| //
   46| 
   47| 
   48| #include "link_map.hh"
   49| #include "filter.hh"
   50| #include "ast.hh"
   51| 
   52| #include <map>
   53| #include <set>
   54| #include <string>
   55| 
   56| //. This vector is initialised on first use (if any) by synopsis_define_hook
   57| std::vector<AST::Macro*>* syn_macro_defines = NULL;
   58| 
   59| namespace
   60| {
   61| struct Node
   62| {
   63|     int start;
   64|     int end;
   65|     enum Type { STARTEND } type;
   66|     int diff;
   67|     bool operator <(const Node& other) const
   68|     {
   69|         return start < other.start;
   70|     }
   71| };
   72| 
   73| typedef std::set<NodeLine;
   74| typedef std::map<int, Line> LineMap;
   75| };
   76| 
   77| // ------------------------------------------
   78| // Private struct
   79| //
   80| struct LinkMap::Private
   81| {
   82|     LineMap lines;
   83| };
   84| 
   85| LinkMap::LinkMap()
   86| {
   87|     m = new Private;
   88| }
   89| 
   90| LinkMapLinkMap::instance()
   91| {
   92|     static LinkMapinst = 0;
   93|     if (!inst)
   94|         inst = new LinkMap;
   95|     return inst;
   96| }
   97| 
   98| void LinkMap::add(const char* name, int linenum, int start, int end, int diff)
   99| {
  100|     Line& line = m->lines[linenum];
  101|     Node node;
  102|     node.start = start;
  103|     node.end = end;
  104|     node.type = Node::START;
  105|     node.diff = diff;
  106|     line.insert(node);
  107| }
  108| 
  109| int LinkMap::map(int linenum, int pos)
  110| {
  111|     LineMap::iterator line_iter = m->lines.find(linenum);
  112|     if (line_iter == m->lines.end())
  113|     {
  114|         return pos;
  115|     }
  116|     Line& line = line_iter->second;
  117|     Line::iterator iter = line.begin(), end = line.end();
  118|     int diff = 0;
  119|     while (iter != end && iter->start < pos)
  120|     {
  121|         const Node& node = *iter++;
  122|         if (pos < node.end)
  123|             return -1;
  124|         //cout << "LinkMap::map: line: "<<linenum<<" pos: "<<pos<<" start: "<<node.start<<endl;
  125|         diff = node.diff;
  126|     }
  127|     //cout << "LinkMap::map: line: "<<linenum<<" pos: "<<pos<<" diff: "<<diff<<endl;
  128|     return pos + diff;
  129| }
  130| 
  131| void LinkMap::clear()
  132| {
  133|     m->lines.clear();
  134| }
  135| 
  136| extern "C"
  137| {
  138|     //. This function is a callback from the ucpp code to store macro
  139|     //. expansions
  140|     void synopsis_macro_hook(const char* name, int line, int start, int end, int diff)
  141|     {
  142|         LinkMap::instance()->add(namelinestartenddiff);
  143|     }
  144| 
  145|     //. This function is a callback from the ucpp code to store includes
  146|     void synopsis_include_hook(const char* source_file, const char* target_file, int is_macro, int is_next)
  147|     {
  148|         // There is not enough code here to make another class..
  149|         FileFilterfilter = FileFilter::instance();
  150|         if (!filter)
  151|            return;
  152| 
  153|         // Add another Include to the source's SourceFile
  154|         // We don't deal with duplicates here. The Linker's Unduplicator will
  155|         // take care of that.
  156|         //std::cout << "Include: " << source_file << " -> " << target_file << std::endl;
  157|         AST::SourceFilefile = filter->get_sourcefile(source_file);
  158|         AST::SourceFiletarget = filter->get_sourcefile(target_file);
  159|         AST::Includeinclude = new AST::Include(target, is_macro, is_next);
  160|         file->includes().push_back(include);
  161|     }
  162| 
  163|     //. This function is a callback from the ucpp code to store macro
  164|     //. definitions
  165|     void synopsis_define_hook(const char* filename, int line, const char* name, int num_args, const char** args, int vaarg, const char* text)
  166|     {
  167|         FileFilterfilter = FileFilter::instance();
  168|         if (!filter)
  169|            return;
  170|         AST::SourceFilefile = filter->get_sourcefile(filename);
  171|         if (!file->is_main())
  172|            return;
  173|         if (syn_macro_defines == NULL)
  174|             syn_macro_defines = new std::vector<AST::Macro*>;
  175|         AST::Macro::Parametersparams = NULL;
  176|         if (args != NULL)
  177|         {
  178|             params = new AST::Macro::Parameters;
  179|             for (int i = 0i < num_argsi++)
  180|                params->push_back(args[i]);
  181|             if (vaarg)
  182|                params->push_back("...");
  183|         }
  184|         ScopedName macro_name;
  185|         macro_name.push_back(name);
  186|         AST::Macromacro = new AST::Macro(file, line, macro_name, params, text);
  187|         //. Don't know global NS yet.. Will have to extract these later
  188|         file->declarations().push_back(macro);
  189|         syn_macro_defines->push_back(macro);
  190|     }
  191| };
  192| // vim: set ts=8 sts=4 sw=4 et: