|
|
Im folgenden habe ich die neuen Sprachelemente einmal ein wenig in einem neuen Programm verwendet, dass das Syntax-Highlighting, die Formatierung der Programmtexte hier im Oma-Tutorial, durchführt. Die Betonung liegt auf "ein wenig". Das Programm ist weit davon entfernt, ein richtiges objektorientiertes Programm zu sein. Aber für so ein kleines Programm wäre das auch gar nicht zweckmässig. Immerhin lernen wir sogar eine Stelle kennen, an der "Vererbung" - ein Sprachelement, das Freebasic in Version 20 noch nicht besitzt, sinnvoll eingesetzt werden könnte.
Ziel ist es, ein Programm zu schreiben, das einen HTML-Text durchgeht, die Basic-Programme selbstständig als solche identifiziert, alle Freebasic-Schlüsselwörter in einer Farbe einfärbt, alle Strings in einer anderen und alle Kommentare in einer dritten. Ausserdem sollte es dafür sorgen, dass alle Schlüsselwörter gross geschrieben sind. Das Programm soll auf der Kommandozeile mittels "fboutline
HTML heisst "HyperText Markup Language" und ist sozusagen die Grundlage des World Wide Web. Es sind einfache Textseiten, die allerdings dazwischen immer wieder Schlüsselwörter haben, die zwischen zwei spitzen Klammern eingebettet sind. <b> wäre so ein Beispiel. Oder <font color=blue >. Es gibt immer zwei Tags, ein Öffnen-Tag und Schliess-Tag. <b> Fett </b> würde z.B. das Wort "Fett" fett machen. Den Textbereich, den wir blau machen wollten, müssten wir mit <font color=blue > und </font> einrahmen.
Es wird nicht so kompliziert, wie man hier befürchten mag, da die BASIC-Texte selbst keine Tags enthalten, sondern nur von einem bestimmten Tag-Paar eingerahmt sind. Es heisst <pre> und <pre> und sorgt dafür, dass aller Text dazwischen in Blocksatz und mit Leerzeichen ausgedruckt wird. Das einzige Problem ist, dass dieses pre-Tag nicht nur für Programmtexte, sondern auch für Tabellen u.a. hergenommen wird.
Das Erste ist, den ganzen Text nach <pre>-Tags abzusuchen. Und alles davor unbesehen rauszuschreiben. Wenn das <pre>-Tag kommt, wird's spannend. Dann müssen wir erstmal alles bis zum Endtag beschnüffeln, also einlesen und untersuchen: Ist es ein BASIC-Text oder nicht? Wir nehmen dazu eine ganz einfache Methode: Wir zählen die darin vorkommenden BASIC-Schlüsselworte und wenn es mehr als 2 sind, dann halten wir das einfach mal für BASIC.
Als Nächstes gehen wir nochmals den ganzen pre-Text, der ja nun als BASIC-Text erkannt wurde, durch. Treffen wir auf ein Schlüsselwort, rahmen wir es mit einem font-Tag ein und konvertieren alles innerhalb in Grossbuchstaben. Ausserdem kontrollieren wir auf einfache und doppelte Anführungszeichen. Alles dazwischen wird auch in ein font-Tag gepackt, einmal mit Farbe "Kommentar" und einem mit Farbe "String". Fertig. Sollte eigentlich nicht schwer sein, oder?
Wir können in unserer Liste schon ein paar Aufgaben identifizieren, die wir uns genauer anschauen sollten:
Beim Speichern der Texte gilt es zu beachten, dass Texte in der Regel in Absätze unterteilt sind und ein Absatz eine nahezu beliebige Länge haben kann. Ebenso kann ein BASIC-Text ziemlich unterschiedlich lang sein, von 1 bis 1000 Zeilen ist da alles drin. Wir können also nicht einfach ein 2-dimensionales statisches Array hernehmen – das würde 1000 x 100.000 Bytes = 1 GByte benötigen – sau-unschön.
Hier bietet sich unsere erste Klasse an. Im Idealfall verwaltet sie eine Container-Liste von Zeilen; um hier das Beispiel nicht zu überfrachten, nehmen wir ein Array aus zstring-Zeigern. Das packen wir in eine Klasse und überlassen es dieser, für Allokation und Freigabe des Speicherplatzes belegter Zeilen zu sorgen.
type textbuf
buf AS ZSTRING PTR PTR
nline AS INTEGER
bufsize AS INTEGER
NAME AS STRING
'Der wird nur formal gebraucht, wegen "Vererbung" bei tokenbuf
DECLARE CONSTRUCTOR()
'Der wird wirklich gebraucht:
DECLARE CONSTRUCTOR(bufsize AS INTEGER, NAME0 AS STRING = "noname")
DECLARE SUB init(bufsize AS INTEGER, NAME0 AS STRING = "noname")
DECLARE DESTRUCTOR()
DECLARE SUB add(s AS string)
DECLARE SUB change(i AS INTEGER, s AS string)
DECLARE FUNCTION OUT(i AS INTEGER) AS STRING
DECLARE SUB fprint0(fileno AS integer)
DECLARE SUB print0
DECLARE SUB CLEAR
END type
' ------------------------------------------------------------------
SUB brkmess(mess AS string)
PRINT mess
END
END SUB
' ------------------------------------------------------------------
CONSTRUCTOR textbuf()
'Leer, da der nur formal gebraucht wird, wegen "Vererbung" bei tokenbuf
END CONSTRUCTOR
' ------------------------------------------------------------------
CONSTRUCTOR textbuf(bufsize0 AS INTEGER, NAME0 AS STRING = "noname")
init(bufsize0,NAME0)
END CONSTRUCTOR
' ------------------------------------------------------------------
SUB textbuf.init(bufsize0 AS INTEGER, NAME0 AS STRING = "noname")
THIS.nline=0
THIS.bufsize=bufsize0
buf=ALLOCATE(bufsize0*SIZEOF(ZSTRING PTR))
IF (buf=0) THEN brkmess("textbuf error: allocation failed")
DIM i AS INTEGER
FOR i=0 TO bufsize-1:buf[i]=0:NEXT i
THIS.NAME=name0
END SUB
' ------------------------------------------------------------------
DESTRUCTOR textbuf()
DIM i AS INTEGER
FOR i=0 TO nline-1
DEALLOCATE buf[i]
NEXT i
DEALLOCATE THIS.buf
THIS.buf=0
END DESTRUCTOR
' ------------------------------------------------------------------
SUB textbuf.add(s AS string)
IF nline>bufsize THEN brkmess("textbuf error: buffer overflow")
buf[nline]=ALLOCATE(LEN(s)+10)
*buf[nline]= s
nline=nline+1
END SUB
' ------------------------------------------------------------------
SUB textbuf.change(i AS INTEGER, s AS string)
IF buf[i]=0 THEN brkmess("error textbuf.change() buf[i] not allocated")
DEALLOCATE buf[i]
buf[i]=ALLOCATE(LEN(s)+10)
*buf[i]=s
END SUB
' ------------------------------------------------------------------
FUNCTION textbuf.OUT(i AS INTEGER) AS STRING
textbuf.OUT=buf[i][0]
END FUNCTION
' ------------------------------------------------------------------
SUB textbuf.CLEAR()
DIM i AS INTEGER
FOR i=0 TO nline-1
add("")
NEXT i
nline=0
END SUB
' ------------------------------------------------------------------
SUB textbuf.print0
DIM i AS INTEGER
PRINT name;":"
PRINT "----------------------------"
FOR i=0 TO nline-1
PRINT i,OUT(i)
NEXT i
END SUB
' ------------------------------------------------------------------
SUB textbuf.fprint0(fileno AS integer)
DIM i AS INTEGER
FOR i=0 TO nline-1
PRINT #fileno,OUT(i)
NEXT i
END SUB
Unsere Klasse hat einen parametrisierten Konstruktor, die Parameter sind Zeilenzahl (bufsize) und ein Name. Letzterer ist für jede Klasse praktisch, wenn man ihre Inhalt auf den Bildschirm oder in ein Logfile schreibt. Allerdings kommt dann nochmal eine init-Routine der gleichen Form vor. Das liegt daran, dass der Aufruf von statisch deklarierten Konstruktoren, wenn sie Parameter benötigen, in Freebasic derzeit noch nicht möglich ist. Der Konstruktor ruft einfach nur die init-Routine auf, damit werden Code-Dopplungen vermieden. Das eigentliche Schicke ist der Destruktor. Er wird automatisch immer aufgerufen, wenn ein statisches, lokales Objekt seine Gültigkeit verliert und gibt die reservierten Zeilen frei.
Nun wollen wir ja Tags in die Zeilen einfügen. Das klingt ganz einfach, ist es aber dann nicht, wenn wir den Speicherplatz für jede Zeile massgeschneidert reserviert haben. Dann haben wir nämlich im String gar keinen Platz für Einfügungen. Natürlich können wir ganz naiv mit "+" die Strings aneinanderhängen. Aber in dem Moment, in dem wir das in unseren ursprünglichen Stringspeicher zurücksichern, macht's "Peng" – oder etwas später. Daher brauchen wir eine Methode change(), die den alten Speicher freigibt und neuen der passenden Grösse reserviert.
Der Textspeicher genügt uns als Zwischenspeicher für den gesamten Programmtext, aber für die Speicherung der Worte, die wir später analysieren wollen, hält er zu wenig Informationen. Wir brauchen etwas, was mehr leistet, eine Klasse, die mehr tut und mehr Informationen bereithält. Dieses "ich brauche im Grunde genommen das, aber mit mehr Leistung" ist der Grundgedanke der Vererbung in der OOP: Man nutzt eine schon vorhandene Klasse als Grundgerüst und fügt noch Eigenschaften und Methoden hinzu. Frage: Warum genügt dafür nicht Copy&Paste? Antwort: Bei Freebasic muss dafür Copy&Paste herhalten und für so kleine Projekte ist das auch gar kein Problem. Aber bei grösseren Projekten hätten wir den Nachteil der Code-Verdopplung. Wir würden die vererbten Methoden mehrfach deklarieren. Fügen wir z.B. zu solch einer Methode ein optionales Argument hinzu, müssten wir den Kopf sowohl in einem Dutzend Klassendeklarationen als auch in den entsprechenden Definitionen ändern. Schöner ist es, wenn die abgeleiteten Klassen sich quasi automatisch anpassen. Richtig mächtig wird das Instrument der Vererbung, wenn die Methoden sich gegenseitig aufrufen. Dann kann es passieren, dass eine Vorfahr-Methode eine Methode aufruft, die im Erben neu definiert wurde. Damit ändert sich dann auch die Funktionsweise der Vorfahr-Methode innerhalb der Erbe-Klasse – vollautomatisch.
Doch zurück zu unserem Programm. Wir brauchen also eine Klasse, die zu jeder gespeicherten Zeile noch die Position bereithält, an der sie im Originalstring gespeichert war (postab[]). Und eventuell weitere Informationen (Basic-Schlüsselwort, String oder Kommentar?). Ausserdem wäre es praktisch, den Originalstring dort bereitzuhalten:
CONST true=-1
CONST false=0
type textbuf
buf AS ZSTRING PTR PTR
nline AS INTEGER
bufsize AS INTEGER
NAME AS STRING
'Der wird nur formal gebraucht, wegen "Vererbung" bei tokenbuf
DECLARE CONSTRUCTOR()
'Der wird wirklich gebraucht:
DECLARE CONSTRUCTOR(bufsize AS INTEGER, NAME0 AS STRING = "noname")
DECLARE SUB init(bufsize AS INTEGER, NAME0 AS STRING = "noname")
DECLARE DESTRUCTOR()
DECLARE SUB add(s AS string)
DECLARE SUB change(i AS INTEGER, s AS string)
DECLARE FUNCTION OUT(i AS INTEGER) AS STRING
DECLARE SUB fprint0(fileno AS integer)
DECLARE SUB print0
DECLARE SUB CLEAR
END type
type tokenbuf
tbuf AS textbuf
orgstring AS STRING
postab AS INTEGER PTR
propertytab AS INTEGER PTR
DECLARE CONSTRUCTOR(bufsize AS INTEGER, NAME0 AS STRING = "noname")
DECLARE DESTRUCTOR()
DECLARE SUB add(s AS STRING, ipos AS integer)
DECLARE SUB shiftpos(ishift AS INTEGER, istart AS integer)
DECLARE FUNCTION OUT(i AS INTEGER) AS STRING
DECLARE SUB print0
DECLARE SUB CLEAR
END type
' ------------------------------------------------------------------
CONSTRUCTOR tokenbuf(bufsize0 AS INTEGER, NAME0 AS STRING = "noname")
tbuf.init(bufsize0,NAME0)
postab=ALLOCATE(LEN(INTEGER)*bufsize0)
propertytab=ALLOCATE(LEN(INTEGER)*bufsize0)
DIM i AS INTEGER
FOR i=0 TO bufsize0-1
postab[i]=0
propertytab[i]=0
NEXT i
END CONSTRUCTOR
' ------------------------------------------------------------------
SUB tokenbuf.add(s AS STRING, ipos AS integer)
postab[tbuf.nline]=ipos
tbuf.add(s)
END SUB
' ------------------------------------------------------------------
FUNCTION tokenbuf.OUT(i AS INTEGER) AS STRING
tokenbuf.OUT=tbuf.OUT(i)
END FUNCTION
' ------------------------------------------------------------------
SUB tokenbuf.CLEAR()
DIM i AS INTEGER
FOR i=0 TO tbuf.nline-1
postab[i]=0
propertytab[i]=0
NEXT i
END SUB
' ------------------------------------------------------------------
SUB tokenbuf.print0
DIM i AS INTEGER
PRINT tbuf.NAME
PRINT "-------------------------------------------"
PRINT orgstring
FOR i=0 TO tbuf.nline-1
? OUT(i),postab[i],propertytab[i]
NEXT i
END SUB
' ------------------------------------------------------------------
SUB tokenbuf.shiftpos(ishift AS INTEGER, istart AS integer)
'Verschiebt Positionstabelle ab Eintrag istart um ishift
DIM i AS INTEGER
FOR i=istart TO tbuf.nline-1
postab[i]=postab[i]+ishift
NEXT i
END SUB
' ------------------------------------------------------------------
DESTRUCTOR tokenbuf()
END DESTRUCTOR
Wir sehen, dass sich die Methode add() geändert hat – hier übergeben wir nun zusätzlich zum String die Position. clear() befasst sich nur mit postab[] und propertytab[]. Und es gibt eine neue Methode shiftpos(): Falls wir etwas in orgstring eingefügt haben, müssen wir die Positionstabelle nach dieser Position entsprechend verschieben.
Zentrale Teilaufgabe ist es, eine Zeile in ihre Bestandteile zu zerlegen. Das macht die Routine tokenize2(). Sie hat drei Abschnitte. Der erste und zweite kümmert sich um Stringabschnitte, die mit Gänsefüsschen eingeklammert sind. Der dritte Abschnitt hat es etwas in sich:
'Zunächst fangen wir ab, ob wir uns grade innerhalb eines Strings oder 'Kommentars befinden. Und wir prüfen, ob wir am Zeilenende angelangt sind.
IF (indoublequote=0 AND insinglequote=0) OR (i=slen) THEN
'Ein Whitespace stellt einen Begrenzer unseres Wortes dar, das wir
'suchen. Das Zeilenende natürlich auch.
IF iswhitespace(mid(s,i,1)) OR (i=slen) THEN
'Es können auch mehrere Whitespaces hintereinander kommen. Dann
'sagt uns das neue Whitespace nichts.
IF NOT ws_before THEN
'istart zeigt auf den Start des letzten Wortes – falls wir
'bereits uns innerhalb eines solchen befinden.
IF (istart>=1) THEN
'Nun ist klar, dass ein Wort abgeschlossen ist und
'abgespeichert werden muss.
DIM s1 AS STRING
'Wir holen das Wort aus dem String raus. Leicht andere
'Positionsangabe, falls wir am Zeilenende sind.
IF (iTHEN s1=omidstr(s,istart,i-1) ELSE s1=omidstr(s,istart,i)
'...und fügen das Wort in den tokenbuffer ein.
buf->add(s1,istart)
END IF
ws_before=true
END IF
ELSE
'Hier startet ein neues Wort
IF ws_before OR i=1 THEN
ws_before=false
istart=i
END IF
END IF
END IF
Es gab zwei Möglichkeiten. In jedem Fall muss eine Liste der BASIC-Schlüsselwörter her – die bekommt man leicht über freebasic.de oder freebasic.net. Die dortige Liste lässt sich in eine Tabellenkalkulation übertragen und von dort in eine reine Textliste.
Die Frage ist nur: Soll man sie als externe Datei einlesen oder soll man sie "hart verkabelt" im Programm verankern? Ich entschied mich für letztere Alternative, da es sich bei unserem Progrämmchen um ein kleines kompaktes Werkzeug handeln soll, das in nur einer exe-Datei besteht. Immer noch eine Textdatei mitrumschleppen wäre unpraktisch.
Die Liste ist – einfacher geht es nicht mehr – als Serie von if-Anweisungen realisiert, die selbst wieder via Tabellenkalkulation generiert wurde – genauso hätte es ein kurzes BASIC-Programm getan.
if (instr(lcase(s),"")>0) then region=0
CONST true=-1
CONST false=0
CONST Crecsize=100000
CONST Ccolor="blue"
CONST Cstringcolor="teal"
CONST Cstring=1
CONST Ccomment=2
CONST Ccommentcolor="gray"
' Sonderfaelle end if, Kommentare
type textbuf
buf AS ZSTRING PTR PTR
nline AS INTEGER
bufsize AS INTEGER
NAME AS STRING
'Der wird nur formal gebraucht, wegen "Vererbung" bei tokenbuf
DECLARE CONSTRUCTOR()
'Der wird wirklich gebraucht:
DECLARE CONSTRUCTOR(bufsize AS INTEGER, NAME0 AS STRING = "noname")
DECLARE SUB init(bufsize AS INTEGER, NAME0 AS STRING = "noname")
DECLARE DESTRUCTOR()
DECLARE SUB add(s AS string)
DECLARE SUB change(i AS INTEGER, s AS string)
DECLARE FUNCTION OUT(i AS INTEGER) AS STRING
DECLARE SUB fprint0(fileno AS integer)
DECLARE SUB print0
DECLARE SUB CLEAR
END type
type tokenbuf
tbuf AS textbuf
orgstring AS STRING
postab AS INTEGER PTR
propertytab AS INTEGER PTR
DECLARE CONSTRUCTOR(bufsize AS INTEGER, NAME0 AS STRING = "noname")
DECLARE DESTRUCTOR()
DECLARE SUB add(s AS STRING, ipos AS integer)
DECLARE SUB shiftpos(ishift AS INTEGER, istart AS integer)
DECLARE FUNCTION OUT(i AS INTEGER) AS STRING
DECLARE SUB print0
DECLARE SUB CLEAR
END type
type tkeyword
word AS STRING
COLOR AS STRING
END type
' ------------------------------------------------------------------
SUB brkmess(mess AS string)
PRINT mess
END
END SUB
' ------------------------------------------------------------------
FUNCTION omidstr(s AS STRING, i1 AS INTEGER, i2 AS INTEGER) AS STRING
omidstr=mid(s,i1,i2-i1+1)
END FUNCTION
' ------------------------------------------------------------------
CONSTRUCTOR textbuf()
'Leer, da der nur formal gebraucht wird, wegen "Vererbung" bei tokenbuf
END CONSTRUCTOR
' ------------------------------------------------------------------
CONSTRUCTOR textbuf(bufsize0 AS INTEGER, NAME0 AS STRING = "noname")
init(bufsize0,NAME0)
END CONSTRUCTOR
' ------------------------------------------------------------------
SUB textbuf.init(bufsize0 AS INTEGER, NAME0 AS STRING = "noname")
THIS.nline=0
THIS.bufsize=bufsize0
buf=ALLOCATE(bufsize0*SIZEOF(ZSTRING PTR))
IF (buf=0) THEN brkmess("textbuf error: allocation failed")
DIM i AS INTEGER
FOR i=0 TO bufsize-1:buf[i]=0:NEXT i
THIS.NAME=name0
END SUB
' ------------------------------------------------------------------
DESTRUCTOR textbuf()
DIM i AS INTEGER
FOR i=0 TO nline-1
DEALLOCATE buf[i]
NEXT i
DEALLOCATE THIS.buf
THIS.buf=0
END DESTRUCTOR
' ------------------------------------------------------------------
SUB textbuf.add(s AS string)
IF nline>bufsize THEN brkmess("textbuf error: buffer overflow")
buf[nline]=ALLOCATE(LEN(s)+10)
*buf[nline]= s
nline=nline+1
END SUB
' ------------------------------------------------------------------
SUB textbuf.change(i AS INTEGER, s AS string)
IF buf[i]=0 THEN brkmess("error textbuf.change() buf[i] not allocated")
DEALLOCATE buf[i]
buf[i]=ALLOCATE(LEN(s)+10)
*buf[i]=s
END SUB
' ------------------------------------------------------------------
FUNCTION textbuf.OUT(i AS INTEGER) AS STRING
textbuf.OUT=buf[i][0]
END FUNCTION
' ------------------------------------------------------------------
SUB textbuf.CLEAR()
DIM i AS INTEGER
FOR i=0 TO nline-1
add("")
NEXT i
nline=0
END SUB
' ------------------------------------------------------------------
SUB textbuf.print0
DIM i AS INTEGER
PRINT name;":"
PRINT "----------------------------"
FOR i=0 TO nline-1
PRINT i,OUT(i)
NEXT i
END SUB
' ------------------------------------------------------------------
SUB textbuf.fprint0(fileno AS integer)
DIM i AS INTEGER
FOR i=0 TO nline-1
PRINT #fileno,OUT(i)
NEXT i
END SUB
' ------------------------------------------------------------------
CONSTRUCTOR tokenbuf(bufsize0 AS INTEGER, NAME0 AS STRING = "noname")
tbuf.init(bufsize0,NAME0)
postab=ALLOCATE(LEN(INTEGER)*bufsize0)
propertytab=ALLOCATE(LEN(INTEGER)*bufsize0)
DIM i AS INTEGER
FOR i=0 TO bufsize0-1
postab[i]=0
propertytab[i]=0
NEXT i
END CONSTRUCTOR
' ------------------------------------------------------------------
SUB tokenbuf.add(s AS STRING, ipos AS integer)
postab[tbuf.nline]=ipos
tbuf.add(s)
END SUB
' ------------------------------------------------------------------
FUNCTION tokenbuf.OUT(i AS INTEGER) AS STRING
tokenbuf.OUT=tbuf.OUT(i)
END FUNCTION
' ------------------------------------------------------------------
SUB tokenbuf.CLEAR()
DIM i AS INTEGER
FOR i=0 TO tbuf.nline-1
postab[i]=0
propertytab[i]=0
NEXT i
END SUB
' ------------------------------------------------------------------
SUB tokenbuf.print0
DIM i AS INTEGER
PRINT tbuf.NAME
PRINT "-------------------------------------------"
PRINT orgstring
FOR i=0 TO tbuf.nline-1
? OUT(i),postab[i],propertytab[i]
NEXT i
END SUB
' ------------------------------------------------------------------
SUB tokenbuf.shiftpos(ishift AS INTEGER, istart AS integer)
'Verschiebt Positionstabelle ab Eintrag istart um ishift
DIM i AS INTEGER
FOR i=istart TO tbuf.nline-1
postab[i]=postab[i]+ishift
NEXT i
END SUB
' ------------------------------------------------------------------
DESTRUCTOR tokenbuf()
END DESTRUCTOR
' ------------------------------------------------------------------
DIM SHARED AS tkeyword keywordlist(500)
DIM SHARED AS INTEGER nkeywordlist = 0
' ------------------------------------------------------------------
FUNCTION iswhitespace(s AS STRING) AS INTEGER
DIM AS STRING wstest=" ,()[]'=$*+/-^:."
DIM AS INTEGER i,j,slen
DIM AS INTEGER retval
slen=LEN(wstest)
retval=false
FOR i=1 TO slen
IF mid(s,1,1)=mid(wstest,i,1) THEN
retval=true
EXIT FOR
END IF
NEXT i
IF (NOT retval) THEN
IF (ASC(mid(s,1,1))>=48 AND ASC(mid(s,1,1))<=57) OR ASC(mid(s,1,1))=9 THEN retval=true
END IF
iswhitespace=retval
END FUNCTION
' ------------------------------------------------------------------
FUNCTION tokenizestring(s AS STRING) AS textbuf PTR
DIM AS INTEGER i,j,slen,istart,ws_before
DIM AS STRING currenttok
DIM AS textbuf PTR buf
buf=NEW textbuf(1000,"tokenize")
currenttok=""
istart=-1
ws_before=false
slen=LEN(s)
FOR i=1 TO slen
IF iswhitespace(mid(s,i,1)) OR (i=slen) THEN
'? "whiteb>",i
IF NOT ws_before THEN
IF (istart>=1) THEN
DIM s1 AS STRING
IF (iTHEN s1=omidstr(s,istart,i-1) ELSE s1=omidstr(s,istart,i)
'print s1
buf->add(s1)
END IF
ws_before=true
END IF
ELSE
IF ws_before OR i=1 THEN
'? "else>",i
ws_before=false
istart=i
END IF
END IF
NEXT i
tokenizestring=buf
END FUNCTION
' ------------------------------------------------------------------
' Das hier ist nicht so ganz schön:
' Codeverdopplung von oben. Verbessern Sie die Stelle!
FUNCTION tokenizestring2(s AS STRING) AS tokenbuf PTR
DIM AS INTEGER i,j,slen,istart,ws_before,indoublequote,token_stored,istart_single,istart_double
DIM AS INTEGER insinglequote
DIM AS STRING currenttok
DIM AS tokenbuf PTR buf
buf=NEW tokenbuf(1000,"tokenize")
IF (buf=0) THEN brkmess("error tokenizestring2() allocation failed")
buf->orgstring=s
currenttok=""
istart=-1
istart_single=-1
istart_double=-1
ws_before=false
slen=LEN(s)
insinglequote=0
indoublequote=0
'Double Quotes
FOR i=1 TO slen
token_stored=false
'Double Quotes
IF mid(s,i,1)=CHR(34) OR (i=slen) THEN
IF indoublequote=1 THEN
IF (istart_double>=1) THEN
DIM s1 AS STRING
IF (iTHEN s1=omidstr(s,istart_double,i-1) ELSE s1=omidstr(s,istart_double,i)
buf->add(s1,istart_double)
buf->propertytab[buf->tbuf.nline-1]=Cstring
token_stored=true
END IF
ELSE
istart_double=i
END IF
indoublequote=1-indoublequote
END IF
'Single Quotes
IF mid(s,i,1)=CHR(39) OR (i=slen) THEN
IF insinglequote=1 THEN
IF (istart_single>=1) THEN
DIM s1 AS STRING
IF (iTHEN s1=omidstr(s,istart_single,i-1) ELSE s1=omidstr(s,istart_single,i)
buf->add(s1,istart_single)
buf->propertytab[buf->tbuf.nline-1]=Ccomment
token_stored=true
END IF
ELSE
istart_single=i
END IF
insinglequote=1-insinglequote
END IF
IF (indoublequote=0 AND insinglequote=0) OR (i=slen) THEN
IF iswhitespace(mid(s,i,1)) OR (i=slen) THEN
IF NOT ws_before THEN
IF (istart>=1) THEN
DIM s1 AS STRING
IF (iTHEN s1=omidstr(s,istart,i-1) ELSE s1=omidstr(s,istart,i)
buf->add(s1,istart)
END IF
ws_before=true
END IF
ELSE
IF ws_before OR i=1 THEN
ws_before=false
istart=i
END IF
END IF
END IF
NEXT i
tokenizestring2=buf
END FUNCTION
' ------------------------------------------------------------------
SUB readkeywordlist()
keywordlist(0).word="ABS":keywordlist(0).COLOR="Blue"
keywordlist(1).word="ACCESS":keywordlist(1).COLOR="Blue"
keywordlist(2).word="ACOS":keywordlist(2).COLOR="Blue"
keywordlist(3).word="PUT":keywordlist(3).COLOR="Blue"
keywordlist(4).word="ALIAS":keywordlist(4).COLOR="Blue"
keywordlist(5).word="ALLOCATE":keywordlist(5).COLOR="Blue"
keywordlist(6).word="PUT":keywordlist(6).COLOR="Blue"
keywordlist(7).word="AND":keywordlist(7).COLOR="Blue"
keywordlist(8).word="ANDALSO":keywordlist(8).COLOR="Blue"
keywordlist(9).word="PUT":keywordlist(9).COLOR="Blue"
keywordlist(10).word="ANY":keywordlist(10).COLOR="Blue"
keywordlist(11).word="APPEND":keywordlist(11).COLOR="Blue"
keywordlist(12).word="AS":keywordlist(12).COLOR="Blue"
keywordlist(13).word="ASSERT":keywordlist(13).COLOR="Blue"
keywordlist(14).word="ASSERTWARN":keywordlist(14).COLOR="Blue"
keywordlist(15).word="ASC":keywordlist(15).COLOR="Blue"
keywordlist(16).word="ASIN":keywordlist(16).COLOR="Blue"
keywordlist(17).word="ASM":keywordlist(17).COLOR="Blue"
keywordlist(18).word="ATAN2":keywordlist(18).COLOR="Blue"
keywordlist(19).word="ATN":keywordlist(19).COLOR="Blue"
keywordlist(20).word="BEEP":keywordlist(20).COLOR="Blue"
keywordlist(21).word="BIN":keywordlist(21).COLOR="Blue"
keywordlist(22).word="BINARY":keywordlist(22).COLOR="Blue"
keywordlist(23).word="BIT":keywordlist(23).COLOR="Blue"
keywordlist(24).word="BITRESET":keywordlist(24).COLOR="Blue"
keywordlist(25).word="BITSET":keywordlist(25).COLOR="Blue"
keywordlist(26).word="BLOAD":keywordlist(26).COLOR="Blue"
keywordlist(27).word="BSAVE":keywordlist(27).COLOR="Blue"
keywordlist(28).word="BYREF":keywordlist(28).COLOR="Blue"
keywordlist(29).word="BYTE":keywordlist(29).COLOR="Blue"
keywordlist(30).word="BYVAL":keywordlist(30).COLOR="Blue"
keywordlist(31).word="CALL":keywordlist(31).COLOR="Blue"
keywordlist(32).word="CALLOCATE":keywordlist(32).COLOR="Blue"
keywordlist(33).word="CASE":keywordlist(33).COLOR="Blue"
keywordlist(34).word="CAST":keywordlist(34).COLOR="Blue"
keywordlist(35).word="CBYTE":keywordlist(35).COLOR="Blue"
keywordlist(36).word="CDBL":keywordlist(36).COLOR="Blue"
keywordlist(37).word="CDECL":keywordlist(37).COLOR="Blue"
keywordlist(38).word="CHAIN":keywordlist(38).COLOR="Blue"
keywordlist(39).word="CHDIR":keywordlist(39).COLOR="Blue"
keywordlist(40).word="CHR":keywordlist(40).COLOR="Blue"
keywordlist(41).word="CINT":keywordlist(41).COLOR="Blue"
keywordlist(42).word="CIRCLE":keywordlist(42).COLOR="Blue"
keywordlist(43).word="CLASS":keywordlist(43).COLOR="Blue"
keywordlist(44).word="CLEAR":keywordlist(44).COLOR="Blue"
keywordlist(45).word="CLNG":keywordlist(45).COLOR="Blue"
keywordlist(46).word="CLNGINT":keywordlist(46).COLOR="Blue"
keywordlist(47).word="CLOSE":keywordlist(47).COLOR="Blue"
keywordlist(48).word="CLS":keywordlist(48).COLOR="Blue"
keywordlist(49).word="COLOR":keywordlist(49).COLOR="Blue"
keywordlist(50).word="COMMAND":keywordlist(50).COLOR="Blue"
keywordlist(51).word="COMMON":keywordlist(51).COLOR="Blue"
keywordlist(52).word="CONDBROADCAST":keywordlist(52).COLOR="Blue"
keywordlist(53).word="CONDCREATE":keywordlist(53).COLOR="Blue"
keywordlist(54).word="CONDDESTROY":keywordlist(54).COLOR="Blue"
keywordlist(55).word="CONDSIGNAL":keywordlist(55).COLOR="Blue"
keywordlist(56).word="CONDWAIT":keywordlist(56).COLOR="Blue"
keywordlist(57).word="CONST":keywordlist(57).COLOR="Blue"
keywordlist(58).word="CONSTRUCTOR":keywordlist(58).COLOR="Blue"
keywordlist(59).word="CONTINUE":keywordlist(59).COLOR="Blue"
keywordlist(60).word="COS":keywordlist(60).COLOR="Blue"
keywordlist(61).word="CPTR":keywordlist(61).COLOR="Blue"
keywordlist(62).word="CSHORT":keywordlist(62).COLOR="Blue"
keywordlist(63).word="CSIGN":keywordlist(63).COLOR="Blue"
keywordlist(64).word="CSNG":keywordlist(64).COLOR="Blue"
keywordlist(65).word="CSRLIN":keywordlist(65).COLOR="Blue"
keywordlist(66).word="CUBYTE":keywordlist(66).COLOR="Blue"
keywordlist(67).word="CUINT":keywordlist(67).COLOR="Blue"
keywordlist(68).word="CULNG":keywordlist(68).COLOR="Blue"
keywordlist(69).word="CULNGINT":keywordlist(69).COLOR="Blue"
keywordlist(70).word="CUNSG":keywordlist(70).COLOR="Blue"
keywordlist(71).word="CURDIR":keywordlist(71).COLOR="Blue"
keywordlist(72).word="CUSHORT":keywordlist(72).COLOR="Blue"
keywordlist(73).word="PUT":keywordlist(73).COLOR="Blue"
keywordlist(74).word="CVD":keywordlist(74).COLOR="Blue"
keywordlist(75).word="CVI":keywordlist(75).COLOR="Blue"
keywordlist(76).word="CVL":keywordlist(76).COLOR="Blue"
keywordlist(77).word="CVLONGINT":keywordlist(77).COLOR="Blue"
keywordlist(78).word="CVS":keywordlist(78).COLOR="Blue"
keywordlist(79).word="CVSHORT":keywordlist(79).COLOR="Blue"
keywordlist(80).word="DATA":keywordlist(80).COLOR="Blue"
keywordlist(81).word="DATE":keywordlist(81).COLOR="Blue"
keywordlist(82).word="DATEADD":keywordlist(82).COLOR="Blue"
keywordlist(83).word="DATEDIFF":keywordlist(83).COLOR="Blue"
keywordlist(84).word="DATEPART":keywordlist(84).COLOR="Blue"
keywordlist(85).word="DATESERIAL":keywordlist(85).COLOR="Blue"
keywordlist(86).word="DATEVALUE":keywordlist(86).COLOR="Blue"
keywordlist(87).word="DAY":keywordlist(87).COLOR="Blue"
keywordlist(88).word="DEALLOCATE":keywordlist(88).COLOR="Blue"
keywordlist(89).word="DECLARE":keywordlist(89).COLOR="Blue"
keywordlist(90).word="DEFBYTE":keywordlist(90).COLOR="Blue"
keywordlist(91).word="DEFDBL":keywordlist(91).COLOR="Blue"
keywordlist(92).word="DEFINED":keywordlist(92).COLOR="Blue"
keywordlist(93).word="DEFINT":keywordlist(93).COLOR="Blue"
keywordlist(94).word="DEFLNG":keywordlist(94).COLOR="Blue"
keywordlist(95).word="DEFLONGINT":keywordlist(95).COLOR="Blue"
keywordlist(96).word="DEFSHORT":keywordlist(96).COLOR="Blue"
keywordlist(97).word="DEFSNG":keywordlist(97).COLOR="Blue"
keywordlist(98).word="DEFSTR":keywordlist(98).COLOR="Blue"
keywordlist(99).word="DEFUBYTE":keywordlist(99).COLOR="Blue"
keywordlist(100).word="DEFUINT":keywordlist(100).COLOR="Blue"
keywordlist(101).word="DEFULONGINT":keywordlist(101).COLOR="Blue"
keywordlist(102).word="DEFUSHORT":keywordlist(102).COLOR="Blue"
keywordlist(103).word="DELETE":keywordlist(103).COLOR="Blue"
keywordlist(104).word="DESTRUCTOR":keywordlist(104).COLOR="Blue"
keywordlist(105).word="DIM":keywordlist(105).COLOR="Blue"
keywordlist(106).word="DIR":keywordlist(106).COLOR="Blue"
keywordlist(107).word="DO":keywordlist(107).COLOR="Blue"
keywordlist(108).word="LOOP":keywordlist(108).COLOR="Blue"
keywordlist(109).word="DOUBLE":keywordlist(109).COLOR="Blue"
keywordlist(110).word="DRAW":keywordlist(110).COLOR="Blue"
keywordlist(111).word="STRING":keywordlist(111).COLOR="Blue"
keywordlist(112).word="DYLIBFREE":keywordlist(112).COLOR="Blue"
keywordlist(113).word="DYLIBLOAD":keywordlist(113).COLOR="Blue"
keywordlist(114).word="DYLIBSYMBOL":keywordlist(114).COLOR="Blue"
keywordlist(115).word="ELSE":keywordlist(115).COLOR="Blue"
keywordlist(116).word="ELSEIF":keywordlist(116).COLOR="Blue"
keywordlist(117).word="ENCODING":keywordlist(117).COLOR="Blue"
keywordlist(118).word="Block":keywordlist(118).COLOR="Blue"
keywordlist(119).word="IF":keywordlist(119).COLOR="Blue"
keywordlist(120).word="ENUM":keywordlist(120).COLOR="Blue"
keywordlist(121).word="ENVIRON":keywordlist(121).COLOR="Blue"
keywordlist(122).word="EOF":keywordlist(122).COLOR="Blue"
keywordlist(123).word="EQV":keywordlist(123).COLOR="Blue"
keywordlist(124).word="ERASE":keywordlist(124).COLOR="Blue"
keywordlist(125).word="ERFN":keywordlist(125).COLOR="Blue"
keywordlist(126).word="ERL":keywordlist(126).COLOR="Blue"
keywordlist(127).word="ERMN":keywordlist(127).COLOR="Blue"
keywordlist(128).word="ERR":keywordlist(128).COLOR="Blue"
keywordlist(129).word="ERROR":keywordlist(129).COLOR="Blue"
keywordlist(130).word="EXEC":keywordlist(130).COLOR="Blue"
keywordlist(131).word="EXEPATH":keywordlist(131).COLOR="Blue"
keywordlist(132).word="EXIT":keywordlist(132).COLOR="Blue"
keywordlist(133).word="EXP":keywordlist(133).COLOR="Blue"
keywordlist(134).word="EXPORT":keywordlist(134).COLOR="Blue"
keywordlist(135).word="EXTERN":keywordlist(135).COLOR="Blue"
keywordlist(136).word="EXTERN":keywordlist(136).COLOR="Blue"
keywordlist(137).word="FIELD":keywordlist(137).COLOR="Blue"
keywordlist(138).word="FILEATTR":keywordlist(138).COLOR="Blue"
keywordlist(139).word="FILECOPY":keywordlist(139).COLOR="Blue"
keywordlist(140).word="FILEDATETIME":keywordlist(140).COLOR="Blue"
keywordlist(141).word="FILEEXISTS":keywordlist(141).COLOR="Blue"
keywordlist(142).word="FILELEN":keywordlist(142).COLOR="Blue"
keywordlist(143).word="FIX":keywordlist(143).COLOR="Blue"
keywordlist(144).word="FLIP":keywordlist(144).COLOR="Blue"
keywordlist(145).word="FOR":keywordlist(145).COLOR="Blue"
keywordlist(146).word="NEXT":keywordlist(146).COLOR="Blue"
keywordlist(147).word="FORMAT":keywordlist(147).COLOR="Blue"
keywordlist(148).word="FRAC":keywordlist(148).COLOR="Blue"
keywordlist(149).word="FRE":keywordlist(149).COLOR="Blue"
keywordlist(150).word="FREEFILE":keywordlist(150).COLOR="Blue"
keywordlist(151).word="FUNCTION":keywordlist(151).COLOR="Blue"
keywordlist(152).word="GETJOYSTICK":keywordlist(152).COLOR="Blue"
keywordlist(153).word="GETKEY":keywordlist(153).COLOR="Blue"
keywordlist(154).word="GETMOUSE":keywordlist(154).COLOR="Blue"
keywordlist(155).word="GOSUB":keywordlist(155).COLOR="Blue"
keywordlist(156).word="GOTO":keywordlist(156).COLOR="Blue"
keywordlist(157).word="HEX":keywordlist(157).COLOR="Blue"
keywordlist(158).word="HIBYTE":keywordlist(158).COLOR="Blue"
keywordlist(159).word="HIWORD":keywordlist(159).COLOR="Blue"
keywordlist(160).word="HOUR":keywordlist(160).COLOR="Blue"
keywordlist(161).word="THEN":keywordlist(161).COLOR="Blue"
keywordlist(162).word="IIF":keywordlist(162).COLOR="Blue"
keywordlist(163).word="IMAGECONVERTROW":keywordlist(163).COLOR="Blue"
keywordlist(164).word="IMAGECREATE":keywordlist(164).COLOR="Blue"
keywordlist(165).word="IMAGEDESTROY":keywordlist(165).COLOR="Blue"
keywordlist(166).word="IMAGEINFO":keywordlist(166).COLOR="Blue"
keywordlist(167).word="IMP":keywordlist(167).COLOR="Blue"
keywordlist(168).word="IMPORT":keywordlist(168).COLOR="Blue"
keywordlist(169).word="INKEY":keywordlist(169).COLOR="Blue"
keywordlist(170).word="INP":keywordlist(170).COLOR="Blue"
keywordlist(171).word="INPUT #":keywordlist(171).COLOR="Blue"
keywordlist(172).word="INPUT$":keywordlist(172).COLOR="Blue"
keywordlist(173).word="INSTR":keywordlist(173).COLOR="Blue"
keywordlist(174).word="INSTRREV":keywordlist(174).COLOR="Blue"
keywordlist(175).word="INT":keywordlist(175).COLOR="Blue"
keywordlist(176).word="INTEGER":keywordlist(176).COLOR="Blue"
keywordlist(177).word="IS":keywordlist(177).COLOR="Blue"
keywordlist(178).word="ISDATE":keywordlist(178).COLOR="Blue"
keywordlist(179).word="KILL":keywordlist(179).COLOR="Blue"
keywordlist(180).word="LBOUND":keywordlist(180).COLOR="Blue"
keywordlist(181).word="LCASE":keywordlist(181).COLOR="Blue"
keywordlist(182).word="LEFT":keywordlist(182).COLOR="Blue"
keywordlist(183).word="LEN":keywordlist(183).COLOR="Blue"
keywordlist(184).word="LET":keywordlist(184).COLOR="Blue"
keywordlist(185).word="LIB":keywordlist(185).COLOR="Blue"
keywordlist(186).word="LINE":keywordlist(186).COLOR="Blue"
keywordlist(187).word="INPUT":keywordlist(187).COLOR="Blue"
keywordlist(188).word="INPUT #":keywordlist(188).COLOR="Blue"
keywordlist(189).word="LOBYTE":keywordlist(189).COLOR="Blue"
keywordlist(190).word="LOC":keywordlist(190).COLOR="Blue"
keywordlist(191).word="LOCAL":keywordlist(191).COLOR="Blue"
keywordlist(192).word="LOCATE":keywordlist(192).COLOR="Blue"
keywordlist(193).word="LOCK":keywordlist(193).COLOR="Blue"
keywordlist(194).word="LOF":keywordlist(194).COLOR="Blue"
keywordlist(195).word="LOG":keywordlist(195).COLOR="Blue"
keywordlist(196).word="LONG":keywordlist(196).COLOR="Blue"
keywordlist(197).word="LONGINT":keywordlist(197).COLOR="Blue"
keywordlist(198).word="LOOP":keywordlist(198).COLOR="Blue"
keywordlist(199).word="LOWORD":keywordlist(199).COLOR="Blue"
keywordlist(200).word="LPOS":keywordlist(200).COLOR="Blue"
keywordlist(201).word="LPRINT":keywordlist(201).COLOR="Blue"
keywordlist(202).word="LSET":keywordlist(202).COLOR="Blue"
keywordlist(203).word="LTRIM":keywordlist(203).COLOR="Blue"
keywordlist(204).word="MINUTE":keywordlist(204).COLOR="Blue"
keywordlist(205).word="MKD":keywordlist(205).COLOR="Blue"
keywordlist(206).word="MKDIR":keywordlist(206).COLOR="Blue"
keywordlist(207).word="MKI":keywordlist(207).COLOR="Blue"
keywordlist(208).word="MKL":keywordlist(208).COLOR="Blue"
keywordlist(209).word="MKLONGINT":keywordlist(209).COLOR="Blue"
keywordlist(210).word="MKS":keywordlist(210).COLOR="Blue"
keywordlist(211).word="MKSHORT":keywordlist(211).COLOR="Blue"
keywordlist(212).word="MOD":keywordlist(212).COLOR="Blue"
keywordlist(213).word="MONTH":keywordlist(213).COLOR="Blue"
keywordlist(214).word="MONTHNAME":keywordlist(214).COLOR="Blue"
keywordlist(215).word="MULTIKEY":keywordlist(215).COLOR="Blue"
keywordlist(216).word="MUTEXCREATE":keywordlist(216).COLOR="Blue"
keywordlist(217).word="MUTEXDESTROY":keywordlist(217).COLOR="Blue"
keywordlist(218).word="MUTEXLOCK":keywordlist(218).COLOR="Blue"
keywordlist(219).word="MUTEXUNLOCK":keywordlist(219).COLOR="Blue"
keywordlist(220).word="NAME":keywordlist(220).COLOR="Blue"
keywordlist(221).word="NAMESPACE":keywordlist(221).COLOR="Blue"
keywordlist(222).word="NEXT":keywordlist(222).COLOR="Blue"
keywordlist(223).word="NEW":keywordlist(223).COLOR="Blue"
keywordlist(224).word="RESUME":keywordlist(224).COLOR="Blue"
keywordlist(225).word="NOT":keywordlist(225).COLOR="Blue"
keywordlist(226).word="NOW":keywordlist(226).COLOR="Blue"
keywordlist(227).word="OFFSETOF":keywordlist(227).COLOR="Blue"
keywordlist(228).word="ERROR":keywordlist(228).COLOR="Blue"
keywordlist(229).word="GOSUB":keywordlist(229).COLOR="Blue"
keywordlist(230).word="GOTO":keywordlist(230).COLOR="Blue"
keywordlist(231).word="ONCE":keywordlist(231).COLOR="Blue"
keywordlist(232).word="OPEN":keywordlist(232).COLOR="Blue"
keywordlist(233).word="COM":keywordlist(233).COLOR="Blue"
keywordlist(234).word="CONS":keywordlist(234).COLOR="Blue"
keywordlist(235).word="ERR":keywordlist(235).COLOR="Blue"
keywordlist(236).word="LPT":keywordlist(236).COLOR="Blue"
keywordlist(237).word="PIPE":keywordlist(237).COLOR="Blue"
keywordlist(238).word="SCRN":keywordlist(238).COLOR="Blue"
keywordlist(239).word="OPTION(":keywordlist(239).COLOR="Blue"
keywordlist(240).word="BASE":keywordlist(240).COLOR="Blue"
keywordlist(241).word="BYVAL":keywordlist(241).COLOR="Blue"
keywordlist(242).word="DYNAMIC":keywordlist(242).COLOR="Blue"
keywordlist(243).word="ESCAPE":keywordlist(243).COLOR="Blue"
keywordlist(244).word="EXPLICIT":keywordlist(244).COLOR="Blue"
keywordlist(245).word="GOSUB":keywordlist(245).COLOR="Blue"
keywordlist(246).word="NOGOSUB":keywordlist(246).COLOR="Blue"
keywordlist(247).word="NOKEYWORD":keywordlist(247).COLOR="Blue"
keywordlist(248).word="PRIVATE":keywordlist(248).COLOR="Blue"
keywordlist(249).word="STATIC":keywordlist(249).COLOR="Blue"
keywordlist(250).word="OPERATOR":keywordlist(250).COLOR="Blue"
keywordlist(251).word="OR":keywordlist(251).COLOR="Blue"
keywordlist(252).word="PUT":keywordlist(252).COLOR="Blue"
keywordlist(253).word="ORELSE":keywordlist(253).COLOR="Blue"
keywordlist(254).word="OUT":keywordlist(254).COLOR="Blue"
keywordlist(255).word="OUTPUT":keywordlist(255).COLOR="Blue"
keywordlist(256).word="OVERLOAD":keywordlist(256).COLOR="Blue"
keywordlist(257).word="PAINT":keywordlist(257).COLOR="Blue"
keywordlist(258).word="PALETTE":keywordlist(258).COLOR="Blue"
keywordlist(259).word="PASCAL":keywordlist(259).COLOR="Blue"
keywordlist(260).word="PCOPY":keywordlist(260).COLOR="Blue"
keywordlist(261).word="PEEK":keywordlist(261).COLOR="Blue"
keywordlist(262).word="PMAP":keywordlist(262).COLOR="Blue"
keywordlist(263).word="POINT":keywordlist(263).COLOR="Blue"
keywordlist(264).word="POINTER":keywordlist(264).COLOR="Blue"
keywordlist(265).word="POKE":keywordlist(265).COLOR="Blue"
keywordlist(266).word="POS":keywordlist(266).COLOR="Blue"
keywordlist(267).word="PRESERVE":keywordlist(267).COLOR="Blue"
keywordlist(268).word="PRESET":keywordlist(268).COLOR="Blue"
keywordlist(269).word="PRINT":keywordlist(269).COLOR="Blue"
keywordlist(270).word="PRINT #":keywordlist(270).COLOR="Blue"
keywordlist(271).word="USING":keywordlist(271).COLOR="Blue"
keywordlist(272).word="USING #":keywordlist(272).COLOR="Blue"
keywordlist(273).word="PRIVATE":keywordlist(273).COLOR="Blue"
keywordlist(274).word="PROCPTR":keywordlist(274).COLOR="Blue"
keywordlist(275).word="PROPERTY":keywordlist(275).COLOR="Blue"
keywordlist(276).word="PUT":keywordlist(276).COLOR="Blue"
keywordlist(277).word="PTR":keywordlist(277).COLOR="Blue"
keywordlist(278).word="PUBLIC":keywordlist(278).COLOR="Blue"
keywordlist(279).word="RANDOM":keywordlist(279).COLOR="Blue"
keywordlist(280).word="RANDOMIZE":keywordlist(280).COLOR="Blue"
keywordlist(281).word="READ":keywordlist(281).COLOR="Blue"
keywordlist(282).word="REALLOCATE":keywordlist(282).COLOR="Blue"
keywordlist(283).word="REDIM":keywordlist(283).COLOR="Blue"
keywordlist(284).word="REM":keywordlist(284).COLOR="Blue"
keywordlist(285).word="RESET":keywordlist(285).COLOR="Blue"
keywordlist(286).word="RESTORE":keywordlist(286).COLOR="Blue"
keywordlist(287).word="RESUME":keywordlist(287).COLOR="Blue"
keywordlist(288).word="NEXT":keywordlist(288).COLOR="Blue"
keywordlist(289).word="RETURN":keywordlist(289).COLOR="Blue"
keywordlist(290).word="RGB":keywordlist(290).COLOR="Blue"
keywordlist(291).word="RGBA":keywordlist(291).COLOR="Blue"
keywordlist(292).word="RIGHT":keywordlist(292).COLOR="Blue"
keywordlist(293).word="RMDIR":keywordlist(293).COLOR="Blue"
keywordlist(294).word="RND":keywordlist(294).COLOR="Blue"
keywordlist(295).word="RSET":keywordlist(295).COLOR="Blue"
keywordlist(296).word="RTRIM":keywordlist(296).COLOR="Blue"
keywordlist(297).word="RUN":keywordlist(297).COLOR="Blue"
keywordlist(298).word="SADD":keywordlist(298).COLOR="Blue"
keywordlist(299).word="SCOPE":keywordlist(299).COLOR="Blue"
keywordlist(300).word="SCREEN":keywordlist(300).COLOR="Blue"
keywordlist(301).word="SCREENCOPY":keywordlist(301).COLOR="Blue"
keywordlist(302).word="SCREENCONTROL":keywordlist(302).COLOR="Blue"
keywordlist(303).word="SCREENEVENT":keywordlist(303).COLOR="Blue"
keywordlist(304).word="SCREENINFO":keywordlist(304).COLOR="Blue"
keywordlist(305).word="SCREENGLPROC":keywordlist(305).COLOR="Blue"
keywordlist(306).word="SCREENLIST":keywordlist(306).COLOR="Blue"
keywordlist(307).word="SCREENLOCK":keywordlist(307).COLOR="Blue"
keywordlist(308).word="SCREENPTR":keywordlist(308).COLOR="Blue"
keywordlist(309).word="SCREENRES":keywordlist(309).COLOR="Blue"
keywordlist(310).word="SCREENSET":keywordlist(310).COLOR="Blue"
keywordlist(311).word="SCREENSYNC":keywordlist(311).COLOR="Blue"
keywordlist(312).word="SCREENUNLOCK":keywordlist(312).COLOR="Blue"
keywordlist(313).word="SECOND":keywordlist(313).COLOR="Blue"
keywordlist(314).word="CASE":keywordlist(314).COLOR="Blue"
keywordlist(315).word="SETDATE":keywordlist(315).COLOR="Blue"
keywordlist(316).word="SETENVIRON":keywordlist(316).COLOR="Blue"
keywordlist(317).word="SETMOUSE":keywordlist(317).COLOR="Blue"
keywordlist(318).word="SETTIME":keywordlist(318).COLOR="Blue"
keywordlist(319).word="SGN":keywordlist(319).COLOR="Blue"
keywordlist(320).word="SHARED":keywordlist(320).COLOR="Blue"
keywordlist(321).word="SHELL":keywordlist(321).COLOR="Blue"
keywordlist(322).word="SHL":keywordlist(322).COLOR="Blue"
keywordlist(323).word="SHR":keywordlist(323).COLOR="Blue"
keywordlist(324).word="SHORT":keywordlist(324).COLOR="Blue"
keywordlist(325).word="SIN":keywordlist(325).COLOR="Blue"
keywordlist(326).word="SINGLE":keywordlist(326).COLOR="Blue"
keywordlist(327).word="SIZEOF":keywordlist(327).COLOR="Blue"
keywordlist(328).word="SLEEP":keywordlist(328).COLOR="Blue"
keywordlist(329).word="SPACE":keywordlist(329).COLOR="Blue"
keywordlist(330).word="SPC":keywordlist(330).COLOR="Blue"
keywordlist(331).word="SQR":keywordlist(331).COLOR="Blue"
keywordlist(332).word="STATIC":keywordlist(332).COLOR="Blue"
keywordlist(333).word="STDCALL":keywordlist(333).COLOR="Blue"
keywordlist(334).word="STEP":keywordlist(334).COLOR="Blue"
keywordlist(335).word="STICK":keywordlist(335).COLOR="Blue"
keywordlist(336).word="STOP":keywordlist(336).COLOR="Blue"
keywordlist(337).word="STR":keywordlist(337).COLOR="Blue"
keywordlist(338).word="STRIG":keywordlist(338).COLOR="Blue"
keywordlist(339).word="STRING":keywordlist(339).COLOR="Blue"
keywordlist(340).word="STRPTR":keywordlist(340).COLOR="Blue"
keywordlist(341).word="SUB":keywordlist(341).COLOR="Blue"
keywordlist(342).word="SWAP":keywordlist(342).COLOR="Blue"
keywordlist(343).word="SYSTEM":keywordlist(343).COLOR="Blue"
keywordlist(344).word="TAB":keywordlist(344).COLOR="Blue"
keywordlist(345).word="TAN":keywordlist(345).COLOR="Blue"
keywordlist(346).word="THEN":keywordlist(346).COLOR="Blue"
keywordlist(347).word="THIS":keywordlist(347).COLOR="Blue"
keywordlist(348).word="THREADCREATE":keywordlist(348).COLOR="Blue"
keywordlist(349).word="THREADWAIT":keywordlist(349).COLOR="Blue"
keywordlist(350).word="TIME":keywordlist(350).COLOR="Blue"
keywordlist(351).word="TIMESERIAL":keywordlist(351).COLOR="Blue"
keywordlist(352).word="TIMEVALUE":keywordlist(352).COLOR="Blue"
keywordlist(353).word="TIMER":keywordlist(353).COLOR="Blue"
keywordlist(354).word="TO":keywordlist(354).COLOR="Blue"
keywordlist(355).word="PUT":keywordlist(355).COLOR="Blue"
keywordlist(356).word="TRIM":keywordlist(356).COLOR="Blue"
keywordlist(357).word="UDT":keywordlist(357).COLOR="Blue"
keywordlist(358).word="TYPEOF":keywordlist(358).COLOR="Blue"
keywordlist(359).word="UBOUND":keywordlist(359).COLOR="Blue"
keywordlist(360).word="UBYTE":keywordlist(360).COLOR="Blue"
keywordlist(361).word="UCASE":keywordlist(361).COLOR="Blue"
keywordlist(362).word="UINTEGER":keywordlist(362).COLOR="Blue"
keywordlist(363).word="ULONG":keywordlist(363).COLOR="Blue"
keywordlist(364).word="ULONGINT":keywordlist(364).COLOR="Blue"
keywordlist(365).word="UNION":keywordlist(365).COLOR="Blue"
keywordlist(366).word="UNLOCK":keywordlist(366).COLOR="Blue"
keywordlist(367).word="UNSIGNED":keywordlist(367).COLOR="Blue"
keywordlist(368).word="UNTIL":keywordlist(368).COLOR="Blue"
keywordlist(369).word="USHORT":keywordlist(369).COLOR="Blue"
keywordlist(370).word="PRINT":keywordlist(370).COLOR="Blue"
keywordlist(371).word="VA_ARG":keywordlist(371).COLOR="Blue"
keywordlist(372).word="VA_FIRST":keywordlist(372).COLOR="Blue"
keywordlist(373).word="VA_NEXT":keywordlist(373).COLOR="Blue"
keywordlist(374).word="VAL":keywordlist(374).COLOR="Blue"
keywordlist(375).word="VALLNG":keywordlist(375).COLOR="Blue"
keywordlist(376).word="VALINT":keywordlist(376).COLOR="Blue"
keywordlist(377).word="VALUINT":keywordlist(377).COLOR="Blue"
keywordlist(378).word="VALULNG":keywordlist(378).COLOR="Blue"
keywordlist(379).word="VAR":keywordlist(379).COLOR="Blue"
keywordlist(380).word="VARPTR":keywordlist(380).COLOR="Blue"
keywordlist(381).word="PRINT":keywordlist(381).COLOR="Blue"
keywordlist(382).word="WAIT":keywordlist(382).COLOR="Blue"
keywordlist(383).word="WBIN":keywordlist(383).COLOR="Blue"
keywordlist(384).word="WCHR":keywordlist(384).COLOR="Blue"
keywordlist(385).word="WEEKDAY":keywordlist(385).COLOR="Blue"
keywordlist(386).word="WEEKDAYNAME":keywordlist(386).COLOR="Blue"
keywordlist(387).word="WEND":keywordlist(387).COLOR="Blue"
keywordlist(388).word="WHILE":keywordlist(388).COLOR="Blue"
keywordlist(389).word="WEND":keywordlist(389).COLOR="Blue"
keywordlist(390).word="WHEX":keywordlist(390).COLOR="Blue"
keywordlist(391).word="WIDTH":keywordlist(391).COLOR="Blue"
keywordlist(392).word="WINDOW":keywordlist(392).COLOR="Blue"
keywordlist(393).word="WINDOWTITLE":keywordlist(393).COLOR="Blue"
keywordlist(394).word="WINPUT":keywordlist(394).COLOR="Blue"
keywordlist(395).word="WITH":keywordlist(395).COLOR="Blue"
keywordlist(396).word="WOCT":keywordlist(396).COLOR="Blue"
keywordlist(397).word="WRITE":keywordlist(397).COLOR="Blue"
keywordlist(398).word="WRITE #":keywordlist(398).COLOR="Blue"
keywordlist(399).word="WSPACE":keywordlist(399).COLOR="Blue"
keywordlist(400).word="WSTR":keywordlist(400).COLOR="Blue"
keywordlist(401).word="XOR":keywordlist(401).COLOR="Blue"
keywordlist(402).word="PUT":keywordlist(402).COLOR="Blue"
keywordlist(403).word="YEAR":keywordlist(403).COLOR="Blue"
keywordlist(404).word="ZSTRING":keywordlist(404).COLOR="Blue"
keywordlist(405).word="END":keywordlist(404).COLOR="Blue"
keywordlist(406).word="#INCLUDE":keywordlist(404).COLOR="Blue"
keywordlist(407).word="GET":keywordlist(404).COLOR="Blue"
keywordlist(408).word="PSET":keywordlist(404).COLOR="Blue"
nkeywordlist=409
END SUB
' ------------------------------------------------------------------
FUNCTION isbasickeyword(s AS STRING) AS INTEGER
DIM AS INTEGER i, retval
retval=false
IF (nkeywordlist=0) THEN readkeywordlist
FOR i=0 TO nkeywordlist-1
IF UCASE(s)=keywordlist(i).word THEN
retval=true
EXIT FOR
END IF
NEXT i
isbasickeyword=retval
END FUNCTION
' ------------------------------------------------------------------
FUNCTION test_basic(x AS textbuf) AS INTEGER
DIM AS INTEGER i, j, icountbasic,retval
DIM AS textbuf PTR tempbuf
icountbasic=0
FOR i=0 TO x.nline-1
tempbuf=tokenizestring(x.OUT(i))
FOR j=0 TO tempbuf->nline-1
IF isbasickeyword(tempbuf->out(j)) THEN icountbasic=icountbasic+1
NEXT j
DELETE tempbuf
NEXT i
retval=false
IF (icountbasic>2) THEN retval=true
test_basic=retval
END FUNCTION
' ------------------------------------------------------------------
SUB test2
DIM AS textbuf x
x.init(10,"Test")
x.add("Adam Eva Function")
x.add("Hallo Eins Print Screen Zwei")
x.add("juhdga 7652 djsh")
x.add("F 7652")
readkeywordlist
PRINT test_basic(x)
END SUB
' ------------------------------------------------------------------
SUB insertstr(BYREF s AS STRING, instring AS STRING, ipos AS integer)
s=LEFT(s,ipos-1)+instring+RIGHT(s,LEN(s)-ipos+1)
END SUB
' ------------------------------------------------------------------
SUB outline_basic(tb AS textbuf)
DIM AS INTEGER i,j
DIM AS tokenbuf PTR tempbuf
DIM AS STRING starttag="<font color="+Ccolor+"><b>"
DIM AS STRING endtag="</b></font>"
DIM AS STRING starttag_str="<font color="+Cstringcolor+"><b>"
DIM AS STRING starttag_com="<font color="+Ccommentcolor+"><b>"
DIM AS STRING starttag0
'? "outline_basic()"
'tb.print0
FOR i=0 TO tb.nline-1
tempbuf=tokenizestring2(tb.OUT(i))
'tempbuf->print0
'sleep
FOR j=0 TO tempbuf->tbuf.nline-1
starttag0=""
IF isbasickeyword(tempbuf->out(j)) THEN starttag0=starttag
IF (tempbuf->propertytab[j]=Cstring) THEN starttag0=starttag_str
IF (tempbuf->propertytab[j]=Ccomment) THEN starttag0=starttag_com
IF (LEN(starttag0)>2) THEN
'? tempbuf->postab[j]
'? len(tempbuf->out(j))
'In Grossbuchstaben umwandeln
IF (tempbuf->propertytab[j]=0) THEN _
mid(tempbuf->orgstring,tempbuf->postab[j],LEN(tempbuf->out(j)))=UCASE(mid(tempbuf->orgstring,tempbuf->postab[j],LEN(tempbuf->out(j))))
'Starttag einfuegen
insertstr(tempbuf->orgstring,starttag0,tempbuf->postab[j])
'Endtag einfuegen
insertstr(tempbuf->orgstring,endtag,tempbuf->postab[j]+LEN(tempbuf->out(j))+LEN(starttag0))
'Positionstabelle nachfuehren
tempbuf->shiftpos(LEN(starttag0)+LEN(endtag),j+1)
'? "outline",i,j,tempbuf->orgstring
'sleep
END IF
NEXT j
tb.change(i,tempbuf->orgstring)
DELETE tempbuf
NEXT i
END SUB
' ------------------------------------------------------------------
SUB convert(infileno AS INTEGER, outfileno AS integer)
DIM s AS STRING
DIM AS INTEGER i,found,region
DIM tb AS textbuf
tb.init(1000,"get_basicpart")
i=0
found=false
region=-1
WHILE NOT found AND NOT EOF(infileno)
LINE INPUT #infileno,s
if (instr(lcase(s)," ")>0) then
region=-1
if test_basic(tb) then
'? "convert() tb.line=",tb.nline
outline_basic(tb)
'? "hallo"
'tb.print0
'sleep
end if
tb.fprint0(outfileno)
tb.clear()
end if
'Eine Zeile nach mit dem Einlesen beginnen
IF region>0 THEN
tb.add(s)
END IF
IF (region>=0) THEN region=region+1
'Rausschreiben
IF (region<=1) THEN PRINT #outfileno,s
i=i+1
WEND
END SUB
' ------------------------------------------------------------------
SUB test3
DIM AS INTEGER infileno,outfileno
infileno=FREEFILE()
OPEN "Y:\kap36.htm" FOR INPUT AS infileno
outfileno=FREEFILE()
OPEN "Y:\kap36col.htm" FOR OUTPUT AS outfileno
convert(infileno,outfileno)
CLOSE(infileno)
CLOSE(outfileno)
END SUB
' ------------------------------------------------------------------
SUB main
DIM AS INTEGER infileno,outfileno
IF COMMAND(1)="" THEN brkmess("Syntax: basicoutline ")
infileno=FREEFILE()
OPEN COMMAND(1) FOR INPUT AS infileno
outfileno=FREEFILE()
OPEN "buffer.htm" FOR OUTPUT AS outfileno
convert(infileno,outfileno)
CLOSE(infileno)
CLOSE(outfileno)
SHELL("copy buffer.htm "+COMMAND(1))
SHELL("del buffer.htm")
END SUB
' ------------------------------------------------------------------
main