home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2233.zip / wxOS2-2_3_3.zip / wxWindows-2.3.3 / utils / HelpGen / src / sourcepainter.cpp < prev    next >
C/C++ Source or Header  |  2001-11-19  |  12KB  |  676 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        No names yet.
  3. // Purpose:     Contrib. demo
  4. // Author:      Aleksandras Gluchovas
  5. // Modified by:
  6. // Created:     22/09/98
  7. // RCS-ID:      $Id: sourcepainter.cpp,v 1.5 2001/11/18 12:25:11 GD Exp $
  8. // Copyright:   (c) Aleskandars Gluchovas
  9. // Licence:       wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. // For compilers that support precompilation, includes "wx/wx.h".
  13. #include "wx/wxprec.h"
  14.  
  15. #ifdef __BORLANDC__
  16. #pragma hdrstop
  17. #endif
  18.  
  19. #ifndef WX_PRECOMP
  20. #include "wx/wx.h"
  21. #endif
  22.  
  23. #if defined( wxUSE_TEMPLATE_STL )
  24. #  include <map>
  25. #else
  26. #  include "wxstlac.h"
  27. #endif
  28.  
  29. #include "sourcepainter.h"
  30.  
  31. const int MAX_KEYWORD_LEN = 16;
  32.  
  33. struct KeywordT
  34. {
  35.     char  keyWord[MAX_KEYWORD_LEN];
  36.     int   rank;
  37. };
  38.  
  39. // source fragment ranks :
  40.  
  41. // 0 - nomral text
  42. // 1 - basic types
  43. // 2 - reserved words
  44.  
  45. // multil-language keywords map
  46.  
  47. static KeywordT __gKeyWords[] =
  48. {
  49.     { "for", 1 },
  50.     { "FOR", 1 },
  51.     { "For", 1 },
  52.     
  53.     { "next", 1 },
  54.     { "Next", 1 },
  55.     { "NEXT", 1 },
  56.  
  57.     { "if", 1 },
  58.     { "If", 1 },
  59.     { "IF", 1 },
  60.  
  61.     { "then", 1 },
  62.     { "Then", 1 },
  63.     { "THEN", 1 },
  64.  
  65.     { "else", 1 },
  66.     { "Else", 1 },
  67.     { "ELSE", 1 },
  68.          
  69.     { "do", 1 },
  70.     { "Do", 1 },
  71.     { "DO", 1 },
  72.  
  73.  
  74.     { "break", 1 },
  75.     { "Break", 1 },
  76.     { "BREAK", 1 },
  77.  
  78.     { "continue", 1 },
  79.  
  80.     { "goto", 1 },
  81.     { "Goto", 1 },
  82.     { "GOTO", 1 },
  83.  
  84.     { "switch",  1 },
  85.     { "default", 1 },
  86.     { "case",    1 },
  87.  
  88.     { "repeat", 1 },
  89.     { "Repeat", 1 },
  90.     { "REPEAT", 1 },
  91.  
  92.     { "until", 1 },
  93.     { "Until", 1 },
  94.     { "UNTIL", 1 },
  95.  
  96.     { "return", 1 },
  97.     { "Return", 1 },
  98.     { "RETURN", 1 },
  99.  
  100.     { "unit",      1 },
  101.     { "Unit",      1 },
  102.     { "UNIT",      1 },
  103.  
  104.     { "procedure", 1 },
  105.     { "Procedure", 1 },
  106.     { "PROCEDURE", 1 },
  107.  
  108.     { "function", 1 },
  109.     { "Function", 1 },
  110.     { "FUNCTION", 1 },
  111.  
  112.     { "begin", 1 },
  113.     { "Begin", 1 },
  114.     { "BEGIN", 1 },
  115.  
  116.     { "End", 1 },
  117.     { "END", 1 },
  118.  
  119.     ////////////////////////////////////////////////////
  120.  
  121.     { "enum",     1 },
  122.     { "static",   1 },
  123.     { "const",    1 },
  124.     { "mutable",  1 },
  125.     { "volatile", 1 },
  126.     { "__asm",    1 },
  127.     { "asm",      1 },
  128.  
  129.     { "typeid",   1 },
  130.     { "sizeof",   1 },
  131.     { "typeof",   1 },
  132.  
  133.  
  134.     { "native",   1 },
  135.  
  136.     { "#include", 1 },
  137.     { "#define",  1 },
  138.     { "#def",     1 },
  139.     { "#undef",   1 },
  140.     { "#ifdef",   1 },
  141.     { "#ifndef",  1 },
  142.     { "#if",      1 },
  143.     { "#endif",   1 },
  144.     { "#elif",    1 },
  145.     { "#else",    1 },
  146.     { "#pragma",  1 },
  147.     { "#line",    1 },
  148.  
  149.     { "package",  1 },
  150.     { "import",   1 },
  151.     { "export",   1 },
  152.  
  153.     ////////////////////////////////////////////////////
  154.  
  155.     { "dynamic_cast",     1 },
  156.     { "const_cast",       1 },
  157.  
  158.     //////// some hacks for VB /////////
  159.  
  160.     { "sub", 1 },
  161.     { "Sub", 1 },
  162.     { "SUB", 1 },
  163.     { "as",  1 },
  164.     { "As",  1 },
  165.     { "AS",  1 },
  166.  
  167.     /////// data types ///////
  168.  
  169.     { "int" ,    1 },
  170.     { "integer", 1 },
  171.     { "Integer", 1 },
  172.     { "INTEGER", 1 },
  173.  
  174.     { "real", 1 },
  175.     { "Real", 1 },
  176.     { "REAL", 1 },
  177.  
  178.     { "float", 1 },
  179.     { "Float", 1 },
  180.     { "FLOAT", 1 },
  181.  
  182.     { "char",  1 },
  183.     { "Char",  1 },
  184.     { "CHAR",  1 },
  185.  
  186.     { "register",   1 },
  187.  
  188.     { "string", 1 },
  189.     { "String", 1 },
  190.     { "STRING", 1 },
  191.  
  192.     { "array", 1 },
  193.     { "Array", 1 },
  194.     { "ARRAY", 1 },
  195.  
  196.     { "packed", 1 },
  197.     { "Packed", 1 },
  198.     { "PACKED", 1 },
  199.  
  200.     { "property", 1 },
  201.     { "Property", 1 },
  202.     { "PROPERTY", 1 },
  203.  
  204.     { "unsigned", 1 },
  205.  
  206.     { "long",   1 },
  207.     { "double", 1 },
  208.     { "short",  1 },
  209.     { "bool",   1 },
  210.  
  211.     { "longint", 1 },
  212.     { "Longint", 1 },
  213.     { "LONGINT", 1 },
  214.  
  215.     { "extended", 1 },
  216.     { "Extended", 1 },
  217.     { "EXTENTED", 1 },
  218.  
  219.     { "pointer", 1 },
  220.     { "Pointer", 1 },
  221.     { "POINTER", 1 },
  222.  
  223.     { "and",     1 },
  224.     { "And",     1 },
  225.     { "AND",     1 },
  226.     { "or",      1 },
  227.     { "Or",      1 },
  228.     { "OR",      1 },
  229.     { "xor",     1 },
  230.     { "Xor",     1 },
  231.     { "XOR",     1 },
  232.  
  233.     { "void",       1 },
  234.     { "__stdcall",  1 },
  235.     { "__declspec",    1 },
  236.     { "extern",     1 },
  237.     { "stdcall",    1 },
  238.     { "dllimport",  1 },
  239.     { "dllexport",  1 },
  240.     { "__cdecl",    1 },
  241.     { "cdecl",      1 },
  242.     { "template",   1 },
  243.     { "typedef",    1 },
  244.     { "naked",      1 },
  245.  
  246.     { "try",        1 },
  247.     { "catch",      1 },
  248.     { "throw",      2 }, // C++
  249.     { "throws",     1 }, // Java
  250.  
  251.  
  252.     { "finalize",   1 },
  253.  
  254.     // "STL-suport"
  255.  
  256.     { "size_t",     1 },
  257.     { "NPOS",       1 },
  258.     { "vector",     1 },
  259.     { "list",       1 },
  260.     { "map",        1 },
  261.     { "multimap",   1 },
  262.  
  263.     { "external", 1 },
  264.     { "External", 1 },
  265.     { "EXTERNAL", 1 },
  266.  
  267.     //////////// meta-information //////////////
  268.  
  269.     { "virtual", 2 },
  270.     { "Virtual", 2 },
  271.  
  272.     { "override", 2 },
  273.     { "Override", 2 },
  274.  
  275.     { "class", 2 },
  276.     { "Class", 2 },
  277.     { "CLASS", 2 },
  278.  
  279.     { "struct", 2 }, 
  280.     { "union",  2 },
  281.  
  282.     { "record", 2 },
  283.     { "Record", 2 },
  284.     { "RECORD", 2 },
  285.  
  286.     { "form",     1 },
  287.     { "Form",     1 },
  288.     { "FORM",     1 },
  289.  
  290.     { "namespace", 2 },
  291.  
  292.     { "interface" , 2 },
  293.     { "abstract",   2 },
  294.  
  295.     { "Interface" , 2 },
  296.     { "INTERFACE" , 2 },
  297.  
  298.     { "implementation", 2 },
  299.     { "Implementation", 2 },
  300.     { "IMPLEMENTATION", 2 },
  301.  
  302.     { "label", 2 },
  303.     { "Label", 2 },
  304.     { "LABEL", 2 },
  305.  
  306.     { "implements", 2 },
  307.  
  308.     { "public",    2 },
  309.     { "private",   2 },
  310.     { "protected", 2 },
  311.  
  312.     { "this", 2 },
  313.     { "This", 2 },
  314.     { "THIS", 2 },
  315.  
  316.     { "new", 2 },
  317.     { "New", 2 },
  318.     { "NEW", 2 },
  319.     
  320.     { "delete", 2 },
  321.     { "inline", 2 },
  322.  
  323.     { "operator",  2 },
  324.  
  325.     { "Inherited", 2 },
  326.     { "Inherited", 2 },
  327.     
  328.     { "final", 2 },
  329.     { "implements", 2 },
  330.     { "super", 2 },
  331.  
  332.     // even more...
  333.     { "java",      2 },
  334.     { "Java",      2 },
  335.     { "JAVA",      2 },
  336.     { "delphi",    2 },
  337.     { "Delphi",    2 },
  338.     { "SmallTalk", 2 },
  339.     { "Smalltalk", 2 },
  340.     { "smalltalk", 2 },
  341.     { "assembler", 2 },
  342.     { "Assembler", 2 },
  343.     { "Basic",     2 },
  344.     { "BASIC",     2 },
  345.     { "basic",     2 },
  346.     { "CORBA",     2 },
  347.     { "COBOL",     2 },
  348.     { "ADA",       2 },
  349.     { "LISP",      2 },
  350.     
  351.     // just for fun...
  352.     { "life",        2 },
  353.     { "sucks",       2 },
  354.     { "rules",       2 },
  355.     { "Quake",       2 },
  356.     { "QuakeWorld",  2 },
  357.     { "[ag_slammer]",2 },
  358.     { "Aleksandras", 2 },
  359.     { "Gluchovas"  , 2 },
  360.     { "Alex",        2 },
  361.     { "alex",        2 },
  362.     { "aleks",       2 },
  363.     { "aleksas",     3 },
  364.     { "AlexSoft",    2 },
  365.     { "Alexsoft",    2 },
  366.     { "SpringSky",   2 },
  367.     { "SK_Team",     2 },
  368.     { "soften",      2 },
  369.     { "UB40",        2 },
  370.     { "U96",         2 }
  371. };
  372.  
  373. struct less_c_str 
  374. {
  375.     inline bool operator()( char* x, char* y) const 
  376.     {     return ( strcmp( x,y ) < 0 );
  377.     }
  378. };
  379.  
  380. #if defined( wxUSE_TEMPLATE_STL )
  381.  
  382.     typedef map< char*, char*, less_c_str > KeywordMapT;
  383.  
  384. #else
  385.  
  386.     typedef char* CharPtrT;
  387.     typedef WXSTL_MAP( CharPtrT, CharPtrT ,less_c_str) KeywordMapT;
  388.  
  389. #endif
  390.  
  391. static KeywordMapT __gMultiLangMap;
  392. static int         __gMapReady = 0;
  393.  
  394. void check_keyword_map( int keywordMapNr )
  395. {
  396.     if ( !__gMapReady )
  397.     {
  398.         __gMapReady = 1;
  399.  
  400.         // "make sure" the address of the first member of non-polimorphic class
  401.         // coinsides with the address of the instance
  402.  
  403. /*
  404.         KeywordT dummy;
  405.  
  406.         if ( (char*)& dummy != &dummy.keyWord[0] )
  407.             throw;
  408. */
  409.  
  410.         int size = sizeof(__gKeyWords) / sizeof( KeywordT );
  411.  
  412.         for( int i = 0; i != size; ++i )
  413.  
  414.             __gMultiLangMap.insert( 
  415.                     KeywordMapT::value_type( (char*)&__gKeyWords[i],
  416.                                              (char*)&__gKeyWords[i]
  417.                                            )
  418.                                   );    
  419.     }
  420. }
  421.  
  422. int get_rank( char* start, char* end )
  423. {
  424.     // FIXME:: what if end is no longer leagal adress?
  425.  
  426.     char tmp = *end;
  427.     *end = '\0'; // put temporary terminator
  428.  
  429.     KeywordMapT::iterator i; 
  430.  
  431.     if (  (i = __gMultiLangMap.find( start ) ) != __gMultiLangMap.end() )
  432.     {
  433.         KeywordT* pKey = (KeywordT*)(*i).second;
  434.  
  435.         *end = tmp;
  436.  
  437.         return pKey->rank;
  438.     }
  439.     else
  440.     {
  441.         *end = tmp;
  442.         return 0;
  443.     }
  444. }
  445.  
  446. static inline void store_range( SPBlockListT& results, int rank, int range_len )
  447. {
  448.     if ( !range_len ) return;
  449.  
  450.     results.push_back ( ( rank << 16 ) | ( range_len ) );
  451. }
  452.  
  453.  
  454. #define STORE_RANGE  store_range( results, cur_rank, cur_range_len );\
  455.                      cur_rank = cur_range_len = 0;
  456.  
  457. #define NEXT_CHAR cur_range_len++; \
  458.                   ++cur;           \
  459.                   continue;
  460.  
  461. static inline int is_alpha( char ch )
  462. {
  463.     return ( (( ch >= '_' ) && ( ch <= 'z' )) ||
  464.              (( ch >= 'A' ) && ( ch <= 'Z' ))
  465.            );
  466. }
  467.  
  468.   // _       .          .
  469.   // Ziema atEjo netikEtai
  470.  
  471. static void heighlight_syntax( char* str,   int strLen, 
  472.                                SPBlockListT& results, bool& isComment )
  473. {
  474.     bool isMultiline = 0;
  475.     char* cur = str;
  476.     char* end = str + strLen;
  477.  
  478.     int cur_rank      = ( isComment == 1 ) ? RANK_GREEN : RANK_BLACK;
  479.     int cur_range_len = 0;
  480.  
  481.     while (    cur != end )
  482.     {
  483.         int has_next = ( cur+1 != end );
  484.  
  485.         if ( isComment )
  486.         {
  487.             if ( *cur == '*' )
  488.                 if ( has_next && *(cur+1) == '/' )
  489.                 {
  490.                      // turn off multiline comment mode
  491.                      cur           += 2;
  492.                      cur_range_len += 2;
  493.                      isComment      = 0;
  494.                      isMultiline    = 0;
  495.                      STORE_RANGE;
  496.  
  497.                      continue;
  498.                 }
  499.  
  500.             ++cur_range_len;
  501.             ++cur;
  502.             continue;
  503.         }
  504.  
  505.         /*
  506.         if ( *cur == 10 )
  507.             if ( isComment )
  508.                if ( isMultiline )
  509.         {
  510.              cur_rank      = RANK_GREEN;
  511.              cur_range_len = end - cur;
  512.              STORE_RANGE;
  513.              isComment = 0;
  514.              isMultiline = 0;
  515.              continue;
  516.         }*/
  517.  
  518.         if ( *cur == '/' )
  519.         {
  520.             if ( has_next )
  521.             {
  522.                  if ( *(cur+1) == '/' )
  523.                  {
  524.                      STORE_RANGE;
  525.  
  526.                      char* eol = cur;
  527.                      while ( eol < end && *eol != 10 )
  528.                          ++eol;
  529.  
  530.                      cur_rank      = RANK_GREEN;
  531.                      cur_range_len = eol - cur;
  532.                      cur = eol;
  533.                      STORE_RANGE;
  534.  
  535.                       continue;
  536.                  }
  537.  
  538.                  if ( *(cur+1) == '*' )
  539.                  {
  540.                      STORE_RANGE;
  541.                      cur_rank      = RANK_GREEN;
  542.                      cur_range_len = 2;
  543.                      isComment     = 1;
  544.                      cur          += 2;
  545.                      isMultiline   = 1;
  546.                      continue;
  547.                  }
  548.             }
  549.             
  550.             NEXT_CHAR;
  551.         }
  552.  
  553.         if (  ( is_alpha( *cur ) || *(cur) == '#' ) 
  554.               && has_next 
  555.            )
  556.         {
  557.             if ( is_alpha( *(cur+1) ) )
  558.             {
  559.                 char* start = cur;
  560.                 cur += 2;
  561.  
  562.                 while ( cur != end && is_alpha(*cur) ) ++cur;
  563.  
  564.                 int wordRank;
  565.                 
  566.                 if ( (wordRank = get_rank( start, cur )) > 0 )
  567.                 {
  568.                     STORE_RANGE;
  569.  
  570.                     store_range( results, wordRank, int(cur-start) );
  571.                     cur_rank = cur_range_len = 0;
  572.                     continue;
  573.                 }
  574.  
  575.                 cur_range_len += ( cur-start );
  576.                 continue;
  577.             }
  578.             else
  579.                 NEXT_CHAR;
  580.         }
  581.  
  582.         NEXT_CHAR;
  583.     }
  584.  
  585.     if ( cur_range_len > 0 )  STORE_RANGE;
  586. }
  587.  
  588. /***** Implementation for class SourcePainter ******/
  589.  
  590. SourcePainter::SourcePainter( bool assembleResultString )
  591.     : mCollectResultsOn( assembleResultString ),
  592.       mIsInComment( FALSE ),
  593.       mCommentIsMultiline( FALSE )
  594. {
  595.     check_keyword_map(0);
  596. }
  597.  
  598. void SourcePainter::ProcessSource( char* src, int srcLen )
  599. {
  600.     // TBD:: multilne state...
  601.  
  602.     heighlight_syntax( src, srcLen, mBlocks, mIsInComment );
  603.  
  604.     if ( mCollectResultsOn )
  605.     
  606.         mResultStr += string( src, srcLen );
  607. }
  608.  
  609. void SourcePainter::SetState( bool isInComment,
  610.                               bool commentIsMultiline )
  611. {
  612.     mIsInComment        = isInComment;
  613.     mCommentIsMultiline = commentIsMultiline;
  614. }
  615.  
  616. void SourcePainter::Init(bool assembleResultString)
  617. {
  618.     mIsInComment        = 0;
  619.     mCommentIsMultiline = 0;
  620.     mCollectResultsOn   = assembleResultString;
  621.  
  622.     mResultStr = "";
  623.  
  624.     mBlocks.erase( mBlocks.begin(), mBlocks.end() );
  625. }
  626.  
  627. static int rank_tags_map[] = 
  628.     TAG_BLACK_FONT, 
  629.     TAG_BLUE_FONT,
  630.     TAG_RED_FONT,
  631.     TAG_GREEN_FONT
  632. };
  633.  
  634. void SourcePainter::GetResultString(string& result, MarkupTagsT tags)
  635. {
  636.     // this method works, only if results of processing 
  637.     // are collected
  638.     // ASSERT( mCollectResultsOn ); 
  639.     result = "";
  640.  
  641.     int pos = 0;
  642.  
  643.     for( size_t i = 0; i != mBlocks.size(); ++i )
  644.     {
  645.         int desc = mBlocks[i];
  646.  
  647.         int len  = desc & 0xFFFF;
  648.         int rank = (desc >> 16) & 0xFFFF;
  649.  
  650.         result += tags[ rank_tags_map[rank] ].start;
  651.  
  652.         for( int n = 0; n != len; ++n )
  653.         
  654.             result += mResultStr[pos+n];
  655.  
  656.         pos += len;
  657.  
  658.         result += tags[ rank_tags_map[rank] ].end;
  659.     }
  660. }
  661.  
  662. SPBlockListT& SourcePainter::GetBlocks()
  663. {
  664.     return mBlocks;
  665. }
  666.  
  667. bool SourcePainter::IsKeyword( char* word, int wordLen )
  668. {
  669.     check_keyword_map(0);
  670.  
  671.     int rank = get_rank( word, word + wordLen );
  672.  
  673.     return (  rank == RANK_BLUE || rank == RANK_RED );
  674. }
  675.