summaryrefslogtreecommitdiff
path: root/setedit/mainsrc/editorfo.cc
diff options
context:
space:
mode:
Diffstat (limited to 'setedit/mainsrc/editorfo.cc')
-rw-r--r--setedit/mainsrc/editorfo.cc3944
1 files changed, 3944 insertions, 0 deletions
diff --git a/setedit/mainsrc/editorfo.cc b/setedit/mainsrc/editorfo.cc
new file mode 100644
index 0000000..30337a1
--- /dev/null
+++ b/setedit/mainsrc/editorfo.cc
@@ -0,0 +1,3944 @@
+/* Copyright (C) 1996-2005 by Salvador E. Tropea (SET),
+ see copyrigh file for details */
+/******************************************************************************
+
+ This file is part of the TCEditor class by SET.
+
+ Made:
+
+ Added the table for comments and preprocessor.
+ Search enhanced by my own fast engine 2.75 to 25 times faster depending on
+ the case.
+ Better floats highlight.
+ Eliminated the in_string, in_char, in_cpp_comment and in_prep test.
+ is_symbol uses a look up table.
+ Eliminated the temporal copy of name (faster and safter).
+ Modified the SetChar for a (char *)DrawBuffer[bufptr*2]=c much better
+ option.
+
+26/9
+ Patch from Robert for:
+ 1) Kill a bug with the garbage at the end of a line, a test for <=0 was
+ added.
+ 2) Get the colors instead of use fixed values, that's includes the assign
+ for EDITOR.
+
+28/9
+ Added Pascal highlight, is very green by now.
+ Added Clipper highlight, is even more green.
+
+30/9
+ Applied the second patch of Robert to support strings crossing lines.
+
+17/10
+ Added a new method to avoid unused warnings (by Robert).
+ Corrected to support reserved words with '_'
+
+28/10
+ Corrected some stuff about the number of bytes filled in the drawbuffer.
+
+******************************************************************************/
+
+// That's the first include because is used to configure the editor.
+#include "ceditint.h"
+#include <stdio.h>
+#define Uses_string
+#define Uses_AllocLocal
+#define Uses_TCEditor
+#define Uses_TCEditor_Internal
+#define Uses_ctype
+#define Uses_TVCodePage
+#include <ceditor.h>
+
+#define Uses_SOStack
+#define Uses_TSOSStringCollection
+#include <settvuti.h>
+
+inline
+static int in_range(uint32 start,uint32 end,uint32 pos)
+{
+ //if (start >= end) return 0;
+ if (pos >= start && pos < end) return 1;
+ return 0;
+}
+
+void SyntaxFormatLine(TCEditor * editor,char *DrawBuf,uint32 LinePtr,int Width,
+ uint32 Attr,unsigned lineLength,int seeTabs);
+void SyntaxFormatLinePascal(TCEditor * editor,char *DrawBuf,uint32 LinePtr,int Width,
+ int check_comment_1,int check_comment_2,unsigned lineLength,
+ int seeTabs);
+void SyntaxFormatLineClipper(TCEditor * editor,char *DrawBuf,uint32 LinePtr,int Width,
+ int check_c_comment, unsigned,int seeTabs);
+void SyntaxFormatLineGeneric(TCEditor * editor,char *DrawBuf,uint32 LinePtr,
+ int Width, uint32 Attr, unsigned lineLength,
+ int seeTabs);
+
+#define CALL(a) if (!call10(buffer,(char *)DrawBuf,color,count,offset,LinePtr,Width,tabSize,SeeTabs,a)) goto paint
+//#define CALL2 if (!call10(buffer,(char *)DrawBuf,color,count,offset,LinePtr,Width,tabSize,SeeTabs)) goto paint
+#define CALL3 call30(buffer,(char *)DrawBuf,bufLen,LinePtr,Width,tabSize,color,normalColor,SeeTabs,TabChar)
+#define CALL4 call20(buffer,(char *)DrawBuf,bufLen,LinePtr,Width,tabSize,color)
+
+static unsigned fl_bufptr;
+// Colored tabs stuff
+// Globals because they must be shared between functions
+static char tabColor;
+static int tabFF;
+
+static char *BUFFER;
+static TCEditor *EDITOR;
+static uint32 lineptr;
+
+/*
+by Robert:
+
+ Enable the following code if you know, what it does.
+
+1. It caches the color attributes for the editor and brings
+ a big speedup especially for the syntax highlight, because
+ TView::getColor is slow and called very often.
+
+2. The cached colors are valid only, if the final application
+ does not change the colors. If it changes the colors, the
+ application should set 'colors_cached' to zero.
+ One possiblity for this is to use that global variable. An
+ other thing would be to change the handleEvent method of the
+ editor to handle to an colors_changed broadcast or something
+ like that.
+
+3. Enabling the cache brings a speedup of about 15%
+ without caching: about 87 lines/second
+ with caching: about 100 lines/second
+*/
+
+uchar TCEditor::cachedColors[cNumColors];
+
+void TCEditor::CacheColors()
+{
+ int i;
+ for (i=1; i<cNumColors; i++)
+ cachedColors[i]=getColor(i);
+}
+
+/**[txh]********************************************************************
+
+ Description:
+ Fills the colors cache with correlative numbers. This can be used to get
+SHL id values instead of colors so you can analyze according to the data
+type instead of the color.
+
+***************************************************************************/
+
+void TCEditor::ColorsCacheToIDs()
+{
+ int i;
+ for (i=1; i<cNumColors; i++)
+ cachedColors[i]=i;
+}
+
+#define GetColor(a) TCEditor::cachedColors[a]
+
+#define NormalColor GetColor(cNormal)
+#define CommentColor GetColor(cComment)
+#define PreproColor GetColor(cPre)
+#define StringColor GetColor(cString)
+#define CharColor GetColor(cChar)
+#define IlegalColor GetColor(cIllegal)
+#define ResColor GetColor(cReserved)
+#define IdentColor GetColor(cIdent)
+#define UserColor GetColor(cUser)
+#define OctalColor GetColor(cOctal)
+#define IntColor GetColor(cInteger)
+#define FloatColor GetColor(cFloat)
+#define SymbolColor GetColor(cSymbol)
+#define Symbol2Color GetColor(cSymbol2)
+#define HexColor GetColor(cHex)
+#define OddTabColor GetColor(cOddTab)
+#define EvenTabColor GetColor(cEvenTab)
+#define ColMarkColor GetColor(cColMark)
+
+inline
+static void ToggleTabColor()
+{
+ tabFF=~tabFF;
+ tabColor=tabFF ? EvenTabColor : OddTabColor;
+}
+
+#define fill_line(flag)\
+{\
+ int count = Width-offset;\
+ if (count<=0) return flag;\
+ offset+=count;\
+ while (count--)\
+ {\
+ drawBuf[fl_bufptr] = ' ';\
+ drawBuf[fl_bufptr+1] = color; \
+ fl_bufptr+=2;\
+ }\
+ return flag;\
+}
+
+#define SETCHAR(c)\
+ {\
+ drawBuf[fl_bufptr]=c;\
+ drawBuf[fl_bufptr+1]=color;\
+ fl_bufptr+=2;\
+ offset++;\
+ }
+
+#define SETCHARTAB(c)\
+ {\
+ drawBuf[fl_bufptr]=c;\
+ drawBuf[fl_bufptr+1]=tabColor;\
+ fl_bufptr+=2;\
+ offset++;\
+ }
+
+
+static Boolean call10(char *buffer,char *drawBuf,char color,int cx,
+ unsigned &offset, unsigned &lineptr,unsigned Width,
+ unsigned tabSize,int seeTabs,char tabChar)
+{
+ uchar c;
+ long count = (long)cx - (long)lineptr;
+ if (count<=0)
+ return True;
+
+ // Colored tabs stuff
+ /*tabFF=0; No here!
+ tabColor=OddTabColor;*/
+
+ do {
+ c = buffer[lineptr++];
+ if ( !c || c == '\n' || c == '\r' || c == '\t')
+ {
+ if (c=='\t')
+ {
+ if (seeTabs)
+ {
+ do
+ {
+ SETCHARTAB(tabChar);
+ }
+ while ((offset % tabSize)!=0);
+ ToggleTabColor();
+ }
+ else
+ {
+ do
+ {
+ SETCHAR(' ');
+ } while ((offset % tabSize)!=0);
+ }
+ }
+ else
+ {
+ fill_line(False);
+ }
+ }
+ else SETCHAR(c);
+ if (offset >= Width)
+ {
+ return False;
+ }
+ count--;
+ } while (count>0);
+ return True;
+}
+
+static unsigned call20(char *buffer,char *drawBuf,int bytesAvail, unsigned lineptr,
+ unsigned Width,unsigned tabSize,char color)
+{
+ uchar c;
+ int count = bytesAvail - (int)lineptr;
+
+ if (count<=0) return 0;
+ unsigned offset=0;
+ buffer+=lineptr;
+
+ do
+ {
+ c = *buffer;
+ buffer++;
+ if (c=='\r' || !c || c=='\n') // !c is for the lines under edition where 0 is the end
+ {
+ int count = Width-offset;
+ if (count<=0) return offset;
+ while (count--)
+ {
+ *drawBuf=' ';
+ *(drawBuf+1)=color;
+ drawBuf+=2;
+ }
+ return Width;
+ }
+ if (c=='\t')
+ {
+ int tabCount=tabSize-(offset % tabSize);
+ while (tabCount--)
+ {
+ *drawBuf=' ';
+ drawBuf+=2;
+ offset++;
+ }
+ }
+ else
+ {
+ *drawBuf=c;
+ drawBuf+=2;
+ offset++;
+ }
+ if (offset >= Width)
+ return offset;
+ count--;
+ }
+ while (count>0);
+ return offset;
+}
+
+static unsigned call30(char *buffer,char *drawBuf,int bytesAvail, unsigned lineptr,
+ unsigned Width,unsigned tabSize,char color,char normalCol,
+ int seeTabs, char tabChar)
+{
+ uchar c;
+ int count = bytesAvail - (int)lineptr;
+
+ // Colored tabs stuff
+ tabFF=0;
+ tabColor=OddTabColor;
+
+ if (count<=0) return 0;
+ unsigned offset=0;
+ buffer+=lineptr;
+
+ do
+ {
+ c = *buffer;
+ buffer++;
+ if (c=='\r' || !c || c=='\n') // !c is for the lines under edition where 0 is the end
+ {
+ int count = Width-offset;
+ if (count<=0) return offset;
+ while (count--)
+ {
+ *drawBuf=' ';
+ *(drawBuf+1)=normalCol;
+ drawBuf+=2;
+ }
+ return Width;
+ }
+ if (c=='\t')
+ {
+ int tabCount=tabSize-(offset % tabSize);
+ if (seeTabs)
+ { // It paints the tabs to be visible
+ while (tabCount--)
+ {
+ *drawBuf=' ';
+ *(drawBuf+1)=tabColor;
+ drawBuf+=2;
+ offset++;
+ }
+ ToggleTabColor();
+ }
+ else
+ {
+ while (tabCount--)
+ {
+ *drawBuf=' ';
+ *(drawBuf+1)=color;
+ drawBuf+=2;
+ offset++;
+ }
+ }
+ }
+ else
+ {
+ *drawBuf=c;
+ *(drawBuf+1)=color;
+ drawBuf+=2;
+ offset++;
+ }
+ if (offset >= Width)
+ return offset;
+ count--;
+ }
+ while (count>0);
+ return offset;
+}
+
+static
+void PaintMarkers(char *db, char Color, unsigned Width, uint32 *colMarkers)
+{
+ int marker=0;
+ unsigned nextCol=colMarkers[marker]-1;
+ char color=Color & 0xF0; // Only the background
+
+ while (nextCol<Width)
+ {
+ db[nextCol*2+1]=(db[nextCol*2+1] & 0xF) | color;
+ nextCol=colMarkers[++marker]-1;
+ }
+}
+
+#define normalColor (Colors & 0xff)
+#define selectColor (Colors >> 8)
+
+/* Old function
+void TCEditor::formatLine( void *DrawBuf,
+ unsigned LinePtr,
+ int Width,
+ unsigned short Colors
+ )
+{
+ unsigned count,offset;
+ char color;
+ fl_bufptr = 0;
+ offset = 0;
+
+
+ if (selHided)
+ {
+ color = normalColor;
+ count = bufLen;
+ CALL;
+ }
+
+ if (selStart > LinePtr)
+ {
+ color = normalColor;
+ count = selStart;
+ CALL;
+ }
+ color = selectColor;
+ count = selEnd;
+ CALL;
+
+ color = normalColor;
+ count = bufLen;
+ CALL;
+ count = Width-offset;
+ //if (count<=offset) return;
+ //while (count--) ((ushort far *)(DrawBuf))[bufptr++] = (color << 8) | ' ';
+ while (count--)
+ {
+ ((char *)(DrawBuf))[fl_bufptr]=' ';
+ ((char *)(DrawBuf))[fl_bufptr+1]=color;
+ fl_bufptr+=2;
+ }
+}
+*/
+
+void TCEditor::formatLine(void *DrawBuf, unsigned LinePtr, int Width, ushort Colors,
+ unsigned , // lineLen
+ uint32 , // shl attributes
+ unsigned , // LineNo needed for RHIDE
+ uint32 *colMarkers)
+{
+ unsigned offset;
+ int count; // must be signed
+ char color;
+ fl_bufptr = 0;
+ offset = 0;
+
+ // Colored tabs stuff
+ tabFF=0;
+ tabColor=OddTabColor;
+
+ if (selHided)
+ {
+ color = normalColor;
+ count = bufLen;
+ CALL(' ');
+ }
+ if (selStart > LinePtr)
+ {
+ color = normalColor;
+ count = selStart>bufLen ? bufLen : selStart;
+ CALL(' ');
+ }
+ color = selectColor;
+ count = selEnd;
+ CALL(TabChar);
+
+ color = normalColor;
+ count = bufLen;
+ CALL(' ');
+
+ count = Width-offset;
+ // Bug corrected by Robert:
+ if (count<=0) return; // This is the fix for the bug with the garbage at
+ // the end of the line
+ while (count--)
+ {
+ ((char *)(DrawBuf))[fl_bufptr]=' ';
+ ((char *)(DrawBuf))[fl_bufptr+1]=color;
+ fl_bufptr+=2;
+ }
+
+paint:
+ // Column markers over the selection
+ if (colMarkers)
+ PaintMarkers((char *)DrawBuf,ColMarkColor,Width,colMarkers);
+}
+
+static void PaintPreproNoSel(unsigned offset,char *db,char *buffer,unsigned lineLen,
+ unsigned VisibleWidth,int tabSize,int extCom,
+ int seeTabs, char tabChar)
+{
+ char col=PreproColor,c;
+ int in_com,in_cpp_com,x=0;
+
+ // Colored tabs stuff
+ tabFF=0;
+ tabColor=OddTabColor;
+
+ in_com=extCom;
+ if (in_com)
+ col=CommentColor;
+ in_cpp_com=0;
+ VisibleWidth<<=1;
+ // adjust lineLen relative to offset
+ lineLen += offset;
+ do
+ {
+ c=buffer[offset++];
+ x++;
+ if (CLY_IsEOL(c)) break;
+ if (in_com)
+ {
+ if (c=='*' && buffer[offset]=='/')
+ {
+ db[fl_bufptr++]=c;
+ db[fl_bufptr++]=col;
+ c=buffer[offset++];
+ x++;
+ db[fl_bufptr++]=c;
+ db[fl_bufptr++]=col;
+ in_com=0;
+ col=PreproColor;
+ continue;
+ }
+ }
+ else
+ {
+ if (!in_cpp_com)
+ {
+ if (c=='/')
+ {
+ if (buffer[offset]=='/')
+ {
+ in_cpp_com=1;
+ in_com=0;
+ col=CommentColor;
+ }
+ else
+ if (buffer[offset]=='*')
+ {
+ in_com=1;
+ col=CommentColor;
+ db[fl_bufptr++]=c;
+ db[fl_bufptr++]=col;
+ c=buffer[offset++];
+ x++;
+ }
+ }
+ }
+ }
+ if (c=='\t')
+ {
+ x--;
+ if (seeTabs)
+ { // It paints the tabs to be visible
+ do
+ {
+ db[fl_bufptr++]=' ';
+ db[fl_bufptr++]=tabColor;
+ x++;
+ }
+ while ((x%tabSize)!=0);
+ ToggleTabColor();
+ }
+ else
+ {
+ do
+ {
+ db[fl_bufptr++]=' ';
+ db[fl_bufptr++]=col;
+ x++;
+ }
+ while ((x%tabSize)!=0);
+ }
+ }
+ else
+ {
+ db[fl_bufptr++]=c;
+ db[fl_bufptr++]=col;
+ }
+ }
+ while (offset<lineLen && fl_bufptr<VisibleWidth);
+}
+
+
+static void PaintSelection(unsigned selStart,unsigned selEnd,unsigned lineStart,
+ char *db,char oldColor,unsigned lineLen,char *buffer,
+ unsigned tabSize,unsigned Width,Boolean TransparentSel,
+ int seeTabs, char tabChar)
+{
+ unsigned offset;
+ int count;
+ char color;
+
+ char *s=buffer+lineStart; // Is a pointer to the char in the buffer
+ char *ori=s;
+ offset=0; // Is the X coordinate
+
+ // Colored tabs stuff
+ tabFF=0;
+ tabColor=OddTabColor;
+
+ // Move s and offset to the start of the selection, calculate the length of
+ // the selected area.
+ count=selStart-lineStart;
+ if (count>0)
+ { // The start is inside the line
+ while (count--)
+ {
+ AdvanceWithTab(*s,offset);
+ ToggleTabColor();
+ s++;
+ }
+ count=selEnd-selStart;
+ }
+ else
+ count=selEnd-lineStart;
+
+ // Prepare the colors
+ color = oldColor & 0xF0; // Only the background
+ char colFor = ((unsigned char)color) >> 4;
+
+ // Prepare a pointer in the buffer
+ char *db2=db+((offset<<1)+1);
+
+ // Adjust count
+ int PaintAll;
+ unsigned skiped=s-ori;
+ if ((unsigned)count+skiped>lineLen)
+ { // If the selection ends outside the line
+ count=lineLen-skiped;
+ PaintAll=1;
+ }
+ else
+ PaintAll=0;
+
+ if (TransparentSel)
+ {
+ // Paint the line in the transparent fashion
+ while (count-- && offset<Width)
+ {
+ if (*s=='\t')
+ {
+ int tabcount = tabSize-(offset % tabSize);
+ if (seeTabs)
+ { // It paints the tabs to be visible
+ while (tabcount--)
+ {
+ db2[0]=tabColor;
+ db2[-1]=tabChar;
+ db2+=2;
+ offset++;
+ }
+ ToggleTabColor();
+ }
+ else
+ {
+ while (tabcount--)
+ {
+ *db2=oldColor;
+ db2+=2;
+ offset++;
+ }
+ }
+ }
+ else
+ {
+ char colOri=(*db2 & 0x0F);
+ if (colOri==colFor)
+ *db2=((colOri+1) & 0x0F) | color; // Ops!, the same color!
+ else
+ *db2=colOri | color;
+ db2+=2;
+ offset++;
+ }
+ s++;
+ }
+ }
+ else
+ {
+ // Paint the line normally
+ while (count-- && offset<Width)
+ {
+ if (*s=='\t')
+ {
+ int tabcount = tabSize-(offset % tabSize);
+ if (seeTabs)
+ { // It paints the tabs to be visible
+ while (tabcount--)
+ {
+ db2[0]=tabColor;
+ db2[-1]=tabChar;
+ db2+=2;
+ offset++;
+ }
+ ToggleTabColor();
+ }
+ else
+ {
+ while (tabcount--)
+ {
+ *db2=oldColor;
+ db2+=2;
+ offset++;
+ }
+ }
+ }
+ else
+ {
+ *db2=oldColor;
+ db2+=2;
+ offset++;
+ }
+ s++;
+ }
+ }
+
+ // Paint outside it, if needed.
+ if (PaintAll)
+ while (offset<(unsigned)Width)
+ {
+ *db2=oldColor;
+ db2+=2;
+ offset++;
+ }
+}
+
+#define FillRestOfLine() \
+ { \
+ count = Width-offset; \
+ if (count>0) \
+ { \
+ while (count--) \
+ { \
+ ((char *)(DrawBuf))[fl_bufptr]=' '; \
+ ((char *)(DrawBuf))[fl_bufptr+1]=color; \
+ fl_bufptr+=2; \
+ } \
+ } \
+ }
+
+void TCEditor::formatLineHighLight(void *DrawBuf, unsigned LinePtr, int Width,
+ ushort Colors, unsigned lineLen, uint32 Attr, unsigned , uint32 *colMarkers)
+{
+ unsigned offset;
+ int count;
+ char color;
+ unsigned lineStart=LinePtr;
+ char *db=(char *)DrawBuf;
+ EDITOR = this; // for the two functions above
+ fl_bufptr = 0;
+ offset = 0;
+
+ if (!lineLen)
+ { // If empty just fill it with spaces
+ color = normalColor;
+ }
+ else
+ if (Attr & InsideCom)
+ { // All comented
+ color = CommentColor;
+ offset= CALL3;
+ fl_bufptr=offset<<1;
+ }
+ else
+ if ((Attr & PartialCom) && (Attr & Prepro))
+ { // Partially comented
+ PaintPreproNoSel(LinePtr,db,buffer,lineLen,Width,tabSize,Attr & StartInCom,
+ SeeTabs,TabChar);
+ offset=fl_bufptr>>1;
+ color = normalColor;
+ }
+ else
+ if ((Attr & Prepro) && !(Attr & PartialCom))
+ { // Preprocesor
+ color = PreproColor;
+ offset= CALL3;
+ fl_bufptr=offset<<1;
+ }
+ else
+ {
+ color = normalColor;
+ offset=CALL4;
+ fl_bufptr=offset<<1;
+ SyntaxFormatLine( this,(char *)DrawBuf,lineStart,Width,Attr,lineLen,SeeTabs);
+ }
+
+ FillRestOfLine();
+
+ // Now paint the selection OVER the buffer
+ if (!selHided && selStart<selEnd && selStart<=lineLen+lineStart && selEnd>lineStart)
+ PaintSelection(selStart,selEnd,lineStart,db,selectColor,
+ lineLen,buffer,tabSize,Width,TransparentSel,SeeTabs,TabChar);
+
+ // Column markers over the selection
+ if (colMarkers)
+ PaintMarkers(db,ColMarkColor,Width,colMarkers);
+}
+
+
+
+void TCEditor::formatLineHighLightPascal(void *DrawBuf, unsigned LinePtr, int Width,
+ ushort Colors, unsigned lineLen, uint32 Attr, unsigned , uint32 *colMarkers)
+{
+ unsigned offset;
+ int count;
+ char color;
+ unsigned lineStart=LinePtr;
+ char *db=(char *)DrawBuf;
+ EDITOR = this; // for the two functions above
+ fl_bufptr = 0;
+ offset = 0;
+
+ if (!lineLen)
+ { // If empty just fill it with spaces
+ color = normalColor;
+ }
+ else
+ if (Attr & InsidePascalCom)
+ { // All comented
+ color = CommentColor;
+ offset= CALL3;
+ fl_bufptr=offset<<1;
+ }
+ else
+ if ((Attr & PartialCom) && (Attr & Prepro))
+ { // Partially comented
+ PaintPreproNoSel(LinePtr,db,buffer,lineLen,Width,tabSize,Attr & StartInCom,
+ SeeTabs,TabChar);
+ offset=fl_bufptr>>1;
+ color = normalColor;
+ }
+ else
+ if ((Attr & Prepro) && !(Attr & PartialCom))
+ { // Preprocesor
+ color = PreproColor;
+ offset= CALL3;
+ fl_bufptr=offset<<1;
+ }
+ else
+ {
+ color = normalColor;
+ offset=CALL4;
+ fl_bufptr=offset<<1;
+ SyntaxFormatLinePascal( this,(char *)DrawBuf,lineStart,Width,
+ Attr & StartInCom,Attr & StartInCom2,lineLen,SeeTabs);
+ }
+
+ FillRestOfLine();
+
+ // Now paint the selection OVER the buffer
+ if (!selHided && selStart<selEnd && selStart<=lineLen+lineStart && selEnd>lineStart)
+ PaintSelection(selStart,selEnd,lineStart,db,selectColor,
+ lineLen,buffer,tabSize,Width,TransparentSel,SeeTabs,TabChar);
+
+ // Column markers over the selection
+ if (colMarkers)
+ PaintMarkers(db,ColMarkColor,Width,colMarkers);
+}
+
+
+
+void TCEditor::formatLineHighLightClipper(void *DrawBuf, unsigned LinePtr, int Width,
+ ushort Colors, unsigned lineLen, uint32 Attr, unsigned, uint32 *colMarkers)
+{
+ unsigned offset;
+ int count;
+ char color;
+ unsigned lineStart=LinePtr;
+ char *db=(char *)DrawBuf;
+ EDITOR = this; // for the two functions above
+ fl_bufptr = 0;
+ offset = 0;
+
+ if (!lineLen)
+ { // If empty just fill it with spaces
+ color = normalColor;
+ }
+ else
+ if (Attr & InsideCom)
+ { // All comented
+ color = CommentColor;
+ offset= CALL3;
+ fl_bufptr=offset<<1;
+ }
+ else
+ if ((Attr & PartialCom) && (Attr & Prepro))
+ { // Partially comented
+ PaintPreproNoSel(LinePtr,db,buffer,lineLen,Width,tabSize,Attr & StartInCom,
+ SeeTabs,TabChar);
+ offset=fl_bufptr>>1;
+ color = normalColor;
+ }
+ else
+ if ((Attr & Prepro) && !(Attr & PartialCom))
+ { // Preprocesor
+ color = PreproColor;
+ offset= CALL3;
+ fl_bufptr=offset<<1;
+ }
+ else
+ {
+ color = normalColor;
+ offset=CALL4;
+ fl_bufptr=offset<<1;
+ SyntaxFormatLineClipper( this,(char *)DrawBuf,lineStart,Width,Attr & StartInCom,
+ lineLen,SeeTabs);
+ }
+
+ FillRestOfLine();
+
+ // Now paint the selection OVER the buffer
+ if (!selHided && selStart<selEnd && selStart<=lineLen+lineStart && selEnd>lineStart)
+ PaintSelection(selStart,selEnd,lineStart,db,selectColor,
+ lineLen,buffer,tabSize,Width,TransparentSel,SeeTabs,TabChar);
+
+ // Column markers over the selection
+ if (colMarkers)
+ PaintMarkers(db,ColMarkColor,Width,colMarkers);
+}
+
+
+void TCEditor::formatLineHighLightGeneric(void *DrawBuf, unsigned LinePtr, int Width,
+ ushort Colors, unsigned lineLen, uint32 Attr, unsigned, uint32 *colMarkers)
+{
+ unsigned offset;
+ int count;
+ char color;
+ unsigned lineStart=LinePtr;
+ char *db=(char *)DrawBuf;
+ EDITOR = this; // for the two functions above
+ fl_bufptr = 0;
+ offset = 0;
+
+ if (!lineLen)
+ { // If empty just fill it with spaces
+ color = normalColor;
+ }
+ else
+ if (Attr & InsideGenericCom)
+ { // All comented
+ color = CommentColor;
+ offset= CALL3;
+ fl_bufptr=offset<<1;
+ }
+ else
+ if ((Attr & PartialCom) && (Attr & Prepro))
+ { // Partially comented
+ PaintPreproNoSel(LinePtr,db,buffer,lineLen,Width,tabSize,Attr & StartInGenericCom,
+ SeeTabs,TabChar);
+ offset=fl_bufptr>>1;
+ color = normalColor;
+ }
+ else
+ if ((Attr & Prepro) && !(Attr & PartialCom))
+ { // Preprocesor
+ color = PreproColor;
+ offset= CALL3;
+ fl_bufptr=offset<<1;
+ }
+ else
+ {
+ color = normalColor;
+ offset=CALL4;
+ fl_bufptr=offset<<1;
+ SyntaxFormatLineGeneric( this,(char *)DrawBuf,lineStart,Width,Attr,lineLen,
+ SeeTabs);
+ }
+
+ FillRestOfLine();
+
+ // Now paint the selection OVER the buffer
+ if (!selHided && selStart<selEnd && selStart<=lineLen+lineStart && selEnd>lineStart)
+ PaintSelection(selStart,selEnd,lineStart,db,selectColor,
+ lineLen,buffer,tabSize,Width,TransparentSel,SeeTabs,TabChar);
+
+ // Column markers over the selection
+ if (colMarkers)
+ PaintMarkers(db,ColMarkColor,Width,colMarkers);
+}
+
+// For Reserved words
+static strSETSE stRW={NULL,NULL,NULL,NULL,NULL,0};
+// For User words
+static strSETSE stUW={NULL,NULL,NULL,NULL,NULL,0};
+// For Pascal Reserved words
+static strSETSE stPR={NULL,NULL,NULL,NULL,NULL,0};
+// For Clipper Reserved words
+static strSETSE stCR={NULL,NULL,NULL,NULL,NULL,0};
+
+#if 0
+/*****************************************************************************
+
+ Function: SETSECreateTables
+
+ Create the necesary tables for the search
+
+*****************************************************************************/
+
+static Boolean SETSECreateTables(char *&firstLetters,
+ int *&lenTable,
+ int *&firstWithLength,
+ char **&mainTable,
+ int *&equalCharsInNext,
+ int &maxLen,
+ TStrCol *TSC)
+{
+ int i;
+ int total=TSC->getCount();
+ int thisLen;
+ maxLen=0;
+
+ for (i=0; i<total; i++)
+ {
+ if ((thisLen=strlen((char *)TSC->at(i)))>maxLen)
+ maxLen=thisLen;
+ }
+
+ // The following is nice but missaling data, some platforms doesn't support it.
+ // Linux/PPC logs it as a warning at kernel level and Linux/SPARC64 just raise
+ // a SIGBUS signal.
+ // *:-P One allocation for the five tables.
+ //firstLetters=new char[total*(sizeof(char)+sizeof(char *)+sizeof(int))+(2*sizeof(int))*(maxLen+1)];
+ firstLetters =new char[total];
+ lenTable =new int[maxLen+1];
+ firstWithLength =new int[maxLen+1];
+ mainTable =new char *[total];
+ equalCharsInNext=new int[total];
+
+ // Fill the length table
+ for (i=0; i<=maxLen; i++)
+ {
+ firstWithLength[i]=0;
+ lenTable[i]=0;
+ }
+
+ for (i=0; i<total; i++)
+ lenTable[strlen((char *)TSC->at(i))]++;
+
+ // Search & Clasify
+ int pos=0;
+ for (i=0; i<=maxLen; i++)
+ {
+ int j=0,n=0;
+ while (j<lenTable[i])
+ {
+ char *s=(char *)TSC->at(n);
+ if ((int)strlen(s)==i)
+ {
+ if (j==0)
+ firstWithLength[i]=pos;
+ mainTable[pos++]=s;
+ j++;
+ }
+ n++;
+ }
+ }
+
+ // Make the first letters
+ for (i=0; i<total; i++)
+ firstLetters[i]=mainTable[i][0];
+
+ // Make the equality table
+ for (pos=0,i=0; i<=maxLen; i++)
+ {
+ int j=lenTable[i];
+ while (j)
+ {
+ if (j>1)
+ {
+ char *este=mainTable[pos];
+ char *prox=mainTable[pos+1];
+ int c;
+ for (c=0; *este==*prox && *este; este++, prox++, c++);
+ equalCharsInNext[pos]=c;
+ }
+ else
+ equalCharsInNext[pos]=0;
+ pos++;
+ j--;
+ }
+ }
+ return True;
+}
+#endif
+
+Boolean SETSECreateTables(strSETSE &st, int CaseSens,
+ TStringCollection *TSC)
+{
+ int i;
+ int total=TSC->getCount();
+ int thisLen;
+ st.maxLen=0;
+
+ for (i=0; i<total; i++)
+ {
+ char *elem=(char *)TSC->at(i);
+ if ((thisLen=strlen(elem))>st.maxLen)
+ st.maxLen=thisLen;
+ if (!CaseSens)
+ strlwr(elem);
+ }
+
+ st.firstLetters =new char[total];
+ st.lenTable =new int[st.maxLen+1];
+ st.firstWithLength =new int[st.maxLen+1];
+ st.mainTable =new char *[total];
+ st.equalCharsInNext=new int[total];
+
+ // Fill the length table
+ for (i=0; i<=st.maxLen; i++)
+ {
+ st.firstWithLength[i]=0;
+ st.lenTable[i]=0;
+ }
+
+ for (i=0; i<total; i++)
+ st.lenTable[strlen((char *)TSC->at(i))]++;
+
+ // Search & Clasify
+ int pos=0;
+ for (i=0; i<=st.maxLen; i++)
+ {
+ int j=0,n=0;
+ while (j<st.lenTable[i])
+ {
+ char *s=(char *)TSC->at(n);
+ if ((int)strlen(s)==i)
+ {
+ if (j==0)
+ st.firstWithLength[i]=pos;
+ st.mainTable[pos++]=s;
+ j++;
+ }
+ n++;
+ }
+ }
+
+ // Make the first letters
+ for (i=0; i<total; i++)
+ st.firstLetters[i]=st.mainTable[i][0];
+
+ // Make the equality table
+ for (pos=0,i=0; i<=st.maxLen; i++)
+ {
+ int j=st.lenTable[i];
+ while (j)
+ {
+ if (j>1)
+ {
+ char *este=st.mainTable[pos];
+ char *prox=st.mainTable[pos+1];
+ int c;
+ for (c=0; *este==*prox && *este; este++, prox++, c++);
+ st.equalCharsInNext[pos]=c;
+ }
+ else
+ st.equalCharsInNext[pos]=0;
+ pos++;
+ j--;
+ }
+ }
+ return True;
+}
+
+/*****************************************************************************
+
+ Function: SETSE_RW_Search
+
+ Is the search engine of the SETSE algorithm.
+ The tables are sorted 1st by string length and then by alphabetic order.
+ When we need to search a string first we check if the length is valid, if
+not the search ends, if the length is OK we go directly to the first element
+with this length, then we use a table with the first letters of the list and
+we search in this table until we found the letter or we exced the range of
+word with the desired length ... puf ..., if we found a match we start to
+compare the whole string, if the any letter fails we ask if the following
+string have enough equal letters (there is a table for this) if not we return,
+if yes we continue the comparison in the next string, not from the start the
+start because we know that this string match the first letters.
+ The goal of the system is: We never retrace in the string index we ever
+advance or still in the same index.
+ If you don't understand what I'm saying don't worry my english is a
+disaster and the algorithm is a little tricky.
+
+*****************************************************************************/
+
+#define is_reserved(a,b) SETSE_RW_Search(a,b)
+static int SETSE_RW_Search(char *s, int l)
+{
+ // Is in the length range?
+ if (l<=stRW.maxLen)
+ {
+ int cant=stRW.lenTable[l];
+ // Exist any of this length?
+ if (cant)
+ {
+ // Take the pos of the first string of this length
+ int pos=stRW.firstWithLength[l];
+ do
+ {
+ // Search a string of this length that starts with the same character
+ if (stRW.firstLetters[pos]==*s)
+ {
+ int equals=1;
+ // Compare the string
+ char *aux=stRW.mainTable[pos]+1;
+ s++;
+RWProxSSearch1:
+ if (--l==0) // Eureka!
+ return pos+1; // +1 because the position 0 exist
+RWProxSSearch2:
+ if (*aux==*s)
+ {
+ // Next char
+ equals++;
+ s++;
+ aux++;
+ goto RWProxSSearch1;
+ }
+ // Is usefull the next string?
+ if (stRW.equalCharsInNext[pos]>=equals)
+ {
+ // Yes!, use it, but don't waste the work already done
+ aux=stRW.mainTable[++pos]+equals;
+ goto RWProxSSearch2;
+ }
+ return 0;
+ }
+ pos++;
+ }
+ while (--cant);
+ }
+ }
+ return 0;
+}
+
+static
+int SETSE_UW_Search(char *s, int l)
+{
+ // Is in the length range?
+ if (l<=stUW.maxLen)
+ {
+ int cant=stUW.lenTable[l];
+ // Exist any of this length?
+ if (cant)
+ {
+ // Take the pos of the first string of this length
+ int pos=stUW.firstWithLength[l];
+ do
+ {
+ // Search a string of this length that starts with the same character
+ if (stUW.firstLetters[pos]==*s)
+ {
+ int equals=1;
+ // Compare the string
+ char *aux=stUW.mainTable[pos]+1;
+ s++;
+UWProxSSearch1:
+ if (--l==0) // Eureka!
+ return pos+1;
+UWProxSSearch2:
+ if (*aux==*s)
+ {
+ // Next char
+ equals++;
+ s++;
+ aux++;
+ goto UWProxSSearch1;
+ }
+ // Is usefull the next string?
+ if (stUW.equalCharsInNext[pos]>=equals)
+ {
+ // Yes!, use it, but don't waste the work already done
+ aux=stUW.mainTable[++pos]+equals;
+ goto UWProxSSearch2;
+ }
+ return 0;
+ }
+ pos++;
+ }
+ while (--cant);
+ }
+ }
+ return 0;
+}
+
+#define is_pascal_rword(a,b) SETSE_PR_Search(a,b)
+static int SETSE_PR_Search(char *s, int l)
+{
+ // Is in the length range?
+ if (l<=stPR.maxLen)
+ {
+ int cant=stPR.lenTable[l];
+ // Exist any of this length?
+ if (cant)
+ {
+ // Take the pos of the first string of this length
+ int pos=stPR.firstWithLength[l];
+ uchar c=TVCodePage::toLower(*s);
+ do
+ {
+ // Search a string of this length that starts with the same character
+ if (stPR.firstLetters[pos]==c)
+ {
+ int equals=1;
+ // Compare the string
+ char *aux=stPR.mainTable[pos]+1;
+ s++; c=TVCodePage::toLower(*s);
+PRProxSSearch1:
+ if (--l==0) // Eureka!
+ return pos+1;
+PRProxSSearch2:
+ if (*aux==c)
+ {
+ // Next char
+ equals++;
+ s++; c=TVCodePage::toLower(*s);
+ aux++;
+ goto PRProxSSearch1;
+ }
+ // Is usefull the next string?
+ if (stPR.equalCharsInNext[pos]>=equals)
+ {
+ // Yes!, use it, but don't waste the work already done
+ aux=stPR.mainTable[++pos]+equals;
+ goto PRProxSSearch2;
+ }
+ return 0;
+ }
+ pos++;
+ }
+ while (--cant);
+ }
+ }
+ return 0;
+}
+
+#define is_clipper_rword(a,b) SETSE_CR_Search(a,b)
+static int SETSE_CR_Search(char *s, int l)
+{
+ // Is in the length range?
+ if (l<=stCR.maxLen)
+ {
+ int cant=stCR.lenTable[l];
+ // Exist any of this length?
+ if (cant)
+ {
+ // Take the pos of the first string of this length
+ int pos=stCR.firstWithLength[l];
+ uchar c=TVCodePage::toLower(*s);
+ do
+ {
+ // Search a string of this length that starts with the same character
+ if (stCR.firstLetters[pos]==c)
+ {
+ int equals=1;
+ // Compare the string
+ char *aux=stCR.mainTable[pos]+1;
+ s++; c=TVCodePage::toLower(*s);
+CRProxSSearch1:
+ if (--l==0) // Eureka!
+ return pos+1;
+CRProxSSearch2:
+ if (*aux==c)
+ {
+ // Next char
+ equals++;
+ s++; c=TVCodePage::toLower(*s);
+ aux++;
+ goto CRProxSSearch1;
+ }
+ // Is usefull the next string?
+ if (stCR.equalCharsInNext[pos]>=equals)
+ {
+ // Yes!, use it, but don't waste the work already done
+ aux=stCR.mainTable[++pos]+equals;
+ goto CRProxSSearch2;
+ }
+ return 0;
+ }
+ pos++;
+ }
+ while (--cant);
+ }
+ }
+ return 0;
+}
+
+static
+int isGeneralReservedWord(char *s, int l, int CaseSens, strSETSE &st)
+{
+ // Is in the length range?
+ if (l<=st.maxLen)
+ {
+ int cant=st.lenTable[l];
+ // Exist any of this length?
+ if (cant)
+ {
+ // Take the pos of the first string of this length
+ int pos=st.firstWithLength[l];
+ uchar c = CaseSens ? *s : TVCodePage::toLower(*s);
+ do
+ {
+ // Search a string of this length that starts with the same character
+ if (st.firstLetters[pos]==c)
+ {
+ int equals=1;
+ // Compare the string
+ char *aux=st.mainTable[pos]+1;
+ s++; c=CaseSens ? *s : TVCodePage::toLower(*s);
+stProxSSearch1:
+ if (--l==0) // Eureka!
+ return pos+1;
+stProxSSearch2:
+ if (*aux==c)
+ {
+ // Next char
+ equals++;
+ s++; c=CaseSens ? *s : TVCodePage::toLower(*s);
+ aux++;
+ goto stProxSSearch1;
+ }
+ // Is usefull the next string?
+ if (st.equalCharsInNext[pos]>=equals)
+ {
+ // Yes!, use it, but don't waste the work already done
+ aux=st.mainTable[++pos]+equals;
+ goto stProxSSearch2;
+ }
+ return 0;
+ }
+ pos++;
+ }
+ while (--cant);
+ }
+ }
+ return 0;
+}
+
+static
+int is_user_word(char *s, int l, int caseSens)
+{
+ if (TCEditor::strC.UserWords)
+ return isGeneralReservedWord(s,l,caseSens,TCEditor::strC.SearchUserWords);
+ return SETSE_UW_Search(s,l);
+}
+
+static
+int isPartialKeyword(char *s, int l, int CaseSens, TStringCollection *keywords,
+ unsigned &end)
+{
+ // Do it ASCIIZ for the search
+ AllocLocalStr(temp,l+1);
+ memcpy(temp,s,l);
+ temp[l]=0;
+ if (!CaseSens)
+ strlwr(temp);
+
+ // Search for it
+ ccIndex pos;
+ Boolean res=keywords->search(temp,pos);
+ if (res) // Full match
+ return 1;
+
+ // Now see if it could be a partial
+ if (pos) // We ever get the next, but dont go negative
+ pos--;
+ char *test=(char *)keywords->at(pos);
+ int i,len;
+ len=strlen(test);
+ if (len>=l) // Impossible, quit
+ return 0;
+ // Check if they match using the length of the keyword
+ if (CaseSens)
+ {
+ for (i=0; i<len; i++)
+ {
+ if (s[i]!=test[i])
+ return 0;
+ }
+ }
+ else
+ {
+ for (i=0; i<len; i++)
+ {
+ if (s[i]!=TVCodePage::toLower(test[i]))
+ return 0;
+ }
+ }
+ // Ok, reduce the length of the word to the matched part
+ end+=len-l;
+ return 1;
+}
+
+void SETSEDeleteTables(strSETSE &st)
+{
+ if (st.firstLetters)
+ {
+ delete[] st.firstLetters;
+ st.firstLetters=NULL;
+ delete[] st.lenTable;
+ delete[] st.firstWithLength;
+ delete[] st.mainTable;
+ delete[] st.equalCharsInNext;
+ }
+}
+
+/*****************************************************************************
+
+ Function: Boolean CreateSHShortCutTables(void)
+
+ Initialize the search tables for ReservedWords and UserWords.
+
+*****************************************************************************/
+
+Boolean CreateSHShortCutTables(void)
+{
+ if (ReservedWords)
+ {
+ SETSEDeleteTables(stRW);
+ if (!SETSECreateTables(stRW,1,ReservedWords))
+ return False;
+ }
+ else
+ stRW.maxLen=0;
+
+ if (UserWords)
+ {
+ SETSEDeleteTables(stUW);
+ if (!SETSECreateTables(stUW,1,UserWords))
+ return False;
+ }
+ else
+ stUW.maxLen=0;
+
+ if (PascalRWords)
+ {
+ SETSEDeleteTables(stPR);
+ if (!SETSECreateTables(stPR,1,PascalRWords))
+ return False;
+ }
+ else
+ stPR.maxLen=0;
+
+ if (ClipperRWords)
+ {
+ SETSEDeleteTables(stCR);
+ if (!SETSECreateTables(stCR,1,ClipperRWords))
+ return False;
+ }
+ else
+ stCR.maxLen=0;
+
+ return True;
+}
+
+
+void DestroySHShortCutTables(void)
+{
+ SETSEDeleteTables(stRW);
+ SETSEDeleteTables(stUW);
+ SETSEDeleteTables(stPR);
+ SETSEDeleteTables(stCR);
+}
+
+
+/*****************************************************************************
+
+ Function: int is_integer_float(const char *name,uint32 l,uint32 rest)
+
+ Parameters:
+ name: string to analyze.
+ l: length.
+ rest: available chars in the line.
+
+ Return:
+ 0 an invalid number.
+ 1 an integer.
+ 2 a float.
+
+ Notes:
+ Adapted for length.
+ Added u and l.
+ Added floats
+ Added support for [uU][lL]{0,2} | [lL][uU]?[lL]? | [lL][lL]?[uU]?
+ Added [lL] | [fF] for floats (Vik's recommendation)
+
+ by SET based in the Robert's version.
+
+*****************************************************************************/
+
+#define OneOrZeroOf(a,b) \
+ if (dispo==0) return 1; \
+ name++; \
+ if (!isalnum((uchar)*name)) return 1; \
+ if (*name!=a && *name!=b) \
+ return 0; \
+ dispo--
+
+#define OkIfSepRet(a) \
+ if (dispo==0) return a; \
+ name++; \
+ if (!isalnum((uchar)*name)) return a
+
+static int is_integer_float(const char *name, uint32 &dispo)
+{
+ while (dispo--)
+ {
+ if (!ucisdigit(*name))
+ {
+ if (*name=='U' || *name=='u') // [uU][lL]{0,2} with brut force
+ {
+ OneOrZeroOf('l','L');
+ OneOrZeroOf('l','L');
+ OkIfSepRet(1);
+ return 0;
+ }
+ if (*name=='L' || *name=='l') // [lL]...
+ {
+ OkIfSepRet(1);
+ if (*name=='u' || *name=='U') // ...[uU][lL]?
+ {
+ dispo--;
+ OneOrZeroOf('l','L');
+ OkIfSepRet(1);
+ }
+ else
+ if (*name=='l' || *name=='L') // ...[lL][uU]?
+ {
+ dispo--;
+ OneOrZeroOf('u','U');
+ OkIfSepRet(1);
+ }
+ return 0;
+ }
+ if (*name=='E' || *name=='e')
+ goto TryFloat1;
+ if (*name=='.')
+ goto TryFloat0;
+ if (!TVCodePage::isAlpha(*name))
+ {
+ dispo++;
+ return 1;
+ }
+ return 0;
+ }
+ name++;
+ }
+
+ if (!dispo || *name!='.')
+ return 1;
+
+TryFloat0:
+ name++;
+ //dispo--;
+ while (dispo--)
+ {
+ if (!ucisdigit(*name))
+ {
+ if (*name=='E' || *name=='e')
+ goto TryFloat1;
+ if (*name=='l' || *name=='L' || *name=='f' || *name=='F')
+ {
+ OkIfSepRet(2);
+ return 0;
+ }
+ if (TVCodePage::isAlpha(*name) || *name=='.')
+ return 0;
+ else
+ {
+ dispo++;
+ return 2;
+ }
+ }
+ name++;
+ }
+
+ return 2;
+
+TryFloat1:
+ if (!dispo) return 0;
+ name++;
+ //dispo--;
+ if (!ucisdigit(*name) && !((*name=='+' || *name=='-') && dispo && ucisdigit(*(name+1)))) return 0;
+ name++;
+ dispo--;
+ while (dispo--)
+ {
+ if (!ucisdigit(*name))
+ {
+ if (*name=='l' || *name=='L' || *name=='f' || *name=='F')
+ {
+ OkIfSepRet(2);
+ return 0;
+ }
+ if (TVCodePage::isAlpha(*name)) return 0;
+ dispo++;
+ return 2;
+ }
+ name++;
+ }
+ return 2;
+}
+
+/**[txh]********************************************************************
+
+ Description:
+ Checks if we have an integer or floating point number in the @var{name}
+string. Only @var{dispo} bytes are tested. The value of @var{dispo} is
+modified to indicate how many characters we parsed.
+
+ Return: 0 an invalid number, 1 an integer and 2 a float.
+
+***************************************************************************/
+
+static
+int is_pascal_integer_float(const char *name, uint32 &dispo)
+{
+ while (dispo--)
+ {
+ if (!ucisdigit(*name))
+ {
+ if (*name=='E' || *name=='e')
+ goto TryFloat1;
+ if (*name=='.')
+ goto TryFloat0;
+ if (!TVCodePage::isAlpha(*name))
+ {
+ dispo++;
+ return 1;
+ }
+ return 0;
+ }
+ name++;
+ }
+
+ if (!dispo || *name!='.')
+ return 1;
+
+TryFloat0:
+ name++;
+ //dispo--;
+ while (dispo--)
+ {
+ if (!ucisdigit(*name))
+ {
+ if (*name=='E' || *name=='e')
+ goto TryFloat1;
+ if (TVCodePage::isAlpha(*name))
+ return 0;
+ if (*name=='.')
+ {
+ dispo+=2;
+ return 1;
+ }
+ dispo++;
+ return 2;
+ }
+ name++;
+ }
+
+ return 2;
+
+TryFloat1:
+ if (!dispo) return 0;
+ name++;
+ //dispo--;
+ if (!ucisdigit(*name) && !((*name=='+' || *name=='-') && dispo && ucisdigit(*(name+1)))) return 0;
+ name++;
+ dispo--;
+ while (dispo--)
+ {
+ if (!ucisdigit(*name))
+ {
+ if (TVCodePage::isAlpha(*name)) return 0;
+ return 2;
+ }
+ name++;
+ }
+ return 2;
+}
+
+/**[txh]********************************************************************
+
+ Description:
+ Checks if the @var{val} represents a digit for @var{base}.
+
+ Return: The equivalent digit or -1 if outside the base.
+
+***************************************************************************/
+
+int vhdl_val_digit(char val, int base)
+{
+ int digit;
+ if (val>='0' && val<='9')
+ digit=val-'0';
+ else
+ if (val>='A' && val<='Z')
+ digit=val-'A'+10;
+ else
+ if (val>='a' && val<='z')
+ digit=val-'a'+10;
+ else
+ return -1;
+ return digit<base ? digit : -1;
+}
+
+// Some helpful macros to make the code easier to read:
+// Handle the _d sequence
+#define CheckUnderscore(doAcum) \
+ if (*s=='_') \
+ {/* Can't end here */ \
+ if (!dispo) \
+ return 0; \
+ s++; \
+ /* Must be followed by a valid digit */\
+ digVal=vhdl_val_digit(*s,base); \
+ if (digVal<0) \
+ return 0; \
+ if (doAcum) \
+ { \
+ acum*=10; \
+ acum+=digVal; \
+ } \
+ dispo--; \
+ s++; \
+ continue; \
+ }
+
+// Verify that's a valid digit
+#define CheckDigit(retVal,ckAlpha) \
+ digVal=vhdl_val_digit(*s,base); \
+ if (digVal<0) \
+ { \
+ dispo++; \
+ if (ckAlpha && TVCodePage::isAlpha(*s)) \
+ return 0; \
+ return retVal; \
+ }
+
+/**[txh]********************************************************************
+
+ Description:
+ Checks if we have an integer or floating point number in the @var{s}
+string. That's VHDL specific. Only @var{dispo} bytes are tested. The value
+of @var{dispo} is modified to indicate how many characters we parsed.@p
+ It must be called only if @var{s} starts with 0-9.@p
+ The code supports abstract literals (decimal and based).
+
+ Return: 0 an invalid number, 1 an integer, 2 a float, 3 not a number.
+
+***************************************************************************/
+
+int isVHDLAbstractLiteral(const char *s, uint32 &dispo)
+{
+ int base, digVal, result;
+ unsigned acum;
+
+ // Abstract literals (13.4)
+ // We assume the first character is a digit (caller responsability)
+ base=10;
+ acum=vhdl_val_digit(*s,base);
+ s++;
+ dispo--;
+ result=1;
+ while (dispo--)
+ {
+ CheckUnderscore(1);
+ if (*s=='.') // dd.
+ goto ParseAfterFP;
+ if (*s=='#')
+ goto ParseBased; // dd#
+ if (*s=='E' || *s=='e')
+ goto ParseAfterExp; // ddE
+ CheckDigit(1,1);
+ acum*=10;
+ acum+=digVal;
+ s++;
+ }
+ return 1;
+
+ParseAfterFP:
+ // Decimal literal (13.4.1)
+ // Here we have dddd.
+ result=2;
+ s++;
+ if (!ucisdigit(*s))
+ return 0; // Incomplete
+ // Here we have dddd.d
+ s++;
+ dispo--;
+ while (dispo--)
+ {
+ CheckUnderscore(0);
+ if (*s=='E' || *s=='e') // dd.ddE
+ goto ParseAfterExp;
+ CheckDigit(2,1);
+ s++;
+ }
+ return 2;
+
+ParseAfterExp:
+ // Here we have dd.ddE
+ s++;
+ if (*s=='+' || (result==2 && *s=='-'))
+ {// Skip the sign
+ dispo--;
+ s++;
+ }
+ if (!ucisdigit(*s))
+ return 0; // Incomplete
+ while (dispo--)
+ {
+ CheckUnderscore(0);
+ CheckDigit(result,1);
+ s++;
+ }
+ return result;
+
+ParseBased:
+ // Based literals (13.4.2)
+ // Here we have dd#
+ base=acum;
+ result=1;
+ if (base<2 || base>16)
+ return 0; // base must be in [2;16] range
+ s++;
+ // Must be followed by a digit
+ if (!dispo)
+ return 0;
+ dispo--;
+ CheckDigit(0,0);
+ s++;
+ while (dispo--)
+ {
+ CheckUnderscore(0);
+ if (*s=='.') // dd#dd.
+ goto ParseAfterFPBL;
+ if (*s=='#')
+ goto ParseExpBL; // dd#dd#
+ CheckDigit(0,0);
+ s++;
+ }
+ // Only dd#dd is incomplete
+ return 0;
+
+ParseAfterFPBL:
+ // Here we have dd#dd.
+ result=2;
+ // A digit must be here
+ s++;
+ if (!dispo)
+ return 0;
+ dispo--;
+ CheckDigit(0,0);
+ s++;
+ // Here we have dd#dd.d
+ while (dispo--)
+ {
+ CheckUnderscore(0);
+ if (*s=='#')
+ goto ParseExpBL; // dd#dd.dd#
+ CheckDigit(0,0);
+ s++;
+ }
+ // Only dd#dd.dd is incomplete
+ return 0;
+
+ParseExpBL:
+ // Here we have dd#dd.dd#
+ // The exponent is decimal
+ base=10;
+ s++;
+ if (dispo && (*s=='e' || *s=='E'))
+ {
+ dispo--;
+ s++;
+ // Here we have dd#dd.dd#E
+ if (!dispo)
+ return 0; // incomplete
+ if (*s=='+' || (result==2 && *s=='-'))
+ {
+ dispo--;
+ s++;
+ }
+ // At least one digit
+ if (!dispo)
+ return 0;
+ dispo--;
+ CheckDigit(0,0);
+ s++;
+ }
+ while (dispo--)
+ {
+ CheckUnderscore(0);
+ CheckDigit(result,1);
+ s++;
+ }
+
+ return result;
+}
+
+/**[txh]********************************************************************
+
+ Description:
+ Checks if we have a "bit string literal" (BSL) in the @var{s} string.
+That's VHDL specific. Only @var{dispo} bytes are tested. The value
+of @var{dispo} is modified to indicate how many characters we parsed.@p
+ It must be called only if @var{s} starts with B,O or X.@p
+
+ Return: 0 invalid BSL, 1 valid BSL, 3 not a BSL.
+
+***************************************************************************/
+
+int isVHDLBitStringLiteral(const char *s, uint32 &dispo)
+{
+ int base, digVal;
+ unsigned acum;
+ char sep;
+
+ if (dispo==1)
+ return 3; // Standalone char
+ switch (*s)
+ {
+ case 'B':
+ case 'b':
+ base=2;
+ break;
+ case 'O':
+ case 'o':
+ base=8;
+ break;
+ case 'X':
+ case 'x':
+ base=16;
+ break;
+ default:
+ return 3;
+ }
+ // Bit string literals (13.7)
+ // B,O,X
+ s++;
+ if (*s=='"' || *s=='%')
+ sep=*s;
+ else
+ return 3; // Not followed by a valid separator
+ dispo-=2;
+ s++;
+ // B"10_" or B%10_%, etc.
+ while (dispo--)
+ {
+ if (*s==sep)
+ return 1;
+ CheckUnderscore(0);
+ CheckDigit(0,0); // Check if it maps to a valid digit
+ s++;
+ }
+ // Incomplete, that's an error
+ return 0;
+}
+
+/*****************************************************************************
+
+ Function: int is_hex(const char *name,uint32 l)
+
+ Parameters:
+ name: string to analyze.
+ l: length.
+
+ Return:
+ 1 if is a valid hexadecimal number.
+
+ Notes:
+ Adapted for length.
+ Added u,U,l and L.
+ Added a check to avoid more than 16 digits, is that correct?
+
+ by SET based in the Robert's version.
+
+*****************************************************************************/
+
+#define OneOrZeroOfHex(a,b) \
+ if (l==0) return (lori<=19); \
+ name++; \
+ if (!isalnum((uchar)*name)) return (lori<=19); \
+ if (*name!=a && *name!=b) \
+ return 0; \
+ l--; lori--
+
+#define OkIfSepRetHex() \
+ if (l==0) return (lori<=19); \
+ name++; \
+ if (!isalnum((uchar)*name)) return (lori<=19)
+
+static int is_hex(const char *name, uint32 l)
+{
+ uint32 lori=l;
+ int notYetANumber=1;
+
+ // We can't use a char * as an uint16 * in some RISC machines like SPARC
+ //if (l<3 || (*(uint16 *)name!=0x7830 && *(uint16 *)name!=0x5830)) return 0;
+ if (l<3 || name[0]!='0' || (name[1]!='x' && name[1]!='X')) return 0;
+ name+=2;
+ l-=2;
+ while (l--)
+ {
+ if (!ucisxdigit(*name))
+ {
+ if (*name=='U' || *name=='u') // [uU][lL]{0,2} with brut force
+ {
+ OneOrZeroOfHex('l','L');
+ OneOrZeroOfHex('l','L');
+ OkIfSepRetHex();
+ return 0;
+ }
+ if (*name=='L' || *name=='l') // [lL]...
+ {
+ OkIfSepRetHex();
+ if (*name=='u' || *name=='U') // ...[uU][lL]?
+ {
+ l--; lori--;
+ OneOrZeroOfHex('l','L');
+ OkIfSepRetHex();
+ }
+ else
+ if (*name=='l' || *name=='L') // ...[lL][uU]?
+ {
+ l--; lori--;
+ OneOrZeroOfHex('u','U');
+ OkIfSepRetHex();
+ }
+ }
+ return 0;
+ }
+ if (notYetANumber)
+ {
+ if (*name=='0')
+ lori--;
+ else
+ notYetANumber=0;
+ }
+ name++;
+ }
+ return (lori<=10);
+}
+
+/*****************************************************************************
+
+ Function: int is_pascal_hex(const char *name,uint32 &dispo)
+
+ Parameters:
+ name: string to analyze.
+ dispo: disponible length.
+
+ Return:
+ 1 if is a valid hexadecimal number for pascal.
+
+ by SET.
+
+*****************************************************************************/
+
+static int is_pascal_hex(const char *name, uint32 &dispo)
+{
+ name++;
+ if (!ucisxdigit(*name))
+ return 0;
+ while (--dispo)
+ {
+ if (!ucisxdigit(*name))
+ {
+ if (*name=='.')
+ return 0;
+ return 1;
+ }
+ name++;
+ }
+ return 1;
+}
+
+static int is_octal(const char *name,uint32 l)
+{
+ // The first is a 0
+ //while (*(name++)=='0') l--;
+ //if (l==0) return 1;
+ while (l--)
+ {
+ if (*name<'0' || *name>'7') return 0;
+ name++;
+ }
+ return 1;
+}
+
+unsigned char TableTypesEditor[256]=
+{
+ 0, // \0
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // \t
+ 0, // \n
+ 0, //
+ 0, //
+ 0, // \r
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // x1A
+ 0, // x1B
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, // 
+ 0, //
+ ttedIsClipSymb | ttedIsCsymb2 | ttedIsPasSymb2, // !
+ 0, // "
+ ttedIsClipSymb | ttedIsPasSymb2, // #
+ ttedIsClipSymb, // $
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // %
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // &
+ 0, // '
+ ttedIsClipSymb | ttedIsPasSymb1 | ttedIsCsymb1, // (
+ ttedIsClipSymb | ttedIsPasSymb1 | ttedIsCsymb1, // )
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // *
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // +
+ ttedIsClipSymb | ttedIsPasSymb1 | ttedIsCsymb1, // ,
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // -
+ ttedIsClipSymb | ttedIsPasSymb1 | ttedIsCsymb1, // .
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // /
+ ttedIsWordChar, // 0
+ ttedIsWordChar, // 1
+ ttedIsWordChar, // 2
+ ttedIsWordChar, // 3
+ ttedIsWordChar, // 4
+ ttedIsWordChar, // 5
+ ttedIsWordChar, // 6
+ ttedIsWordChar, // 7
+ ttedIsWordChar, // 8
+ ttedIsWordChar, // 9
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // :
+ ttedIsClipSymb | ttedIsPasSymb1 | ttedIsCsymb1, // ;
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // <
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // =
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // >
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // ?
+ ttedIsClipSymb | ttedIsPasSymb2, // @
+ ttedIsWordChar, // A
+ ttedIsWordChar, // B
+ ttedIsWordChar, // C
+ ttedIsWordChar, // D
+ ttedIsWordChar, // E
+ ttedIsWordChar, // F
+ ttedIsWordChar, // G
+ ttedIsWordChar, // H
+ ttedIsWordChar, // I
+ ttedIsWordChar, // J
+ ttedIsWordChar, // K
+ ttedIsWordChar, // L
+ ttedIsWordChar, // M
+ ttedIsWordChar, // N
+ ttedIsWordChar, // O
+ ttedIsWordChar, // P
+ ttedIsWordChar, // Q
+ ttedIsWordChar, // R
+ ttedIsWordChar, // S
+ ttedIsWordChar, // T
+ ttedIsWordChar, // U
+ ttedIsWordChar, // V
+ ttedIsWordChar, // W
+ ttedIsWordChar, // X
+ ttedIsWordChar, // Y
+ ttedIsWordChar, // Z
+ ttedIsClipSymb | ttedIsPasSymb1 | ttedIsCsymb1, // [
+ 0, // \.
+ ttedIsClipSymb | ttedIsPasSymb1 | ttedIsCsymb1, // ]
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // ^
+ ttedIsWordChar, // _
+ 0, // `
+ ttedIsWordChar, // a
+ ttedIsWordChar, // b
+ ttedIsWordChar, // c
+ ttedIsWordChar, // d
+ ttedIsWordChar, // e
+ ttedIsWordChar, // f
+ ttedIsWordChar, // g
+ ttedIsWordChar, // h
+ ttedIsWordChar, // i
+ ttedIsWordChar, // j
+ ttedIsWordChar, // k
+ ttedIsWordChar, // l
+ ttedIsWordChar, // m
+ ttedIsWordChar, // n
+ ttedIsWordChar, // o
+ ttedIsWordChar, // p
+ ttedIsWordChar, // q
+ ttedIsWordChar, // r
+ ttedIsWordChar, // s
+ ttedIsWordChar, // t
+ ttedIsWordChar, // u
+ ttedIsWordChar, // v
+ ttedIsWordChar, // w
+ ttedIsWordChar, // x
+ ttedIsWordChar, // y
+ ttedIsWordChar, // z
+ ttedIsClipSymb | ttedIsPasSymb1 | ttedIsCsymb1, // {
+ ttedIsClipSymb | ttedIsPasSymb2 | ttedIsCsymb2, // |
+ ttedIsClipSymb | ttedIsPasSymb1 | ttedIsCsymb1, // }
+ ttedIsCsymb2, // ~
+ 0, // 
+ ttedIsWordChar, // €
+ ttedIsWordChar, //
+ ttedIsWordChar, // ‚
+ ttedIsWordChar, // ƒ
+ ttedIsWordChar, // „
+ ttedIsWordChar, // …
+ ttedIsWordChar, // †
+ ttedIsWordChar, // ‡
+ ttedIsWordChar, // ˆ
+ ttedIsWordChar, // ‰
+ ttedIsWordChar, // Š
+ ttedIsWordChar, // ‹
+ ttedIsWordChar, // Œ
+ ttedIsWordChar, //
+ ttedIsWordChar, // Ž
+ ttedIsWordChar, //
+ ttedIsWordChar, //
+ ttedIsWordChar, // ‘
+ ttedIsWordChar, // ’
+ ttedIsWordChar, // “
+ ttedIsWordChar, // ”
+ ttedIsWordChar, // •
+ ttedIsWordChar, // –
+ ttedIsWordChar, // —
+ ttedIsWordChar, // ˜
+ ttedIsWordChar, // ™
+ ttedIsWordChar, // š
+ 0, // ›
+ 0, // œ
+ 0, //
+ 0, // ž
+ 0, // Ÿ
+ ttedIsWordChar, //  
+ ttedIsWordChar, // ¡
+ ttedIsWordChar, // ¢
+ ttedIsWordChar, // £
+ ttedIsWordChar, // ¤
+ ttedIsWordChar, // ¥
+ 0, // ¦
+ 0, // §
+ 0, // ¨
+ 0, // ©
+ 0, // ª
+ 0, // «
+ 0, // ¬
+ 0, // ­
+ 0, // ®
+ 0, // ¯
+ 0, // °
+ 0, // ±
+ 0, // ²
+ 0, // ³
+ 0, // ´
+ 0, // µ
+ 0, // ¶
+ 0, // ·
+ 0, // ¸
+ 0, // ¹
+ 0, // º
+ 0, // »
+ 0, // ¼
+ 0, // ½
+ 0, // ¾
+ 0, // ¿
+ 0, // À
+ 0, // Á
+ 0, // Â
+ 0, // Ã
+ 0, // Ä
+ 0, // Å
+ 0, // Æ
+ 0, // Ç
+ 0, // È
+ 0, // É
+ 0, // Ê
+ 0, // Ë
+ 0, // Ì
+ 0, // Í
+ 0, // Î
+ 0, // Ï
+ 0, // Ð
+ 0, // Ñ
+ 0, // Ò
+ 0, // Ó
+ 0, // Ô
+ 0, // Õ
+ 0, // Ö
+ 0, // ×
+ 0, // Ø
+ 0, // Ù
+ 0, // Ú
+ 0, // Û
+ 0, // Ü
+ 0, // Ý
+ 0, // Þ
+ 0, // ß
+ 0, // à
+ ttedIsWordChar, // á
+ 0, // â
+ 0, // ã
+ 0, // ä
+ 0, // å
+ 0, // æ
+ 0, // ç
+ 0, // è
+ 0, // é
+ 0, // ê
+ 0, // ë
+ 0, // ì
+ 0, // í
+ 0, // î
+ 0, // ï
+ 0, // ð
+ 0, // ñ
+ 0, // ò
+ 0, // ó
+ 0, // ô
+ 0, // õ
+ 0, // ö
+ 0, // ÷
+ 0, // ø
+ 0, // ù
+ 0, // ú
+ 0, // û
+ 0, // ü
+ 0, // ý
+ 0, // þ
+ 0 // ÿ
+};
+
+
+/*****************************************************************************
+
+ Function: int is_symbol(char *name, uint32 l)
+
+ Parameters:
+ name: string to analyze.
+ l: length.
+
+ Return:
+ 1 if is a group of symbols.
+
+ by SET based in a Molnar's idea.
+
+*****************************************************************************/
+
+static int is_symbol(char *name, uint32 l)
+{
+ int ret=0;
+
+ while (l--)
+ {
+ if ((ret=TableTypesEditor[(uchar)*(name++)] & ttedIsCsymb)==0)
+ return 0;
+ }
+ return ret & ttedIsCsymb1 ? 1 : 2;
+}
+
+/*****************************************************************************
+
+ Function: int is_pascal_symbol(char *name, uint32 l)
+
+ Parameters:
+ name: string to analyze.
+ l: length.
+
+ Return:
+ 1 if is a group of symbols.
+
+ Differences with C:
+ @ and # are symbols.
+
+ by SET.
+
+*****************************************************************************/
+
+static int is_pascal_symbol(char *name, uint32 l)
+{
+ int ret=0;
+
+ while (l--)
+ {
+ if ((ret=TableTypesEditor[(uchar)*(name++)] & ttedIsPasSymb)==0)
+ return 0;
+ }
+ return ret & ttedIsPasSymb1 ? 1 : 2;
+}
+
+/*****************************************************************************
+
+ Function: int is_clipper_symbol(char *name, uint32 l)
+
+ Parameters:
+ name: string to analyze.
+ l: length.
+
+ Return:
+ 1 if is a group of symbols.
+
+ Differences with C:
+ @,# and $ are symbols.
+
+ by SET.
+
+*****************************************************************************/
+
+static int is_clipper_symbol(char *name, uint32 l)
+{
+ int ret=0;
+
+ while (l--)
+ {
+ if ((ret=TableTypesEditor[(uchar)*(name++)] & ttedIsClipSymb)==0)
+ return 0;
+ }
+ return 1;
+}
+
+
+inline
+static int isWordChar(char c)
+{
+ return TVCodePage::isAlNum(c) || c == '_';
+}
+
+
+void SyntaxFormatLine( TCEditor * editor,
+ char *DrawBuf,
+ uint32 LinePtr,
+ int Width,
+ uint32 Attr,
+ unsigned lineLength,
+ int seeTabs
+ )
+{
+ unsigned bufptr;
+ unsigned offset;
+ unsigned tabSize=editor->tabSize;
+ char color;
+ int in_c_comment=Attr & StartInCom;
+ int in_string=Attr & StartString;
+ uint32 word_end;
+
+ // Colored tabs stuff
+ tabFF=0;
+ tabColor=OddTabColor;
+
+ EDITOR = editor;
+ BUFFER = editor->buffer;
+ DrawBuf++;
+ lineptr = LinePtr;
+ bufptr = 0;
+ offset = 0;
+
+ // Draw until we reach the EOL of we filled the visible line
+ while (offset<=lineLength && bufptr<(unsigned)Width)
+ {
+ char c2=0;
+ int c2_valid = 0;
+
+ // Take a word
+ word_end = offset-1;
+ do
+ {
+ word_end++;
+ }
+ while (word_end <= lineLength &&
+ isWordChar(BUFFER[lineptr+word_end]));
+
+ if (word_end > lineLength ||
+ (word_end > offset && !isWordChar(BUFFER[lineptr+word_end])))
+ word_end--;
+
+ { // Analize the word
+ char *name;
+ char c1;
+ uint32 LenOfName;
+
+ name=&BUFFER[lineptr+offset];
+ c1=*name;
+ LenOfName=word_end-offset+1;
+
+ if (word_end+1<=lineLength)
+ {
+ c2_valid = 1;
+ c2 = name[1];
+ }
+
+ if (TVCodePage::isAlpha(c1))
+ color = IdentColor;
+ else
+ color = NormalColor;
+
+ if (in_c_comment)
+ { // The line is commented by the last
+ color = CommentColor;
+ word_end=0;
+ char *s=name=&BUFFER[lineptr];
+ while (word_end<lineLength)
+ {
+ if (*s=='*')
+ {
+ if (word_end<lineLength)
+ {
+ s++;
+ word_end++;
+ if (*s=='/')
+ {
+ in_c_comment=0;
+ break;
+ }
+ } // more chars
+ } // '*'
+ s++;
+ word_end++;
+ } // Of while
+ } // Is c comment
+ else
+ if (in_string || c1 == '\"')
+ {
+ uint32 ll=lineLength-1;
+ char *s=name + (LenOfName - 1); // if in_string LenOfName > 1
+ if (!(in_string && c1 == '\"')) // the line may be start with \"
+ // which means the end of the string
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='\\')
+ {
+ if (word_end<ll)
+ {
+ s++;
+ word_end++;
+ }
+ }
+ else
+ if (*s=='\"')
+ break;
+ }
+ color = StringColor;
+ in_string = 0;
+ }
+ else
+ if (c1 == '\'')
+ {
+ uint32 ll=lineLength-1;
+ char *s=name;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='\\')
+ {
+ if (word_end<ll)
+ {
+ s++;
+ word_end++;
+ }
+ }
+ else
+ if (*s=='\'')
+ break;
+ }
+ color = CharColor;
+ }
+ else
+ if (c1 == '\\')
+ color = IlegalColor;
+ else
+ if (c1 == '#')
+ color = IlegalColor;
+ else
+ if (c1 == '/' && c2_valid && (c2 == '/' || c2 == '*'))
+ {
+ color = CommentColor;
+ word_end++;
+ if (c2=='/')
+ word_end=lineLength-1; // Paint the rest of the line
+ else
+ {
+ // Search the end
+ char *s=name;
+ s++;
+ uint32 ll=lineLength-1;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='*')
+ {
+ if (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='/')
+ break;
+ } // more chars
+ } // '*'
+ } // Of while
+ } // Is c comment
+ }
+ else
+ if ((TVCodePage::isLower(c1) || c1=='_') && is_reserved(name,LenOfName))
+ color = ResColor;
+ else
+ if ((TVCodePage::isAlpha(c1) || c1=='_') && is_user_word(name,LenOfName,1))
+ color = UserColor;
+ else
+ if (ucisdigit(c1))
+ {
+ if (c1=='0' && c2_valid && (c2=='x' || c2=='X' || ucisdigit(c2)))
+ {
+ // Octal or Hexa or Invalid
+ if (is_hex(name,LenOfName))
+ color=HexColor;
+ else
+ if (is_octal(name,LenOfName))
+ color=OctalColor;
+ else
+ {
+ color=IlegalColor;
+ // Is a float camuflated?
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ if (is_integer_float(name,dispo)==2)
+ {
+ color = FloatColor;
+ word_end=lineLength-dispo-1;
+ }
+ }
+ }
+ else
+ {
+ // Integer, float or Invalid
+ // Calculate the available space in the line
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ // Check if the namber is an integer or a float or an invalid
+ // sequence
+ switch (is_integer_float(name,dispo))
+ {
+ case 0: color = IlegalColor;
+ break;
+ case 1: color = IntColor;
+ break;
+ case 2: color = FloatColor;
+ break;
+ }
+ // Adjust the length according to the routine use
+ word_end=lineLength-dispo-1;
+ }
+ }
+ else
+ if (c1=='.' && c2_valid && ucisdigit(c2))
+ {
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ // Check if the namber is a float or an invalid sequence
+ switch (is_integer_float(name,dispo))
+ {
+ case 0: color = IlegalColor;
+ break;
+ case 2: color = FloatColor;
+ break;
+ }
+ // Adjust the length according to the routine use
+ word_end=lineLength-dispo-1;
+ }
+ else
+ switch (is_symbol(name,LenOfName))
+ {
+ case 1: color = SymbolColor;
+ break;
+ case 2: color = Symbol2Color;
+ break;
+ }
+
+ while (offset<=word_end && bufptr<(unsigned)Width)
+ {
+ if (*(name++)=='\t')
+ {
+ int tabcount=tabSize-(bufptr % tabSize);
+ if (seeTabs)
+ { // It paints the tabs to be visible
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=tabColor;
+ ToggleTabColor();
+ }
+ else
+ {
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=color;
+ }
+ }
+ else
+ {
+ DrawBuf[bufptr*2]=color;
+ bufptr++;
+ }
+ offset++;
+ }
+ }
+ }
+}
+
+
+
+void SyntaxFormatLinePascal( TCEditor * editor,
+ char *DrawBuf,
+ uint32 LinePtr,
+ int Width,
+ int check_comment_1,
+ int check_comment_2,
+ unsigned lineLength,
+ int seeTabs
+ )
+{
+ unsigned bufptr;
+ unsigned tabSize=editor->tabSize;
+ unsigned offset;
+ char color;
+ // Colored tabs stuff
+ tabFF=0;
+ tabColor=OddTabColor;
+
+ EDITOR = editor;
+ BUFFER = editor->buffer;
+ DrawBuf++;
+ lineptr = LinePtr;
+ bufptr = 0;
+ offset = 0;
+
+ {
+ int in_comment1=check_comment_1;
+ int in_comment2=check_comment_2;
+ uint32 word_end;
+ while (offset<=lineLength && bufptr<(unsigned)Width)
+ {
+ char c2=0;
+ int c2_valid = 0;
+ word_end = offset-1;
+ do
+ {
+ word_end++;
+ }
+ while (word_end <= lineLength &&
+ isWordChar(BUFFER[lineptr+word_end]));
+
+ if (word_end > lineLength ||
+ (word_end > offset && !isWordChar(BUFFER[lineptr+word_end])))
+ word_end--;
+
+ {
+ char *name;
+ char c1;
+ uint32 LenOfName;
+
+ name=&BUFFER[lineptr+offset];
+ c1=*name;
+ LenOfName=word_end-offset+1;
+
+ if (word_end+1<=lineLength)
+ {
+ c2_valid = 1;
+ c2 = BUFFER[lineptr+offset+1];
+ }
+
+ if (TVCodePage::isAlpha(c1))
+ color = IdentColor;
+ else
+ color = NormalColor;
+
+ if (in_comment1)
+ { // The line is commented by the last
+ color = CommentColor;
+ word_end=0;
+ char *s=name=&BUFFER[lineptr];
+ while (word_end<lineLength)
+ {
+ s++;
+ word_end++;
+ if (*s=='*')
+ {
+ if (word_end<lineLength)
+ {
+ s++;
+ word_end++;
+ if (*s==')')
+ {
+ in_comment1=0;
+ break;
+ }
+ } // more chars
+ } // '*'
+ } // Of while
+ } // Is comment 1
+ else
+ if (in_comment2)
+ { // The line is commented by the last
+ color = CommentColor;
+ word_end=0;
+ char *s=name=&BUFFER[lineptr];
+ while (word_end<lineLength)
+ {
+ s++;
+ word_end++;
+ if (*s=='}')
+ {
+ in_comment2=0;
+ break;
+ } // '}'
+ } // Of while
+ } // Is comment 2
+ else
+ if (c1 == '\'')
+ {
+ uint32 ll=lineLength-1;
+ char *s=name;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='\'')
+ break;
+ }
+ color = StringColor;
+ }
+ else
+ if (c1 == '\\')
+ color = IlegalColor;
+ else
+ if (c1 == '(' && c2_valid && c2 == '*')
+ {
+ color = CommentColor;
+ word_end++;
+ // Search the end
+ char *s=name;
+ s++;
+ uint32 ll=lineLength-1;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='*')
+ {
+ if (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s==')')
+ break;
+ } // more chars
+ } // '*'
+ } // Of while
+ }
+ else
+ if (c1 == '{')
+ {
+ color = CommentColor;
+ word_end++;
+ // Search the end
+ char *s=name;
+ s++;
+ uint32 ll=lineLength-1;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='}')
+ break;
+ } // Of while
+ }
+ else
+ if (is_pascal_rword(name,LenOfName))
+ color = ResColor;
+ else
+ if (is_user_word(name,LenOfName,1))
+ color = UserColor;
+ else
+ if (c1=='$')
+ {
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ if (dispo && is_pascal_hex(name,dispo))
+ color=HexColor;
+ else
+ {
+ color=IlegalColor;
+ dispo--;
+ }
+ word_end=lineLength-dispo-1;
+ }
+ else
+ if (ucisdigit(c1))
+ {
+ // Integer, float or Invalid
+ // Calculate the available space in the line
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ // Check if the namber is an integer or a float or an invalid
+ // sequence
+ switch (is_pascal_integer_float(name,dispo))
+ {
+ case 0: color = IlegalColor;
+ break;
+ case 1: color = IntColor;
+ break;
+ case 2: color = FloatColor;
+ break;
+ }
+ // Adjust the length according to the routine use
+ word_end=lineLength-dispo-1;
+ }
+ else
+ if (c1=='.' && c2_valid && ucisdigit(c2))
+ {
+ color = IlegalColor;
+ word_end++;
+ }
+ else
+ if (c1=='.' && c2_valid && c2=='.')
+ {
+ color = Symbol2Color;
+ word_end++;
+ }
+ else
+ switch (is_pascal_symbol(name,LenOfName))
+ {
+ case 1: color = SymbolColor;
+ break;
+ case 2: color = Symbol2Color;
+ break;
+ }
+
+ while (offset<=word_end && bufptr<(unsigned)Width)
+ {
+ if (*(name++)=='\t')
+ {
+ int tabcount=tabSize-(bufptr % tabSize);
+ if (seeTabs)
+ { // It paints the tabs to be visible
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=tabColor;
+ ToggleTabColor();
+ }
+ else
+ {
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=color;
+ }
+ }
+ else
+ {
+ DrawBuf[bufptr*2]=color;
+ bufptr++;
+ }
+ offset++;
+ }
+ }
+ }
+ }
+}
+
+
+void SyntaxFormatLineClipper( TCEditor * editor,
+ char *DrawBuf,
+ uint32 LinePtr,
+ int Width,
+ int check_c_comment,
+ unsigned lineLength,
+ int seeTabs
+ )
+{
+ unsigned bufptr;
+ unsigned offset;
+ unsigned tabSize=editor->tabSize;
+ char color;
+ // Colored tabs stuff
+ tabFF=0;
+ tabColor=OddTabColor;
+
+ EDITOR = editor;
+ BUFFER = editor->buffer;
+ DrawBuf++;
+ lineptr = LinePtr;
+ bufptr = 0;
+ offset = 0;
+
+ {
+ int in_c_comment=check_c_comment;
+ uint32 word_end;
+ while (offset<=lineLength && bufptr<(unsigned)Width)
+ {
+ char c2=0,c3=0;
+ int c2_valid=0, c3_valid=0;
+ word_end = offset-1;
+ do
+ {
+ word_end++;
+ }
+ while (word_end <= lineLength &&
+ isWordChar(BUFFER[lineptr+word_end]));
+
+ if (word_end > lineLength ||
+ (word_end > offset && !isWordChar(BUFFER[lineptr+word_end])))
+ word_end--;
+
+ {
+ char *name;
+ char c1;
+ uint32 LenOfName;
+
+ name=&BUFFER[lineptr+offset];
+ c1=*name;
+ LenOfName=word_end-offset+1;
+
+ if (word_end+1<=lineLength)
+ {
+ c2_valid = 1;
+ c2 = BUFFER[lineptr+offset+1];
+ }
+
+ if (word_end+2<=lineLength)
+ {
+ c3_valid = 1;
+ c3 = BUFFER[lineptr+offset+2];
+ }
+
+ if (TVCodePage::isAlpha(c1))
+ color = IdentColor;
+ else
+ color = NormalColor;
+
+ if (in_c_comment)
+ { // The line is commented by the last
+ color = CommentColor;
+ word_end=0;
+ char *s=name=&BUFFER[lineptr];
+ while (word_end<lineLength)
+ {
+ if (*s=='*')
+ {
+ if (word_end<lineLength)
+ {
+ s++;
+ word_end++;
+ if (*s=='/')
+ {
+ in_c_comment=0;
+ // Check for extra chars after the end of a comment,
+ // Clipper 5 doesn't support this
+ while (word_end<lineLength-1)
+ {
+ s++;
+ if (!ucisspace(*s) && *s!=26) // Let the EOF
+ {
+ word_end=lineLength-1;
+ color=IlegalColor;
+ break;
+ }
+ word_end++;
+ }
+ break;
+ }
+ } // more chars
+ } // '*'
+ s++;
+ word_end++;
+ } // Of while
+ } // Is c comment
+ else
+ // Strings as "xxxx"
+ if (c1 == '\"')
+ {
+ uint32 ll=lineLength-1;
+ char *s=name;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='\"')
+ break;
+ }
+ color = StringColor;
+ }
+ else
+ // Strings as 'xxxx' are supported too
+ if (c1 == '\'')
+ {
+ uint32 ll=lineLength-1;
+ char *s=name;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='\'')
+ break;
+ }
+ color = StringColor;
+ }
+ else
+ if (c1 == '\\')
+ color = IlegalColor;
+ else
+ // The C++ comments and C comments are supported
+ if (c1 == '/' && c2_valid && (c2 == '/' || c2 == '*'))
+ {
+ color = CommentColor;
+ word_end++;
+ if (c2=='/')
+ word_end=lineLength-1; // Paint the rest of the line
+ else
+ {
+ // Search the end
+ char *s=name;
+ s++;
+ uint32 ll=lineLength-1;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='*')
+ {
+ if (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='/')
+ break;
+ } // more chars
+ } // '*'
+ } // Of while
+ } // Is c comment
+ }
+ else
+ // The && is like // in C++, is arkaic but ...
+ if (c1=='&' && c2_valid && c2=='&')
+ {
+ color = CommentColor;
+ word_end=lineLength-1; // Paint the rest of the line
+ }
+ else
+ // The '* -' is like // in C++, is arkaic but ...
+ if (c1=='*' && c2_valid && c2==' ' && c3_valid && c3=='-')
+ {
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ if (dispo>3)
+ {
+ // Clipper 5 doesn't support this if there is no comment
+ color = CommentColor;
+ word_end=lineLength-1; // Paint the rest of the line
+ }
+ else
+ {
+ word_end+=2;
+ color=IlegalColor;
+ }
+ }
+ else
+ if (is_clipper_rword(name,LenOfName))
+ color = ResColor;
+ else
+ if (is_user_word(name,LenOfName,0))
+ color = UserColor;
+ else
+ if (ucisdigit(c1))
+ {
+ // Integer, float or Invalid
+ // Calculate the available space in the line
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ // Check if the namber is an integer or a float or an invalid
+ // sequence
+ switch (is_integer_float(name,dispo))
+ {
+ case 0: color = IlegalColor;
+ break;
+ case 1: color = IntColor;
+ break;
+ case 2: color = FloatColor;
+ break;
+ }
+ // Adjust the length according to the routine use
+ word_end=lineLength-dispo-1;
+ }
+ else
+ // Clipper supports .NNNN floats
+ if (c1=='.' && c2_valid && ucisdigit(c2))
+ {
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ // Check if the number is a float or an invalid sequence
+ switch (is_integer_float(name,dispo))
+ {
+ case 0: color = IlegalColor;
+ break;
+ case 2: color = FloatColor;
+ break;
+ }
+ // Adjust the length according to the routine use
+ word_end=lineLength-dispo-1;
+ }
+ else
+ // .t. .f. .and. .or. are special
+ if (c1=='.' && c2_valid && TVCodePage::isAlpha(c2))
+ {
+ uint32 ll=lineLength-1;
+ int ok=0;
+ char *s=name+1;
+ char *s1=s;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s=='.')
+ {
+ word_end++;
+ ll=(uint32)(s-s1);
+ switch (ll)
+ {
+ case 1:
+ ok = *s1=='t' || *s1=='T' || *s1=='f' ||
+ *s1=='F' || *s1=='y' || *s1=='Y' ||
+ *s1=='n' || *s1=='N';
+ break;
+ case 2:
+ ok = (*s1=='o' || *s1=='O') &&
+ (*(s1+1)=='r' || *(s1+1)=='R');
+ break;
+ case 3:
+ ok = ((*s1=='a' || *s1=='A') &&
+ (*(s1+1)=='n' || *(s1+1)=='N') &&
+ (*(s1+2)=='d' || *(s1+2)=='D')) ||
+ ((*s1=='n' || *s1=='N') &&
+ (*(s1+1)=='o' || *(s1+1)=='O') &&
+ (*(s1+2)=='t' || *(s1+2)=='T'));
+ break;
+ }
+ if (ok)
+ color = ResColor;
+ else
+ color = IlegalColor;
+ break;
+ }
+ if (!TVCodePage::isAlpha(*s))
+ {
+ color = IlegalColor;
+ break;
+ }
+ }
+ }
+ else
+ if (is_clipper_symbol(name,LenOfName))
+ color = SymbolColor;
+
+ while (offset<=word_end && bufptr<(unsigned)Width)
+ {
+ if (*(name++)=='\t')
+ {
+ int tabcount=tabSize-(bufptr % tabSize);
+ if (seeTabs)
+ { // It paints the tabs to be visible
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=tabColor;
+ ToggleTabColor();
+ }
+ else
+ {
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=color;
+ }
+ }
+ else
+ {
+ DrawBuf[bufptr*2]=color;
+ bufptr++;
+ }
+ offset++;
+ }
+ }
+ }
+ }
+}
+
+char CheckSeqCase;
+
+int CheckForSequence(char *s, int len, int available, char *d)
+{
+ int pos;
+
+ if (available<len || len==0)
+ return 0;
+ if (CheckSeqCase)
+ for (pos=0; pos<len && s[pos]==d[pos]; pos++);
+ else
+ for (pos=0; pos<len && s[pos]==TVCodePage::toUpper(d[pos]); pos++);
+ return pos==len;
+}
+
+
+int CheckForSequenceNotFirst(char *s, int len, int available, char *d)
+{
+ int pos;
+
+ if (available<len || len==0)
+ return 0;
+ if (CheckSeqCase)
+ for (pos=1; pos<len && s[pos]==d[pos]; pos++);
+ else
+ for (pos=1; pos<len && s[pos]==TVCodePage::toUpper(d[pos]); pos++);
+ return pos==len;
+}
+
+
+void SyntaxFormatLineGeneric(TCEditor * editor,
+ char *DrawBuf,
+ uint32 LinePtr,
+ int Width,
+ uint32 Attr,
+ unsigned lineLength,
+ int seeTabs
+ )
+{
+ unsigned bufptr;
+ unsigned offset;
+ unsigned tabSize=editor->tabSize;
+ char color;
+ int in_c_comment1=Attr & StartInCom;
+ int in_c_comment2=Attr & StartInCom2;
+ int in_string =Attr & StartString;
+ int in_string2=Attr & StartString2;
+ int in_string3=Attr & StartString3;
+ uint32 word_end;
+ char Escape;
+ int TestNumbers,isInFirstCol=1,PartialKeywords,RelaxNumbers;
+ int isInFirstUsed=1,checkEOLC1=1,checkEOLC2=1;
+ int EscapeAnywhere, VHDLNumbers, VHDLStr1, VHDLStr2, VHDLShortStr;
+
+ // Set the Case Sensitive comparation status to check sequence
+ CheckSeqCase =(TCEditor::strC.Flags1 & FG1_CaseSensitive)!=0;
+ TestNumbers =(TCEditor::strC.Flags1 & FG1_NoNumbers)==0;
+ PartialKeywords =(TCEditor::strC.Flags1 & FG1_PartialKeyword)!=0;
+ RelaxNumbers =(TCEditor::strC.Flags1 & FG1_RelaxNumbers)!=0;
+ EscapeAnywhere =(TCEditor::strC.Flags2 & FG2_EscapeAnywhere)!=0;
+ VHDLNumbers =(TCEditor::strC.Flags2 & FG2_VHDLNumbers)!=0;
+ VHDLStr1 =(TCEditor::strC.Flags2 & FG2_VHDLStr1)!=0;
+ VHDLStr2 =(TCEditor::strC.Flags2 & FG2_VHDLStr2)!=0;
+ VHDLShortStr =(TCEditor::strC.Flags2 & FG2_VHDLShortStr)!=0;
+ EDITOR = editor;
+ // Colored tabs stuff
+ tabFF=0;
+ tabColor=OddTabColor;
+
+ DrawBuf++;
+ lineptr = LinePtr;
+ BUFFER = &(editor->buffer[lineptr]);
+ bufptr = 0;
+ offset = 0;
+
+ // Draw until we reach the EOL of we filled the visible line
+ while (offset<=lineLength && bufptr<(unsigned)Width)
+ {
+ char c2=0;
+ int c2_valid = 0;
+
+ // Eat spaces
+ color = NormalColor;
+ while (offset<=lineLength && bufptr<(unsigned)Width && ucisspace(BUFFER[offset]))
+ {
+ if (BUFFER[offset]=='\t')
+ {
+ int tabcount=tabSize-(bufptr % tabSize);
+ if (seeTabs)
+ { // It paints the tabs to be visible
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=tabColor;
+ ToggleTabColor();
+ }
+ else
+ {
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=color;
+ }
+ }
+ else
+ {
+ DrawBuf[bufptr*2]=color;
+ bufptr++;
+ }
+ offset++;
+ }
+ if (offset>=lineLength || bufptr==(unsigned)Width)
+ return;
+
+ if (isInFirstCol && bufptr!=0)
+ {
+ isInFirstCol=0;
+ if (TCEditor::strC.Flags1 & FG1_EOLCInFirstCol1)
+ checkEOLC1=0;
+ if (TCEditor::strC.Flags1 & FG1_EOLCInFirstCol2)
+ checkEOLC2=0;
+ }
+ // Take a word
+ word_end = offset;
+ if (!in_c_comment1 && !in_c_comment2)
+ {
+ if (word_end<=lineLength && isWordCharBe(BUFFER[word_end]))
+ {
+ do
+ {
+ word_end++;
+ }
+ while (word_end<=lineLength && isWordCharIn(BUFFER[word_end]));
+ }
+
+ if (word_end > lineLength ||
+ (word_end > offset && !isWordCharIn(BUFFER[word_end])))
+ word_end--;
+ }
+
+ { // Analize the word
+ char *name;
+ char c1;
+ uint32 LenOfName,BytesLeft;
+
+ name=&BUFFER[offset];
+ c1=*name;
+ LenOfName=word_end-offset+1;
+ BytesLeft=lineLength-offset;
+
+ if (word_end+1<=lineLength)
+ {
+ c2_valid = 1;
+ c2 = name[1];
+ }
+
+ if (TVCodePage::isAlpha(c1))
+ color = IdentColor;
+ else
+ color = NormalColor;
+
+ if (in_c_comment1)
+ { // The line is commented by the last
+ color=CommentColor;
+ char *s=name=BUFFER+word_end;
+ while (word_end<lineLength)
+ {
+ if (CheckForSequence(TCEditor::strC.CloseCom1,TCEditor::strC.lCloseCom1,BytesLeft,&BUFFER[word_end]))
+ {
+ word_end+=TCEditor::strC.lCloseCom1-1;
+ in_c_comment1=0;
+ break;
+ }
+ s++;
+ word_end++;
+ BytesLeft--;
+ } // Of while
+ } // Is c comment
+ else
+ if (in_c_comment2)
+ { // The line is commented by the last
+ color=CommentColor;
+ char *s=name=BUFFER+word_end;
+ while (word_end<lineLength)
+ {
+ if (CheckForSequence(TCEditor::strC.CloseCom2,TCEditor::strC.lCloseCom2,BytesLeft,&BUFFER[word_end]))
+ {
+ word_end+=TCEditor::strC.lCloseCom2-1;
+ in_c_comment2=0;
+ break;
+ }
+ s++;
+ word_end++;
+ BytesLeft--;
+ } // Of while
+ } // Is c comment
+ else
+ if (EscapeAnywhere && c2_valid && c1==TCEditor::strC.Escape)
+ {
+ color = SymbolColor;
+ word_end=offset+1;
+ }
+ else
+ if (in_string || isString(c1))
+ {
+ uint32 ll=lineLength-1;
+ char *s=name+(LenOfName-1); // if in_string LenOfName>1
+ Escape=TCEditor::strC.Escape;
+ if (!(in_string && isString(c1))) // the line may start with \"
+ // which means the end of the string
+ {
+ in_string=1;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s==Escape)
+ {
+ if (word_end<ll)
+ {
+ s++;
+ word_end++;
+ }
+ }
+ else
+ if (isString(*s))
+ {
+ if (VHDLStr1 && word_end<ll && isString(s[1]))
+ {// String literals 13.6
+ s++;
+ word_end++;
+ }
+ else
+ {
+ in_string=0;
+ break;
+ }
+ }
+ }
+ }
+ if (in_string && VHDLStr1)
+ color=IlegalColor;
+ else
+ color=StringColor;
+ in_string=0;
+ }
+ else // Repeated for string2
+ if (in_string2 || isString2(c1))
+ {
+ uint32 ll=lineLength-1;
+ char *s=name+(LenOfName-1); // if in_string LenOfName>1
+ Escape=TCEditor::strC.Escape;
+ if (!(in_string2 && isString2(c1))) // the line may start with \"
+ // which means the end of the string
+ {
+ in_string=1;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s==Escape)
+ {
+ if (word_end<ll)
+ {
+ s++;
+ word_end++;
+ }
+ }
+ else
+ if (isString2(*s))
+ {
+ if (VHDLStr2 && word_end<ll && isString2(s[1]))
+ {
+ s++;
+ word_end++;
+ }
+ else
+ {
+ in_string=0;
+ break;
+ }
+ }
+ }
+ }
+ if (in_string && VHDLStr2)
+ color=IlegalColor;
+ else
+ color=CharColor;
+ in_string=0;
+ }
+ else // Repeated for string3
+ if (in_string3 || isString3(c1))
+ {
+ uint32 ll=lineLength-1;
+ char *s=name + (LenOfName - 1); // if in_string LenOfName > 1
+ Escape=TCEditor::strC.Escape;
+ if (!(in_string3 && isString3(c1))) // the line may be start with \"
+ // which means the end of the string
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s==Escape)
+ {
+ if (word_end<ll)
+ {
+ s++;
+ word_end++;
+ }
+ }
+ else
+ if (isString3(*s))
+ break;
+ }
+ color = StringColor;
+ in_string3 = 0;
+ }
+ else
+ if (isCharacter(c1))
+ {
+ uint32 ll=lineLength-1;
+ char *s=name;
+ if (VHDLShortStr)
+ {// Character literals 13.5
+ if (ll>=2 && isCharacter(s[2]))
+ {
+ s+=2;
+ word_end+=2;
+ }
+ }
+ else
+ {
+ Escape=TCEditor::strC.Escape;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ if (*s==Escape)
+ {
+ if (word_end<ll)
+ {
+ s++;
+ word_end++;
+ }
+ }
+ else
+ if (isCharacter(*s))
+ break;
+ }
+ }
+ color=CharColor;
+ }
+ else
+ if (c1==TCEditor::strC.Preprocessor || c1==TCEditor::strC.Preprocessor2)
+ color = IlegalColor;
+ else
+ if (CheckForSequence(TCEditor::strC.OpenCom1,TCEditor::strC.lOpenCom1,BytesLeft,name))
+ {
+ color = CommentColor;
+ word_end++;
+ // Search the end
+ char *s=name;
+ s++;
+ uint32 ll=lineLength-1;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ BytesLeft--;
+ if (CheckForSequence(TCEditor::strC.CloseCom1,TCEditor::strC.lCloseCom1,BytesLeft,s))
+ {
+ word_end++;
+ break;
+ }
+ } // Of while
+ }
+ else
+ if (CheckForSequence(TCEditor::strC.OpenCom2,TCEditor::strC.lOpenCom2,BytesLeft,name))
+ {
+ color = CommentColor;
+ word_end++;
+ // Search the end
+ char *s=name;
+ s++;
+ uint32 ll=lineLength-1;
+ while (word_end<ll)
+ {
+ s++;
+ word_end++;
+ BytesLeft--;
+ if (CheckForSequence(TCEditor::strC.CloseCom2,TCEditor::strC.lCloseCom2,BytesLeft,s))
+ {
+ word_end++;
+ break;
+ }
+ } // Of while
+ }
+ else
+ if ((checkEOLC1 &&
+ CheckForSequence(TCEditor::strC.EOLCom1,TCEditor::strC.lEOLCom1,BytesLeft,name))
+ ||
+ (checkEOLC2 &&
+ CheckForSequence(TCEditor::strC.EOLCom2,TCEditor::strC.lEOLCom2,BytesLeft,name)))
+ {
+ color = CommentColor;
+ word_end=lineLength-1; // Paint the rest of the line
+ }
+ else
+ if (CheckForSequence(TCEditor::strC.HexStart,TCEditor::strC.lHexStart,BytesLeft,name))
+ {
+ int extra=TCEditor::strC.lHexStart;
+ uint32 dispo=lineLength-word_end+LenOfName-extra;
+ name+=extra-1;
+ if (dispo && is_pascal_hex(name,dispo))
+ color=HexColor;
+ else
+ {
+ color=IlegalColor;
+ dispo--;
+ }
+ name-=extra-1;
+ word_end=lineLength-dispo-1;
+ }
+ else
+ if (TestNumbers && ucisdigit(c1))
+ {
+ // Integer, float or Invalid
+ // Calculate the available space in the line
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ // Check if the number is an integer or a float or an invalid
+ // sequence
+ int res=VHDLNumbers ? isVHDLAbstractLiteral(name,dispo) :
+ is_pascal_integer_float(name,dispo);
+ switch (res)
+ {
+ case 0:
+ color=RelaxNumbers ? NormalColor : IlegalColor;
+ break;
+ case 1:
+ color=IntColor;
+ break;
+ case 2:
+ color=FloatColor;
+ break;
+ }
+ // Adjust the length according to the routine use
+ if (res!=3)
+ word_end=lineLength-dispo-1;
+ }
+ else
+ if (TestNumbers && !VHDLNumbers && c1=='.' && c2_valid && ucisdigit(c2))
+ {
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ // Check if the namber is a float or an invalid sequence
+ switch (is_integer_float(name,dispo))
+ {
+ case 0: color = RelaxNumbers ? NormalColor : IlegalColor;
+ break;
+ case 2: color = FloatColor;
+ break;
+ }
+ // Adjust the length according to the routine use
+ word_end=lineLength-dispo-1;
+ }
+ else
+ if (!PartialKeywords && isGeneralReservedWord(name,LenOfName,CheckSeqCase,TCEditor::strC.Search))
+ color = ResColor;
+ else // Check if a user word does a full match before checking for a partial
+ // match with a reserved (@ref v.s. @refMenu).
+ if (is_user_word(name,LenOfName,CheckSeqCase))
+ color = UserColor;
+ else
+ if (PartialKeywords && isPartialKeyword(name,LenOfName,CheckSeqCase,TCEditor::strC.Keywords,word_end))
+ color = ResColor;
+ else
+ if (isSpecialSymb(*name) && c2_valid && isSpecialSCon(c2))
+ {
+ color = SymbolColor;
+ word_end=offset+1;
+ }
+ else
+ if (isSymbol1(*name))
+ {
+ color = SymbolColor;
+ word_end=offset;
+ }
+ else
+ if (isSymbol2(*name))
+ {
+ color = Symbol2Color;
+ word_end=offset;
+ }
+ else
+ if (c1==TCEditor::strC.Escape)
+ color=IlegalColor;
+ else
+ if (TestNumbers && VHDLNumbers && (c1=='B' || c1=='O' || c1=='X' ||
+ c1=='b' || c1=='o' || c1=='x'))
+ {// VHDL Bit String Literals, at the end because they are a mess ...
+ // Note that we highlight them as integers.
+ uint32 dispo=lineLength-word_end+LenOfName-1;
+ int res=isVHDLBitStringLiteral(name,dispo);
+ switch (res)
+ {
+ case 0:
+ color=RelaxNumbers ? NormalColor : IlegalColor;
+ break;
+ case 1:
+ color=IntColor;
+ break;
+ }
+ if (res!=3)
+ word_end=lineLength-dispo-1;
+ }
+
+
+ while (offset<=word_end && bufptr<(unsigned)Width)
+ {
+ if (*(name++)=='\t')
+ {
+ int tabcount=tabSize-(bufptr % tabSize);
+ if (seeTabs)
+ { // It paints the tabs to be visible
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=tabColor;
+ ToggleTabColor();
+ }
+ else
+ {
+ while (tabcount--)
+ DrawBuf[(bufptr++)*2]=color;
+ }
+ }
+ else
+ {
+ DrawBuf[bufptr*2]=color;
+ bufptr++;
+ }
+ offset++;
+ }
+ }
+ if (isInFirstUsed)
+ {
+ isInFirstUsed=0;
+ if (TCEditor::strC.Flags1 & FG1_EOLCInFirstUse1)
+ checkEOLC1=0;
+ if (TCEditor::strC.Flags2 & FG2_EOLCInFirstUse2)
+ checkEOLC2=0;
+ }
+ }
+}