"Fossies" - the Fresh Open Source Software Archive

Member "yudit-3.0.7/stoolkit/syntax/SSyntaxMarker.cpp" (2 Jun 2020, 8619 Bytes) of package /linux/misc/yudit-3.0.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "SSyntaxMarker.cpp" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 3.0.5_vs_3.0.7.

    1 /** 
    2  *  Yudit Unicode Editor Source File
    3  *
    4  *  GNU Copyright (C) 1997-2006  Gaspar Sinai <gaspar@yudit.org>  
    5  *
    6  *  This program is free software; you can redistribute it and/or modify
    7  *  it under the terms of the GNU General Public License, version 2,
    8  *  dated June 1991. See file COPYYING for details.
    9  *
   10  *  This program is distributed in the hope that it will be useful,
   11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  *  GNU General Public License for more details.
   14  *
   15  *  You should have received a copy of the GNU General Public License
   16  *  along with this program; if not, write to the Free Software
   17  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
   18  */
   19  
   20 #include "stoolkit/syntax/SSyntaxMarker.h"
   21 #include "stoolkit/syntax/SSyntax.h"
   22 
   23 
   24 /**
   25  * The _textData and _lines arrays should be in sync, they
   26  * should have the same sizes.
   27  * @param _around is around which we should mark unmarked in our buffer.
   28  */
   29 SSyntaxMarker::SSyntaxMarker (SSyntaxData& _lines, const SUnicodeData& _ulines, 
   30   const STextIndex& _around) 
   31    : syntaxLines (_lines), dataLines (_ulines)
   32 {
   33   STextIndex first = _around;
   34   // look backwards for a sync
   35   if (decrement(&first)) while ((getSyntaxAt (first) & SGC_BEGIN_MARK) == 0)
   36   {
   37     if (!decrement(&first)) break;
   38   }
   39   // hack, commment this out if you have a proper parser.
   40   // FIXME FIXME
   41   //first = STextIndex (0,0);
   42 //  fprintf (stderr, "SGC syntax started around=%u,%u found=%u,%u\n", 
   43 //     _around.line, _around.index, first.line, first.index); 
   44 
   45   startIndex = first;
   46   unsigned int firstLineSize = getLineSize (startIndex.line) 
   47         - startIndex.index;
   48   // linesizes always contains 1 more lines than real lines.
   49   lineSizes.append (0);
   50   lineSizes.append (firstLineSize);
   51 /*
   52   fprintf (stderr, "firstLineSize=%u getLineSize=%u\n", 
   53      firstLineSize, getLineSize (startIndex.line));
   54 */
   55 
   56   isStarted = true;
   57   actionMap.put ("none", ((int) SSyntax::SD_NONE) << 8);
   58   actionMap.put ("error", ((int) SSyntax::SD_ERROR) << 8);
   59   actionMap.put ("number", ((int) SSyntax::SD_NUMBER) << 8); 
   60   actionMap.put ("string", ((int) SSyntax::SD_STRING) << 8); 
   61   actionMap.put ("comment", ((int) SSyntax::SD_COMMENT) << 8);
   62   actionMap.put ("keyword", ((int) SSyntax::SD_KEYWORD) << 8);
   63   actionMap.put ("variable", ((int) SSyntax::SD_VARIABLE) << 8);
   64   actionMap.put ("define", ((int) SSyntax::SD_DEFINE) << 8);
   65   actionMap.put ("control", ((int) SSyntax::SD_CONTROL) << 8);
   66   actionMap.put ("other", ((int) SSyntax::SD_OTHER) << 8);
   67 } 
   68 
   69 SSyntaxMarker::~SSyntaxMarker ()
   70 {
   71 }
   72 
   73 /* SMatcherIterator */
   74 // FIXME FIXME FIXME 
   75 int
   76 SSyntaxMarker::getNextCharacter ()
   77 {
   78   if (isStarted)
   79   {
   80     currentIndex = startIndex;
   81     isStarted = false;
   82     if (isEOD (currentIndex)) return -1;
   83   }
   84   else
   85   {
   86     if (!increment (&currentIndex)) return -1;
   87   }
   88   // lineSizes keeps track of incremental sizes.
   89   if (currentIndex.line - startIndex.line == lineSizes.size()-1)
   90   {
   91     lineSizes.append (getLineSize (currentIndex.line) 
   92           + lineSizes[currentIndex.line - startIndex.line ]);
   93   }
   94   return getCharAt (currentIndex);
   95 }
   96 
   97 bool
   98 SSyntaxMarker::isEOD (const STextIndex& idx) const
   99 {
  100   if (idx.line >= dataLines.size()) return true;
  101   if (idx.index >= getLineSize(idx.line)) return true;
  102   return false;
  103 }
  104 
  105 void
  106 SSyntaxMarker::beginActionBlock ()
  107 {
  108   minModified = STextIndex (dataLines.size(), 0);
  109   maxModified = STextIndex (0, 0);
  110 }
  111 
  112 
  113 /* SMatcherAction */
  114 // Apply action from from till till exclusive
  115 // 1. Mark shadow syntax
  116 // 2. modify minModified and maxModified
  117 void
  118 SSyntaxMarker::applyAction (const SString& name,
  119     unsigned int markFrom, unsigned int markTill)
  120 {
  121   STextIndex from = position2Index (markFrom);
  122   STextIndex till = position2Index (markTill);
  123 
  124 #if DEBUG_PARSER
  125 fprintf (stderr, "applyAction %*.*s %u..%u  %u.%u..%u,%u\n", 
  126   SSARGS(name), markFrom, markTill, 
  127   from.line, from.index, till.line, till.index);
  128 #endif
  129   if (from < minModified)
  130   {
  131     minModified = from;
  132   }
  133   if (till > maxModified)
  134   {
  135     maxModified = till;
  136   }
  137   int shadow = actionMap.get (name);
  138   while (from < till)
  139   {
  140     int old = getSyntaxAt (from);
  141     shadow = (old & 0xff) | shadow;
  142     // This will wipe out extra marks
  143     setSyntaxAt (from, shadow);
  144     if (!increment (&from)) break;
  145   }
  146 }
  147 
  148 // 1. move shadow syntax to real
  149 // 2. update minModified and maxModified
  150 // 3. update the minLimits and minLimits to know where stuff changed.
  151 void
  152 SSyntaxMarker::endActionBlock ()
  153 {
  154 #if DEBUG_PARSER
  155 fprintf (stderr, "finish %u.%u..%u,%u\n", 
  156   minModified.line, minModified.index,
  157   maxModified.line, maxModified.index);
  158 #endif
  159 
  160   STextIndex min = STextIndex (dataLines.size(), 0);
  161   STextIndex max = STextIndex (0, 0);
  162 
  163   STextIndex from = minModified;
  164   while (from < maxModified)
  165   {
  166     int vle = getSyntaxAt (from);
  167     int o = (vle & 0xff);
  168     int n = (vle & 0xff00) >> 8;
  169     if (o == n)
  170     {
  171       if (!increment (&from)) break;
  172       continue;
  173     }
  174     if (from < min) min = from;
  175     if (from > max) max = from;
  176     setSyntaxAt (from, n);
  177     if (!increment (&from)) break;
  178   }
  179   // multiline, scrolled editor. write yuko in Hungarian kmap
  180   // yuko is not first line. o is not error with test SPattern.
  181   // dont know why...
  182 //  minModified = min;
  183 //  maxModified = max;
  184 }
  185 
  186 // Increment the in index
  187 // return false if in is already at the end
  188 // For non expanded lines we generate virtual new index if 
  189 // it is has a proper ending.
  190 bool
  191 SSyntaxMarker::decrement (STextIndex* in)
  192 {
  193   if (in->line == 0 && in->index==0) return false;
  194   if (in->index == 0)
  195   {
  196     in->line--;
  197     in->index = getLineSize (in->line);
  198     if (in->index==0)
  199     {
  200 #if DEBUG_PARSER
  201       fprintf (stderr, "SSyntaxMarker::decrement: empty line detected.\n");
  202 #endif
  203       return false;
  204     }
  205   }
  206   // There can be no empty lines in the middle of the file 
  207   in->index = in->index-1;
  208   return true;
  209 }
  210 
  211 // Decrement the in index
  212 // return false if in is already at the end
  213 // For non expanded lines we generate virtual new index if 
  214 // it is has a proper ending.
  215 bool
  216 SSyntaxMarker::increment (STextIndex* in)
  217 {
  218   if (in->line >= dataLines.size()) return false;
  219   unsigned int ls = getLineSize (in->line);
  220   if (in->index+1 == ls)
  221   {
  222     in->line++;
  223     in->index=0;
  224     if (in->line >= dataLines.size()) return false;
  225     ls = getLineSize (in->line);
  226     if (ls == 0) return false;
  227     return true;
  228   }
  229   in->index++;
  230   if (in->index >= ls) return false;
  231   return true;
  232 }
  233 
  234 // Get character at the index.
  235 // return -1 if in is out of bounds.
  236 int
  237 SSyntaxMarker::getCharAt (const STextIndex& in) const
  238 {
  239   if (in.line >= dataLines.size()) return -1;
  240   if (in.index >= dataLines[in.line]->size()) return -1;
  241   // todo sanity check here
  242   SS_UCS4 ret = dataLines[in.line]->peek (in.index);
  243   // Paragraph separator
  244 //fprintf (stderr, "%u,%u=[%c]", in.line, in.index, (char) ret);
  245   if (ret == 0x2029) return (int) '\n';
  246   return (int) ret;
  247 }
  248 
  249 // Get character at the index.
  250 // return -1 if in is out of bounds.
  251 int
  252 SSyntaxMarker::getSyntaxAt (const STextIndex& in) const
  253 {
  254   if (in.line >= syntaxLines.size()) return -1;
  255   if (in.index >= syntaxLines[in.line]->size()) return -1;
  256   // todo sanity check here
  257   return syntaxLines[in.line]->peek (in.index);
  258 }
  259 
  260 // Get character at the index.
  261 // return false if in is out of bounds.
  262 bool
  263 SSyntaxMarker::setSyntaxAt (const STextIndex& in, int syn)
  264 {
  265   if (in.line >= syntaxLines.size()) return false;
  266   if (in.index >= syntaxLines[in.line]->size()) return false;
  267   syntaxLines[in.line]->replace (in.index, syn);
  268   return true;
  269 }
  270 
  271 // get the line size, adjusted for non-expanded chanacters.
  272 // an extra functionality is to sync expanded lines, as
  273 // they are not always reported elsewhere.
  274 unsigned int
  275 SSyntaxMarker::getLineSize  (unsigned int lineno) const
  276 {
  277   if (lineno >= dataLines.size()) return 0;
  278   // line is expaned
  279   return dataLines[lineno]->size();
  280 }
  281 
  282 // linsizes[line] contain the accumulated number of characters 
  283 // from startIndex at the end of the line.
  284 STextIndex
  285 SSyntaxMarker::position2Index (unsigned int position)
  286 {
  287   if (position < lineSizes[1])
  288   {
  289     return STextIndex (startIndex.line, startIndex.index + position);
  290   }
  291   // This can return a bigger value
  292   unsigned int mapIndex = lineSizes.findSorted (position);
  293   if (mapIndex>=lineSizes.size()) 
  294   {
  295     return STextIndex (startIndex.line+lineSizes.size()-1, 0);
  296   }
  297   while (position < lineSizes[mapIndex] && mapIndex > 0) mapIndex--;
  298   unsigned int addValue =  lineSizes[mapIndex];
  299   return STextIndex (mapIndex+startIndex.line, position-addValue);
  300 }