Modules | Files | Inheritance Tree | Inheritance Graph | Name Index | Config
File: Synopsis/Parser/C++/syn/decoder.hh
    1| // Synopsis C++ Parser: decoder.hh header file
    2| // Decodes the names and types encoded by OCC
    3| 
    4| // $Id: decoder.hh,v 1.14 2002/11/17 12:11:43 chalky Exp $
    5| //
    6| // This file is a part of Synopsis.
    7| // Copyright (C) 2002 Stephen Davies
    8| //
    9| // Synopsis is free software; you can redistribute it and/or modify it
   10| // under the terms of the GNU General Public License as published by
   11| // the Free Software Foundation; either version 2 of the License, or
   12| // (at your option) any later version.
   13| //
   14| // This program 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.  See the GNU
   17| // General Public License for more details.
   18| //
   19| // You should have received a copy of the GNU General Public License
   20| // along with this program; if not, write to the Free Software
   21| // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
   22| // 02111-1307, USA.
   23| 
   24| #ifndef H_SYNOPSIS_CPP_DECODER
   25| #define H_SYNOPSIS_CPP_DECODER
   26| 
   27| #include <string>
   28| #include <vector>
   29| 
   30| // Forward decl of Types::Type
   31| namespace Types
   32| {
   33| class Type;
   34| }
   35| 
   36| // bad duplicate typedef.. hmm
   37| typedef std::vector<std::stringScopedName;
   38| 
   39| // Forward decl of Builder
   40| class Builder;
   41| 
   42| class Lookup;
   43| 
   44| #if defined(__GNUC__) && __GNUC__ >= 3 && __GNUC_MINOR__ >= 2
   45| namespace std
   46| {
   47| //. A specialization of the char_traits for unsigned char
   48| template<>
   49| struct char_traits<unsigned char>
   50| {
   51|     typedef unsigned char       char_type;
   52|     typedef int                 int_type;
   53|     typedef streampos   pos_type;
   54|     typedef streamoff   off_type;
   55|     typedef mbstate_t   state_type;
   56| 
   57|     static void
   58|     assign(char_type& __c1, const char_type& __c2)
   59|     {
   60|         __c1 = __c2;
   61|     }
   62| 
   63|     static bool
   64|     eq(const char_type& __c1, const char_type& __c2)
   65|     {
   66|         return __c1 == __c2;
   67|     }
   68| 
   69|     static bool
   70|     lt(const char_type& __c1, const char_type& __c2)
   71|     {
   72|         return __c1 < __c2;
   73|     }
   74| 
   75|     static int
   76|     compare(const char_type* __s1, const char_type* __s2, size_t __n)
   77|     {
   78|         return memcmp(__s1__s2__n);
   79|     }
   80| 
   81|     static size_t
   82|     length(const char_type* __s)
   83|     {
   84|         return strlen(reinterpret_cast<const char*>(__s));
   85|     }
   86| 
   87|     static const char_type*
   88|     find(const char_type* __s, size_t __n, const char_type& __a)
   89|     {
   90|         return static_cast<const char_type*>(memchr(__s__a__n));
   91|     }
   92| 
   93|     static char_type*
   94|     move(char_type* __s1, const char_type* __s2, size_t __n)
   95|     {
   96|         return static_cast<char_type*>(memmove(__s1__s2__n));
   97|     }
   98| 
   99|     static char_type*
  100|     copy(char_type* __s1, const char_type* __s2, size_t __n)
  101|     {
  102|         return static_cast<char_type*>(memcpy(__s1__s2__n));
  103|     }
  104| 
  105|     static char_type*
  106|     assign(char_type* __s, size_t __n, char_type __a)
  107|     {
  108|         return static_cast<char_type*>(memset(__s__a__n));
  109|     }
  110| 
  111|     static char_type
  112|     to_char_type(const int_type& __c)
  113|     {
  114|         return static_cast<char_type>(__c);
  115|     }
  116| 
  117|     // To keep both the byte 0xff and the eof symbol 0xffffffff
  118|     // from ending up as 0xffffffff.
  119|     static int_type
  120|     to_int_type(const char_type& __c)
  121|     {
  122|         return static_cast<int_type>(static_cast<unsigned char>(__c));
  123|     }
  124| 
  125|     static bool
  126|     eq_int_type(const int_type& __c1, const int_type& __c2)
  127|     {
  128|         return __c1 == __c2;
  129|     }
  130| 
  131|     static int_type
  132|     eof()
  133|     {
  134|         return static_cast<int_type>(EOF);
  135|     }
  136| 
  137|     static int_type
  138|     not_eof(const int_type& __c)
  139|     {
  140|         return (__c == eof()) ? 0 : __c;
  141|     }
  142| };
  143| };
  144| #endif
  145| 
  146| //. A string type for the encoded names and types
  147| typedef std::basic_string<unsigned charcode;
  148| //. A string iterator type for the encoded names and types
  149| typedef code::iterator code_iter;
  150| 
  151| //. A function to make a code string from a normal string
  152| inline code make_code(const char* c)
  153| {
  154|     if (c == NULL)
  155|         return code();
  156|     return code((const unsigned char*)c);
  157| }
  158| 
  159| //. Insertion operator for encoded names and types
  160| std::ostreamoperator <<(std::ostream& o, const code& s);
  161| 
  162| //. Decoder for OCC encodings. This class can be used to decode the names and
  163| //. types encoded by OCC for function and variable types and names.
  164| class Decoder
  165| {
  166| public:
  167|     //. Constructor
  168|     Decoder(Builder*);
  169| 
  170|     //. Convert a char* to a 'code' type
  171|     static code toCode(char*);
  172| 
  173|     //. Initialise the type decoder
  174|     void init(char*);
  175| 
  176|     //. Returns the iterator used in decoding
  177|     code_iteriter()
  178|     {
  179|         return m_iter;
  180|     }
  181| 
  182|     //. Return a Type object from the encoded type.
  183|     //. @preconditions You must call init() first.
  184|     Types::Type* decodeType();
  185| 
  186|     //. Decodes a Qualified type. iter must be just after the Q
  187|     Types::Type* decodeQualType();
  188| 
  189|     //. Decodes a Template type. iter must be just after the T
  190|     Types::Type* decodeTemplate();
  191| 
  192|     //. Decodes a FuncPtr type. iter must be just after the F. The vector is
  193|     //. the postmod - if it contains a * then it will be removed and given to
  194|     //. the funcptr instead
  195|     Types::Type* decodeFuncPtr(std::vector<std::string>&);
  196| 
  197|     //. Decode a name
  198|     std::string decodeName();
  199| 
  200|     //. Decode a qualified name
  201|     ScopedName decodeQualified();
  202| 
  203|     //. Decode a name starting from the given iterator.
  204|     //. Note the iterator passed need not be from the currently decoding
  205|     //. string since this is a simple method.
  206|     std::string decodeName(code_iter);
  207| 
  208|     //. Decode a name starting from the given char*
  209|     std::string decodeName(char*);
  210| 
  211|     //. Decode a qualified name with only names in it
  212|     void decodeQualName(ScopedName& names);
  213| 
  214|     //. Returns true if the char* is pointing to a name (that starts with a
  215|     //. length). This is needed since char can be signed or unsigned, and
  216|     //. explicitly casting to one or the other is ugly
  217|     bool isName(char* ptr);
  218| 
  219| private:
  220|     //. The encoded type string currently being decoded
  221|     code m_string;
  222|     //. The current position in m_enc_iter
  223|     code_iter m_iter;
  224| 
  225|     //. The builder
  226|     Builder* m_builder;
  227| 
  228|     //. The lookup
  229|     Lookup* m_lookup;
  230| };
  231| 
  232| inline bool Decoder::isName(char* ptr)
  233| {
  234|     code::value_type* iter = reinterpret_cast<code::value_type*>(ptr);
  235|     return iter && iter[0] > 0x80;
  236| }
  237| 
  238| #endif // header guard
  239| // vim: set ts=8 sts=4 sw=4 et: