Fossil SCM

Modify the TH1 script interperter to use native characters rather than unsigned characters. Fix a bug in the combobox extension command of TH1.

drh 2008-10-24 16:36 trunk
Commit 0c99a1554a22b74a881b2d6360c4ddd769aeaf23
5 files changed +138 -202 +29 -33 +67 -69 +30 -26 +1 -1
+138 -202
--- src/th.c
+++ src/th.c
@@ -15,11 +15,11 @@
1515
/*
1616
** Interpreter structure.
1717
*/
1818
struct Th_Interp {
1919
Th_Vtab *pVtab; /* Copy of the argument passed to Th_CreateInterp() */
20
- uchar *zResult; /* Current interpreter result (Th_Malloc()ed) */
20
+ char *zResult; /* Current interpreter result (Th_Malloc()ed) */
2121
int nResult; /* number of bytes in zResult */
2222
Th_Hash *paCmd; /* Table of registered commands */
2323
Th_Frame *pFrame; /* Current execution frame */
2424
int isListMode; /* True if thSplitList() should operate in "list" mode */
2525
};
@@ -28,11 +28,11 @@
2828
** Each TH command registered using Th_CreateCommand() is represented
2929
** by an instance of the following structure stored in the Th_Interp.paCmd
3030
** hash-table.
3131
*/
3232
struct Th_Command {
33
- int (*xProc)(Th_Interp *, void *, int, const uchar **, int *);
33
+ int (*xProc)(Th_Interp *, void *, int, const char **, int *);
3434
void *pContext;
3535
void (*xDel)(Th_Interp *, void *);
3636
};
3737
3838
/*
@@ -83,11 +83,11 @@
8383
** value.
8484
*/
8585
struct Th_Variable {
8686
int nRef; /* Number of references to this structure */
8787
int nData; /* Number of bytes at Th_Variable.zData */
88
- uchar *zData; /* Data for scalar variables */
88
+ char *zData; /* Data for scalar variables */
8989
Th_Hash *pHash; /* Data for array variables */
9090
};
9191
9292
/*
9393
** Hash table API:
@@ -95,15 +95,15 @@
9595
#define TH_HASHSIZE 257
9696
struct Th_Hash {
9797
Th_HashEntry *a[TH_HASHSIZE];
9898
};
9999
100
-static int thEvalLocal(Th_Interp *, const uchar *, int);
101
-static int thSplitList(Th_Interp*, const uchar*, int, uchar***, int **, int*);
100
+static int thEvalLocal(Th_Interp *, const char *, int);
101
+static int thSplitList(Th_Interp*, const char*, int, char***, int **, int*);
102102
103
-static int thHexdigit(uchar c);
104
-static int thEndOfLine(const uchar *, int);
103
+static int thHexdigit(char c);
104
+static int thEndOfLine(const char *, int);
105105
106106
static int thPushFrame(Th_Interp*, Th_Frame*);
107107
static void thPopFrame(Th_Interp*);
108108
109109
static void thFreeVariable(Th_HashEntry*, void*);
@@ -123,53 +123,53 @@
123123
**
124124
** thNextVarname(interp, "$a+1", 4, &nByte);
125125
**
126126
** results in nByte being set to 2.
127127
*/
128
-static int thNextCommand(Th_Interp*, const uchar *z, int n, int *pN);
129
-static int thNextEscape (Th_Interp*, const uchar *z, int n, int *pN);
130
-static int thNextVarname(Th_Interp*, const uchar *z, int n, int *pN);
131
-static int thNextNumber (Th_Interp*, const uchar *z, int n, int *pN);
132
-static int thNextSpace (Th_Interp*, const uchar *z, int n, int *pN);
128
+static int thNextCommand(Th_Interp*, const char *z, int n, int *pN);
129
+static int thNextEscape (Th_Interp*, const char *z, int n, int *pN);
130
+static int thNextVarname(Th_Interp*, const char *z, int n, int *pN);
131
+static int thNextNumber (Th_Interp*, const char *z, int n, int *pN);
132
+static int thNextSpace (Th_Interp*, const char *z, int n, int *pN);
133133
134134
/*
135135
** Given that the input string (z, n) contains a language construct of
136136
** the relevant type (a command enclosed in [], an escape sequence
137137
** like "\xFF" or a variable reference like "${varname}", perform
138138
** substitution on the string and store the resulting string in
139139
** the interpreter result.
140140
*/
141
-static int thSubstCommand(Th_Interp*, const uchar *z, int n);
142
-static int thSubstEscape (Th_Interp*, const uchar *z, int n);
143
-static int thSubstVarname(Th_Interp*, const uchar *z, int n);
141
+static int thSubstCommand(Th_Interp*, const char *z, int n);
142
+static int thSubstEscape (Th_Interp*, const char *z, int n);
143
+static int thSubstVarname(Th_Interp*, const char *z, int n);
144144
145145
/*
146146
** Given that there is a th1 word located at the start of the input
147147
** string (z, n), determine the length in bytes of that word. If the
148148
** isCmd argument is non-zero, then an unescaped ";" byte not
149149
** located inside of a block or quoted string is considered to mark
150150
** the end of the word.
151151
*/
152
-static int thNextWord(Th_Interp*, const uchar *z, int n, int *pN, int isCmd);
152
+static int thNextWord(Th_Interp*, const char *z, int n, int *pN, int isCmd);
153153
154154
/*
155155
** Perform substitution on the word contained in the input string (z, n).
156156
** Store the resulting string in the interpreter result.
157157
*/
158
-static int thSubstWord(Th_Interp*, const uchar *z, int n);
158
+static int thSubstWord(Th_Interp*, const char *z, int n);
159159
160160
/*
161161
** The Buffer structure and the thBufferXXX() functions are used to make
162162
** memory allocation easier when building up a result.
163163
*/
164164
struct Buffer {
165
- uchar *zBuf;
165
+ char *zBuf;
166166
int nBuf;
167167
int nBufAlloc;
168168
};
169169
typedef struct Buffer Buffer;
170
-static int thBufferWrite(Th_Interp *interp, Buffer *, const uchar *, int);
170
+static int thBufferWrite(Th_Interp *interp, Buffer *, const char *, int);
171171
static void thBufferInit(Buffer *);
172172
static void thBufferFree(Th_Interp *interp, Buffer *);
173173
174174
/*
175175
** Append nAdd bytes of content copied from zAdd to the end of buffer
@@ -177,11 +177,11 @@
177177
** the allocation to make space.
178178
*/
179179
static int thBufferWrite(
180180
Th_Interp *interp,
181181
Buffer *pBuffer,
182
- const uchar *zAdd,
182
+ const char *zAdd,
183183
int nAdd
184184
){
185185
int nReq;
186186
187187
if( nAdd<0 ){
@@ -188,15 +188,15 @@
188188
nAdd = th_strlen(zAdd);
189189
}
190190
nReq = pBuffer->nBuf+nAdd+1;
191191
192192
if( nReq>pBuffer->nBufAlloc ){
193
- uchar *zNew;
193
+ char *zNew;
194194
int nNew;
195195
196196
nNew = nReq*2;
197
- zNew = (uchar *)Th_Malloc(interp, nNew);
197
+ zNew = (char *)Th_Malloc(interp, nNew);
198198
memcpy(zNew, pBuffer->zBuf, pBuffer->nBuf);
199199
Th_Free(interp, pBuffer->zBuf);
200200
pBuffer->nBufAlloc = nNew;
201201
pBuffer->zBuf = zNew;
202202
}
@@ -205,11 +205,11 @@
205205
pBuffer->nBuf += nAdd;
206206
pBuffer->zBuf[pBuffer->nBuf] = '\0';
207207
208208
return TH_OK;
209209
}
210
-#define thBufferWrite(a,b,c,d) thBufferWrite(a,b,(const uchar *)c,d)
210
+#define thBufferWrite(a,b,c,d) thBufferWrite(a,b,(const char *)c,d)
211211
212212
/*
213213
** Initialize the Buffer structure pointed to by pBuffer.
214214
*/
215215
static void thBufferInit(Buffer *pBuffer){
@@ -228,11 +228,11 @@
228228
/*
229229
** Assuming parameter c contains a hexadecimal digit character,
230230
** return the corresponding value of that digit. If c is not
231231
** a hexadecimal digit character, -1 is returned.
232232
*/
233
-static int thHexdigit(uchar c){
233
+static int thHexdigit(char c){
234234
switch (c) {
235235
case '0': return 0;
236236
case '1': return 1;
237237
case '2': return 2;
238238
case '3': return 3;
@@ -317,11 +317,11 @@
317317
** If there is a parse error, return TH_ERROR and set the interpreter
318318
** result to an error message. Otherwise return TH_OK.
319319
*/
320320
static int thNextEscape(
321321
Th_Interp *interp,
322
- const uchar *zInput,
322
+ const char *zInput,
323323
int nInput,
324324
int *pnEscape
325325
){
326326
int i = 2;
327327
@@ -349,11 +349,11 @@
349349
** reference. If there is a parse error, return TH_ERROR and set the
350350
** interpreter result to an error message. Otherwise return TH_OK.
351351
*/
352352
int thNextVarname(
353353
Th_Interp *interp,
354
- const uchar *zInput,
354
+ const char *zInput,
355355
int nInput,
356356
int *pnVarname
357357
){
358358
int i;
359359
@@ -407,11 +407,11 @@
407407
** and set the interpreter result to an error message. Otherwise return
408408
** TH_OK.
409409
*/
410410
int thNextCommand(
411411
Th_Interp *interp,
412
- const uchar *zInput,
412
+ const char *zInput,
413413
int nInput,
414414
int *pnCommand
415415
){
416416
int nBrace = 0;
417417
int nSquare = 0;
@@ -442,11 +442,11 @@
442442
** Set *pnSpace to the number of whitespace bytes at the start of
443443
** input string (zInput, nInput). Always return TH_OK.
444444
*/
445445
int thNextSpace(
446446
Th_Interp *interp,
447
- const uchar *zInput,
447
+ const char *zInput,
448448
int nInput,
449449
int *pnSpace
450450
){
451451
int i;
452452
for(i=0; i<nInput && th_isspace(zInput[i]); i++);
@@ -465,11 +465,11 @@
465465
** located inside of a block or quoted string is considered to mark
466466
** the end of the word.
467467
*/
468468
static int thNextWord(
469469
Th_Interp *interp,
470
- const uchar *zInput,
470
+ const char *zInput,
471471
int nInput,
472472
int *pnWord,
473473
int isCmd
474474
){
475475
int iEnd = 0;
@@ -520,11 +520,11 @@
520520
** a [] block. Perform substitution on the input string and store the
521521
** resulting string in the interpreter result.
522522
*/
523523
static int thSubstCommand(
524524
Th_Interp *interp,
525
- const uchar *zWord,
525
+ const char *zWord,
526526
int nWord
527527
){
528528
assert(nWord>=2);
529529
assert(zWord[0]=='[' && zWord[nWord-1]==']');
530530
return thEvalLocal(interp, &zWord[1], nWord-2);
@@ -536,11 +536,11 @@
536536
** the input string and store the resulting string in the interpreter
537537
** result.
538538
*/
539539
static int thSubstVarname(
540540
Th_Interp *interp,
541
- const uchar *zWord,
541
+ const char *zWord,
542542
int nWord
543543
){
544544
assert(nWord>=1);
545545
assert(zWord[0]=='$');
546546
assert(nWord==1 || zWord[1]!='{' || zWord[nWord-1]=='}');
@@ -551,11 +551,11 @@
551551
int i;
552552
for(i=1; i<nWord && zWord[i]!='('; i++);
553553
if( i<nWord ){
554554
Buffer varname;
555555
int nInner;
556
- const uchar *zInner;
556
+ const char *zInner;
557557
558558
int rc = thSubstWord(interp, &zWord[i+1], nWord-i-2);
559559
if( rc!=TH_OK ) return rc;
560560
561561
zInner = Th_GetResult(interp, &nInner);
@@ -576,14 +576,14 @@
576576
** Perform substitution on the input string and store the resulting
577577
** string in the interpreter result.
578578
*/
579579
static int thSubstEscape(
580580
Th_Interp *interp,
581
- const uchar *zWord,
581
+ const char *zWord,
582582
int nWord
583583
){
584
- uchar c;
584
+ char c;
585585
586586
assert(nWord>=2);
587587
assert(zWord[0]=='\\');
588588
589589
switch( zWord[1] ){
@@ -612,11 +612,11 @@
612612
** substitution on the input string and store the resulting
613613
** string in the interpreter result.
614614
*/
615615
static int thSubstWord(
616616
Th_Interp *interp,
617
- const uchar *zWord,
617
+ const char *zWord,
618618
int nWord
619619
){
620620
int rc = TH_OK;
621621
Buffer output;
622622
int i;
@@ -634,12 +634,12 @@
634634
}
635635
636636
for(i=0; rc==TH_OK && i<nWord; i++){
637637
int nGet;
638638
639
- int (*xGet)(Th_Interp *, const uchar*, int, int *) = 0;
640
- int (*xSubst)(Th_Interp *, const uchar*, int) = 0;
639
+ int (*xGet)(Th_Interp *, const char*, int, int *) = 0;
640
+ int (*xSubst)(Th_Interp *, const char*, int) = 0;
641641
642642
switch( zWord[i] ){
643643
case '\\':
644644
xGet = thNextEscape; xSubst = thSubstEscape;
645645
break;
@@ -662,11 +662,11 @@
662662
rc = xGet(interp, &zWord[i], nWord-i, &nGet);
663663
if( rc==TH_OK ){
664664
rc = xSubst(interp, &zWord[i], nGet);
665665
}
666666
if( rc==TH_OK ){
667
- const uchar *zRes;
667
+ const char *zRes;
668668
int nRes;
669669
zRes = Th_GetResult(interp, &nRes);
670670
rc = thBufferWrite(interp, &output, zRes, nRes);
671671
i += (nGet-1);
672672
}
@@ -689,11 +689,11 @@
689689
** + It contains no non-white-space characters before the first
690690
** newline character.
691691
**
692692
** Otherwise return false.
693693
*/
694
-static int thEndOfLine(const uchar *zInput, int nInput){
694
+static int thEndOfLine(const char *zInput, int nInput){
695695
int i;
696696
for(i=0; i<nInput && zInput[i]!='\n' && th_isspace(zInput[i]); i++);
697697
return ((i==nInput || zInput[i]=='\n')?1:0);
698698
}
699699
@@ -710,11 +710,11 @@
710710
**
711711
** If TH_OK is returned and pazElem is not NULL, the caller should free the
712712
** pointer written to (*pazElem) using Th_Free(). This releases memory
713713
** allocated for both the (*pazElem) and (*panElem) arrays. Example:
714714
**
715
-** uchar **argv;
715
+** char **argv;
716716
** int *argl;
717717
** int argc;
718718
**
719719
** // After this call, argv and argl point to valid arrays. The
720720
** // number of elements in each is argc.
@@ -727,30 +727,30 @@
727727
** Th_Free(interp, argv);
728728
**
729729
*/
730730
static int thSplitList(
731731
Th_Interp *interp, /* Interpreter context */
732
- const uchar *zList, /* Pointer to buffer containing input list */
732
+ const char *zList, /* Pointer to buffer containing input list */
733733
int nList, /* Size of buffer pointed to by zList */
734
- uchar ***pazElem, /* OUT: Array of list elements */
734
+ char ***pazElem, /* OUT: Array of list elements */
735735
int **panElem, /* OUT: Lengths of each list element */
736736
int *pnCount /* OUT: Number of list elements */
737737
){
738738
int rc = TH_OK;
739739
740740
Buffer strbuf;
741741
Buffer lenbuf;
742742
int nCount = 0;
743743
744
- const uchar *zInput = zList;
744
+ const char *zInput = zList;
745745
int nInput = nList;
746746
747747
thBufferInit(&strbuf);
748748
thBufferInit(&lenbuf);
749749
750750
while( nInput>0 ){
751
- const uchar *zWord;
751
+ const char *zWord;
752752
int nWord;
753753
754754
thNextSpace(interp, zInput, nInput, &nWord);
755755
zInput += nWord;
756756
nInput = nList-(zInput-zList);
@@ -773,19 +773,19 @@
773773
assert((lenbuf.nBuf/sizeof(int))==nCount);
774774
775775
assert((pazElem && panElem) || (!pazElem && !panElem));
776776
if( pazElem && rc==TH_OK ){
777777
int i;
778
- uchar *zElem;
778
+ char *zElem;
779779
int *anElem;
780
- uchar **azElem = Th_Malloc(interp,
781
- sizeof(uchar*) * nCount + /* azElem */
780
+ char **azElem = Th_Malloc(interp,
781
+ sizeof(char*) * nCount + /* azElem */
782782
sizeof(int) * nCount + /* anElem */
783783
strbuf.nBuf /* space for list element strings */
784784
);
785785
anElem = (int *)&azElem[nCount];
786
- zElem = (uchar *)&anElem[nCount];
786
+ zElem = (char *)&anElem[nCount];
787787
memcpy(anElem, lenbuf.zBuf, lenbuf.nBuf);
788788
memcpy(zElem, strbuf.zBuf, strbuf.nBuf);
789789
for(i=0; i<nCount;i++){
790790
azElem[i] = zElem;
791791
zElem += (anElem[i] + 1);
@@ -805,21 +805,21 @@
805805
806806
/*
807807
** Evaluate the th1 script contained in the string (zProgram, nProgram)
808808
** in the current stack frame.
809809
*/
810
-static int thEvalLocal(Th_Interp *interp, const uchar *zProgram, int nProgram){
810
+static int thEvalLocal(Th_Interp *interp, const char *zProgram, int nProgram){
811811
int rc = TH_OK;
812
- const uchar *zInput = zProgram;
812
+ const char *zInput = zProgram;
813813
int nInput = nProgram;
814814
815815
while( rc==TH_OK && nInput ){
816816
Th_HashEntry *pEntry;
817817
int nSpace;
818
- const uchar *zFirst;
818
+ const char *zFirst;
819819
820
- uchar **argv;
820
+ char **argv;
821821
int *argl;
822822
int argc;
823823
824824
assert(nInput>=0);
825825
@@ -872,27 +872,27 @@
872872
}
873873
874874
/* Call the command procedure. */
875875
if( rc==TH_OK ){
876876
Th_Command *p = (Th_Command *)(pEntry->pData);
877
- const uchar **azArg = (const uchar **)argv;
877
+ const char **azArg = (const char **)argv;
878878
rc = p->xProc(interp, p->pContext, argc, azArg, argl);
879879
}
880880
881881
/* If an error occured, add this command to the stack trace report. */
882882
if( rc==TH_ERROR ){
883
- uchar *zRes;
883
+ char *zRes;
884884
int nRes;
885
- uchar *zStack = 0;
885
+ char *zStack = 0;
886886
int nStack = 0;
887887
888888
zRes = Th_TakeResult(interp, &nRes);
889
- if( TH_OK==Th_GetVar(interp, (uchar *)"::th_stack_trace", -1) ){
889
+ if( TH_OK==Th_GetVar(interp, (char *)"::th_stack_trace", -1) ){
890890
zStack = Th_TakeResult(interp, &nStack);
891891
}
892892
Th_ListAppend(interp, &zStack, &nStack, zFirst, zInput-zFirst);
893
- Th_SetVar(interp, (uchar *)"::th_stack_trace", -1, zStack, nStack);
893
+ Th_SetVar(interp, (char *)"::th_stack_trace", -1, zStack, nStack);
894894
Th_SetResult(interp, zRes, nRes);
895895
Th_Free(interp, zRes);
896896
Th_Free(interp, zStack);
897897
}
898898
}
@@ -933,11 +933,11 @@
933933
for(i=0; p && i<(iFrame*-1); i++){
934934
p = p->pCaller;
935935
}
936936
937937
if( !p ){
938
- uchar *zFrame;
938
+ char *zFrame;
939939
int nFrame;
940940
Th_SetResultInt(interp, iFrame);
941941
zFrame = Th_TakeResult(interp, &nFrame);
942942
Th_ErrorMessage(interp, "no such frame:", zFrame, nFrame);
943943
Th_Free(interp, zFrame);
@@ -950,11 +950,11 @@
950950
** Evaluate th1 script (zProgram, nProgram) in the frame identified by
951951
** argument iFrame. Leave either an error message or a result in the
952952
** interpreter result and return a th1 error code (TH_OK, TH_ERROR,
953953
** TH_RETURN, TH_CONTINUE or TH_BREAK).
954954
*/
955
-int Th_Eval(Th_Interp *interp, int iFrame, const uchar *zProgram, int nProgram){
955
+int Th_Eval(Th_Interp *interp, int iFrame, const char *zProgram, int nProgram){
956956
int rc = TH_OK;
957957
Th_Frame *pSavedFrame = interp->pFrame;
958958
959959
/* Set Th_Interp.pFrame to the frame that this script is to be
960960
** evaluated in. The current frame is saved in pSavedFrame and will
@@ -992,21 +992,21 @@
992992
** array variable. If the variable is a scalar, *pzInner is set to 0.
993993
** If it is an array variable, (*pzInner, *pnInner) is set to the
994994
** array key name.
995995
*/
996996
static int thAnalyseVarname(
997
- const uchar *zVarname,
997
+ const char *zVarname,
998998
int nVarname,
999
- const uchar **pzOuter, /* OUT: Pointer to scalar/array name */
999
+ const char **pzOuter, /* OUT: Pointer to scalar/array name */
10001000
int *pnOuter, /* OUT: Number of bytes at *pzOuter */
1001
- const uchar **pzInner, /* OUT: Pointer to array key (or null) */
1001
+ const char **pzInner, /* OUT: Pointer to array key (or null) */
10021002
int *pnInner, /* OUT: Number of bytes at *pzInner */
10031003
int *pisGlobal /* OUT: Set to true if this is a global ref */
10041004
){
1005
- const uchar *zOuter = zVarname;
1005
+ const char *zOuter = zVarname;
10061006
int nOuter;
1007
- const uchar *zInner = 0;
1007
+ const char *zInner = 0;
10081008
int nInner = 0;
10091009
int isGlobal = 0;
10101010
int i;
10111011
10121012
if( nVarname<0 ){
@@ -1056,18 +1056,18 @@
10561056
** an error is left in the interpreter result and NULL returned. If
10571057
** arrayok is true an array name is Ok.
10581058
*/
10591059
static Th_Variable *thFindValue(
10601060
Th_Interp *interp,
1061
- const uchar *zVar, /* Pointer to variable name */
1061
+ const char *zVar, /* Pointer to variable name */
10621062
int nVar, /* Number of bytes at nVar */
10631063
int create, /* If true, create the variable if not found */
10641064
int arrayok /* If true, an array is Ok. Othewise array==error */
10651065
){
1066
- const uchar *zOuter;
1066
+ const char *zOuter;
10671067
int nOuter;
1068
- const uchar *zInner;
1068
+ const char *zInner;
10691069
int nInner;
10701070
int isGlobal;
10711071
10721072
Th_HashEntry *pEntry;
10731073
Th_Frame *pFrame = interp->pFrame;
@@ -1134,11 +1134,11 @@
11341134
** the interpreter result and return TH_OK.
11351135
**
11361136
** If the named variable does not exist, return TH_ERROR and leave
11371137
** an error message in the interpreter result.
11381138
*/
1139
-int Th_GetVar(Th_Interp *interp, const uchar *zVar, int nVar){
1139
+int Th_GetVar(Th_Interp *interp, const char *zVar, int nVar){
11401140
Th_Variable *pValue;
11411141
11421142
pValue = thFindValue(interp, zVar, nVar, 0, 0);
11431143
if( !pValue ){
11441144
return TH_ERROR;
@@ -1159,13 +1159,13 @@
11591159
** If (zVar, nVar) refers to an existing array, TH_ERROR is returned
11601160
** and an error message left in the interpreter result.
11611161
*/
11621162
int Th_SetVar(
11631163
Th_Interp *interp,
1164
- const uchar *zVar,
1164
+ const char *zVar,
11651165
int nVar,
1166
- const uchar *zValue,
1166
+ const char *zValue,
11671167
int nValue
11681168
){
11691169
Th_Variable *pValue;
11701170
11711171
pValue = thFindValue(interp, zVar, nVar, 1, 0);
@@ -1194,13 +1194,13 @@
11941194
** Create a variable link so that accessing variable (zLocal, nLocal) is
11951195
** the same as accessing variable (zLink, nLink) in stack frame iFrame.
11961196
*/
11971197
int Th_LinkVar(
11981198
Th_Interp *interp, /* Interpreter */
1199
- const uchar *zLocal, int nLocal, /* Local varname */
1199
+ const char *zLocal, int nLocal, /* Local varname */
12001200
int iFrame, /* Stack frame of linked var */
1201
- const uchar *zLink, int nLink /* Linked varname */
1201
+ const char *zLink, int nLink /* Linked varname */
12021202
){
12031203
Th_Frame *pSavedFrame = interp->pFrame;
12041204
Th_Frame *pFrame;
12051205
Th_HashEntry *pEntry;
12061206
Th_Variable *pValue;
@@ -1229,11 +1229,11 @@
12291229
** Input string (zVar, nVar) must contain the name of a scalar variable,
12301230
** an array, or an array member. If the identified variable exists, it
12311231
** is deleted and TH_OK returned. Otherwise, an error message is left
12321232
** in the interpreter result and TH_ERROR is returned.
12331233
*/
1234
-int Th_UnsetVar(Th_Interp *interp, const uchar *zVar, int nVar){
1234
+int Th_UnsetVar(Th_Interp *interp, const char *zVar, int nVar){
12351235
Th_Variable *pValue;
12361236
12371237
pValue = thFindValue(interp, zVar, nVar, 1, 1);
12381238
if( !pValue ){
12391239
return TH_ERROR;
@@ -1252,12 +1252,12 @@
12521252
/*
12531253
** Return an allocated buffer containing a copy of string (z, n). The
12541254
** caller is responsible for eventually calling Th_Free() to free
12551255
** the returned buffer.
12561256
*/
1257
-uchar *th_strdup(Th_Interp *interp, const uchar *z, int n){
1258
- uchar *zRes;
1257
+char *th_strdup(Th_Interp *interp, const char *z, int n){
1258
+ char *zRes;
12591259
if( n<0 ){
12601260
n = th_strlen(z);
12611261
}
12621262
zRes = Th_Malloc(interp, n+1);
12631263
memcpy(zRes, z, n);
@@ -1277,24 +1277,23 @@
12771277
** Example:
12781278
**
12791279
** Th_ErrorMessage(interp, "no such variable:", zVarname, nVarname);
12801280
**
12811281
*/
1282
-int Th_ErrorMessage(Th_Interp *interp, const char *zPre, const uchar *z, int n){
1282
+int Th_ErrorMessage(Th_Interp *interp, const char *zPre, const char *z, int n){
12831283
if( interp ){
1284
- uchar *zRes = 0;
1284
+ char *zRes = 0;
12851285
int nRes = 0;
1286
- int nPre = th_strlen(zPre);
12871286
1288
- Th_SetVar(interp, (uchar *)"::th_stack_trace", -1, 0, 0);
1287
+ Th_SetVar(interp, (char *)"::th_stack_trace", -1, 0, 0);
12891288
12901289
Th_StringAppend(interp, &zRes, &nRes, zPre, -1);
12911290
if( zRes[nRes-1]=='"' ){
12921291
Th_StringAppend(interp, &zRes, &nRes, z, n);
1293
- Th_StringAppend(interp, &zRes, &nRes, (const uchar *)"\"", 1);
1292
+ Th_StringAppend(interp, &zRes, &nRes, (const char *)"\"", 1);
12941293
}else{
1295
- Th_StringAppend(interp, &zRes, &nRes, (const uchar *)" ", 1);
1294
+ Th_StringAppend(interp, &zRes, &nRes, (const char *)" ", 1);
12961295
Th_StringAppend(interp, &zRes, &nRes, z, n);
12971296
}
12981297
12991298
Th_SetResult(interp, zRes, nRes);
13001299
Th_Free(interp, zRes);
@@ -1305,11 +1304,11 @@
13051304
13061305
/*
13071306
** Set the current interpreter result by taking a copy of the buffer
13081307
** pointed to by z, size n bytes. TH_OK is always returned.
13091308
*/
1310
-int Th_SetResult(Th_Interp *pInterp, const uchar *z, int n){
1309
+int Th_SetResult(Th_Interp *pInterp, const char *z, int n){
13111310
13121311
/* Free the current result */
13131312
Th_Free(pInterp, pInterp->zResult);
13141313
pInterp->zResult = 0;
13151314
pInterp->nResult = 0;
@@ -1317,11 +1316,11 @@
13171316
if( n<0 ){
13181317
n = th_strlen(z);
13191318
}
13201319
13211320
if( z && n>0 ){
1322
- uchar *zResult;
1321
+ char *zResult;
13231322
zResult = Th_Malloc(pInterp, n+1);
13241323
memcpy(zResult, z, n);
13251324
zResult[n] = '\0';
13261325
pInterp->zResult = zResult;
13271326
pInterp->nResult = n;
@@ -1333,16 +1332,16 @@
13331332
/*
13341333
** Return a pointer to the buffer containing the current interpreter
13351334
** result. If pN is not NULL, set *pN to the size of the returned
13361335
** buffer.
13371336
*/
1338
-const uchar *Th_GetResult(Th_Interp *pInterp, int *pN){
1337
+const char *Th_GetResult(Th_Interp *pInterp, int *pN){
13391338
assert(pInterp->zResult || pInterp->nResult==0);
13401339
if( pN ){
13411340
*pN = pInterp->nResult;
13421341
}
1343
- return (pInterp->zResult ? pInterp->zResult : (const uchar *)"");
1342
+ return (pInterp->zResult ? pInterp->zResult : (const char *)"");
13441343
}
13451344
13461345
/*
13471346
** Return a pointer to the buffer containing the current interpreter
13481347
** result. If pN is not NULL, set *pN to the size of the returned
@@ -1351,21 +1350,21 @@
13511350
** This function is the same as Th_GetResult() except that the
13521351
** caller is responsible for eventually calling Th_Free() on the
13531352
** returned buffer. The internal interpreter result is cleared
13541353
** after this function is called.
13551354
*/
1356
-uchar *Th_TakeResult(Th_Interp *pInterp, int *pN){
1355
+char *Th_TakeResult(Th_Interp *pInterp, int *pN){
13571356
if( pN ){
13581357
*pN = pInterp->nResult;
13591358
}
13601359
if( pInterp->zResult ){
1361
- uchar *zResult = pInterp->zResult;
1360
+ char *zResult = pInterp->zResult;
13621361
pInterp->zResult = 0;
13631362
pInterp->nResult = 0;
13641363
return zResult;
13651364
}else{
1366
- return (uchar *)Th_Malloc(pInterp, 1);
1365
+ return (char *)Th_Malloc(pInterp, 1);
13671366
}
13681367
}
13691368
13701369
13711370
/*
@@ -1397,11 +1396,11 @@
13971396
void (*xDel)(Th_Interp *, void *) /* Command destructor callback */
13981397
){
13991398
Th_HashEntry *pEntry;
14001399
Th_Command *pCommand;
14011400
1402
- pEntry = Th_HashFind(interp, interp->paCmd, (const uchar *)zName, -1, 1);
1401
+ pEntry = Th_HashFind(interp, interp->paCmd, (const char *)zName, -1, 1);
14031402
if( pEntry->pData ){
14041403
pCommand = pEntry->pData;
14051404
if( pCommand->xDel ){
14061405
pCommand->xDel(interp, pCommand->pContext);
14071406
}
@@ -1424,13 +1423,13 @@
14241423
** if command zNew already exists, an error message is left in the
14251424
** interpreter result and TH_ERROR is returned.
14261425
*/
14271426
int Th_RenameCommand(
14281427
Th_Interp *interp,
1429
- const uchar *zName, /* Existing command name */
1428
+ const char *zName, /* Existing command name */
14301429
int nName, /* Number of bytes at zName */
1431
- const uchar *zNew, /* New command name */
1430
+ const char *zNew, /* New command name */
14321431
int nNew /* Number of bytes at zNew */
14331432
){
14341433
Th_HashEntry *pEntry;
14351434
Th_HashEntry *pNewEntry;
14361435
@@ -1495,28 +1494,28 @@
14951494
**
14961495
** Example:
14971496
**
14981497
** int nElem;
14991498
** int *anElem;
1500
-** uchar **azElem;
1499
+** char **azElem;
15011500
** int i;
15021501
**
15031502
** Th_SplitList(interp, zList, nList, &azElem, &anElem, &nElem);
15041503
** for(i=0; i<nElem; i++){
15051504
** int nData = anElem[i];
1506
-** uchar *zData = azElem[i];
1505
+** char *zData = azElem[i];
15071506
** ...
15081507
** }
15091508
**
15101509
** Th_Free(interp, azElem);
15111510
**
15121511
*/
15131512
int Th_SplitList(
15141513
Th_Interp *interp,
1515
- const uchar *zList, /* Pointer to buffer containing list */
1514
+ const char *zList, /* Pointer to buffer containing list */
15161515
int nList, /* Number of bytes at zList */
1517
- uchar ***pazElem, /* OUT: Array of pointers to element data */
1516
+ char ***pazElem, /* OUT: Array of pointers to element data */
15181517
int **panElem, /* OUT: Array of element data lengths */
15191518
int *pnCount /* OUT: Number of elements in list */
15201519
){
15211520
int rc;
15221521
interp->isListMode = 1;
@@ -1541,25 +1540,25 @@
15411540
** *pzList to point to a new buffer containing the new list value. *pnList
15421541
** is similarly updated before returning. The return value is always TH_OK.
15431542
**
15441543
** Example:
15451544
**
1546
-** uchar *zList = 0;
1545
+** char *zList = 0;
15471546
** int nList = 0;
15481547
** for (...) {
1549
-** uchar *zElem = <some expression>;
1548
+** char *zElem = <some expression>;
15501549
** Th_ListAppend(interp, &zList, &nList, zElem, -1);
15511550
** }
15521551
** Th_SetResult(interp, zList, nList);
15531552
** Th_Free(interp, zList);
15541553
**
15551554
*/
15561555
int Th_ListAppend(
15571556
Th_Interp *interp, /* Interpreter context */
1558
- uchar **pzList, /* IN/OUT: Ptr to ptr to list */
1557
+ char **pzList, /* IN/OUT: Ptr to ptr to list */
15591558
int *pnList, /* IN/OUT: Current length of *pzList */
1560
- const uchar *zElem, /* Data to append */
1559
+ const char *zElem, /* Data to append */
15611560
int nElem /* Length of nElem */
15621561
){
15631562
Buffer output;
15641563
int i;
15651564
@@ -1577,11 +1576,11 @@
15771576
if( output.nBuf>0 ){
15781577
thBufferWrite(interp, &output, " ", 1);
15791578
}
15801579
15811580
for(i=0; i<nElem; i++){
1582
- uchar c = zElem[i];
1581
+ char c = zElem[i];
15831582
if( th_isspecial(c) ) hasSpecialChar = 1;
15841583
if( c=='\\' ) hasEscapeChar = 1;
15851584
if( c=='{' ) nBrace++;
15861585
if( c=='}' ) nBrace--;
15871586
}
@@ -1590,11 +1589,11 @@
15901589
thBufferWrite(interp, &output, "{", 1);
15911590
thBufferWrite(interp, &output, zElem, nElem);
15921591
thBufferWrite(interp, &output, "}", 1);
15931592
}else{
15941593
for(i=0; i<nElem; i++){
1595
- uchar c = zElem[i];
1594
+ char c = zElem[i];
15961595
if( th_isspecial(c) ) thBufferWrite(interp, &output, "\\", 1);
15971596
thBufferWrite(interp, &output, &c, 1);
15981597
}
15991598
}
16001599
@@ -1608,16 +1607,16 @@
16081607
** Append a new element to an existing th1 string. This function uses
16091608
** the same interface as the Th_ListAppend() function.
16101609
*/
16111610
int Th_StringAppend(
16121611
Th_Interp *interp, /* Interpreter context */
1613
- uchar **pzStr, /* IN/OUT: Ptr to ptr to list */
1612
+ char **pzStr, /* IN/OUT: Ptr to ptr to list */
16141613
int *pnStr, /* IN/OUT: Current length of *pzStr */
1615
- const uchar *zElem, /* Data to append */
1614
+ const char *zElem, /* Data to append */
16161615
int nElem /* Length of nElem */
16171616
){
1618
- uchar *zNew;
1617
+ char *zNew;
16191618
int nNew;
16201619
16211620
if( nElem<0 ){
16221621
nElem = th_strlen(zElem);
16231622
}
@@ -1687,11 +1686,11 @@
16871686
Operator *pOp;
16881687
Expr *pParent;
16891688
Expr *pLeft;
16901689
Expr *pRight;
16911690
1692
- uchar *zValue; /* Pointer to literal value */
1691
+ char *zValue; /* Pointer to literal value */
16931692
int nValue; /* Length of literal value buffer */
16941693
};
16951694
16961695
/* Unary operators */
16971696
#define OP_UNARY_MINUS 2
@@ -1778,18 +1777,18 @@
17781777
** The first part of the string (zInput,nInput) contains a number.
17791778
** Set *pnVarname to the number of bytes in the numeric string.
17801779
*/
17811780
static int thNextNumber(
17821781
Th_Interp *interp,
1783
- const uchar *zInput,
1782
+ const char *zInput,
17841783
int nInput,
17851784
int *pnLiteral
17861785
){
17871786
int i;
17881787
int seenDot = 0;
17891788
for(i=0; i<nInput; i++){
1790
- uchar c = zInput[i];
1789
+ char c = zInput[i];
17911790
if( (seenDot || c!='.') && !th_isdigit(c) ) break;
17921791
if( c=='.' ) seenDot = 1;
17931792
}
17941793
*pnLiteral = i;
17951794
return TH_OK;
@@ -1824,12 +1823,12 @@
18241823
int iRight;
18251824
double fLeft;
18261825
double fRight;
18271826
18281827
/* Left and right arguments as strings */
1829
- uchar *zLeft = 0; int nLeft;
1830
- uchar *zRight = 0; int nRight;
1828
+ char *zLeft = 0; int nLeft;
1829
+ char *zRight = 0; int nRight;
18311830
18321831
/* Evaluate left and right arguments, if they exist. */
18331832
if( pExpr->pLeft ){
18341833
rc = exprEval(interp, pExpr->pLeft);
18351834
if( rc==TH_OK ){
@@ -2014,11 +2013,11 @@
20142013
/*
20152014
** Parse a string containing a TH expression to a list of tokens.
20162015
*/
20172016
static int exprParse(
20182017
Th_Interp *interp, /* Interpreter to leave error message in */
2019
- const uchar *zExpr, /* Pointer to input string */
2018
+ const char *zExpr, /* Pointer to input string */
20202019
int nExpr, /* Number of bytes at zExpr */
20212020
Expr ***papToken, /* OUT: Array of tokens. */
20222021
int *pnToken /* OUT: Size of token array */
20232022
){
20242023
int i;
@@ -2026,16 +2025,16 @@
20262025
int rc = TH_OK;
20272026
int nToken = 0;
20282027
Expr **apToken = 0;
20292028
20302029
for(i=0; rc==TH_OK && i<nExpr; ){
2031
- uchar c = zExpr[i];
2030
+ char c = zExpr[i];
20322031
if( th_isspace(c) ){ /* White-space */
20332032
i++;
20342033
}else{
20352034
Expr *pNew = (Expr *)Th_Malloc(interp, sizeof(Expr));
2036
- const uchar *z = &zExpr[i];
2035
+ const char *z = &zExpr[i];
20372036
20382037
switch (c) {
20392038
case '0': case '1': case '2': case '3': case '4':
20402039
case '5': case '6': case '7': case '8': case '9':
20412040
thNextNumber(interp, z, nExpr-i, &pNew->nValue);
@@ -2069,11 +2068,11 @@
20692068
Expr *pPrev = apToken[nToken-1];
20702069
if( !pPrev->pOp || pPrev->pOp->eOp==OP_CLOSE_BRACKET ){
20712070
continue;
20722071
}
20732072
}
2074
- nOp = th_strlen((const uchar *)aOperator[j].zOp);
2073
+ nOp = th_strlen((const char *)aOperator[j].zOp);
20752074
if( (nExpr-i)>=nOp && 0==memcmp(aOperator[j].zOp, &zExpr[i], nOp) ){
20762075
pNew->pOp = &aOperator[j];
20772076
i += nOp;
20782077
break;
20792078
}
@@ -2115,11 +2114,11 @@
21152114
** Evaluate the string (zExpr, nExpr) as a Th expression. Store
21162115
** the result in the interpreter interp and return TH_OK if
21172116
** successful. If an error occurs, store an error message in
21182117
** the interpreter result and return an error code.
21192118
*/
2120
-int Th_Expr(Th_Interp *interp, const uchar *zExpr, int nExpr){
2119
+int Th_Expr(Th_Interp *interp, const char *zExpr, int nExpr){
21212120
int rc; /* Return Code */
21222121
int i; /* Loop counter */
21232122
21242123
int nToken = 0;
21252124
Expr **apToken = 0;
@@ -2222,11 +2221,11 @@
22222221
** not already present in the hash-table.
22232222
*/
22242223
Th_HashEntry *Th_HashFind(
22252224
Th_Interp *interp,
22262225
Th_Hash *pHash,
2227
- const uchar *zKey,
2226
+ const char *zKey,
22282227
int nKey,
22292228
int op /* -ve = delete, 0 = find, +ve = insert */
22302229
){
22312230
unsigned int iKey = 0;
22322231
int i;
@@ -2254,11 +2253,11 @@
22542253
pRet = 0;
22552254
}
22562255
22572256
if( op>0 && !pRet ){
22582257
pRet = (Th_HashEntry *)Th_Malloc(interp, sizeof(Th_HashEntry) + nKey);
2259
- pRet->zKey = (uchar *)&pRet[1];
2258
+ pRet->zKey = (char *)&pRet[1];
22602259
pRet->nKey = nKey;
22612260
memcpy(pRet->zKey, zKey, nKey);
22622261
pRet->pNext = pHash->a[iKey];
22632262
pHash->a[iKey] = pRet;
22642263
}
@@ -2269,11 +2268,11 @@
22692268
/*
22702269
** This function is the same as the standard strlen() function, except
22712270
** that it returns 0 (instead of being undefined) if the argument is
22722271
** a null pointer.
22732272
*/
2274
-int th_strlen(const unsigned char *zStr){
2273
+int th_strlen(const char *zStr){
22752274
int n = 0;
22762275
if( zStr ){
22772276
while( zStr[n] ) n++;
22782277
}
22792278
return n;
@@ -2320,27 +2319,27 @@
23202319
};
23212320
23222321
/*
23232322
** Clone of the standard isspace() and isdigit function/macros.
23242323
*/
2325
-int th_isspace(unsigned char c){
2326
- return (aCharProp[c] & 0x01);
2327
-}
2328
-int th_isdigit(unsigned char c){
2329
- return (aCharProp[c] & 0x02);
2330
-}
2331
-int th_isspecial(unsigned char c){
2332
- return (aCharProp[c] & 0x11);
2333
-}
2334
-int th_isalnum(unsigned char c){
2335
- return (aCharProp[c] & 0x0A);
2324
+int th_isspace(char c){
2325
+ return (aCharProp[(unsigned char)c] & 0x01);
2326
+}
2327
+int th_isdigit(char c){
2328
+ return (aCharProp[(unsigned char)c] & 0x02);
2329
+}
2330
+int th_isspecial(char c){
2331
+ return (aCharProp[(unsigned char)c] & 0x11);
2332
+}
2333
+int th_isalnum(char c){
2334
+ return (aCharProp[(unsigned char)c] & 0x0A);
23362335
}
23372336
23382337
#ifndef LONGDOUBLE_TYPE
23392338
# define LONGDOUBLE_TYPE long double
23402339
#endif
2341
-typedef uchar u8;
2340
+typedef char u8;
23422341
23432342
23442343
/*
23452344
** Return TRUE if z is a pure numeric string. Return FALSE if the
23462345
** string contains any character which is not part of a number. If
@@ -2446,11 +2445,11 @@
24462445
**
24472446
** If the string cannot be converted to an integer, return TH_ERROR.
24482447
** If the interp argument is not NULL, leave an error message in the
24492448
** interpreter result too.
24502449
*/
2451
-int Th_ToInt(Th_Interp *interp, const uchar *z, int n, int *piOut){
2450
+int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){
24522451
int i = 0;
24532452
int iOut = 0;
24542453
24552454
if( n<0 ){
24562455
n = th_strlen(z);
@@ -2483,11 +2482,11 @@
24832482
** If the interp argument is not NULL, leave an error message in the
24842483
** interpreter result too.
24852484
*/
24862485
int Th_ToDouble(
24872486
Th_Interp *interp,
2488
- const uchar *z,
2487
+ const char *z,
24892488
int n,
24902489
double *pfOut
24912490
){
24922491
if( !sqlite3IsNumber((const char *)z, 0) ){
24932492
Th_ErrorMessage(interp, "expected number, got: \"", z, n);
@@ -2502,21 +2501,21 @@
25022501
** Set the result of the interpreter to the th1 representation of
25032502
** the integer iVal and return TH_OK.
25042503
*/
25052504
int Th_SetResultInt(Th_Interp *interp, int iVal){
25062505
int isNegative = 0;
2507
- uchar zBuf[32];
2508
- uchar *z = &zBuf[32];
2506
+ char zBuf[32];
2507
+ char *z = &zBuf[32];
25092508
25102509
if( iVal<0 ){
25112510
isNegative = 1;
25122511
iVal = iVal * -1;
25132512
}
25142513
*(--z) = '\0';
2515
- *(--z) = (uchar)(48+(iVal%10));
2514
+ *(--z) = (char)(48+(iVal%10));
25162515
while( (iVal = (iVal/10))>0 ){
2517
- *(--z) = (uchar)(48+(iVal%10));
2516
+ *(--z) = (char)(48+(iVal%10));
25182517
assert(z>zBuf);
25192518
}
25202519
if( isNegative ){
25212520
*(--z) = '-';
25222521
}
@@ -2529,15 +2528,15 @@
25292528
** the double fVal and return TH_OK.
25302529
*/
25312530
int Th_SetResultDouble(Th_Interp *interp, double fVal){
25322531
int i; /* Iterator variable */
25332532
double v = fVal; /* Input value */
2534
- uchar zBuf[128]; /* Output buffer */
2535
- uchar *z = zBuf; /* Output cursor */
2533
+ char zBuf[128]; /* Output buffer */
2534
+ char *z = zBuf; /* Output cursor */
25362535
int iDot = 0; /* Digit after which to place decimal point */
25372536
int iExp = 0; /* Exponent (NN in eNN) */
2538
- const uchar *zExp; /* String representation of iExp */
2537
+ const char *zExp; /* String representation of iExp */
25392538
25402539
/* Precision: */
25412540
#define INSIGNIFICANT 0.000000000001
25422541
#define ROUNDER 0.0000000000005
25432542
double insignificant = INSIGNIFICANT;
@@ -2583,11 +2582,11 @@
25832582
25842583
/* Output the digits in real value v. The value of iDot determines
25852584
* where (if at all) the decimal point is placed.
25862585
*/
25872586
for(i=0; i<=(iDot+1) || v>=insignificant; i++){
2588
- *z++ = (uchar)(48 + (int)v);
2587
+ *z++ = (char)(48 + (int)v);
25892588
v = (v - ((double)(int)v)) * 10.0;
25902589
insignificant *= 10.0;
25912590
if( iDot==i ){
25922591
*z++ = '.';
25932592
}
@@ -2606,68 +2605,5 @@
26062605
}
26072606
26082607
*z = '\0';
26092608
return Th_SetResult(interp, zBuf, -1);
26102609
}
2611
-
2612
-/*
2613
-** Set the result of the interpreter to the th1 representation of
2614
-** the pointer p and return TH_OK. The th1 representation can be
2615
-** converted back to a pointer using Th_ToPtr().
2616
-*/
2617
-int Th_SetResultPtr(Th_Interp *interp, void *p){
2618
- char zBuf[32];
2619
- char *z;
2620
- int i;
2621
- unsigned int v = (unsigned int)p;
2622
-
2623
- const char zHex[16] = "0123456789ABCDEF";
2624
-
2625
- assert( sizeof(unsigned int)==sizeof(void *) );
2626
-
2627
- zBuf[31] = '\0';
2628
- z = &zBuf[30];
2629
-
2630
- for(i=0; i<(sizeof(unsigned int)*2); i++){
2631
- *z-- = zHex[(v&0x0000000F)];
2632
- v = v>>4;
2633
- }
2634
-
2635
- *z-- = 'x';
2636
- *z = '0';
2637
-
2638
- return Th_SetResult(interp, (uchar *)z, -1);
2639
-}
2640
-
2641
-/*
2642
-** Convert input string (z, n) to a generic pointer. If the conversion
2643
-** is successful, store the result in *pp and return TH_OK.
2644
-**
2645
-** If the string cannot be converted to a pointer, return TH_ERROR.
2646
-** If the interp argument is not NULL, leave an error message in the
2647
-** interpreter result too.
2648
-*/
2649
-int Th_ToPtr(Th_Interp *interp, const uchar *z, int n, void **pp){
2650
- unsigned int iPtr;
2651
- int i;
2652
- assert(sizeof(unsigned int)==sizeof(void *));
2653
-
2654
- if( n<3 || z[0]!='0' || z[1]!='x' ){
2655
- goto error_out;
2656
- }
2657
-
2658
- iPtr = 0;
2659
- for(i=2; i<n; i++){
2660
- int digit = thHexdigit(z[i]);
2661
- if( digit<0 ){
2662
- goto error_out;
2663
- }
2664
- iPtr = (iPtr<<4) + digit;
2665
- }
2666
-
2667
- *pp = (void *)iPtr;
2668
- return TH_OK;
2669
-
2670
-error_out:
2671
- Th_ErrorMessage(interp, "expected pointer, got: \"", z, n);
2672
- return TH_ERROR;
2673
-}
26742610
--- src/th.c
+++ src/th.c
@@ -15,11 +15,11 @@
15 /*
16 ** Interpreter structure.
17 */
18 struct Th_Interp {
19 Th_Vtab *pVtab; /* Copy of the argument passed to Th_CreateInterp() */
20 uchar *zResult; /* Current interpreter result (Th_Malloc()ed) */
21 int nResult; /* number of bytes in zResult */
22 Th_Hash *paCmd; /* Table of registered commands */
23 Th_Frame *pFrame; /* Current execution frame */
24 int isListMode; /* True if thSplitList() should operate in "list" mode */
25 };
@@ -28,11 +28,11 @@
28 ** Each TH command registered using Th_CreateCommand() is represented
29 ** by an instance of the following structure stored in the Th_Interp.paCmd
30 ** hash-table.
31 */
32 struct Th_Command {
33 int (*xProc)(Th_Interp *, void *, int, const uchar **, int *);
34 void *pContext;
35 void (*xDel)(Th_Interp *, void *);
36 };
37
38 /*
@@ -83,11 +83,11 @@
83 ** value.
84 */
85 struct Th_Variable {
86 int nRef; /* Number of references to this structure */
87 int nData; /* Number of bytes at Th_Variable.zData */
88 uchar *zData; /* Data for scalar variables */
89 Th_Hash *pHash; /* Data for array variables */
90 };
91
92 /*
93 ** Hash table API:
@@ -95,15 +95,15 @@
95 #define TH_HASHSIZE 257
96 struct Th_Hash {
97 Th_HashEntry *a[TH_HASHSIZE];
98 };
99
100 static int thEvalLocal(Th_Interp *, const uchar *, int);
101 static int thSplitList(Th_Interp*, const uchar*, int, uchar***, int **, int*);
102
103 static int thHexdigit(uchar c);
104 static int thEndOfLine(const uchar *, int);
105
106 static int thPushFrame(Th_Interp*, Th_Frame*);
107 static void thPopFrame(Th_Interp*);
108
109 static void thFreeVariable(Th_HashEntry*, void*);
@@ -123,53 +123,53 @@
123 **
124 ** thNextVarname(interp, "$a+1", 4, &nByte);
125 **
126 ** results in nByte being set to 2.
127 */
128 static int thNextCommand(Th_Interp*, const uchar *z, int n, int *pN);
129 static int thNextEscape (Th_Interp*, const uchar *z, int n, int *pN);
130 static int thNextVarname(Th_Interp*, const uchar *z, int n, int *pN);
131 static int thNextNumber (Th_Interp*, const uchar *z, int n, int *pN);
132 static int thNextSpace (Th_Interp*, const uchar *z, int n, int *pN);
133
134 /*
135 ** Given that the input string (z, n) contains a language construct of
136 ** the relevant type (a command enclosed in [], an escape sequence
137 ** like "\xFF" or a variable reference like "${varname}", perform
138 ** substitution on the string and store the resulting string in
139 ** the interpreter result.
140 */
141 static int thSubstCommand(Th_Interp*, const uchar *z, int n);
142 static int thSubstEscape (Th_Interp*, const uchar *z, int n);
143 static int thSubstVarname(Th_Interp*, const uchar *z, int n);
144
145 /*
146 ** Given that there is a th1 word located at the start of the input
147 ** string (z, n), determine the length in bytes of that word. If the
148 ** isCmd argument is non-zero, then an unescaped ";" byte not
149 ** located inside of a block or quoted string is considered to mark
150 ** the end of the word.
151 */
152 static int thNextWord(Th_Interp*, const uchar *z, int n, int *pN, int isCmd);
153
154 /*
155 ** Perform substitution on the word contained in the input string (z, n).
156 ** Store the resulting string in the interpreter result.
157 */
158 static int thSubstWord(Th_Interp*, const uchar *z, int n);
159
160 /*
161 ** The Buffer structure and the thBufferXXX() functions are used to make
162 ** memory allocation easier when building up a result.
163 */
164 struct Buffer {
165 uchar *zBuf;
166 int nBuf;
167 int nBufAlloc;
168 };
169 typedef struct Buffer Buffer;
170 static int thBufferWrite(Th_Interp *interp, Buffer *, const uchar *, int);
171 static void thBufferInit(Buffer *);
172 static void thBufferFree(Th_Interp *interp, Buffer *);
173
174 /*
175 ** Append nAdd bytes of content copied from zAdd to the end of buffer
@@ -177,11 +177,11 @@
177 ** the allocation to make space.
178 */
179 static int thBufferWrite(
180 Th_Interp *interp,
181 Buffer *pBuffer,
182 const uchar *zAdd,
183 int nAdd
184 ){
185 int nReq;
186
187 if( nAdd<0 ){
@@ -188,15 +188,15 @@
188 nAdd = th_strlen(zAdd);
189 }
190 nReq = pBuffer->nBuf+nAdd+1;
191
192 if( nReq>pBuffer->nBufAlloc ){
193 uchar *zNew;
194 int nNew;
195
196 nNew = nReq*2;
197 zNew = (uchar *)Th_Malloc(interp, nNew);
198 memcpy(zNew, pBuffer->zBuf, pBuffer->nBuf);
199 Th_Free(interp, pBuffer->zBuf);
200 pBuffer->nBufAlloc = nNew;
201 pBuffer->zBuf = zNew;
202 }
@@ -205,11 +205,11 @@
205 pBuffer->nBuf += nAdd;
206 pBuffer->zBuf[pBuffer->nBuf] = '\0';
207
208 return TH_OK;
209 }
210 #define thBufferWrite(a,b,c,d) thBufferWrite(a,b,(const uchar *)c,d)
211
212 /*
213 ** Initialize the Buffer structure pointed to by pBuffer.
214 */
215 static void thBufferInit(Buffer *pBuffer){
@@ -228,11 +228,11 @@
228 /*
229 ** Assuming parameter c contains a hexadecimal digit character,
230 ** return the corresponding value of that digit. If c is not
231 ** a hexadecimal digit character, -1 is returned.
232 */
233 static int thHexdigit(uchar c){
234 switch (c) {
235 case '0': return 0;
236 case '1': return 1;
237 case '2': return 2;
238 case '3': return 3;
@@ -317,11 +317,11 @@
317 ** If there is a parse error, return TH_ERROR and set the interpreter
318 ** result to an error message. Otherwise return TH_OK.
319 */
320 static int thNextEscape(
321 Th_Interp *interp,
322 const uchar *zInput,
323 int nInput,
324 int *pnEscape
325 ){
326 int i = 2;
327
@@ -349,11 +349,11 @@
349 ** reference. If there is a parse error, return TH_ERROR and set the
350 ** interpreter result to an error message. Otherwise return TH_OK.
351 */
352 int thNextVarname(
353 Th_Interp *interp,
354 const uchar *zInput,
355 int nInput,
356 int *pnVarname
357 ){
358 int i;
359
@@ -407,11 +407,11 @@
407 ** and set the interpreter result to an error message. Otherwise return
408 ** TH_OK.
409 */
410 int thNextCommand(
411 Th_Interp *interp,
412 const uchar *zInput,
413 int nInput,
414 int *pnCommand
415 ){
416 int nBrace = 0;
417 int nSquare = 0;
@@ -442,11 +442,11 @@
442 ** Set *pnSpace to the number of whitespace bytes at the start of
443 ** input string (zInput, nInput). Always return TH_OK.
444 */
445 int thNextSpace(
446 Th_Interp *interp,
447 const uchar *zInput,
448 int nInput,
449 int *pnSpace
450 ){
451 int i;
452 for(i=0; i<nInput && th_isspace(zInput[i]); i++);
@@ -465,11 +465,11 @@
465 ** located inside of a block or quoted string is considered to mark
466 ** the end of the word.
467 */
468 static int thNextWord(
469 Th_Interp *interp,
470 const uchar *zInput,
471 int nInput,
472 int *pnWord,
473 int isCmd
474 ){
475 int iEnd = 0;
@@ -520,11 +520,11 @@
520 ** a [] block. Perform substitution on the input string and store the
521 ** resulting string in the interpreter result.
522 */
523 static int thSubstCommand(
524 Th_Interp *interp,
525 const uchar *zWord,
526 int nWord
527 ){
528 assert(nWord>=2);
529 assert(zWord[0]=='[' && zWord[nWord-1]==']');
530 return thEvalLocal(interp, &zWord[1], nWord-2);
@@ -536,11 +536,11 @@
536 ** the input string and store the resulting string in the interpreter
537 ** result.
538 */
539 static int thSubstVarname(
540 Th_Interp *interp,
541 const uchar *zWord,
542 int nWord
543 ){
544 assert(nWord>=1);
545 assert(zWord[0]=='$');
546 assert(nWord==1 || zWord[1]!='{' || zWord[nWord-1]=='}');
@@ -551,11 +551,11 @@
551 int i;
552 for(i=1; i<nWord && zWord[i]!='('; i++);
553 if( i<nWord ){
554 Buffer varname;
555 int nInner;
556 const uchar *zInner;
557
558 int rc = thSubstWord(interp, &zWord[i+1], nWord-i-2);
559 if( rc!=TH_OK ) return rc;
560
561 zInner = Th_GetResult(interp, &nInner);
@@ -576,14 +576,14 @@
576 ** Perform substitution on the input string and store the resulting
577 ** string in the interpreter result.
578 */
579 static int thSubstEscape(
580 Th_Interp *interp,
581 const uchar *zWord,
582 int nWord
583 ){
584 uchar c;
585
586 assert(nWord>=2);
587 assert(zWord[0]=='\\');
588
589 switch( zWord[1] ){
@@ -612,11 +612,11 @@
612 ** substitution on the input string and store the resulting
613 ** string in the interpreter result.
614 */
615 static int thSubstWord(
616 Th_Interp *interp,
617 const uchar *zWord,
618 int nWord
619 ){
620 int rc = TH_OK;
621 Buffer output;
622 int i;
@@ -634,12 +634,12 @@
634 }
635
636 for(i=0; rc==TH_OK && i<nWord; i++){
637 int nGet;
638
639 int (*xGet)(Th_Interp *, const uchar*, int, int *) = 0;
640 int (*xSubst)(Th_Interp *, const uchar*, int) = 0;
641
642 switch( zWord[i] ){
643 case '\\':
644 xGet = thNextEscape; xSubst = thSubstEscape;
645 break;
@@ -662,11 +662,11 @@
662 rc = xGet(interp, &zWord[i], nWord-i, &nGet);
663 if( rc==TH_OK ){
664 rc = xSubst(interp, &zWord[i], nGet);
665 }
666 if( rc==TH_OK ){
667 const uchar *zRes;
668 int nRes;
669 zRes = Th_GetResult(interp, &nRes);
670 rc = thBufferWrite(interp, &output, zRes, nRes);
671 i += (nGet-1);
672 }
@@ -689,11 +689,11 @@
689 ** + It contains no non-white-space characters before the first
690 ** newline character.
691 **
692 ** Otherwise return false.
693 */
694 static int thEndOfLine(const uchar *zInput, int nInput){
695 int i;
696 for(i=0; i<nInput && zInput[i]!='\n' && th_isspace(zInput[i]); i++);
697 return ((i==nInput || zInput[i]=='\n')?1:0);
698 }
699
@@ -710,11 +710,11 @@
710 **
711 ** If TH_OK is returned and pazElem is not NULL, the caller should free the
712 ** pointer written to (*pazElem) using Th_Free(). This releases memory
713 ** allocated for both the (*pazElem) and (*panElem) arrays. Example:
714 **
715 ** uchar **argv;
716 ** int *argl;
717 ** int argc;
718 **
719 ** // After this call, argv and argl point to valid arrays. The
720 ** // number of elements in each is argc.
@@ -727,30 +727,30 @@
727 ** Th_Free(interp, argv);
728 **
729 */
730 static int thSplitList(
731 Th_Interp *interp, /* Interpreter context */
732 const uchar *zList, /* Pointer to buffer containing input list */
733 int nList, /* Size of buffer pointed to by zList */
734 uchar ***pazElem, /* OUT: Array of list elements */
735 int **panElem, /* OUT: Lengths of each list element */
736 int *pnCount /* OUT: Number of list elements */
737 ){
738 int rc = TH_OK;
739
740 Buffer strbuf;
741 Buffer lenbuf;
742 int nCount = 0;
743
744 const uchar *zInput = zList;
745 int nInput = nList;
746
747 thBufferInit(&strbuf);
748 thBufferInit(&lenbuf);
749
750 while( nInput>0 ){
751 const uchar *zWord;
752 int nWord;
753
754 thNextSpace(interp, zInput, nInput, &nWord);
755 zInput += nWord;
756 nInput = nList-(zInput-zList);
@@ -773,19 +773,19 @@
773 assert((lenbuf.nBuf/sizeof(int))==nCount);
774
775 assert((pazElem && panElem) || (!pazElem && !panElem));
776 if( pazElem && rc==TH_OK ){
777 int i;
778 uchar *zElem;
779 int *anElem;
780 uchar **azElem = Th_Malloc(interp,
781 sizeof(uchar*) * nCount + /* azElem */
782 sizeof(int) * nCount + /* anElem */
783 strbuf.nBuf /* space for list element strings */
784 );
785 anElem = (int *)&azElem[nCount];
786 zElem = (uchar *)&anElem[nCount];
787 memcpy(anElem, lenbuf.zBuf, lenbuf.nBuf);
788 memcpy(zElem, strbuf.zBuf, strbuf.nBuf);
789 for(i=0; i<nCount;i++){
790 azElem[i] = zElem;
791 zElem += (anElem[i] + 1);
@@ -805,21 +805,21 @@
805
806 /*
807 ** Evaluate the th1 script contained in the string (zProgram, nProgram)
808 ** in the current stack frame.
809 */
810 static int thEvalLocal(Th_Interp *interp, const uchar *zProgram, int nProgram){
811 int rc = TH_OK;
812 const uchar *zInput = zProgram;
813 int nInput = nProgram;
814
815 while( rc==TH_OK && nInput ){
816 Th_HashEntry *pEntry;
817 int nSpace;
818 const uchar *zFirst;
819
820 uchar **argv;
821 int *argl;
822 int argc;
823
824 assert(nInput>=0);
825
@@ -872,27 +872,27 @@
872 }
873
874 /* Call the command procedure. */
875 if( rc==TH_OK ){
876 Th_Command *p = (Th_Command *)(pEntry->pData);
877 const uchar **azArg = (const uchar **)argv;
878 rc = p->xProc(interp, p->pContext, argc, azArg, argl);
879 }
880
881 /* If an error occured, add this command to the stack trace report. */
882 if( rc==TH_ERROR ){
883 uchar *zRes;
884 int nRes;
885 uchar *zStack = 0;
886 int nStack = 0;
887
888 zRes = Th_TakeResult(interp, &nRes);
889 if( TH_OK==Th_GetVar(interp, (uchar *)"::th_stack_trace", -1) ){
890 zStack = Th_TakeResult(interp, &nStack);
891 }
892 Th_ListAppend(interp, &zStack, &nStack, zFirst, zInput-zFirst);
893 Th_SetVar(interp, (uchar *)"::th_stack_trace", -1, zStack, nStack);
894 Th_SetResult(interp, zRes, nRes);
895 Th_Free(interp, zRes);
896 Th_Free(interp, zStack);
897 }
898 }
@@ -933,11 +933,11 @@
933 for(i=0; p && i<(iFrame*-1); i++){
934 p = p->pCaller;
935 }
936
937 if( !p ){
938 uchar *zFrame;
939 int nFrame;
940 Th_SetResultInt(interp, iFrame);
941 zFrame = Th_TakeResult(interp, &nFrame);
942 Th_ErrorMessage(interp, "no such frame:", zFrame, nFrame);
943 Th_Free(interp, zFrame);
@@ -950,11 +950,11 @@
950 ** Evaluate th1 script (zProgram, nProgram) in the frame identified by
951 ** argument iFrame. Leave either an error message or a result in the
952 ** interpreter result and return a th1 error code (TH_OK, TH_ERROR,
953 ** TH_RETURN, TH_CONTINUE or TH_BREAK).
954 */
955 int Th_Eval(Th_Interp *interp, int iFrame, const uchar *zProgram, int nProgram){
956 int rc = TH_OK;
957 Th_Frame *pSavedFrame = interp->pFrame;
958
959 /* Set Th_Interp.pFrame to the frame that this script is to be
960 ** evaluated in. The current frame is saved in pSavedFrame and will
@@ -992,21 +992,21 @@
992 ** array variable. If the variable is a scalar, *pzInner is set to 0.
993 ** If it is an array variable, (*pzInner, *pnInner) is set to the
994 ** array key name.
995 */
996 static int thAnalyseVarname(
997 const uchar *zVarname,
998 int nVarname,
999 const uchar **pzOuter, /* OUT: Pointer to scalar/array name */
1000 int *pnOuter, /* OUT: Number of bytes at *pzOuter */
1001 const uchar **pzInner, /* OUT: Pointer to array key (or null) */
1002 int *pnInner, /* OUT: Number of bytes at *pzInner */
1003 int *pisGlobal /* OUT: Set to true if this is a global ref */
1004 ){
1005 const uchar *zOuter = zVarname;
1006 int nOuter;
1007 const uchar *zInner = 0;
1008 int nInner = 0;
1009 int isGlobal = 0;
1010 int i;
1011
1012 if( nVarname<0 ){
@@ -1056,18 +1056,18 @@
1056 ** an error is left in the interpreter result and NULL returned. If
1057 ** arrayok is true an array name is Ok.
1058 */
1059 static Th_Variable *thFindValue(
1060 Th_Interp *interp,
1061 const uchar *zVar, /* Pointer to variable name */
1062 int nVar, /* Number of bytes at nVar */
1063 int create, /* If true, create the variable if not found */
1064 int arrayok /* If true, an array is Ok. Othewise array==error */
1065 ){
1066 const uchar *zOuter;
1067 int nOuter;
1068 const uchar *zInner;
1069 int nInner;
1070 int isGlobal;
1071
1072 Th_HashEntry *pEntry;
1073 Th_Frame *pFrame = interp->pFrame;
@@ -1134,11 +1134,11 @@
1134 ** the interpreter result and return TH_OK.
1135 **
1136 ** If the named variable does not exist, return TH_ERROR and leave
1137 ** an error message in the interpreter result.
1138 */
1139 int Th_GetVar(Th_Interp *interp, const uchar *zVar, int nVar){
1140 Th_Variable *pValue;
1141
1142 pValue = thFindValue(interp, zVar, nVar, 0, 0);
1143 if( !pValue ){
1144 return TH_ERROR;
@@ -1159,13 +1159,13 @@
1159 ** If (zVar, nVar) refers to an existing array, TH_ERROR is returned
1160 ** and an error message left in the interpreter result.
1161 */
1162 int Th_SetVar(
1163 Th_Interp *interp,
1164 const uchar *zVar,
1165 int nVar,
1166 const uchar *zValue,
1167 int nValue
1168 ){
1169 Th_Variable *pValue;
1170
1171 pValue = thFindValue(interp, zVar, nVar, 1, 0);
@@ -1194,13 +1194,13 @@
1194 ** Create a variable link so that accessing variable (zLocal, nLocal) is
1195 ** the same as accessing variable (zLink, nLink) in stack frame iFrame.
1196 */
1197 int Th_LinkVar(
1198 Th_Interp *interp, /* Interpreter */
1199 const uchar *zLocal, int nLocal, /* Local varname */
1200 int iFrame, /* Stack frame of linked var */
1201 const uchar *zLink, int nLink /* Linked varname */
1202 ){
1203 Th_Frame *pSavedFrame = interp->pFrame;
1204 Th_Frame *pFrame;
1205 Th_HashEntry *pEntry;
1206 Th_Variable *pValue;
@@ -1229,11 +1229,11 @@
1229 ** Input string (zVar, nVar) must contain the name of a scalar variable,
1230 ** an array, or an array member. If the identified variable exists, it
1231 ** is deleted and TH_OK returned. Otherwise, an error message is left
1232 ** in the interpreter result and TH_ERROR is returned.
1233 */
1234 int Th_UnsetVar(Th_Interp *interp, const uchar *zVar, int nVar){
1235 Th_Variable *pValue;
1236
1237 pValue = thFindValue(interp, zVar, nVar, 1, 1);
1238 if( !pValue ){
1239 return TH_ERROR;
@@ -1252,12 +1252,12 @@
1252 /*
1253 ** Return an allocated buffer containing a copy of string (z, n). The
1254 ** caller is responsible for eventually calling Th_Free() to free
1255 ** the returned buffer.
1256 */
1257 uchar *th_strdup(Th_Interp *interp, const uchar *z, int n){
1258 uchar *zRes;
1259 if( n<0 ){
1260 n = th_strlen(z);
1261 }
1262 zRes = Th_Malloc(interp, n+1);
1263 memcpy(zRes, z, n);
@@ -1277,24 +1277,23 @@
1277 ** Example:
1278 **
1279 ** Th_ErrorMessage(interp, "no such variable:", zVarname, nVarname);
1280 **
1281 */
1282 int Th_ErrorMessage(Th_Interp *interp, const char *zPre, const uchar *z, int n){
1283 if( interp ){
1284 uchar *zRes = 0;
1285 int nRes = 0;
1286 int nPre = th_strlen(zPre);
1287
1288 Th_SetVar(interp, (uchar *)"::th_stack_trace", -1, 0, 0);
1289
1290 Th_StringAppend(interp, &zRes, &nRes, zPre, -1);
1291 if( zRes[nRes-1]=='"' ){
1292 Th_StringAppend(interp, &zRes, &nRes, z, n);
1293 Th_StringAppend(interp, &zRes, &nRes, (const uchar *)"\"", 1);
1294 }else{
1295 Th_StringAppend(interp, &zRes, &nRes, (const uchar *)" ", 1);
1296 Th_StringAppend(interp, &zRes, &nRes, z, n);
1297 }
1298
1299 Th_SetResult(interp, zRes, nRes);
1300 Th_Free(interp, zRes);
@@ -1305,11 +1304,11 @@
1305
1306 /*
1307 ** Set the current interpreter result by taking a copy of the buffer
1308 ** pointed to by z, size n bytes. TH_OK is always returned.
1309 */
1310 int Th_SetResult(Th_Interp *pInterp, const uchar *z, int n){
1311
1312 /* Free the current result */
1313 Th_Free(pInterp, pInterp->zResult);
1314 pInterp->zResult = 0;
1315 pInterp->nResult = 0;
@@ -1317,11 +1316,11 @@
1317 if( n<0 ){
1318 n = th_strlen(z);
1319 }
1320
1321 if( z && n>0 ){
1322 uchar *zResult;
1323 zResult = Th_Malloc(pInterp, n+1);
1324 memcpy(zResult, z, n);
1325 zResult[n] = '\0';
1326 pInterp->zResult = zResult;
1327 pInterp->nResult = n;
@@ -1333,16 +1332,16 @@
1333 /*
1334 ** Return a pointer to the buffer containing the current interpreter
1335 ** result. If pN is not NULL, set *pN to the size of the returned
1336 ** buffer.
1337 */
1338 const uchar *Th_GetResult(Th_Interp *pInterp, int *pN){
1339 assert(pInterp->zResult || pInterp->nResult==0);
1340 if( pN ){
1341 *pN = pInterp->nResult;
1342 }
1343 return (pInterp->zResult ? pInterp->zResult : (const uchar *)"");
1344 }
1345
1346 /*
1347 ** Return a pointer to the buffer containing the current interpreter
1348 ** result. If pN is not NULL, set *pN to the size of the returned
@@ -1351,21 +1350,21 @@
1351 ** This function is the same as Th_GetResult() except that the
1352 ** caller is responsible for eventually calling Th_Free() on the
1353 ** returned buffer. The internal interpreter result is cleared
1354 ** after this function is called.
1355 */
1356 uchar *Th_TakeResult(Th_Interp *pInterp, int *pN){
1357 if( pN ){
1358 *pN = pInterp->nResult;
1359 }
1360 if( pInterp->zResult ){
1361 uchar *zResult = pInterp->zResult;
1362 pInterp->zResult = 0;
1363 pInterp->nResult = 0;
1364 return zResult;
1365 }else{
1366 return (uchar *)Th_Malloc(pInterp, 1);
1367 }
1368 }
1369
1370
1371 /*
@@ -1397,11 +1396,11 @@
1397 void (*xDel)(Th_Interp *, void *) /* Command destructor callback */
1398 ){
1399 Th_HashEntry *pEntry;
1400 Th_Command *pCommand;
1401
1402 pEntry = Th_HashFind(interp, interp->paCmd, (const uchar *)zName, -1, 1);
1403 if( pEntry->pData ){
1404 pCommand = pEntry->pData;
1405 if( pCommand->xDel ){
1406 pCommand->xDel(interp, pCommand->pContext);
1407 }
@@ -1424,13 +1423,13 @@
1424 ** if command zNew already exists, an error message is left in the
1425 ** interpreter result and TH_ERROR is returned.
1426 */
1427 int Th_RenameCommand(
1428 Th_Interp *interp,
1429 const uchar *zName, /* Existing command name */
1430 int nName, /* Number of bytes at zName */
1431 const uchar *zNew, /* New command name */
1432 int nNew /* Number of bytes at zNew */
1433 ){
1434 Th_HashEntry *pEntry;
1435 Th_HashEntry *pNewEntry;
1436
@@ -1495,28 +1494,28 @@
1495 **
1496 ** Example:
1497 **
1498 ** int nElem;
1499 ** int *anElem;
1500 ** uchar **azElem;
1501 ** int i;
1502 **
1503 ** Th_SplitList(interp, zList, nList, &azElem, &anElem, &nElem);
1504 ** for(i=0; i<nElem; i++){
1505 ** int nData = anElem[i];
1506 ** uchar *zData = azElem[i];
1507 ** ...
1508 ** }
1509 **
1510 ** Th_Free(interp, azElem);
1511 **
1512 */
1513 int Th_SplitList(
1514 Th_Interp *interp,
1515 const uchar *zList, /* Pointer to buffer containing list */
1516 int nList, /* Number of bytes at zList */
1517 uchar ***pazElem, /* OUT: Array of pointers to element data */
1518 int **panElem, /* OUT: Array of element data lengths */
1519 int *pnCount /* OUT: Number of elements in list */
1520 ){
1521 int rc;
1522 interp->isListMode = 1;
@@ -1541,25 +1540,25 @@
1541 ** *pzList to point to a new buffer containing the new list value. *pnList
1542 ** is similarly updated before returning. The return value is always TH_OK.
1543 **
1544 ** Example:
1545 **
1546 ** uchar *zList = 0;
1547 ** int nList = 0;
1548 ** for (...) {
1549 ** uchar *zElem = <some expression>;
1550 ** Th_ListAppend(interp, &zList, &nList, zElem, -1);
1551 ** }
1552 ** Th_SetResult(interp, zList, nList);
1553 ** Th_Free(interp, zList);
1554 **
1555 */
1556 int Th_ListAppend(
1557 Th_Interp *interp, /* Interpreter context */
1558 uchar **pzList, /* IN/OUT: Ptr to ptr to list */
1559 int *pnList, /* IN/OUT: Current length of *pzList */
1560 const uchar *zElem, /* Data to append */
1561 int nElem /* Length of nElem */
1562 ){
1563 Buffer output;
1564 int i;
1565
@@ -1577,11 +1576,11 @@
1577 if( output.nBuf>0 ){
1578 thBufferWrite(interp, &output, " ", 1);
1579 }
1580
1581 for(i=0; i<nElem; i++){
1582 uchar c = zElem[i];
1583 if( th_isspecial(c) ) hasSpecialChar = 1;
1584 if( c=='\\' ) hasEscapeChar = 1;
1585 if( c=='{' ) nBrace++;
1586 if( c=='}' ) nBrace--;
1587 }
@@ -1590,11 +1589,11 @@
1590 thBufferWrite(interp, &output, "{", 1);
1591 thBufferWrite(interp, &output, zElem, nElem);
1592 thBufferWrite(interp, &output, "}", 1);
1593 }else{
1594 for(i=0; i<nElem; i++){
1595 uchar c = zElem[i];
1596 if( th_isspecial(c) ) thBufferWrite(interp, &output, "\\", 1);
1597 thBufferWrite(interp, &output, &c, 1);
1598 }
1599 }
1600
@@ -1608,16 +1607,16 @@
1608 ** Append a new element to an existing th1 string. This function uses
1609 ** the same interface as the Th_ListAppend() function.
1610 */
1611 int Th_StringAppend(
1612 Th_Interp *interp, /* Interpreter context */
1613 uchar **pzStr, /* IN/OUT: Ptr to ptr to list */
1614 int *pnStr, /* IN/OUT: Current length of *pzStr */
1615 const uchar *zElem, /* Data to append */
1616 int nElem /* Length of nElem */
1617 ){
1618 uchar *zNew;
1619 int nNew;
1620
1621 if( nElem<0 ){
1622 nElem = th_strlen(zElem);
1623 }
@@ -1687,11 +1686,11 @@
1687 Operator *pOp;
1688 Expr *pParent;
1689 Expr *pLeft;
1690 Expr *pRight;
1691
1692 uchar *zValue; /* Pointer to literal value */
1693 int nValue; /* Length of literal value buffer */
1694 };
1695
1696 /* Unary operators */
1697 #define OP_UNARY_MINUS 2
@@ -1778,18 +1777,18 @@
1778 ** The first part of the string (zInput,nInput) contains a number.
1779 ** Set *pnVarname to the number of bytes in the numeric string.
1780 */
1781 static int thNextNumber(
1782 Th_Interp *interp,
1783 const uchar *zInput,
1784 int nInput,
1785 int *pnLiteral
1786 ){
1787 int i;
1788 int seenDot = 0;
1789 for(i=0; i<nInput; i++){
1790 uchar c = zInput[i];
1791 if( (seenDot || c!='.') && !th_isdigit(c) ) break;
1792 if( c=='.' ) seenDot = 1;
1793 }
1794 *pnLiteral = i;
1795 return TH_OK;
@@ -1824,12 +1823,12 @@
1824 int iRight;
1825 double fLeft;
1826 double fRight;
1827
1828 /* Left and right arguments as strings */
1829 uchar *zLeft = 0; int nLeft;
1830 uchar *zRight = 0; int nRight;
1831
1832 /* Evaluate left and right arguments, if they exist. */
1833 if( pExpr->pLeft ){
1834 rc = exprEval(interp, pExpr->pLeft);
1835 if( rc==TH_OK ){
@@ -2014,11 +2013,11 @@
2014 /*
2015 ** Parse a string containing a TH expression to a list of tokens.
2016 */
2017 static int exprParse(
2018 Th_Interp *interp, /* Interpreter to leave error message in */
2019 const uchar *zExpr, /* Pointer to input string */
2020 int nExpr, /* Number of bytes at zExpr */
2021 Expr ***papToken, /* OUT: Array of tokens. */
2022 int *pnToken /* OUT: Size of token array */
2023 ){
2024 int i;
@@ -2026,16 +2025,16 @@
2026 int rc = TH_OK;
2027 int nToken = 0;
2028 Expr **apToken = 0;
2029
2030 for(i=0; rc==TH_OK && i<nExpr; ){
2031 uchar c = zExpr[i];
2032 if( th_isspace(c) ){ /* White-space */
2033 i++;
2034 }else{
2035 Expr *pNew = (Expr *)Th_Malloc(interp, sizeof(Expr));
2036 const uchar *z = &zExpr[i];
2037
2038 switch (c) {
2039 case '0': case '1': case '2': case '3': case '4':
2040 case '5': case '6': case '7': case '8': case '9':
2041 thNextNumber(interp, z, nExpr-i, &pNew->nValue);
@@ -2069,11 +2068,11 @@
2069 Expr *pPrev = apToken[nToken-1];
2070 if( !pPrev->pOp || pPrev->pOp->eOp==OP_CLOSE_BRACKET ){
2071 continue;
2072 }
2073 }
2074 nOp = th_strlen((const uchar *)aOperator[j].zOp);
2075 if( (nExpr-i)>=nOp && 0==memcmp(aOperator[j].zOp, &zExpr[i], nOp) ){
2076 pNew->pOp = &aOperator[j];
2077 i += nOp;
2078 break;
2079 }
@@ -2115,11 +2114,11 @@
2115 ** Evaluate the string (zExpr, nExpr) as a Th expression. Store
2116 ** the result in the interpreter interp and return TH_OK if
2117 ** successful. If an error occurs, store an error message in
2118 ** the interpreter result and return an error code.
2119 */
2120 int Th_Expr(Th_Interp *interp, const uchar *zExpr, int nExpr){
2121 int rc; /* Return Code */
2122 int i; /* Loop counter */
2123
2124 int nToken = 0;
2125 Expr **apToken = 0;
@@ -2222,11 +2221,11 @@
2222 ** not already present in the hash-table.
2223 */
2224 Th_HashEntry *Th_HashFind(
2225 Th_Interp *interp,
2226 Th_Hash *pHash,
2227 const uchar *zKey,
2228 int nKey,
2229 int op /* -ve = delete, 0 = find, +ve = insert */
2230 ){
2231 unsigned int iKey = 0;
2232 int i;
@@ -2254,11 +2253,11 @@
2254 pRet = 0;
2255 }
2256
2257 if( op>0 && !pRet ){
2258 pRet = (Th_HashEntry *)Th_Malloc(interp, sizeof(Th_HashEntry) + nKey);
2259 pRet->zKey = (uchar *)&pRet[1];
2260 pRet->nKey = nKey;
2261 memcpy(pRet->zKey, zKey, nKey);
2262 pRet->pNext = pHash->a[iKey];
2263 pHash->a[iKey] = pRet;
2264 }
@@ -2269,11 +2268,11 @@
2269 /*
2270 ** This function is the same as the standard strlen() function, except
2271 ** that it returns 0 (instead of being undefined) if the argument is
2272 ** a null pointer.
2273 */
2274 int th_strlen(const unsigned char *zStr){
2275 int n = 0;
2276 if( zStr ){
2277 while( zStr[n] ) n++;
2278 }
2279 return n;
@@ -2320,27 +2319,27 @@
2320 };
2321
2322 /*
2323 ** Clone of the standard isspace() and isdigit function/macros.
2324 */
2325 int th_isspace(unsigned char c){
2326 return (aCharProp[c] & 0x01);
2327 }
2328 int th_isdigit(unsigned char c){
2329 return (aCharProp[c] & 0x02);
2330 }
2331 int th_isspecial(unsigned char c){
2332 return (aCharProp[c] & 0x11);
2333 }
2334 int th_isalnum(unsigned char c){
2335 return (aCharProp[c] & 0x0A);
2336 }
2337
2338 #ifndef LONGDOUBLE_TYPE
2339 # define LONGDOUBLE_TYPE long double
2340 #endif
2341 typedef uchar u8;
2342
2343
2344 /*
2345 ** Return TRUE if z is a pure numeric string. Return FALSE if the
2346 ** string contains any character which is not part of a number. If
@@ -2446,11 +2445,11 @@
2446 **
2447 ** If the string cannot be converted to an integer, return TH_ERROR.
2448 ** If the interp argument is not NULL, leave an error message in the
2449 ** interpreter result too.
2450 */
2451 int Th_ToInt(Th_Interp *interp, const uchar *z, int n, int *piOut){
2452 int i = 0;
2453 int iOut = 0;
2454
2455 if( n<0 ){
2456 n = th_strlen(z);
@@ -2483,11 +2482,11 @@
2483 ** If the interp argument is not NULL, leave an error message in the
2484 ** interpreter result too.
2485 */
2486 int Th_ToDouble(
2487 Th_Interp *interp,
2488 const uchar *z,
2489 int n,
2490 double *pfOut
2491 ){
2492 if( !sqlite3IsNumber((const char *)z, 0) ){
2493 Th_ErrorMessage(interp, "expected number, got: \"", z, n);
@@ -2502,21 +2501,21 @@
2502 ** Set the result of the interpreter to the th1 representation of
2503 ** the integer iVal and return TH_OK.
2504 */
2505 int Th_SetResultInt(Th_Interp *interp, int iVal){
2506 int isNegative = 0;
2507 uchar zBuf[32];
2508 uchar *z = &zBuf[32];
2509
2510 if( iVal<0 ){
2511 isNegative = 1;
2512 iVal = iVal * -1;
2513 }
2514 *(--z) = '\0';
2515 *(--z) = (uchar)(48+(iVal%10));
2516 while( (iVal = (iVal/10))>0 ){
2517 *(--z) = (uchar)(48+(iVal%10));
2518 assert(z>zBuf);
2519 }
2520 if( isNegative ){
2521 *(--z) = '-';
2522 }
@@ -2529,15 +2528,15 @@
2529 ** the double fVal and return TH_OK.
2530 */
2531 int Th_SetResultDouble(Th_Interp *interp, double fVal){
2532 int i; /* Iterator variable */
2533 double v = fVal; /* Input value */
2534 uchar zBuf[128]; /* Output buffer */
2535 uchar *z = zBuf; /* Output cursor */
2536 int iDot = 0; /* Digit after which to place decimal point */
2537 int iExp = 0; /* Exponent (NN in eNN) */
2538 const uchar *zExp; /* String representation of iExp */
2539
2540 /* Precision: */
2541 #define INSIGNIFICANT 0.000000000001
2542 #define ROUNDER 0.0000000000005
2543 double insignificant = INSIGNIFICANT;
@@ -2583,11 +2582,11 @@
2583
2584 /* Output the digits in real value v. The value of iDot determines
2585 * where (if at all) the decimal point is placed.
2586 */
2587 for(i=0; i<=(iDot+1) || v>=insignificant; i++){
2588 *z++ = (uchar)(48 + (int)v);
2589 v = (v - ((double)(int)v)) * 10.0;
2590 insignificant *= 10.0;
2591 if( iDot==i ){
2592 *z++ = '.';
2593 }
@@ -2606,68 +2605,5 @@
2606 }
2607
2608 *z = '\0';
2609 return Th_SetResult(interp, zBuf, -1);
2610 }
2611
2612 /*
2613 ** Set the result of the interpreter to the th1 representation of
2614 ** the pointer p and return TH_OK. The th1 representation can be
2615 ** converted back to a pointer using Th_ToPtr().
2616 */
2617 int Th_SetResultPtr(Th_Interp *interp, void *p){
2618 char zBuf[32];
2619 char *z;
2620 int i;
2621 unsigned int v = (unsigned int)p;
2622
2623 const char zHex[16] = "0123456789ABCDEF";
2624
2625 assert( sizeof(unsigned int)==sizeof(void *) );
2626
2627 zBuf[31] = '\0';
2628 z = &zBuf[30];
2629
2630 for(i=0; i<(sizeof(unsigned int)*2); i++){
2631 *z-- = zHex[(v&0x0000000F)];
2632 v = v>>4;
2633 }
2634
2635 *z-- = 'x';
2636 *z = '0';
2637
2638 return Th_SetResult(interp, (uchar *)z, -1);
2639 }
2640
2641 /*
2642 ** Convert input string (z, n) to a generic pointer. If the conversion
2643 ** is successful, store the result in *pp and return TH_OK.
2644 **
2645 ** If the string cannot be converted to a pointer, return TH_ERROR.
2646 ** If the interp argument is not NULL, leave an error message in the
2647 ** interpreter result too.
2648 */
2649 int Th_ToPtr(Th_Interp *interp, const uchar *z, int n, void **pp){
2650 unsigned int iPtr;
2651 int i;
2652 assert(sizeof(unsigned int)==sizeof(void *));
2653
2654 if( n<3 || z[0]!='0' || z[1]!='x' ){
2655 goto error_out;
2656 }
2657
2658 iPtr = 0;
2659 for(i=2; i<n; i++){
2660 int digit = thHexdigit(z[i]);
2661 if( digit<0 ){
2662 goto error_out;
2663 }
2664 iPtr = (iPtr<<4) + digit;
2665 }
2666
2667 *pp = (void *)iPtr;
2668 return TH_OK;
2669
2670 error_out:
2671 Th_ErrorMessage(interp, "expected pointer, got: \"", z, n);
2672 return TH_ERROR;
2673 }
2674
--- src/th.c
+++ src/th.c
@@ -15,11 +15,11 @@
15 /*
16 ** Interpreter structure.
17 */
18 struct Th_Interp {
19 Th_Vtab *pVtab; /* Copy of the argument passed to Th_CreateInterp() */
20 char *zResult; /* Current interpreter result (Th_Malloc()ed) */
21 int nResult; /* number of bytes in zResult */
22 Th_Hash *paCmd; /* Table of registered commands */
23 Th_Frame *pFrame; /* Current execution frame */
24 int isListMode; /* True if thSplitList() should operate in "list" mode */
25 };
@@ -28,11 +28,11 @@
28 ** Each TH command registered using Th_CreateCommand() is represented
29 ** by an instance of the following structure stored in the Th_Interp.paCmd
30 ** hash-table.
31 */
32 struct Th_Command {
33 int (*xProc)(Th_Interp *, void *, int, const char **, int *);
34 void *pContext;
35 void (*xDel)(Th_Interp *, void *);
36 };
37
38 /*
@@ -83,11 +83,11 @@
83 ** value.
84 */
85 struct Th_Variable {
86 int nRef; /* Number of references to this structure */
87 int nData; /* Number of bytes at Th_Variable.zData */
88 char *zData; /* Data for scalar variables */
89 Th_Hash *pHash; /* Data for array variables */
90 };
91
92 /*
93 ** Hash table API:
@@ -95,15 +95,15 @@
95 #define TH_HASHSIZE 257
96 struct Th_Hash {
97 Th_HashEntry *a[TH_HASHSIZE];
98 };
99
100 static int thEvalLocal(Th_Interp *, const char *, int);
101 static int thSplitList(Th_Interp*, const char*, int, char***, int **, int*);
102
103 static int thHexdigit(char c);
104 static int thEndOfLine(const char *, int);
105
106 static int thPushFrame(Th_Interp*, Th_Frame*);
107 static void thPopFrame(Th_Interp*);
108
109 static void thFreeVariable(Th_HashEntry*, void*);
@@ -123,53 +123,53 @@
123 **
124 ** thNextVarname(interp, "$a+1", 4, &nByte);
125 **
126 ** results in nByte being set to 2.
127 */
128 static int thNextCommand(Th_Interp*, const char *z, int n, int *pN);
129 static int thNextEscape (Th_Interp*, const char *z, int n, int *pN);
130 static int thNextVarname(Th_Interp*, const char *z, int n, int *pN);
131 static int thNextNumber (Th_Interp*, const char *z, int n, int *pN);
132 static int thNextSpace (Th_Interp*, const char *z, int n, int *pN);
133
134 /*
135 ** Given that the input string (z, n) contains a language construct of
136 ** the relevant type (a command enclosed in [], an escape sequence
137 ** like "\xFF" or a variable reference like "${varname}", perform
138 ** substitution on the string and store the resulting string in
139 ** the interpreter result.
140 */
141 static int thSubstCommand(Th_Interp*, const char *z, int n);
142 static int thSubstEscape (Th_Interp*, const char *z, int n);
143 static int thSubstVarname(Th_Interp*, const char *z, int n);
144
145 /*
146 ** Given that there is a th1 word located at the start of the input
147 ** string (z, n), determine the length in bytes of that word. If the
148 ** isCmd argument is non-zero, then an unescaped ";" byte not
149 ** located inside of a block or quoted string is considered to mark
150 ** the end of the word.
151 */
152 static int thNextWord(Th_Interp*, const char *z, int n, int *pN, int isCmd);
153
154 /*
155 ** Perform substitution on the word contained in the input string (z, n).
156 ** Store the resulting string in the interpreter result.
157 */
158 static int thSubstWord(Th_Interp*, const char *z, int n);
159
160 /*
161 ** The Buffer structure and the thBufferXXX() functions are used to make
162 ** memory allocation easier when building up a result.
163 */
164 struct Buffer {
165 char *zBuf;
166 int nBuf;
167 int nBufAlloc;
168 };
169 typedef struct Buffer Buffer;
170 static int thBufferWrite(Th_Interp *interp, Buffer *, const char *, int);
171 static void thBufferInit(Buffer *);
172 static void thBufferFree(Th_Interp *interp, Buffer *);
173
174 /*
175 ** Append nAdd bytes of content copied from zAdd to the end of buffer
@@ -177,11 +177,11 @@
177 ** the allocation to make space.
178 */
179 static int thBufferWrite(
180 Th_Interp *interp,
181 Buffer *pBuffer,
182 const char *zAdd,
183 int nAdd
184 ){
185 int nReq;
186
187 if( nAdd<0 ){
@@ -188,15 +188,15 @@
188 nAdd = th_strlen(zAdd);
189 }
190 nReq = pBuffer->nBuf+nAdd+1;
191
192 if( nReq>pBuffer->nBufAlloc ){
193 char *zNew;
194 int nNew;
195
196 nNew = nReq*2;
197 zNew = (char *)Th_Malloc(interp, nNew);
198 memcpy(zNew, pBuffer->zBuf, pBuffer->nBuf);
199 Th_Free(interp, pBuffer->zBuf);
200 pBuffer->nBufAlloc = nNew;
201 pBuffer->zBuf = zNew;
202 }
@@ -205,11 +205,11 @@
205 pBuffer->nBuf += nAdd;
206 pBuffer->zBuf[pBuffer->nBuf] = '\0';
207
208 return TH_OK;
209 }
210 #define thBufferWrite(a,b,c,d) thBufferWrite(a,b,(const char *)c,d)
211
212 /*
213 ** Initialize the Buffer structure pointed to by pBuffer.
214 */
215 static void thBufferInit(Buffer *pBuffer){
@@ -228,11 +228,11 @@
228 /*
229 ** Assuming parameter c contains a hexadecimal digit character,
230 ** return the corresponding value of that digit. If c is not
231 ** a hexadecimal digit character, -1 is returned.
232 */
233 static int thHexdigit(char c){
234 switch (c) {
235 case '0': return 0;
236 case '1': return 1;
237 case '2': return 2;
238 case '3': return 3;
@@ -317,11 +317,11 @@
317 ** If there is a parse error, return TH_ERROR and set the interpreter
318 ** result to an error message. Otherwise return TH_OK.
319 */
320 static int thNextEscape(
321 Th_Interp *interp,
322 const char *zInput,
323 int nInput,
324 int *pnEscape
325 ){
326 int i = 2;
327
@@ -349,11 +349,11 @@
349 ** reference. If there is a parse error, return TH_ERROR and set the
350 ** interpreter result to an error message. Otherwise return TH_OK.
351 */
352 int thNextVarname(
353 Th_Interp *interp,
354 const char *zInput,
355 int nInput,
356 int *pnVarname
357 ){
358 int i;
359
@@ -407,11 +407,11 @@
407 ** and set the interpreter result to an error message. Otherwise return
408 ** TH_OK.
409 */
410 int thNextCommand(
411 Th_Interp *interp,
412 const char *zInput,
413 int nInput,
414 int *pnCommand
415 ){
416 int nBrace = 0;
417 int nSquare = 0;
@@ -442,11 +442,11 @@
442 ** Set *pnSpace to the number of whitespace bytes at the start of
443 ** input string (zInput, nInput). Always return TH_OK.
444 */
445 int thNextSpace(
446 Th_Interp *interp,
447 const char *zInput,
448 int nInput,
449 int *pnSpace
450 ){
451 int i;
452 for(i=0; i<nInput && th_isspace(zInput[i]); i++);
@@ -465,11 +465,11 @@
465 ** located inside of a block or quoted string is considered to mark
466 ** the end of the word.
467 */
468 static int thNextWord(
469 Th_Interp *interp,
470 const char *zInput,
471 int nInput,
472 int *pnWord,
473 int isCmd
474 ){
475 int iEnd = 0;
@@ -520,11 +520,11 @@
520 ** a [] block. Perform substitution on the input string and store the
521 ** resulting string in the interpreter result.
522 */
523 static int thSubstCommand(
524 Th_Interp *interp,
525 const char *zWord,
526 int nWord
527 ){
528 assert(nWord>=2);
529 assert(zWord[0]=='[' && zWord[nWord-1]==']');
530 return thEvalLocal(interp, &zWord[1], nWord-2);
@@ -536,11 +536,11 @@
536 ** the input string and store the resulting string in the interpreter
537 ** result.
538 */
539 static int thSubstVarname(
540 Th_Interp *interp,
541 const char *zWord,
542 int nWord
543 ){
544 assert(nWord>=1);
545 assert(zWord[0]=='$');
546 assert(nWord==1 || zWord[1]!='{' || zWord[nWord-1]=='}');
@@ -551,11 +551,11 @@
551 int i;
552 for(i=1; i<nWord && zWord[i]!='('; i++);
553 if( i<nWord ){
554 Buffer varname;
555 int nInner;
556 const char *zInner;
557
558 int rc = thSubstWord(interp, &zWord[i+1], nWord-i-2);
559 if( rc!=TH_OK ) return rc;
560
561 zInner = Th_GetResult(interp, &nInner);
@@ -576,14 +576,14 @@
576 ** Perform substitution on the input string and store the resulting
577 ** string in the interpreter result.
578 */
579 static int thSubstEscape(
580 Th_Interp *interp,
581 const char *zWord,
582 int nWord
583 ){
584 char c;
585
586 assert(nWord>=2);
587 assert(zWord[0]=='\\');
588
589 switch( zWord[1] ){
@@ -612,11 +612,11 @@
612 ** substitution on the input string and store the resulting
613 ** string in the interpreter result.
614 */
615 static int thSubstWord(
616 Th_Interp *interp,
617 const char *zWord,
618 int nWord
619 ){
620 int rc = TH_OK;
621 Buffer output;
622 int i;
@@ -634,12 +634,12 @@
634 }
635
636 for(i=0; rc==TH_OK && i<nWord; i++){
637 int nGet;
638
639 int (*xGet)(Th_Interp *, const char*, int, int *) = 0;
640 int (*xSubst)(Th_Interp *, const char*, int) = 0;
641
642 switch( zWord[i] ){
643 case '\\':
644 xGet = thNextEscape; xSubst = thSubstEscape;
645 break;
@@ -662,11 +662,11 @@
662 rc = xGet(interp, &zWord[i], nWord-i, &nGet);
663 if( rc==TH_OK ){
664 rc = xSubst(interp, &zWord[i], nGet);
665 }
666 if( rc==TH_OK ){
667 const char *zRes;
668 int nRes;
669 zRes = Th_GetResult(interp, &nRes);
670 rc = thBufferWrite(interp, &output, zRes, nRes);
671 i += (nGet-1);
672 }
@@ -689,11 +689,11 @@
689 ** + It contains no non-white-space characters before the first
690 ** newline character.
691 **
692 ** Otherwise return false.
693 */
694 static int thEndOfLine(const char *zInput, int nInput){
695 int i;
696 for(i=0; i<nInput && zInput[i]!='\n' && th_isspace(zInput[i]); i++);
697 return ((i==nInput || zInput[i]=='\n')?1:0);
698 }
699
@@ -710,11 +710,11 @@
710 **
711 ** If TH_OK is returned and pazElem is not NULL, the caller should free the
712 ** pointer written to (*pazElem) using Th_Free(). This releases memory
713 ** allocated for both the (*pazElem) and (*panElem) arrays. Example:
714 **
715 ** char **argv;
716 ** int *argl;
717 ** int argc;
718 **
719 ** // After this call, argv and argl point to valid arrays. The
720 ** // number of elements in each is argc.
@@ -727,30 +727,30 @@
727 ** Th_Free(interp, argv);
728 **
729 */
730 static int thSplitList(
731 Th_Interp *interp, /* Interpreter context */
732 const char *zList, /* Pointer to buffer containing input list */
733 int nList, /* Size of buffer pointed to by zList */
734 char ***pazElem, /* OUT: Array of list elements */
735 int **panElem, /* OUT: Lengths of each list element */
736 int *pnCount /* OUT: Number of list elements */
737 ){
738 int rc = TH_OK;
739
740 Buffer strbuf;
741 Buffer lenbuf;
742 int nCount = 0;
743
744 const char *zInput = zList;
745 int nInput = nList;
746
747 thBufferInit(&strbuf);
748 thBufferInit(&lenbuf);
749
750 while( nInput>0 ){
751 const char *zWord;
752 int nWord;
753
754 thNextSpace(interp, zInput, nInput, &nWord);
755 zInput += nWord;
756 nInput = nList-(zInput-zList);
@@ -773,19 +773,19 @@
773 assert((lenbuf.nBuf/sizeof(int))==nCount);
774
775 assert((pazElem && panElem) || (!pazElem && !panElem));
776 if( pazElem && rc==TH_OK ){
777 int i;
778 char *zElem;
779 int *anElem;
780 char **azElem = Th_Malloc(interp,
781 sizeof(char*) * nCount + /* azElem */
782 sizeof(int) * nCount + /* anElem */
783 strbuf.nBuf /* space for list element strings */
784 );
785 anElem = (int *)&azElem[nCount];
786 zElem = (char *)&anElem[nCount];
787 memcpy(anElem, lenbuf.zBuf, lenbuf.nBuf);
788 memcpy(zElem, strbuf.zBuf, strbuf.nBuf);
789 for(i=0; i<nCount;i++){
790 azElem[i] = zElem;
791 zElem += (anElem[i] + 1);
@@ -805,21 +805,21 @@
805
806 /*
807 ** Evaluate the th1 script contained in the string (zProgram, nProgram)
808 ** in the current stack frame.
809 */
810 static int thEvalLocal(Th_Interp *interp, const char *zProgram, int nProgram){
811 int rc = TH_OK;
812 const char *zInput = zProgram;
813 int nInput = nProgram;
814
815 while( rc==TH_OK && nInput ){
816 Th_HashEntry *pEntry;
817 int nSpace;
818 const char *zFirst;
819
820 char **argv;
821 int *argl;
822 int argc;
823
824 assert(nInput>=0);
825
@@ -872,27 +872,27 @@
872 }
873
874 /* Call the command procedure. */
875 if( rc==TH_OK ){
876 Th_Command *p = (Th_Command *)(pEntry->pData);
877 const char **azArg = (const char **)argv;
878 rc = p->xProc(interp, p->pContext, argc, azArg, argl);
879 }
880
881 /* If an error occured, add this command to the stack trace report. */
882 if( rc==TH_ERROR ){
883 char *zRes;
884 int nRes;
885 char *zStack = 0;
886 int nStack = 0;
887
888 zRes = Th_TakeResult(interp, &nRes);
889 if( TH_OK==Th_GetVar(interp, (char *)"::th_stack_trace", -1) ){
890 zStack = Th_TakeResult(interp, &nStack);
891 }
892 Th_ListAppend(interp, &zStack, &nStack, zFirst, zInput-zFirst);
893 Th_SetVar(interp, (char *)"::th_stack_trace", -1, zStack, nStack);
894 Th_SetResult(interp, zRes, nRes);
895 Th_Free(interp, zRes);
896 Th_Free(interp, zStack);
897 }
898 }
@@ -933,11 +933,11 @@
933 for(i=0; p && i<(iFrame*-1); i++){
934 p = p->pCaller;
935 }
936
937 if( !p ){
938 char *zFrame;
939 int nFrame;
940 Th_SetResultInt(interp, iFrame);
941 zFrame = Th_TakeResult(interp, &nFrame);
942 Th_ErrorMessage(interp, "no such frame:", zFrame, nFrame);
943 Th_Free(interp, zFrame);
@@ -950,11 +950,11 @@
950 ** Evaluate th1 script (zProgram, nProgram) in the frame identified by
951 ** argument iFrame. Leave either an error message or a result in the
952 ** interpreter result and return a th1 error code (TH_OK, TH_ERROR,
953 ** TH_RETURN, TH_CONTINUE or TH_BREAK).
954 */
955 int Th_Eval(Th_Interp *interp, int iFrame, const char *zProgram, int nProgram){
956 int rc = TH_OK;
957 Th_Frame *pSavedFrame = interp->pFrame;
958
959 /* Set Th_Interp.pFrame to the frame that this script is to be
960 ** evaluated in. The current frame is saved in pSavedFrame and will
@@ -992,21 +992,21 @@
992 ** array variable. If the variable is a scalar, *pzInner is set to 0.
993 ** If it is an array variable, (*pzInner, *pnInner) is set to the
994 ** array key name.
995 */
996 static int thAnalyseVarname(
997 const char *zVarname,
998 int nVarname,
999 const char **pzOuter, /* OUT: Pointer to scalar/array name */
1000 int *pnOuter, /* OUT: Number of bytes at *pzOuter */
1001 const char **pzInner, /* OUT: Pointer to array key (or null) */
1002 int *pnInner, /* OUT: Number of bytes at *pzInner */
1003 int *pisGlobal /* OUT: Set to true if this is a global ref */
1004 ){
1005 const char *zOuter = zVarname;
1006 int nOuter;
1007 const char *zInner = 0;
1008 int nInner = 0;
1009 int isGlobal = 0;
1010 int i;
1011
1012 if( nVarname<0 ){
@@ -1056,18 +1056,18 @@
1056 ** an error is left in the interpreter result and NULL returned. If
1057 ** arrayok is true an array name is Ok.
1058 */
1059 static Th_Variable *thFindValue(
1060 Th_Interp *interp,
1061 const char *zVar, /* Pointer to variable name */
1062 int nVar, /* Number of bytes at nVar */
1063 int create, /* If true, create the variable if not found */
1064 int arrayok /* If true, an array is Ok. Othewise array==error */
1065 ){
1066 const char *zOuter;
1067 int nOuter;
1068 const char *zInner;
1069 int nInner;
1070 int isGlobal;
1071
1072 Th_HashEntry *pEntry;
1073 Th_Frame *pFrame = interp->pFrame;
@@ -1134,11 +1134,11 @@
1134 ** the interpreter result and return TH_OK.
1135 **
1136 ** If the named variable does not exist, return TH_ERROR and leave
1137 ** an error message in the interpreter result.
1138 */
1139 int Th_GetVar(Th_Interp *interp, const char *zVar, int nVar){
1140 Th_Variable *pValue;
1141
1142 pValue = thFindValue(interp, zVar, nVar, 0, 0);
1143 if( !pValue ){
1144 return TH_ERROR;
@@ -1159,13 +1159,13 @@
1159 ** If (zVar, nVar) refers to an existing array, TH_ERROR is returned
1160 ** and an error message left in the interpreter result.
1161 */
1162 int Th_SetVar(
1163 Th_Interp *interp,
1164 const char *zVar,
1165 int nVar,
1166 const char *zValue,
1167 int nValue
1168 ){
1169 Th_Variable *pValue;
1170
1171 pValue = thFindValue(interp, zVar, nVar, 1, 0);
@@ -1194,13 +1194,13 @@
1194 ** Create a variable link so that accessing variable (zLocal, nLocal) is
1195 ** the same as accessing variable (zLink, nLink) in stack frame iFrame.
1196 */
1197 int Th_LinkVar(
1198 Th_Interp *interp, /* Interpreter */
1199 const char *zLocal, int nLocal, /* Local varname */
1200 int iFrame, /* Stack frame of linked var */
1201 const char *zLink, int nLink /* Linked varname */
1202 ){
1203 Th_Frame *pSavedFrame = interp->pFrame;
1204 Th_Frame *pFrame;
1205 Th_HashEntry *pEntry;
1206 Th_Variable *pValue;
@@ -1229,11 +1229,11 @@
1229 ** Input string (zVar, nVar) must contain the name of a scalar variable,
1230 ** an array, or an array member. If the identified variable exists, it
1231 ** is deleted and TH_OK returned. Otherwise, an error message is left
1232 ** in the interpreter result and TH_ERROR is returned.
1233 */
1234 int Th_UnsetVar(Th_Interp *interp, const char *zVar, int nVar){
1235 Th_Variable *pValue;
1236
1237 pValue = thFindValue(interp, zVar, nVar, 1, 1);
1238 if( !pValue ){
1239 return TH_ERROR;
@@ -1252,12 +1252,12 @@
1252 /*
1253 ** Return an allocated buffer containing a copy of string (z, n). The
1254 ** caller is responsible for eventually calling Th_Free() to free
1255 ** the returned buffer.
1256 */
1257 char *th_strdup(Th_Interp *interp, const char *z, int n){
1258 char *zRes;
1259 if( n<0 ){
1260 n = th_strlen(z);
1261 }
1262 zRes = Th_Malloc(interp, n+1);
1263 memcpy(zRes, z, n);
@@ -1277,24 +1277,23 @@
1277 ** Example:
1278 **
1279 ** Th_ErrorMessage(interp, "no such variable:", zVarname, nVarname);
1280 **
1281 */
1282 int Th_ErrorMessage(Th_Interp *interp, const char *zPre, const char *z, int n){
1283 if( interp ){
1284 char *zRes = 0;
1285 int nRes = 0;
 
1286
1287 Th_SetVar(interp, (char *)"::th_stack_trace", -1, 0, 0);
1288
1289 Th_StringAppend(interp, &zRes, &nRes, zPre, -1);
1290 if( zRes[nRes-1]=='"' ){
1291 Th_StringAppend(interp, &zRes, &nRes, z, n);
1292 Th_StringAppend(interp, &zRes, &nRes, (const char *)"\"", 1);
1293 }else{
1294 Th_StringAppend(interp, &zRes, &nRes, (const char *)" ", 1);
1295 Th_StringAppend(interp, &zRes, &nRes, z, n);
1296 }
1297
1298 Th_SetResult(interp, zRes, nRes);
1299 Th_Free(interp, zRes);
@@ -1305,11 +1304,11 @@
1304
1305 /*
1306 ** Set the current interpreter result by taking a copy of the buffer
1307 ** pointed to by z, size n bytes. TH_OK is always returned.
1308 */
1309 int Th_SetResult(Th_Interp *pInterp, const char *z, int n){
1310
1311 /* Free the current result */
1312 Th_Free(pInterp, pInterp->zResult);
1313 pInterp->zResult = 0;
1314 pInterp->nResult = 0;
@@ -1317,11 +1316,11 @@
1316 if( n<0 ){
1317 n = th_strlen(z);
1318 }
1319
1320 if( z && n>0 ){
1321 char *zResult;
1322 zResult = Th_Malloc(pInterp, n+1);
1323 memcpy(zResult, z, n);
1324 zResult[n] = '\0';
1325 pInterp->zResult = zResult;
1326 pInterp->nResult = n;
@@ -1333,16 +1332,16 @@
1332 /*
1333 ** Return a pointer to the buffer containing the current interpreter
1334 ** result. If pN is not NULL, set *pN to the size of the returned
1335 ** buffer.
1336 */
1337 const char *Th_GetResult(Th_Interp *pInterp, int *pN){
1338 assert(pInterp->zResult || pInterp->nResult==0);
1339 if( pN ){
1340 *pN = pInterp->nResult;
1341 }
1342 return (pInterp->zResult ? pInterp->zResult : (const char *)"");
1343 }
1344
1345 /*
1346 ** Return a pointer to the buffer containing the current interpreter
1347 ** result. If pN is not NULL, set *pN to the size of the returned
@@ -1351,21 +1350,21 @@
1350 ** This function is the same as Th_GetResult() except that the
1351 ** caller is responsible for eventually calling Th_Free() on the
1352 ** returned buffer. The internal interpreter result is cleared
1353 ** after this function is called.
1354 */
1355 char *Th_TakeResult(Th_Interp *pInterp, int *pN){
1356 if( pN ){
1357 *pN = pInterp->nResult;
1358 }
1359 if( pInterp->zResult ){
1360 char *zResult = pInterp->zResult;
1361 pInterp->zResult = 0;
1362 pInterp->nResult = 0;
1363 return zResult;
1364 }else{
1365 return (char *)Th_Malloc(pInterp, 1);
1366 }
1367 }
1368
1369
1370 /*
@@ -1397,11 +1396,11 @@
1396 void (*xDel)(Th_Interp *, void *) /* Command destructor callback */
1397 ){
1398 Th_HashEntry *pEntry;
1399 Th_Command *pCommand;
1400
1401 pEntry = Th_HashFind(interp, interp->paCmd, (const char *)zName, -1, 1);
1402 if( pEntry->pData ){
1403 pCommand = pEntry->pData;
1404 if( pCommand->xDel ){
1405 pCommand->xDel(interp, pCommand->pContext);
1406 }
@@ -1424,13 +1423,13 @@
1423 ** if command zNew already exists, an error message is left in the
1424 ** interpreter result and TH_ERROR is returned.
1425 */
1426 int Th_RenameCommand(
1427 Th_Interp *interp,
1428 const char *zName, /* Existing command name */
1429 int nName, /* Number of bytes at zName */
1430 const char *zNew, /* New command name */
1431 int nNew /* Number of bytes at zNew */
1432 ){
1433 Th_HashEntry *pEntry;
1434 Th_HashEntry *pNewEntry;
1435
@@ -1495,28 +1494,28 @@
1494 **
1495 ** Example:
1496 **
1497 ** int nElem;
1498 ** int *anElem;
1499 ** char **azElem;
1500 ** int i;
1501 **
1502 ** Th_SplitList(interp, zList, nList, &azElem, &anElem, &nElem);
1503 ** for(i=0; i<nElem; i++){
1504 ** int nData = anElem[i];
1505 ** char *zData = azElem[i];
1506 ** ...
1507 ** }
1508 **
1509 ** Th_Free(interp, azElem);
1510 **
1511 */
1512 int Th_SplitList(
1513 Th_Interp *interp,
1514 const char *zList, /* Pointer to buffer containing list */
1515 int nList, /* Number of bytes at zList */
1516 char ***pazElem, /* OUT: Array of pointers to element data */
1517 int **panElem, /* OUT: Array of element data lengths */
1518 int *pnCount /* OUT: Number of elements in list */
1519 ){
1520 int rc;
1521 interp->isListMode = 1;
@@ -1541,25 +1540,25 @@
1540 ** *pzList to point to a new buffer containing the new list value. *pnList
1541 ** is similarly updated before returning. The return value is always TH_OK.
1542 **
1543 ** Example:
1544 **
1545 ** char *zList = 0;
1546 ** int nList = 0;
1547 ** for (...) {
1548 ** char *zElem = <some expression>;
1549 ** Th_ListAppend(interp, &zList, &nList, zElem, -1);
1550 ** }
1551 ** Th_SetResult(interp, zList, nList);
1552 ** Th_Free(interp, zList);
1553 **
1554 */
1555 int Th_ListAppend(
1556 Th_Interp *interp, /* Interpreter context */
1557 char **pzList, /* IN/OUT: Ptr to ptr to list */
1558 int *pnList, /* IN/OUT: Current length of *pzList */
1559 const char *zElem, /* Data to append */
1560 int nElem /* Length of nElem */
1561 ){
1562 Buffer output;
1563 int i;
1564
@@ -1577,11 +1576,11 @@
1576 if( output.nBuf>0 ){
1577 thBufferWrite(interp, &output, " ", 1);
1578 }
1579
1580 for(i=0; i<nElem; i++){
1581 char c = zElem[i];
1582 if( th_isspecial(c) ) hasSpecialChar = 1;
1583 if( c=='\\' ) hasEscapeChar = 1;
1584 if( c=='{' ) nBrace++;
1585 if( c=='}' ) nBrace--;
1586 }
@@ -1590,11 +1589,11 @@
1589 thBufferWrite(interp, &output, "{", 1);
1590 thBufferWrite(interp, &output, zElem, nElem);
1591 thBufferWrite(interp, &output, "}", 1);
1592 }else{
1593 for(i=0; i<nElem; i++){
1594 char c = zElem[i];
1595 if( th_isspecial(c) ) thBufferWrite(interp, &output, "\\", 1);
1596 thBufferWrite(interp, &output, &c, 1);
1597 }
1598 }
1599
@@ -1608,16 +1607,16 @@
1607 ** Append a new element to an existing th1 string. This function uses
1608 ** the same interface as the Th_ListAppend() function.
1609 */
1610 int Th_StringAppend(
1611 Th_Interp *interp, /* Interpreter context */
1612 char **pzStr, /* IN/OUT: Ptr to ptr to list */
1613 int *pnStr, /* IN/OUT: Current length of *pzStr */
1614 const char *zElem, /* Data to append */
1615 int nElem /* Length of nElem */
1616 ){
1617 char *zNew;
1618 int nNew;
1619
1620 if( nElem<0 ){
1621 nElem = th_strlen(zElem);
1622 }
@@ -1687,11 +1686,11 @@
1686 Operator *pOp;
1687 Expr *pParent;
1688 Expr *pLeft;
1689 Expr *pRight;
1690
1691 char *zValue; /* Pointer to literal value */
1692 int nValue; /* Length of literal value buffer */
1693 };
1694
1695 /* Unary operators */
1696 #define OP_UNARY_MINUS 2
@@ -1778,18 +1777,18 @@
1777 ** The first part of the string (zInput,nInput) contains a number.
1778 ** Set *pnVarname to the number of bytes in the numeric string.
1779 */
1780 static int thNextNumber(
1781 Th_Interp *interp,
1782 const char *zInput,
1783 int nInput,
1784 int *pnLiteral
1785 ){
1786 int i;
1787 int seenDot = 0;
1788 for(i=0; i<nInput; i++){
1789 char c = zInput[i];
1790 if( (seenDot || c!='.') && !th_isdigit(c) ) break;
1791 if( c=='.' ) seenDot = 1;
1792 }
1793 *pnLiteral = i;
1794 return TH_OK;
@@ -1824,12 +1823,12 @@
1823 int iRight;
1824 double fLeft;
1825 double fRight;
1826
1827 /* Left and right arguments as strings */
1828 char *zLeft = 0; int nLeft;
1829 char *zRight = 0; int nRight;
1830
1831 /* Evaluate left and right arguments, if they exist. */
1832 if( pExpr->pLeft ){
1833 rc = exprEval(interp, pExpr->pLeft);
1834 if( rc==TH_OK ){
@@ -2014,11 +2013,11 @@
2013 /*
2014 ** Parse a string containing a TH expression to a list of tokens.
2015 */
2016 static int exprParse(
2017 Th_Interp *interp, /* Interpreter to leave error message in */
2018 const char *zExpr, /* Pointer to input string */
2019 int nExpr, /* Number of bytes at zExpr */
2020 Expr ***papToken, /* OUT: Array of tokens. */
2021 int *pnToken /* OUT: Size of token array */
2022 ){
2023 int i;
@@ -2026,16 +2025,16 @@
2025 int rc = TH_OK;
2026 int nToken = 0;
2027 Expr **apToken = 0;
2028
2029 for(i=0; rc==TH_OK && i<nExpr; ){
2030 char c = zExpr[i];
2031 if( th_isspace(c) ){ /* White-space */
2032 i++;
2033 }else{
2034 Expr *pNew = (Expr *)Th_Malloc(interp, sizeof(Expr));
2035 const char *z = &zExpr[i];
2036
2037 switch (c) {
2038 case '0': case '1': case '2': case '3': case '4':
2039 case '5': case '6': case '7': case '8': case '9':
2040 thNextNumber(interp, z, nExpr-i, &pNew->nValue);
@@ -2069,11 +2068,11 @@
2068 Expr *pPrev = apToken[nToken-1];
2069 if( !pPrev->pOp || pPrev->pOp->eOp==OP_CLOSE_BRACKET ){
2070 continue;
2071 }
2072 }
2073 nOp = th_strlen((const char *)aOperator[j].zOp);
2074 if( (nExpr-i)>=nOp && 0==memcmp(aOperator[j].zOp, &zExpr[i], nOp) ){
2075 pNew->pOp = &aOperator[j];
2076 i += nOp;
2077 break;
2078 }
@@ -2115,11 +2114,11 @@
2114 ** Evaluate the string (zExpr, nExpr) as a Th expression. Store
2115 ** the result in the interpreter interp and return TH_OK if
2116 ** successful. If an error occurs, store an error message in
2117 ** the interpreter result and return an error code.
2118 */
2119 int Th_Expr(Th_Interp *interp, const char *zExpr, int nExpr){
2120 int rc; /* Return Code */
2121 int i; /* Loop counter */
2122
2123 int nToken = 0;
2124 Expr **apToken = 0;
@@ -2222,11 +2221,11 @@
2221 ** not already present in the hash-table.
2222 */
2223 Th_HashEntry *Th_HashFind(
2224 Th_Interp *interp,
2225 Th_Hash *pHash,
2226 const char *zKey,
2227 int nKey,
2228 int op /* -ve = delete, 0 = find, +ve = insert */
2229 ){
2230 unsigned int iKey = 0;
2231 int i;
@@ -2254,11 +2253,11 @@
2253 pRet = 0;
2254 }
2255
2256 if( op>0 && !pRet ){
2257 pRet = (Th_HashEntry *)Th_Malloc(interp, sizeof(Th_HashEntry) + nKey);
2258 pRet->zKey = (char *)&pRet[1];
2259 pRet->nKey = nKey;
2260 memcpy(pRet->zKey, zKey, nKey);
2261 pRet->pNext = pHash->a[iKey];
2262 pHash->a[iKey] = pRet;
2263 }
@@ -2269,11 +2268,11 @@
2268 /*
2269 ** This function is the same as the standard strlen() function, except
2270 ** that it returns 0 (instead of being undefined) if the argument is
2271 ** a null pointer.
2272 */
2273 int th_strlen(const char *zStr){
2274 int n = 0;
2275 if( zStr ){
2276 while( zStr[n] ) n++;
2277 }
2278 return n;
@@ -2320,27 +2319,27 @@
2319 };
2320
2321 /*
2322 ** Clone of the standard isspace() and isdigit function/macros.
2323 */
2324 int th_isspace(char c){
2325 return (aCharProp[(unsigned char)c] & 0x01);
2326 }
2327 int th_isdigit(char c){
2328 return (aCharProp[(unsigned char)c] & 0x02);
2329 }
2330 int th_isspecial(char c){
2331 return (aCharProp[(unsigned char)c] & 0x11);
2332 }
2333 int th_isalnum(char c){
2334 return (aCharProp[(unsigned char)c] & 0x0A);
2335 }
2336
2337 #ifndef LONGDOUBLE_TYPE
2338 # define LONGDOUBLE_TYPE long double
2339 #endif
2340 typedef char u8;
2341
2342
2343 /*
2344 ** Return TRUE if z is a pure numeric string. Return FALSE if the
2345 ** string contains any character which is not part of a number. If
@@ -2446,11 +2445,11 @@
2445 **
2446 ** If the string cannot be converted to an integer, return TH_ERROR.
2447 ** If the interp argument is not NULL, leave an error message in the
2448 ** interpreter result too.
2449 */
2450 int Th_ToInt(Th_Interp *interp, const char *z, int n, int *piOut){
2451 int i = 0;
2452 int iOut = 0;
2453
2454 if( n<0 ){
2455 n = th_strlen(z);
@@ -2483,11 +2482,11 @@
2482 ** If the interp argument is not NULL, leave an error message in the
2483 ** interpreter result too.
2484 */
2485 int Th_ToDouble(
2486 Th_Interp *interp,
2487 const char *z,
2488 int n,
2489 double *pfOut
2490 ){
2491 if( !sqlite3IsNumber((const char *)z, 0) ){
2492 Th_ErrorMessage(interp, "expected number, got: \"", z, n);
@@ -2502,21 +2501,21 @@
2501 ** Set the result of the interpreter to the th1 representation of
2502 ** the integer iVal and return TH_OK.
2503 */
2504 int Th_SetResultInt(Th_Interp *interp, int iVal){
2505 int isNegative = 0;
2506 char zBuf[32];
2507 char *z = &zBuf[32];
2508
2509 if( iVal<0 ){
2510 isNegative = 1;
2511 iVal = iVal * -1;
2512 }
2513 *(--z) = '\0';
2514 *(--z) = (char)(48+(iVal%10));
2515 while( (iVal = (iVal/10))>0 ){
2516 *(--z) = (char)(48+(iVal%10));
2517 assert(z>zBuf);
2518 }
2519 if( isNegative ){
2520 *(--z) = '-';
2521 }
@@ -2529,15 +2528,15 @@
2528 ** the double fVal and return TH_OK.
2529 */
2530 int Th_SetResultDouble(Th_Interp *interp, double fVal){
2531 int i; /* Iterator variable */
2532 double v = fVal; /* Input value */
2533 char zBuf[128]; /* Output buffer */
2534 char *z = zBuf; /* Output cursor */
2535 int iDot = 0; /* Digit after which to place decimal point */
2536 int iExp = 0; /* Exponent (NN in eNN) */
2537 const char *zExp; /* String representation of iExp */
2538
2539 /* Precision: */
2540 #define INSIGNIFICANT 0.000000000001
2541 #define ROUNDER 0.0000000000005
2542 double insignificant = INSIGNIFICANT;
@@ -2583,11 +2582,11 @@
2582
2583 /* Output the digits in real value v. The value of iDot determines
2584 * where (if at all) the decimal point is placed.
2585 */
2586 for(i=0; i<=(iDot+1) || v>=insignificant; i++){
2587 *z++ = (char)(48 + (int)v);
2588 v = (v - ((double)(int)v)) * 10.0;
2589 insignificant *= 10.0;
2590 if( iDot==i ){
2591 *z++ = '.';
2592 }
@@ -2606,68 +2605,5 @@
2605 }
2606
2607 *z = '\0';
2608 return Th_SetResult(interp, zBuf, -1);
2609 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2610
+29 -33
--- src/th.h
+++ src/th.h
@@ -1,13 +1,11 @@
11
22
/* This header file defines the external interface to the custom Scripting
3
-** Language (TH) interpreter used to create test cases for SQLiteRT. The
4
-** interpreted language and API are both based on Tcl.
3
+** Language (TH) interpreter. TH is very similar to TCL but is not an
4
+** exact clone.
55
*/
66
7
-typedef unsigned char uchar;
8
-
97
/*
108
** Before creating an interpreter, the application must allocate and
119
** populate an instance of the following structure. It must remain valid
1210
** for the lifetime of the interpreter.
1311
*/
@@ -39,45 +37,45 @@
3937
** procedure.
4038
**
4139
** * If iFrame is +ve, then the nth frame from the bottom of the stack.
4240
** An iFrame value of 1 means the toplevel (global) frame.
4341
*/
44
-int Th_Eval(Th_Interp *interp, int iFrame, const uchar *zProg, int nProg);
42
+int Th_Eval(Th_Interp *interp, int iFrame, const char *zProg, int nProg);
4543
4644
/*
4745
** Evaluate a TH expression. The result is stored in the
4846
** interpreter result.
4947
*/
50
-int Th_Expr(Th_Interp *interp, const uchar *, int);
48
+int Th_Expr(Th_Interp *interp, const char *, int);
5149
5250
/*
5351
** Access TH variables in the current stack frame. If the variable name
5452
** begins with "::", the lookup is in the top level (global) frame.
5553
*/
56
-int Th_GetVar(Th_Interp *, const uchar *, int);
57
-int Th_SetVar(Th_Interp *, const uchar *, int, const uchar *, int);
58
-int Th_LinkVar(Th_Interp *, const uchar *, int, int, const uchar *, int);
59
-int Th_UnsetVar(Th_Interp *, const uchar *, int);
54
+int Th_GetVar(Th_Interp *, const char *, int);
55
+int Th_SetVar(Th_Interp *, const char *, int, const char *, int);
56
+int Th_LinkVar(Th_Interp *, const char *, int, int, const char *, int);
57
+int Th_UnsetVar(Th_Interp *, const char *, int);
6058
61
-typedef int (*Th_CommandProc)(Th_Interp *, void *, int, const uchar **, int *);
59
+typedef int (*Th_CommandProc)(Th_Interp *, void *, int, const char **, int *);
6260
6361
/*
6462
** Register new commands.
6563
*/
6664
int Th_CreateCommand(
6765
Th_Interp *interp,
6866
const char *zName,
69
- /* int (*xProc)(Th_Interp *, void *, int, const uchar **, int *), */
67
+ /* int (*xProc)(Th_Interp *, void *, int, const char **, int *), */
7068
Th_CommandProc xProc,
7169
void *pContext,
7270
void (*xDel)(Th_Interp *, void *)
7371
);
7472
7573
/*
7674
** Delete or rename commands.
7775
*/
78
-int Th_RenameCommand(Th_Interp *, const uchar *, int, const uchar *, int);
76
+int Th_RenameCommand(Th_Interp *, const char *, int, const char *, int);
7977
8078
/*
8179
** Push a new stack frame (local variable context) onto the interpreter
8280
** stack, call the function supplied as parameter xCall with the two
8381
** context arguments,
@@ -106,19 +104,19 @@
106104
#define TH_CONTINUE 4
107105
108106
/*
109107
** Set and get the interpreter result.
110108
*/
111
-int Th_SetResult(Th_Interp *, const uchar *, int);
112
-const uchar *Th_GetResult(Th_Interp *, int *);
113
-uchar *Th_TakeResult(Th_Interp *, int *);
109
+int Th_SetResult(Th_Interp *, const char *, int);
110
+const char *Th_GetResult(Th_Interp *, int *);
111
+char *Th_TakeResult(Th_Interp *, int *);
114112
115113
/*
116114
** Set an error message as the interpreter result. This also
117115
** sets the global stack-trace variable $::th_stack_trace.
118116
*/
119
-int Th_ErrorMessage(Th_Interp *, const char *, const uchar *, int);
117
+int Th_ErrorMessage(Th_Interp *, const char *, const char *, int);
120118
121119
/*
122120
** Access the memory management functions associated with the specified
123121
** interpreter.
124122
*/
@@ -126,34 +124,32 @@
126124
void Th_Free(Th_Interp *, void *);
127125
128126
/*
129127
** Functions for handling TH lists.
130128
*/
131
-int Th_ListAppend(Th_Interp *, uchar **, int *, const uchar *, int);
132
-int Th_SplitList(Th_Interp *, const uchar *, int, uchar ***, int **, int *);
129
+int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
130
+int Th_SplitList(Th_Interp *, const char *, int, char ***, int **, int *);
133131
134
-int Th_StringAppend(Th_Interp *, uchar **, int *, const uchar *, int);
132
+int Th_StringAppend(Th_Interp *, char **, int *, const char *, int);
135133
136134
/*
137135
** Functions for handling numbers and pointers.
138136
*/
139
-int Th_ToInt(Th_Interp *, const uchar *, int, int *);
140
-int Th_ToDouble(Th_Interp *, const uchar *, int, double *);
141
-int Th_ToPtr(Th_Interp *, const uchar *, int, void **);
137
+int Th_ToInt(Th_Interp *, const char *, int, int *);
138
+int Th_ToDouble(Th_Interp *, const char *, int, double *);
142139
int Th_SetResultInt(Th_Interp *, int);
143140
int Th_SetResultDouble(Th_Interp *, double);
144
-int Th_SetResultPtr(Th_Interp *, void *);
145141
146142
/*
147143
** Drop in replacements for the corresponding standard library functions.
148144
*/
149
-int th_strlen(const unsigned char *);
150
-int th_isdigit(unsigned char);
151
-int th_isspace(unsigned char);
152
-int th_isalnum(unsigned char);
153
-int th_isspecial(unsigned char);
154
-uchar *th_strdup(Th_Interp *interp, const uchar *z, int n);
145
+int th_strlen(const char *);
146
+int th_isdigit(char);
147
+int th_isspace(char);
148
+int th_isalnum(char);
149
+int th_isspecial(char);
150
+char *th_strdup(Th_Interp *interp, const char *z, int n);
155151
156152
/*
157153
** Interfaces to register the language extensions.
158154
*/
159155
int th_register_language(Th_Interp *interp); /* th_lang.c */
@@ -166,21 +162,21 @@
166162
*/
167163
typedef struct Th_Hash Th_Hash;
168164
typedef struct Th_HashEntry Th_HashEntry;
169165
struct Th_HashEntry {
170166
void *pData;
171
- uchar *zKey;
167
+ char *zKey;
172168
int nKey;
173169
Th_HashEntry *pNext; /* Internal use only */
174170
};
175171
Th_Hash *Th_HashNew(Th_Interp *);
176172
void Th_HashDelete(Th_Interp *, Th_Hash *);
177173
void Th_HashIterate(Th_Interp*,Th_Hash*,void (*x)(Th_HashEntry*, void*),void*);
178
-Th_HashEntry *Th_HashFind(Th_Interp*, Th_Hash*, const uchar*, int, int);
174
+Th_HashEntry *Th_HashFind(Th_Interp*, Th_Hash*, const char*, int, int);
179175
180176
/*
181177
** Useful functions from th_lang.c.
182178
*/
183179
int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg);
184180
185181
typedef struct Th_SubCommand {char *zName; Th_CommandProc xProc;} Th_SubCommand;
186
-int Th_CallSubCommand(Th_Interp*,void*,int,const uchar**,int*,Th_SubCommand*);
182
+int Th_CallSubCommand(Th_Interp*,void*,int,const char**,int*,Th_SubCommand*);
187183
--- src/th.h
+++ src/th.h
@@ -1,13 +1,11 @@
1
2 /* This header file defines the external interface to the custom Scripting
3 ** Language (TH) interpreter used to create test cases for SQLiteRT. The
4 ** interpreted language and API are both based on Tcl.
5 */
6
7 typedef unsigned char uchar;
8
9 /*
10 ** Before creating an interpreter, the application must allocate and
11 ** populate an instance of the following structure. It must remain valid
12 ** for the lifetime of the interpreter.
13 */
@@ -39,45 +37,45 @@
39 ** procedure.
40 **
41 ** * If iFrame is +ve, then the nth frame from the bottom of the stack.
42 ** An iFrame value of 1 means the toplevel (global) frame.
43 */
44 int Th_Eval(Th_Interp *interp, int iFrame, const uchar *zProg, int nProg);
45
46 /*
47 ** Evaluate a TH expression. The result is stored in the
48 ** interpreter result.
49 */
50 int Th_Expr(Th_Interp *interp, const uchar *, int);
51
52 /*
53 ** Access TH variables in the current stack frame. If the variable name
54 ** begins with "::", the lookup is in the top level (global) frame.
55 */
56 int Th_GetVar(Th_Interp *, const uchar *, int);
57 int Th_SetVar(Th_Interp *, const uchar *, int, const uchar *, int);
58 int Th_LinkVar(Th_Interp *, const uchar *, int, int, const uchar *, int);
59 int Th_UnsetVar(Th_Interp *, const uchar *, int);
60
61 typedef int (*Th_CommandProc)(Th_Interp *, void *, int, const uchar **, int *);
62
63 /*
64 ** Register new commands.
65 */
66 int Th_CreateCommand(
67 Th_Interp *interp,
68 const char *zName,
69 /* int (*xProc)(Th_Interp *, void *, int, const uchar **, int *), */
70 Th_CommandProc xProc,
71 void *pContext,
72 void (*xDel)(Th_Interp *, void *)
73 );
74
75 /*
76 ** Delete or rename commands.
77 */
78 int Th_RenameCommand(Th_Interp *, const uchar *, int, const uchar *, int);
79
80 /*
81 ** Push a new stack frame (local variable context) onto the interpreter
82 ** stack, call the function supplied as parameter xCall with the two
83 ** context arguments,
@@ -106,19 +104,19 @@
106 #define TH_CONTINUE 4
107
108 /*
109 ** Set and get the interpreter result.
110 */
111 int Th_SetResult(Th_Interp *, const uchar *, int);
112 const uchar *Th_GetResult(Th_Interp *, int *);
113 uchar *Th_TakeResult(Th_Interp *, int *);
114
115 /*
116 ** Set an error message as the interpreter result. This also
117 ** sets the global stack-trace variable $::th_stack_trace.
118 */
119 int Th_ErrorMessage(Th_Interp *, const char *, const uchar *, int);
120
121 /*
122 ** Access the memory management functions associated with the specified
123 ** interpreter.
124 */
@@ -126,34 +124,32 @@
126 void Th_Free(Th_Interp *, void *);
127
128 /*
129 ** Functions for handling TH lists.
130 */
131 int Th_ListAppend(Th_Interp *, uchar **, int *, const uchar *, int);
132 int Th_SplitList(Th_Interp *, const uchar *, int, uchar ***, int **, int *);
133
134 int Th_StringAppend(Th_Interp *, uchar **, int *, const uchar *, int);
135
136 /*
137 ** Functions for handling numbers and pointers.
138 */
139 int Th_ToInt(Th_Interp *, const uchar *, int, int *);
140 int Th_ToDouble(Th_Interp *, const uchar *, int, double *);
141 int Th_ToPtr(Th_Interp *, const uchar *, int, void **);
142 int Th_SetResultInt(Th_Interp *, int);
143 int Th_SetResultDouble(Th_Interp *, double);
144 int Th_SetResultPtr(Th_Interp *, void *);
145
146 /*
147 ** Drop in replacements for the corresponding standard library functions.
148 */
149 int th_strlen(const unsigned char *);
150 int th_isdigit(unsigned char);
151 int th_isspace(unsigned char);
152 int th_isalnum(unsigned char);
153 int th_isspecial(unsigned char);
154 uchar *th_strdup(Th_Interp *interp, const uchar *z, int n);
155
156 /*
157 ** Interfaces to register the language extensions.
158 */
159 int th_register_language(Th_Interp *interp); /* th_lang.c */
@@ -166,21 +162,21 @@
166 */
167 typedef struct Th_Hash Th_Hash;
168 typedef struct Th_HashEntry Th_HashEntry;
169 struct Th_HashEntry {
170 void *pData;
171 uchar *zKey;
172 int nKey;
173 Th_HashEntry *pNext; /* Internal use only */
174 };
175 Th_Hash *Th_HashNew(Th_Interp *);
176 void Th_HashDelete(Th_Interp *, Th_Hash *);
177 void Th_HashIterate(Th_Interp*,Th_Hash*,void (*x)(Th_HashEntry*, void*),void*);
178 Th_HashEntry *Th_HashFind(Th_Interp*, Th_Hash*, const uchar*, int, int);
179
180 /*
181 ** Useful functions from th_lang.c.
182 */
183 int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg);
184
185 typedef struct Th_SubCommand {char *zName; Th_CommandProc xProc;} Th_SubCommand;
186 int Th_CallSubCommand(Th_Interp*,void*,int,const uchar**,int*,Th_SubCommand*);
187
--- src/th.h
+++ src/th.h
@@ -1,13 +1,11 @@
1
2 /* This header file defines the external interface to the custom Scripting
3 ** Language (TH) interpreter. TH is very similar to TCL but is not an
4 ** exact clone.
5 */
6
 
 
7 /*
8 ** Before creating an interpreter, the application must allocate and
9 ** populate an instance of the following structure. It must remain valid
10 ** for the lifetime of the interpreter.
11 */
@@ -39,45 +37,45 @@
37 ** procedure.
38 **
39 ** * If iFrame is +ve, then the nth frame from the bottom of the stack.
40 ** An iFrame value of 1 means the toplevel (global) frame.
41 */
42 int Th_Eval(Th_Interp *interp, int iFrame, const char *zProg, int nProg);
43
44 /*
45 ** Evaluate a TH expression. The result is stored in the
46 ** interpreter result.
47 */
48 int Th_Expr(Th_Interp *interp, const char *, int);
49
50 /*
51 ** Access TH variables in the current stack frame. If the variable name
52 ** begins with "::", the lookup is in the top level (global) frame.
53 */
54 int Th_GetVar(Th_Interp *, const char *, int);
55 int Th_SetVar(Th_Interp *, const char *, int, const char *, int);
56 int Th_LinkVar(Th_Interp *, const char *, int, int, const char *, int);
57 int Th_UnsetVar(Th_Interp *, const char *, int);
58
59 typedef int (*Th_CommandProc)(Th_Interp *, void *, int, const char **, int *);
60
61 /*
62 ** Register new commands.
63 */
64 int Th_CreateCommand(
65 Th_Interp *interp,
66 const char *zName,
67 /* int (*xProc)(Th_Interp *, void *, int, const char **, int *), */
68 Th_CommandProc xProc,
69 void *pContext,
70 void (*xDel)(Th_Interp *, void *)
71 );
72
73 /*
74 ** Delete or rename commands.
75 */
76 int Th_RenameCommand(Th_Interp *, const char *, int, const char *, int);
77
78 /*
79 ** Push a new stack frame (local variable context) onto the interpreter
80 ** stack, call the function supplied as parameter xCall with the two
81 ** context arguments,
@@ -106,19 +104,19 @@
104 #define TH_CONTINUE 4
105
106 /*
107 ** Set and get the interpreter result.
108 */
109 int Th_SetResult(Th_Interp *, const char *, int);
110 const char *Th_GetResult(Th_Interp *, int *);
111 char *Th_TakeResult(Th_Interp *, int *);
112
113 /*
114 ** Set an error message as the interpreter result. This also
115 ** sets the global stack-trace variable $::th_stack_trace.
116 */
117 int Th_ErrorMessage(Th_Interp *, const char *, const char *, int);
118
119 /*
120 ** Access the memory management functions associated with the specified
121 ** interpreter.
122 */
@@ -126,34 +124,32 @@
124 void Th_Free(Th_Interp *, void *);
125
126 /*
127 ** Functions for handling TH lists.
128 */
129 int Th_ListAppend(Th_Interp *, char **, int *, const char *, int);
130 int Th_SplitList(Th_Interp *, const char *, int, char ***, int **, int *);
131
132 int Th_StringAppend(Th_Interp *, char **, int *, const char *, int);
133
134 /*
135 ** Functions for handling numbers and pointers.
136 */
137 int Th_ToInt(Th_Interp *, const char *, int, int *);
138 int Th_ToDouble(Th_Interp *, const char *, int, double *);
 
139 int Th_SetResultInt(Th_Interp *, int);
140 int Th_SetResultDouble(Th_Interp *, double);
 
141
142 /*
143 ** Drop in replacements for the corresponding standard library functions.
144 */
145 int th_strlen(const char *);
146 int th_isdigit(char);
147 int th_isspace(char);
148 int th_isalnum(char);
149 int th_isspecial(char);
150 char *th_strdup(Th_Interp *interp, const char *z, int n);
151
152 /*
153 ** Interfaces to register the language extensions.
154 */
155 int th_register_language(Th_Interp *interp); /* th_lang.c */
@@ -166,21 +162,21 @@
162 */
163 typedef struct Th_Hash Th_Hash;
164 typedef struct Th_HashEntry Th_HashEntry;
165 struct Th_HashEntry {
166 void *pData;
167 char *zKey;
168 int nKey;
169 Th_HashEntry *pNext; /* Internal use only */
170 };
171 Th_Hash *Th_HashNew(Th_Interp *);
172 void Th_HashDelete(Th_Interp *, Th_Hash *);
173 void Th_HashIterate(Th_Interp*,Th_Hash*,void (*x)(Th_HashEntry*, void*),void*);
174 Th_HashEntry *Th_HashFind(Th_Interp*, Th_Hash*, const char*, int, int);
175
176 /*
177 ** Useful functions from th_lang.c.
178 */
179 int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg);
180
181 typedef struct Th_SubCommand {char *zName; Th_CommandProc xProc;} Th_SubCommand;
182 int Th_CallSubCommand(Th_Interp*,void*,int,const char**,int*,Th_SubCommand*);
183
+67 -69
--- src/th_lang.c
+++ src/th_lang.c
@@ -12,13 +12,11 @@
1212
#include "th.h"
1313
#include <string.h>
1414
#include <assert.h>
1515
1616
int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg){
17
- Th_ErrorMessage(interp,
18
- "wrong # args: should be \"", (const uchar*)zMsg, -1
19
- );
17
+ Th_ErrorMessage(interp, "wrong # args: should be \"", zMsg, -1);
2018
return TH_ERROR;
2119
}
2220
2321
/*
2422
** Syntax:
@@ -27,11 +25,11 @@
2725
*/
2826
static int catch_command(
2927
Th_Interp *interp,
3028
void *ctx,
3129
int argc,
32
- const uchar **argv,
30
+ const char **argv,
3331
int *argl
3432
){
3533
int rc;
3634
3735
if( argc!=2 && argc!=3 ){
@@ -39,11 +37,11 @@
3937
}
4038
4139
rc = Th_Eval(interp, 0, argv[1], -1);
4240
if( argc==3 ){
4341
int nResult;
44
- const uchar *zResult = Th_GetResult(interp, &nResult);
42
+ const char *zResult = Th_GetResult(interp, &nResult);
4543
Th_SetVar(interp, argv[2], argl[2], zResult, nResult);
4644
}
4745
4846
Th_SetResultInt(interp, rc);
4947
return TH_OK;
@@ -56,19 +54,19 @@
5654
*/
5755
static int if_command(
5856
Th_Interp *interp,
5957
void *ctx,
6058
int argc,
61
- const uchar **argv,
59
+ const char **argv,
6260
int *argl
6361
){
6462
int rc = TH_OK;
6563
6664
int iCond; /* Result of evaluating expression */
6765
int i;
6866
69
- const uchar *zResult;
67
+ const char *zResult;
7068
int nResult;
7169
7270
if( argc<3 ){
7371
goto wrong_args;
7472
}
@@ -103,11 +101,11 @@
103101
*/
104102
static int expr_command(
105103
Th_Interp *interp,
106104
void *ctx,
107105
int argc,
108
- const uchar **argv,
106
+ const char **argv,
109107
int *argl
110108
){
111109
if( argc!=2 ){
112110
return Th_WrongNumArgs(interp, "expr expression");
113111
}
@@ -118,11 +116,11 @@
118116
/*
119117
** Evaluate the th1 script (zBody, nBody) in the local stack frame.
120118
** Return the result of the evaluation, except if the result
121119
** is TH_CONTINUE, return TH_OK instead.
122120
*/
123
-static int eval_loopbody(Th_Interp *interp, const uchar *zBody, int nBody){
121
+static int eval_loopbody(Th_Interp *interp, const char *zBody, int nBody){
124122
int rc = Th_Eval(interp, 0, zBody, nBody);
125123
if( rc==TH_CONTINUE ){
126124
rc = TH_OK;
127125
}
128126
return rc;
@@ -135,11 +133,11 @@
135133
*/
136134
static int for_command(
137135
Th_Interp *interp,
138136
void *ctx,
139137
int argc,
140
- const uchar **argv,
138
+ const char **argv,
141139
int *argl
142140
){
143141
int rc;
144142
int iCond;
145143
@@ -170,14 +168,14 @@
170168
*/
171169
static int list_command(
172170
Th_Interp *interp,
173171
void *ctx,
174172
int argc,
175
- const uchar **argv,
173
+ const char **argv,
176174
int *argl
177175
){
178
- uchar *zList = 0;
176
+ char *zList = 0;
179177
int nList = 0;
180178
int i;
181179
182180
for(i=1; i<argc; i++){
183181
Th_ListAppend(interp, &zList, &nList, argv[i], argl[i]);
@@ -196,17 +194,17 @@
196194
*/
197195
static int lindex_command(
198196
Th_Interp *interp,
199197
void *ctx,
200198
int argc,
201
- const uchar **argv,
199
+ const char **argv,
202200
int *argl
203201
){
204202
int iElem;
205203
int rc;
206204
207
- uchar **azElem;
205
+ char **azElem;
208206
int *anElem;
209207
int nCount;
210208
211209
if( argc!=3 ){
212210
return Th_WrongNumArgs(interp, "lindex list index");
@@ -236,11 +234,11 @@
236234
*/
237235
static int llength_command(
238236
Th_Interp *interp,
239237
void *ctx,
240238
int argc,
241
- const uchar **argv,
239
+ const char **argv,
242240
int *argl
243241
){
244242
int nElem;
245243
int rc;
246244
@@ -263,11 +261,11 @@
263261
*/
264262
static int set_command(
265263
Th_Interp *interp,
266264
void *ctx,
267265
int argc,
268
- const uchar **argv,
266
+ const char **argv,
269267
int *argl
270268
){
271269
if( argc!=2 && argc!=3 ){
272270
return Th_WrongNumArgs(interp, "set varname ?value?");
273271
}
@@ -285,18 +283,18 @@
285283
** to function proc_call1() when the new command is executed.
286284
*/
287285
typedef struct ProcDefn ProcDefn;
288286
struct ProcDefn {
289287
int nParam; /* Number of formal (non "args") parameters */
290
- uchar **azParam; /* Parameter names */
288
+ char **azParam; /* Parameter names */
291289
int *anParam; /* Lengths of parameter names */
292
- uchar **azDefault; /* Default values */
290
+ char **azDefault; /* Default values */
293291
int *anDefault; /* Lengths of default values */
294292
int hasArgs; /* True if there is an "args" parameter */
295
- uchar *zProgram; /* Body of proc */
293
+ char *zProgram; /* Body of proc */
296294
int nProgram; /* Number of bytes at zProgram */
297
- uchar *zUsage; /* Usage message */
295
+ char *zUsage; /* Usage message */
298296
int nUsage; /* Number of bytes at zUsage */
299297
};
300298
301299
/* This structure is used to temporarily store arguments passed to an
302300
** invocation of a command created using [proc]. A pointer to an
@@ -303,11 +301,11 @@
303301
** instance is passed as the second argument to the proc_call2() function.
304302
*/
305303
typedef struct ProcArgs ProcArgs;
306304
struct ProcArgs {
307305
int argc;
308
- const uchar **argv;
306
+ const char **argv;
309307
int *argl;
310308
};
311309
312310
/*
313311
** Each time a command created using [proc] is invoked, a new
@@ -327,23 +325,23 @@
327325
** not, generate a usage message for the command.
328326
*/
329327
if( (pArgs->argc>(p->nParam+1) && !p->hasArgs)
330328
|| (pArgs->argc<=(p->nParam) && !p->azDefault[pArgs->argc-1])
331329
){
332
- uchar *zUsage = 0;
330
+ char *zUsage = 0;
333331
int nUsage = 0;
334332
Th_StringAppend(interp, &zUsage, &nUsage, pArgs->argv[0], pArgs->argl[0]);
335333
Th_StringAppend(interp, &zUsage, &nUsage, p->zUsage, p->nUsage);
336
- Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)"", 1);
334
+ Th_StringAppend(interp, &zUsage, &nUsage, (const char *)"", 1);
337335
Th_WrongNumArgs(interp, zUsage);
338336
Th_Free(interp, zUsage);
339337
return TH_ERROR;
340338
}
341339
342340
/* Populate the formal proc parameters. */
343341
for(i=0; i<p->nParam; i++){
344
- const uchar *zVal;
342
+ const char *zVal;
345343
int nVal;
346344
if( pArgs->argc>(i+1) ){
347345
zVal = pArgs->argv[i+1];
348346
nVal = pArgs->argl[i+1];
349347
}else{
@@ -353,16 +351,16 @@
353351
Th_SetVar(interp, p->azParam[i], p->anParam[i], zVal, nVal);
354352
}
355353
356354
/* Populate the "args" parameter, if it exists */
357355
if( p->hasArgs ){
358
- uchar *zArgs = 0;
356
+ char *zArgs = 0;
359357
int nArgs = 0;
360358
for(i=p->nParam+1; i<pArgs->argc; i++){
361359
Th_ListAppend(interp, &zArgs, &nArgs, pArgs->argv[i], pArgs->argl[i]);
362360
}
363
- Th_SetVar(interp, (const uchar *)"args", -1, zArgs, nArgs);
361
+ Th_SetVar(interp, (const char *)"args", -1, zArgs, nArgs);
364362
}
365363
366364
Th_SetResult(interp, 0, 0);
367365
return Th_Eval(interp, 0, p->zProgram, p->nProgram);
368366
}
@@ -374,11 +372,11 @@
374372
*/
375373
static int proc_call1(
376374
Th_Interp *interp,
377375
void *pContext,
378376
int argc,
379
- const uchar **argv,
377
+ const char **argv,
380378
int *argl
381379
){
382380
int rc;
383381
384382
ProcDefn *p = (ProcDefn *)pContext;
@@ -419,26 +417,26 @@
419417
*/
420418
static int proc_command(
421419
Th_Interp *interp,
422420
void *ctx,
423421
int argc,
424
- const uchar **argv,
422
+ const char **argv,
425423
int *argl
426424
){
427425
int rc;
428426
char *zName;
429427
430428
ProcDefn *p;
431429
int nByte;
432430
int i;
433
- uchar *zSpace;
431
+ char *zSpace;
434432
435
- uchar **azParam;
433
+ char **azParam;
436434
int *anParam;
437435
int nParam;
438436
439
- uchar *zUsage = 0; /* Build up a usage message here */
437
+ char *zUsage = 0; /* Build up a usage message here */
440438
int nUsage = 0; /* Number of bytes at zUsage */
441439
442440
if( argc!=4 ){
443441
return Th_WrongNumArgs(interp, "proc name arglist code");
444442
}
@@ -446,12 +444,12 @@
446444
return TH_ERROR;
447445
}
448446
449447
/* Allocate the new ProcDefn structure. */
450448
nByte = sizeof(ProcDefn) + /* ProcDefn structure */
451
- (sizeof(uchar *) + sizeof(int)) * nParam + /* azParam, anParam */
452
- (sizeof(uchar *) + sizeof(int)) * nParam + /* azDefault, anDefault */
449
+ (sizeof(char *) + sizeof(int)) * nParam + /* azParam, anParam */
450
+ (sizeof(char *) + sizeof(int)) * nParam + /* azDefault, anDefault */
453451
argl[3] + /* zProgram */
454452
argl[2]; /* Space for copies of parameter names and default values */
455453
p = (ProcDefn *)Th_Malloc(interp, nByte);
456454
457455
/* If the last parameter in the parameter list is "args", then set the
@@ -462,21 +460,21 @@
462460
p->hasArgs = 1;
463461
nParam--;
464462
}
465463
466464
p->nParam = nParam;
467
- p->azParam = (uchar **)&p[1];
465
+ p->azParam = (char **)&p[1];
468466
p->anParam = (int *)&p->azParam[nParam];
469
- p->azDefault = (uchar **)&p->anParam[nParam];
467
+ p->azDefault = (char **)&p->anParam[nParam];
470468
p->anDefault = (int *)&p->azDefault[nParam];
471
- p->zProgram = (uchar *)&p->anDefault[nParam];
469
+ p->zProgram = (char *)&p->anDefault[nParam];
472470
memcpy(p->zProgram, argv[3], argl[3]);
473471
p->nProgram = argl[3];
474472
zSpace = &p->zProgram[p->nProgram];
475473
476474
for(i=0; i<nParam; i++){
477
- uchar **az;
475
+ char **az;
478476
int *an;
479477
int n;
480478
if( Th_SplitList(interp, azParam[i], anParam[i], &az, &an, &n) ){
481479
goto error_out;
482480
}
@@ -495,29 +493,29 @@
495493
p->azDefault[i] = zSpace;
496494
memcpy(zSpace, az[1], an[1]);
497495
zSpace += an[1];
498496
}
499497
500
- Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)" ", 1);
498
+ Th_StringAppend(interp, &zUsage, &nUsage, (const char *)" ", 1);
501499
if( n==2 ){
502
- Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)"?", 1);
500
+ Th_StringAppend(interp, &zUsage, &nUsage, (const char *)"?", 1);
503501
Th_StringAppend(interp, &zUsage, &nUsage, az[0], an[0]);
504
- Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)"?", 1);
502
+ Th_StringAppend(interp, &zUsage, &nUsage, (const char *)"?", 1);
505503
}else{
506504
Th_StringAppend(interp, &zUsage, &nUsage, az[0], an[0]);
507505
}
508506
509507
Th_Free(interp, az);
510508
}
511
- assert( zSpace-(uchar *)p<=nByte );
509
+ assert( zSpace-(char *)p<=nByte );
512510
513511
/* If there is an "args" parameter, append it to the end of the usage
514512
** message. Set ProcDefn.zUsage to point at the usage message. It will
515513
** be freed along with the rest of the proc-definition by proc_del().
516514
*/
517515
if( p->hasArgs ){
518
- Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)" ?args...?", -1);
516
+ Th_StringAppend(interp, &zUsage, &nUsage, (const char *)" ?args...?", -1);
519517
}
520518
p->zUsage = zUsage;
521519
p->nUsage = nUsage;
522520
523521
/* Register the new command with the th1 interpreter. */
@@ -543,11 +541,11 @@
543541
*/
544542
static int rename_command(
545543
Th_Interp *interp,
546544
void *ctx,
547545
int argc,
548
- const uchar **argv,
546
+ const char **argv,
549547
int *argl
550548
){
551549
if( argc!=3 ){
552550
return Th_WrongNumArgs(interp, "rename oldcmd newcmd");
553551
}
@@ -564,11 +562,11 @@
564562
*/
565563
static int simple_command(
566564
Th_Interp *interp,
567565
void *ctx,
568566
int argc,
569
- const uchar **argv,
567
+ const char **argv,
570568
int *argl
571569
){
572570
if( argc!=1 && argc!=2 ){
573571
return Th_WrongNumArgs(interp, "return ?value?");
574572
}
@@ -585,11 +583,11 @@
585583
*/
586584
static int return_command(
587585
Th_Interp *interp,
588586
void *ctx,
589587
int argc,
590
- const uchar **argv,
588
+ const char **argv,
591589
int *argl
592590
){
593591
int iCode = TH_RETURN;
594592
if( argc<1 || argc>4 ){
595593
return Th_WrongNumArgs(interp, "return ?-code code? ?value?");
@@ -610,14 +608,14 @@
610608
** TH Syntax:
611609
**
612610
** string compare STRING1 STRING2
613611
*/
614612
static int string_compare_command(
615
- Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
613
+ Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
616614
){
617
- const uchar *zRight; int nRight;
618
- const uchar *zLeft; int nLeft;
615
+ const char *zRight; int nRight;
616
+ const char *zLeft; int nLeft;
619617
620618
int i;
621619
int iRes = 0;
622620
623621
if( argc!=4 ){
@@ -646,15 +644,15 @@
646644
** TH Syntax:
647645
**
648646
** string first NEEDLE HAYSTACK
649647
*/
650648
static int string_first_command(
651
- Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
649
+ Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
652650
){
653
- const uchar *zNeedle;
651
+ const char *zNeedle;
654652
int nNeedle;
655
- const uchar *zHaystack;
653
+ const char *zHaystack;
656654
int nHaystack;
657655
int i;
658656
int iRes;
659657
660658
if( argc!=4 ){
@@ -680,11 +678,11 @@
680678
** TH Syntax:
681679
**
682680
** string is CLASS STRING
683681
*/
684682
static int string_is_command(
685
- Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
683
+ Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
686684
){
687685
int i;
688686
int iRes = 1;
689687
if( argc!=4 ){
690688
return Th_WrongNumArgs(interp, "string is class string");
@@ -707,15 +705,15 @@
707705
** TH Syntax:
708706
**
709707
** string last NEEDLE HAYSTACK
710708
*/
711709
static int string_last_command(
712
- Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
710
+ Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
713711
){
714
- const uchar *zNeedle;
712
+ const char *zNeedle;
715713
int nNeedle;
716
- const uchar *zHaystack;
714
+ const char *zHaystack;
717715
int nHaystack;
718716
int i;
719717
int iRes;
720718
721719
if( argc!=4 ){
@@ -741,11 +739,11 @@
741739
** TH Syntax:
742740
**
743741
** string length STRING
744742
*/
745743
static int string_length_command(
746
- Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
744
+ Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
747745
){
748746
if( argc!=3 ){
749747
return Th_WrongNumArgs(interp, "string length string");
750748
}
751749
return Th_SetResultInt(interp, argl[2]);
@@ -755,11 +753,11 @@
755753
** TH Syntax:
756754
**
757755
** string range STRING FIRST LAST
758756
*/
759757
static int string_range_command(
760
- Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
758
+ Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
761759
){
762760
int iStart;
763761
int iEnd;
764762
765763
if( argc!=5 ){
@@ -788,16 +786,16 @@
788786
** TH Syntax:
789787
**
790788
** string repeat STRING COUNT
791789
*/
792790
static int string_repeat_command(
793
- Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
791
+ Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
794792
){
795793
int n;
796794
int i;
797795
int nByte;
798
- uchar *zByte;
796
+ char *zByte;
799797
800798
if( argc!=4 ){
801799
return Th_WrongNumArgs(interp, "string repeat string n");
802800
}
803801
if( Th_ToInt(interp, argv[3], argl[3], &n) ){
@@ -819,11 +817,11 @@
819817
** TH Syntax:
820818
**
821819
** info exists VAR
822820
*/
823821
static int info_exists_command(
824
- Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
822
+ Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
825823
){
826824
int rc;
827825
828826
if( argc!=3 ){
829827
return Th_WrongNumArgs(interp, "info exists var");
@@ -840,11 +838,11 @@
840838
*/
841839
static int unset_command(
842840
Th_Interp *interp,
843841
void *ctx,
844842
int argc,
845
- const uchar **argv,
843
+ const char **argv,
846844
int *argl
847845
){
848846
if( argc!=2 ){
849847
return Th_WrongNumArgs(interp, "unset var");
850848
}
@@ -853,17 +851,17 @@
853851
854852
int Th_CallSubCommand(
855853
Th_Interp *interp,
856854
void *ctx,
857855
int argc,
858
- const uchar **argv,
856
+ const char **argv,
859857
int *argl,
860858
Th_SubCommand *aSub
861859
){
862860
int i;
863861
for(i=0; aSub[i].zName; i++){
864
- uchar *zName = (uchar *)aSub[i].zName;
862
+ char *zName = (char *)aSub[i].zName;
865863
if( th_strlen(zName)==argl[1] && 0==memcmp(zName, argv[1], argl[1]) ){
866864
return aSub[i].xProc(interp, ctx, argc, argv, argl);
867865
}
868866
}
869867
@@ -884,11 +882,11 @@
884882
*/
885883
static int string_command(
886884
Th_Interp *interp,
887885
void *ctx,
888886
int argc,
889
- const uchar **argv,
887
+ const char **argv,
890888
int *argl
891889
){
892890
Th_SubCommand aSub[] = {
893891
{ "compare", string_compare_command },
894892
{ "first", string_first_command },
@@ -909,11 +907,11 @@
909907
*/
910908
static int info_command(
911909
Th_Interp *interp,
912910
void *ctx,
913911
int argc,
914
- const uchar **argv,
912
+ const char **argv,
915913
int *argl
916914
){
917915
Th_SubCommand aSub[] = {
918916
{ "exists", info_exists_command },
919917
{ 0, 0 }
@@ -928,11 +926,11 @@
928926
** frame level to *piFrame and return TH_OK. Otherwise, return TH_ERROR
929927
** and leave an error message in the interpreter result.
930928
*/
931929
static int thToFrame(
932930
Th_Interp *interp,
933
- const uchar *zFrame,
931
+ const char *zFrame,
934932
int nFrame,
935933
int *piFrame
936934
){
937935
int iFrame;
938936
if( th_isdigit(zFrame[0]) ){
@@ -957,11 +955,11 @@
957955
*/
958956
static int uplevel_command(
959957
Th_Interp *interp,
960958
void *ctx,
961959
int argc,
962
- const uchar **argv,
960
+ const char **argv,
963961
int *argl
964962
){
965963
int iFrame = -1;
966964
967965
if( argc!=2 && argc!=3 ){
@@ -980,11 +978,11 @@
980978
*/
981979
static int upvar_command(
982980
Th_Interp *interp,
983981
void *ctx,
984982
int argc,
985
- const uchar **argv,
983
+ const char **argv,
986984
int *argl
987985
){
988986
int iVar = 1;
989987
int iFrame = -1;
990988
int rc = TH_OK;
@@ -1013,11 +1011,11 @@
10131011
*/
10141012
static int breakpoint_command(
10151013
Th_Interp *interp,
10161014
void *ctx,
10171015
int argc,
1018
- const uchar **argv,
1016
+ const char **argv,
10191017
int *argl
10201018
){
10211019
int cnt = 0;
10221020
cnt++;
10231021
return TH_OK;
10241022
--- src/th_lang.c
+++ src/th_lang.c
@@ -12,13 +12,11 @@
12 #include "th.h"
13 #include <string.h>
14 #include <assert.h>
15
16 int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg){
17 Th_ErrorMessage(interp,
18 "wrong # args: should be \"", (const uchar*)zMsg, -1
19 );
20 return TH_ERROR;
21 }
22
23 /*
24 ** Syntax:
@@ -27,11 +25,11 @@
27 */
28 static int catch_command(
29 Th_Interp *interp,
30 void *ctx,
31 int argc,
32 const uchar **argv,
33 int *argl
34 ){
35 int rc;
36
37 if( argc!=2 && argc!=3 ){
@@ -39,11 +37,11 @@
39 }
40
41 rc = Th_Eval(interp, 0, argv[1], -1);
42 if( argc==3 ){
43 int nResult;
44 const uchar *zResult = Th_GetResult(interp, &nResult);
45 Th_SetVar(interp, argv[2], argl[2], zResult, nResult);
46 }
47
48 Th_SetResultInt(interp, rc);
49 return TH_OK;
@@ -56,19 +54,19 @@
56 */
57 static int if_command(
58 Th_Interp *interp,
59 void *ctx,
60 int argc,
61 const uchar **argv,
62 int *argl
63 ){
64 int rc = TH_OK;
65
66 int iCond; /* Result of evaluating expression */
67 int i;
68
69 const uchar *zResult;
70 int nResult;
71
72 if( argc<3 ){
73 goto wrong_args;
74 }
@@ -103,11 +101,11 @@
103 */
104 static int expr_command(
105 Th_Interp *interp,
106 void *ctx,
107 int argc,
108 const uchar **argv,
109 int *argl
110 ){
111 if( argc!=2 ){
112 return Th_WrongNumArgs(interp, "expr expression");
113 }
@@ -118,11 +116,11 @@
118 /*
119 ** Evaluate the th1 script (zBody, nBody) in the local stack frame.
120 ** Return the result of the evaluation, except if the result
121 ** is TH_CONTINUE, return TH_OK instead.
122 */
123 static int eval_loopbody(Th_Interp *interp, const uchar *zBody, int nBody){
124 int rc = Th_Eval(interp, 0, zBody, nBody);
125 if( rc==TH_CONTINUE ){
126 rc = TH_OK;
127 }
128 return rc;
@@ -135,11 +133,11 @@
135 */
136 static int for_command(
137 Th_Interp *interp,
138 void *ctx,
139 int argc,
140 const uchar **argv,
141 int *argl
142 ){
143 int rc;
144 int iCond;
145
@@ -170,14 +168,14 @@
170 */
171 static int list_command(
172 Th_Interp *interp,
173 void *ctx,
174 int argc,
175 const uchar **argv,
176 int *argl
177 ){
178 uchar *zList = 0;
179 int nList = 0;
180 int i;
181
182 for(i=1; i<argc; i++){
183 Th_ListAppend(interp, &zList, &nList, argv[i], argl[i]);
@@ -196,17 +194,17 @@
196 */
197 static int lindex_command(
198 Th_Interp *interp,
199 void *ctx,
200 int argc,
201 const uchar **argv,
202 int *argl
203 ){
204 int iElem;
205 int rc;
206
207 uchar **azElem;
208 int *anElem;
209 int nCount;
210
211 if( argc!=3 ){
212 return Th_WrongNumArgs(interp, "lindex list index");
@@ -236,11 +234,11 @@
236 */
237 static int llength_command(
238 Th_Interp *interp,
239 void *ctx,
240 int argc,
241 const uchar **argv,
242 int *argl
243 ){
244 int nElem;
245 int rc;
246
@@ -263,11 +261,11 @@
263 */
264 static int set_command(
265 Th_Interp *interp,
266 void *ctx,
267 int argc,
268 const uchar **argv,
269 int *argl
270 ){
271 if( argc!=2 && argc!=3 ){
272 return Th_WrongNumArgs(interp, "set varname ?value?");
273 }
@@ -285,18 +283,18 @@
285 ** to function proc_call1() when the new command is executed.
286 */
287 typedef struct ProcDefn ProcDefn;
288 struct ProcDefn {
289 int nParam; /* Number of formal (non "args") parameters */
290 uchar **azParam; /* Parameter names */
291 int *anParam; /* Lengths of parameter names */
292 uchar **azDefault; /* Default values */
293 int *anDefault; /* Lengths of default values */
294 int hasArgs; /* True if there is an "args" parameter */
295 uchar *zProgram; /* Body of proc */
296 int nProgram; /* Number of bytes at zProgram */
297 uchar *zUsage; /* Usage message */
298 int nUsage; /* Number of bytes at zUsage */
299 };
300
301 /* This structure is used to temporarily store arguments passed to an
302 ** invocation of a command created using [proc]. A pointer to an
@@ -303,11 +301,11 @@
303 ** instance is passed as the second argument to the proc_call2() function.
304 */
305 typedef struct ProcArgs ProcArgs;
306 struct ProcArgs {
307 int argc;
308 const uchar **argv;
309 int *argl;
310 };
311
312 /*
313 ** Each time a command created using [proc] is invoked, a new
@@ -327,23 +325,23 @@
327 ** not, generate a usage message for the command.
328 */
329 if( (pArgs->argc>(p->nParam+1) && !p->hasArgs)
330 || (pArgs->argc<=(p->nParam) && !p->azDefault[pArgs->argc-1])
331 ){
332 uchar *zUsage = 0;
333 int nUsage = 0;
334 Th_StringAppend(interp, &zUsage, &nUsage, pArgs->argv[0], pArgs->argl[0]);
335 Th_StringAppend(interp, &zUsage, &nUsage, p->zUsage, p->nUsage);
336 Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)"", 1);
337 Th_WrongNumArgs(interp, zUsage);
338 Th_Free(interp, zUsage);
339 return TH_ERROR;
340 }
341
342 /* Populate the formal proc parameters. */
343 for(i=0; i<p->nParam; i++){
344 const uchar *zVal;
345 int nVal;
346 if( pArgs->argc>(i+1) ){
347 zVal = pArgs->argv[i+1];
348 nVal = pArgs->argl[i+1];
349 }else{
@@ -353,16 +351,16 @@
353 Th_SetVar(interp, p->azParam[i], p->anParam[i], zVal, nVal);
354 }
355
356 /* Populate the "args" parameter, if it exists */
357 if( p->hasArgs ){
358 uchar *zArgs = 0;
359 int nArgs = 0;
360 for(i=p->nParam+1; i<pArgs->argc; i++){
361 Th_ListAppend(interp, &zArgs, &nArgs, pArgs->argv[i], pArgs->argl[i]);
362 }
363 Th_SetVar(interp, (const uchar *)"args", -1, zArgs, nArgs);
364 }
365
366 Th_SetResult(interp, 0, 0);
367 return Th_Eval(interp, 0, p->zProgram, p->nProgram);
368 }
@@ -374,11 +372,11 @@
374 */
375 static int proc_call1(
376 Th_Interp *interp,
377 void *pContext,
378 int argc,
379 const uchar **argv,
380 int *argl
381 ){
382 int rc;
383
384 ProcDefn *p = (ProcDefn *)pContext;
@@ -419,26 +417,26 @@
419 */
420 static int proc_command(
421 Th_Interp *interp,
422 void *ctx,
423 int argc,
424 const uchar **argv,
425 int *argl
426 ){
427 int rc;
428 char *zName;
429
430 ProcDefn *p;
431 int nByte;
432 int i;
433 uchar *zSpace;
434
435 uchar **azParam;
436 int *anParam;
437 int nParam;
438
439 uchar *zUsage = 0; /* Build up a usage message here */
440 int nUsage = 0; /* Number of bytes at zUsage */
441
442 if( argc!=4 ){
443 return Th_WrongNumArgs(interp, "proc name arglist code");
444 }
@@ -446,12 +444,12 @@
446 return TH_ERROR;
447 }
448
449 /* Allocate the new ProcDefn structure. */
450 nByte = sizeof(ProcDefn) + /* ProcDefn structure */
451 (sizeof(uchar *) + sizeof(int)) * nParam + /* azParam, anParam */
452 (sizeof(uchar *) + sizeof(int)) * nParam + /* azDefault, anDefault */
453 argl[3] + /* zProgram */
454 argl[2]; /* Space for copies of parameter names and default values */
455 p = (ProcDefn *)Th_Malloc(interp, nByte);
456
457 /* If the last parameter in the parameter list is "args", then set the
@@ -462,21 +460,21 @@
462 p->hasArgs = 1;
463 nParam--;
464 }
465
466 p->nParam = nParam;
467 p->azParam = (uchar **)&p[1];
468 p->anParam = (int *)&p->azParam[nParam];
469 p->azDefault = (uchar **)&p->anParam[nParam];
470 p->anDefault = (int *)&p->azDefault[nParam];
471 p->zProgram = (uchar *)&p->anDefault[nParam];
472 memcpy(p->zProgram, argv[3], argl[3]);
473 p->nProgram = argl[3];
474 zSpace = &p->zProgram[p->nProgram];
475
476 for(i=0; i<nParam; i++){
477 uchar **az;
478 int *an;
479 int n;
480 if( Th_SplitList(interp, azParam[i], anParam[i], &az, &an, &n) ){
481 goto error_out;
482 }
@@ -495,29 +493,29 @@
495 p->azDefault[i] = zSpace;
496 memcpy(zSpace, az[1], an[1]);
497 zSpace += an[1];
498 }
499
500 Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)" ", 1);
501 if( n==2 ){
502 Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)"?", 1);
503 Th_StringAppend(interp, &zUsage, &nUsage, az[0], an[0]);
504 Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)"?", 1);
505 }else{
506 Th_StringAppend(interp, &zUsage, &nUsage, az[0], an[0]);
507 }
508
509 Th_Free(interp, az);
510 }
511 assert( zSpace-(uchar *)p<=nByte );
512
513 /* If there is an "args" parameter, append it to the end of the usage
514 ** message. Set ProcDefn.zUsage to point at the usage message. It will
515 ** be freed along with the rest of the proc-definition by proc_del().
516 */
517 if( p->hasArgs ){
518 Th_StringAppend(interp, &zUsage, &nUsage, (const uchar *)" ?args...?", -1);
519 }
520 p->zUsage = zUsage;
521 p->nUsage = nUsage;
522
523 /* Register the new command with the th1 interpreter. */
@@ -543,11 +541,11 @@
543 */
544 static int rename_command(
545 Th_Interp *interp,
546 void *ctx,
547 int argc,
548 const uchar **argv,
549 int *argl
550 ){
551 if( argc!=3 ){
552 return Th_WrongNumArgs(interp, "rename oldcmd newcmd");
553 }
@@ -564,11 +562,11 @@
564 */
565 static int simple_command(
566 Th_Interp *interp,
567 void *ctx,
568 int argc,
569 const uchar **argv,
570 int *argl
571 ){
572 if( argc!=1 && argc!=2 ){
573 return Th_WrongNumArgs(interp, "return ?value?");
574 }
@@ -585,11 +583,11 @@
585 */
586 static int return_command(
587 Th_Interp *interp,
588 void *ctx,
589 int argc,
590 const uchar **argv,
591 int *argl
592 ){
593 int iCode = TH_RETURN;
594 if( argc<1 || argc>4 ){
595 return Th_WrongNumArgs(interp, "return ?-code code? ?value?");
@@ -610,14 +608,14 @@
610 ** TH Syntax:
611 **
612 ** string compare STRING1 STRING2
613 */
614 static int string_compare_command(
615 Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
616 ){
617 const uchar *zRight; int nRight;
618 const uchar *zLeft; int nLeft;
619
620 int i;
621 int iRes = 0;
622
623 if( argc!=4 ){
@@ -646,15 +644,15 @@
646 ** TH Syntax:
647 **
648 ** string first NEEDLE HAYSTACK
649 */
650 static int string_first_command(
651 Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
652 ){
653 const uchar *zNeedle;
654 int nNeedle;
655 const uchar *zHaystack;
656 int nHaystack;
657 int i;
658 int iRes;
659
660 if( argc!=4 ){
@@ -680,11 +678,11 @@
680 ** TH Syntax:
681 **
682 ** string is CLASS STRING
683 */
684 static int string_is_command(
685 Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
686 ){
687 int i;
688 int iRes = 1;
689 if( argc!=4 ){
690 return Th_WrongNumArgs(interp, "string is class string");
@@ -707,15 +705,15 @@
707 ** TH Syntax:
708 **
709 ** string last NEEDLE HAYSTACK
710 */
711 static int string_last_command(
712 Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
713 ){
714 const uchar *zNeedle;
715 int nNeedle;
716 const uchar *zHaystack;
717 int nHaystack;
718 int i;
719 int iRes;
720
721 if( argc!=4 ){
@@ -741,11 +739,11 @@
741 ** TH Syntax:
742 **
743 ** string length STRING
744 */
745 static int string_length_command(
746 Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
747 ){
748 if( argc!=3 ){
749 return Th_WrongNumArgs(interp, "string length string");
750 }
751 return Th_SetResultInt(interp, argl[2]);
@@ -755,11 +753,11 @@
755 ** TH Syntax:
756 **
757 ** string range STRING FIRST LAST
758 */
759 static int string_range_command(
760 Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
761 ){
762 int iStart;
763 int iEnd;
764
765 if( argc!=5 ){
@@ -788,16 +786,16 @@
788 ** TH Syntax:
789 **
790 ** string repeat STRING COUNT
791 */
792 static int string_repeat_command(
793 Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
794 ){
795 int n;
796 int i;
797 int nByte;
798 uchar *zByte;
799
800 if( argc!=4 ){
801 return Th_WrongNumArgs(interp, "string repeat string n");
802 }
803 if( Th_ToInt(interp, argv[3], argl[3], &n) ){
@@ -819,11 +817,11 @@
819 ** TH Syntax:
820 **
821 ** info exists VAR
822 */
823 static int info_exists_command(
824 Th_Interp *interp, void *ctx, int argc, const uchar **argv, int *argl
825 ){
826 int rc;
827
828 if( argc!=3 ){
829 return Th_WrongNumArgs(interp, "info exists var");
@@ -840,11 +838,11 @@
840 */
841 static int unset_command(
842 Th_Interp *interp,
843 void *ctx,
844 int argc,
845 const uchar **argv,
846 int *argl
847 ){
848 if( argc!=2 ){
849 return Th_WrongNumArgs(interp, "unset var");
850 }
@@ -853,17 +851,17 @@
853
854 int Th_CallSubCommand(
855 Th_Interp *interp,
856 void *ctx,
857 int argc,
858 const uchar **argv,
859 int *argl,
860 Th_SubCommand *aSub
861 ){
862 int i;
863 for(i=0; aSub[i].zName; i++){
864 uchar *zName = (uchar *)aSub[i].zName;
865 if( th_strlen(zName)==argl[1] && 0==memcmp(zName, argv[1], argl[1]) ){
866 return aSub[i].xProc(interp, ctx, argc, argv, argl);
867 }
868 }
869
@@ -884,11 +882,11 @@
884 */
885 static int string_command(
886 Th_Interp *interp,
887 void *ctx,
888 int argc,
889 const uchar **argv,
890 int *argl
891 ){
892 Th_SubCommand aSub[] = {
893 { "compare", string_compare_command },
894 { "first", string_first_command },
@@ -909,11 +907,11 @@
909 */
910 static int info_command(
911 Th_Interp *interp,
912 void *ctx,
913 int argc,
914 const uchar **argv,
915 int *argl
916 ){
917 Th_SubCommand aSub[] = {
918 { "exists", info_exists_command },
919 { 0, 0 }
@@ -928,11 +926,11 @@
928 ** frame level to *piFrame and return TH_OK. Otherwise, return TH_ERROR
929 ** and leave an error message in the interpreter result.
930 */
931 static int thToFrame(
932 Th_Interp *interp,
933 const uchar *zFrame,
934 int nFrame,
935 int *piFrame
936 ){
937 int iFrame;
938 if( th_isdigit(zFrame[0]) ){
@@ -957,11 +955,11 @@
957 */
958 static int uplevel_command(
959 Th_Interp *interp,
960 void *ctx,
961 int argc,
962 const uchar **argv,
963 int *argl
964 ){
965 int iFrame = -1;
966
967 if( argc!=2 && argc!=3 ){
@@ -980,11 +978,11 @@
980 */
981 static int upvar_command(
982 Th_Interp *interp,
983 void *ctx,
984 int argc,
985 const uchar **argv,
986 int *argl
987 ){
988 int iVar = 1;
989 int iFrame = -1;
990 int rc = TH_OK;
@@ -1013,11 +1011,11 @@
1013 */
1014 static int breakpoint_command(
1015 Th_Interp *interp,
1016 void *ctx,
1017 int argc,
1018 const uchar **argv,
1019 int *argl
1020 ){
1021 int cnt = 0;
1022 cnt++;
1023 return TH_OK;
1024
--- src/th_lang.c
+++ src/th_lang.c
@@ -12,13 +12,11 @@
12 #include "th.h"
13 #include <string.h>
14 #include <assert.h>
15
16 int Th_WrongNumArgs(Th_Interp *interp, const char *zMsg){
17 Th_ErrorMessage(interp, "wrong # args: should be \"", zMsg, -1);
 
 
18 return TH_ERROR;
19 }
20
21 /*
22 ** Syntax:
@@ -27,11 +25,11 @@
25 */
26 static int catch_command(
27 Th_Interp *interp,
28 void *ctx,
29 int argc,
30 const char **argv,
31 int *argl
32 ){
33 int rc;
34
35 if( argc!=2 && argc!=3 ){
@@ -39,11 +37,11 @@
37 }
38
39 rc = Th_Eval(interp, 0, argv[1], -1);
40 if( argc==3 ){
41 int nResult;
42 const char *zResult = Th_GetResult(interp, &nResult);
43 Th_SetVar(interp, argv[2], argl[2], zResult, nResult);
44 }
45
46 Th_SetResultInt(interp, rc);
47 return TH_OK;
@@ -56,19 +54,19 @@
54 */
55 static int if_command(
56 Th_Interp *interp,
57 void *ctx,
58 int argc,
59 const char **argv,
60 int *argl
61 ){
62 int rc = TH_OK;
63
64 int iCond; /* Result of evaluating expression */
65 int i;
66
67 const char *zResult;
68 int nResult;
69
70 if( argc<3 ){
71 goto wrong_args;
72 }
@@ -103,11 +101,11 @@
101 */
102 static int expr_command(
103 Th_Interp *interp,
104 void *ctx,
105 int argc,
106 const char **argv,
107 int *argl
108 ){
109 if( argc!=2 ){
110 return Th_WrongNumArgs(interp, "expr expression");
111 }
@@ -118,11 +116,11 @@
116 /*
117 ** Evaluate the th1 script (zBody, nBody) in the local stack frame.
118 ** Return the result of the evaluation, except if the result
119 ** is TH_CONTINUE, return TH_OK instead.
120 */
121 static int eval_loopbody(Th_Interp *interp, const char *zBody, int nBody){
122 int rc = Th_Eval(interp, 0, zBody, nBody);
123 if( rc==TH_CONTINUE ){
124 rc = TH_OK;
125 }
126 return rc;
@@ -135,11 +133,11 @@
133 */
134 static int for_command(
135 Th_Interp *interp,
136 void *ctx,
137 int argc,
138 const char **argv,
139 int *argl
140 ){
141 int rc;
142 int iCond;
143
@@ -170,14 +168,14 @@
168 */
169 static int list_command(
170 Th_Interp *interp,
171 void *ctx,
172 int argc,
173 const char **argv,
174 int *argl
175 ){
176 char *zList = 0;
177 int nList = 0;
178 int i;
179
180 for(i=1; i<argc; i++){
181 Th_ListAppend(interp, &zList, &nList, argv[i], argl[i]);
@@ -196,17 +194,17 @@
194 */
195 static int lindex_command(
196 Th_Interp *interp,
197 void *ctx,
198 int argc,
199 const char **argv,
200 int *argl
201 ){
202 int iElem;
203 int rc;
204
205 char **azElem;
206 int *anElem;
207 int nCount;
208
209 if( argc!=3 ){
210 return Th_WrongNumArgs(interp, "lindex list index");
@@ -236,11 +234,11 @@
234 */
235 static int llength_command(
236 Th_Interp *interp,
237 void *ctx,
238 int argc,
239 const char **argv,
240 int *argl
241 ){
242 int nElem;
243 int rc;
244
@@ -263,11 +261,11 @@
261 */
262 static int set_command(
263 Th_Interp *interp,
264 void *ctx,
265 int argc,
266 const char **argv,
267 int *argl
268 ){
269 if( argc!=2 && argc!=3 ){
270 return Th_WrongNumArgs(interp, "set varname ?value?");
271 }
@@ -285,18 +283,18 @@
283 ** to function proc_call1() when the new command is executed.
284 */
285 typedef struct ProcDefn ProcDefn;
286 struct ProcDefn {
287 int nParam; /* Number of formal (non "args") parameters */
288 char **azParam; /* Parameter names */
289 int *anParam; /* Lengths of parameter names */
290 char **azDefault; /* Default values */
291 int *anDefault; /* Lengths of default values */
292 int hasArgs; /* True if there is an "args" parameter */
293 char *zProgram; /* Body of proc */
294 int nProgram; /* Number of bytes at zProgram */
295 char *zUsage; /* Usage message */
296 int nUsage; /* Number of bytes at zUsage */
297 };
298
299 /* This structure is used to temporarily store arguments passed to an
300 ** invocation of a command created using [proc]. A pointer to an
@@ -303,11 +301,11 @@
301 ** instance is passed as the second argument to the proc_call2() function.
302 */
303 typedef struct ProcArgs ProcArgs;
304 struct ProcArgs {
305 int argc;
306 const char **argv;
307 int *argl;
308 };
309
310 /*
311 ** Each time a command created using [proc] is invoked, a new
@@ -327,23 +325,23 @@
325 ** not, generate a usage message for the command.
326 */
327 if( (pArgs->argc>(p->nParam+1) && !p->hasArgs)
328 || (pArgs->argc<=(p->nParam) && !p->azDefault[pArgs->argc-1])
329 ){
330 char *zUsage = 0;
331 int nUsage = 0;
332 Th_StringAppend(interp, &zUsage, &nUsage, pArgs->argv[0], pArgs->argl[0]);
333 Th_StringAppend(interp, &zUsage, &nUsage, p->zUsage, p->nUsage);
334 Th_StringAppend(interp, &zUsage, &nUsage, (const char *)"", 1);
335 Th_WrongNumArgs(interp, zUsage);
336 Th_Free(interp, zUsage);
337 return TH_ERROR;
338 }
339
340 /* Populate the formal proc parameters. */
341 for(i=0; i<p->nParam; i++){
342 const char *zVal;
343 int nVal;
344 if( pArgs->argc>(i+1) ){
345 zVal = pArgs->argv[i+1];
346 nVal = pArgs->argl[i+1];
347 }else{
@@ -353,16 +351,16 @@
351 Th_SetVar(interp, p->azParam[i], p->anParam[i], zVal, nVal);
352 }
353
354 /* Populate the "args" parameter, if it exists */
355 if( p->hasArgs ){
356 char *zArgs = 0;
357 int nArgs = 0;
358 for(i=p->nParam+1; i<pArgs->argc; i++){
359 Th_ListAppend(interp, &zArgs, &nArgs, pArgs->argv[i], pArgs->argl[i]);
360 }
361 Th_SetVar(interp, (const char *)"args", -1, zArgs, nArgs);
362 }
363
364 Th_SetResult(interp, 0, 0);
365 return Th_Eval(interp, 0, p->zProgram, p->nProgram);
366 }
@@ -374,11 +372,11 @@
372 */
373 static int proc_call1(
374 Th_Interp *interp,
375 void *pContext,
376 int argc,
377 const char **argv,
378 int *argl
379 ){
380 int rc;
381
382 ProcDefn *p = (ProcDefn *)pContext;
@@ -419,26 +417,26 @@
417 */
418 static int proc_command(
419 Th_Interp *interp,
420 void *ctx,
421 int argc,
422 const char **argv,
423 int *argl
424 ){
425 int rc;
426 char *zName;
427
428 ProcDefn *p;
429 int nByte;
430 int i;
431 char *zSpace;
432
433 char **azParam;
434 int *anParam;
435 int nParam;
436
437 char *zUsage = 0; /* Build up a usage message here */
438 int nUsage = 0; /* Number of bytes at zUsage */
439
440 if( argc!=4 ){
441 return Th_WrongNumArgs(interp, "proc name arglist code");
442 }
@@ -446,12 +444,12 @@
444 return TH_ERROR;
445 }
446
447 /* Allocate the new ProcDefn structure. */
448 nByte = sizeof(ProcDefn) + /* ProcDefn structure */
449 (sizeof(char *) + sizeof(int)) * nParam + /* azParam, anParam */
450 (sizeof(char *) + sizeof(int)) * nParam + /* azDefault, anDefault */
451 argl[3] + /* zProgram */
452 argl[2]; /* Space for copies of parameter names and default values */
453 p = (ProcDefn *)Th_Malloc(interp, nByte);
454
455 /* If the last parameter in the parameter list is "args", then set the
@@ -462,21 +460,21 @@
460 p->hasArgs = 1;
461 nParam--;
462 }
463
464 p->nParam = nParam;
465 p->azParam = (char **)&p[1];
466 p->anParam = (int *)&p->azParam[nParam];
467 p->azDefault = (char **)&p->anParam[nParam];
468 p->anDefault = (int *)&p->azDefault[nParam];
469 p->zProgram = (char *)&p->anDefault[nParam];
470 memcpy(p->zProgram, argv[3], argl[3]);
471 p->nProgram = argl[3];
472 zSpace = &p->zProgram[p->nProgram];
473
474 for(i=0; i<nParam; i++){
475 char **az;
476 int *an;
477 int n;
478 if( Th_SplitList(interp, azParam[i], anParam[i], &az, &an, &n) ){
479 goto error_out;
480 }
@@ -495,29 +493,29 @@
493 p->azDefault[i] = zSpace;
494 memcpy(zSpace, az[1], an[1]);
495 zSpace += an[1];
496 }
497
498 Th_StringAppend(interp, &zUsage, &nUsage, (const char *)" ", 1);
499 if( n==2 ){
500 Th_StringAppend(interp, &zUsage, &nUsage, (const char *)"?", 1);
501 Th_StringAppend(interp, &zUsage, &nUsage, az[0], an[0]);
502 Th_StringAppend(interp, &zUsage, &nUsage, (const char *)"?", 1);
503 }else{
504 Th_StringAppend(interp, &zUsage, &nUsage, az[0], an[0]);
505 }
506
507 Th_Free(interp, az);
508 }
509 assert( zSpace-(char *)p<=nByte );
510
511 /* If there is an "args" parameter, append it to the end of the usage
512 ** message. Set ProcDefn.zUsage to point at the usage message. It will
513 ** be freed along with the rest of the proc-definition by proc_del().
514 */
515 if( p->hasArgs ){
516 Th_StringAppend(interp, &zUsage, &nUsage, (const char *)" ?args...?", -1);
517 }
518 p->zUsage = zUsage;
519 p->nUsage = nUsage;
520
521 /* Register the new command with the th1 interpreter. */
@@ -543,11 +541,11 @@
541 */
542 static int rename_command(
543 Th_Interp *interp,
544 void *ctx,
545 int argc,
546 const char **argv,
547 int *argl
548 ){
549 if( argc!=3 ){
550 return Th_WrongNumArgs(interp, "rename oldcmd newcmd");
551 }
@@ -564,11 +562,11 @@
562 */
563 static int simple_command(
564 Th_Interp *interp,
565 void *ctx,
566 int argc,
567 const char **argv,
568 int *argl
569 ){
570 if( argc!=1 && argc!=2 ){
571 return Th_WrongNumArgs(interp, "return ?value?");
572 }
@@ -585,11 +583,11 @@
583 */
584 static int return_command(
585 Th_Interp *interp,
586 void *ctx,
587 int argc,
588 const char **argv,
589 int *argl
590 ){
591 int iCode = TH_RETURN;
592 if( argc<1 || argc>4 ){
593 return Th_WrongNumArgs(interp, "return ?-code code? ?value?");
@@ -610,14 +608,14 @@
608 ** TH Syntax:
609 **
610 ** string compare STRING1 STRING2
611 */
612 static int string_compare_command(
613 Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
614 ){
615 const char *zRight; int nRight;
616 const char *zLeft; int nLeft;
617
618 int i;
619 int iRes = 0;
620
621 if( argc!=4 ){
@@ -646,15 +644,15 @@
644 ** TH Syntax:
645 **
646 ** string first NEEDLE HAYSTACK
647 */
648 static int string_first_command(
649 Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
650 ){
651 const char *zNeedle;
652 int nNeedle;
653 const char *zHaystack;
654 int nHaystack;
655 int i;
656 int iRes;
657
658 if( argc!=4 ){
@@ -680,11 +678,11 @@
678 ** TH Syntax:
679 **
680 ** string is CLASS STRING
681 */
682 static int string_is_command(
683 Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
684 ){
685 int i;
686 int iRes = 1;
687 if( argc!=4 ){
688 return Th_WrongNumArgs(interp, "string is class string");
@@ -707,15 +705,15 @@
705 ** TH Syntax:
706 **
707 ** string last NEEDLE HAYSTACK
708 */
709 static int string_last_command(
710 Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
711 ){
712 const char *zNeedle;
713 int nNeedle;
714 const char *zHaystack;
715 int nHaystack;
716 int i;
717 int iRes;
718
719 if( argc!=4 ){
@@ -741,11 +739,11 @@
739 ** TH Syntax:
740 **
741 ** string length STRING
742 */
743 static int string_length_command(
744 Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
745 ){
746 if( argc!=3 ){
747 return Th_WrongNumArgs(interp, "string length string");
748 }
749 return Th_SetResultInt(interp, argl[2]);
@@ -755,11 +753,11 @@
753 ** TH Syntax:
754 **
755 ** string range STRING FIRST LAST
756 */
757 static int string_range_command(
758 Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
759 ){
760 int iStart;
761 int iEnd;
762
763 if( argc!=5 ){
@@ -788,16 +786,16 @@
786 ** TH Syntax:
787 **
788 ** string repeat STRING COUNT
789 */
790 static int string_repeat_command(
791 Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
792 ){
793 int n;
794 int i;
795 int nByte;
796 char *zByte;
797
798 if( argc!=4 ){
799 return Th_WrongNumArgs(interp, "string repeat string n");
800 }
801 if( Th_ToInt(interp, argv[3], argl[3], &n) ){
@@ -819,11 +817,11 @@
817 ** TH Syntax:
818 **
819 ** info exists VAR
820 */
821 static int info_exists_command(
822 Th_Interp *interp, void *ctx, int argc, const char **argv, int *argl
823 ){
824 int rc;
825
826 if( argc!=3 ){
827 return Th_WrongNumArgs(interp, "info exists var");
@@ -840,11 +838,11 @@
838 */
839 static int unset_command(
840 Th_Interp *interp,
841 void *ctx,
842 int argc,
843 const char **argv,
844 int *argl
845 ){
846 if( argc!=2 ){
847 return Th_WrongNumArgs(interp, "unset var");
848 }
@@ -853,17 +851,17 @@
851
852 int Th_CallSubCommand(
853 Th_Interp *interp,
854 void *ctx,
855 int argc,
856 const char **argv,
857 int *argl,
858 Th_SubCommand *aSub
859 ){
860 int i;
861 for(i=0; aSub[i].zName; i++){
862 char *zName = (char *)aSub[i].zName;
863 if( th_strlen(zName)==argl[1] && 0==memcmp(zName, argv[1], argl[1]) ){
864 return aSub[i].xProc(interp, ctx, argc, argv, argl);
865 }
866 }
867
@@ -884,11 +882,11 @@
882 */
883 static int string_command(
884 Th_Interp *interp,
885 void *ctx,
886 int argc,
887 const char **argv,
888 int *argl
889 ){
890 Th_SubCommand aSub[] = {
891 { "compare", string_compare_command },
892 { "first", string_first_command },
@@ -909,11 +907,11 @@
907 */
908 static int info_command(
909 Th_Interp *interp,
910 void *ctx,
911 int argc,
912 const char **argv,
913 int *argl
914 ){
915 Th_SubCommand aSub[] = {
916 { "exists", info_exists_command },
917 { 0, 0 }
@@ -928,11 +926,11 @@
926 ** frame level to *piFrame and return TH_OK. Otherwise, return TH_ERROR
927 ** and leave an error message in the interpreter result.
928 */
929 static int thToFrame(
930 Th_Interp *interp,
931 const char *zFrame,
932 int nFrame,
933 int *piFrame
934 ){
935 int iFrame;
936 if( th_isdigit(zFrame[0]) ){
@@ -957,11 +955,11 @@
955 */
956 static int uplevel_command(
957 Th_Interp *interp,
958 void *ctx,
959 int argc,
960 const char **argv,
961 int *argl
962 ){
963 int iFrame = -1;
964
965 if( argc!=2 && argc!=3 ){
@@ -980,11 +978,11 @@
978 */
979 static int upvar_command(
980 Th_Interp *interp,
981 void *ctx,
982 int argc,
983 const char **argv,
984 int *argl
985 ){
986 int iVar = 1;
987 int iFrame = -1;
988 int rc = TH_OK;
@@ -1013,11 +1011,11 @@
1011 */
1012 static int breakpoint_command(
1013 Th_Interp *interp,
1014 void *ctx,
1015 int argc,
1016 const char **argv,
1017 int *argl
1018 ){
1019 int cnt = 0;
1020 cnt++;
1021 return TH_OK;
1022
+30 -26
--- src/th_main.c
+++ src/th_main.c
@@ -65,11 +65,11 @@
6565
*/
6666
static int enableOutputCmd(
6767
Th_Interp *interp,
6868
void *p,
6969
int argc,
70
- const unsigned char **argv,
70
+ const char **argv,
7171
int *argl
7272
){
7373
if( argc!=2 ){
7474
return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
7575
}
@@ -104,11 +104,11 @@
104104
*/
105105
static int putsCmd(
106106
Th_Interp *interp,
107107
void *pConvert,
108108
int argc,
109
- const unsigned char **argv,
109
+ const char **argv,
110110
int *argl
111111
){
112112
if( argc!=2 ){
113113
return Th_WrongNumArgs(interp, "puts STRING");
114114
}
@@ -123,11 +123,11 @@
123123
*/
124124
static int wikiCmd(
125125
Th_Interp *interp,
126126
void *p,
127127
int argc,
128
- const unsigned char **argv,
128
+ const char **argv,
129129
int *argl
130130
){
131131
if( argc!=2 ){
132132
return Th_WrongNumArgs(interp, "wiki STRING");
133133
}
@@ -148,19 +148,19 @@
148148
*/
149149
static int htmlizeCmd(
150150
Th_Interp *interp,
151151
void *p,
152152
int argc,
153
- const unsigned char **argv,
153
+ const char **argv,
154154
int *argl
155155
){
156156
char *zOut;
157157
if( argc!=2 ){
158158
return Th_WrongNumArgs(interp, "htmlize STRING");
159159
}
160160
zOut = htmlize((char*)argv[1], argl[1]);
161
- Th_SetResult(interp, (unsigned char*)zOut, -1);
161
+ Th_SetResult(interp, zOut, -1);
162162
free(zOut);
163163
return TH_OK;
164164
}
165165
166166
/*
@@ -170,15 +170,15 @@
170170
*/
171171
static int dateCmd(
172172
Th_Interp *interp,
173173
void *p,
174174
int argc,
175
- const unsigned char **argv,
175
+ const char **argv,
176176
int *argl
177177
){
178178
char *zOut = db_text("??", "SELECT datetime('now')");
179
- Th_SetResult(interp, (unsigned char*)zOut, -1);
179
+ Th_SetResult(interp, zOut, -1);
180180
free(zOut);
181181
return TH_OK;
182182
}
183183
184184
/*
@@ -188,11 +188,11 @@
188188
*/
189189
static int hascapCmd(
190190
Th_Interp *interp,
191191
void *p,
192192
int argc,
193
- const unsigned char **argv,
193
+ const char **argv,
194194
int *argl
195195
){
196196
if( argc!=2 ){
197197
return Th_WrongNumArgs(interp, "hascap STRING");
198198
}
@@ -212,46 +212,50 @@
212212
*/
213213
static int comboboxCmd(
214214
Th_Interp *interp,
215215
void *p,
216216
int argc,
217
- const unsigned char **argv,
217
+ const char **argv,
218218
int *argl
219219
){
220220
if( argc!=4 ){
221221
return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES");
222222
}
223223
if( enableOutput ){
224224
int height;
225
- Blob list, elem, name;
225
+ Blob name;
226226
int nValue;
227227
const char *zValue;
228228
char *z, *zH;
229
+ int nElem;
230
+ int *aszElem;
231
+ char **azElem;
232
+ int i;
229233
230234
if( Th_ToInt(interp, argv[3], argl[3], &height) ) return TH_ERROR;
231
- blob_init(&list, (char*)argv[2], argl[2]);
235
+ Th_SplitList(interp, argv[2], argl[2], &azElem, &aszElem, &nElem);
232236
blob_init(&name, (char*)argv[1], argl[1]);
233237
zValue = Th_Fetch(blob_str(&name), &nValue);
234238
z = mprintf("<select name=\"%z\" size=\"%d\">",
235239
htmlize(blob_buffer(&name), blob_size(&name)), height);
236240
sendText(z, -1, 0);
237241
free(z);
238242
blob_reset(&name);
239
- while( blob_token(&list, &elem) ){
240
- zH = htmlize(blob_buffer(&elem), blob_size(&elem));
241
- if( zValue && blob_size(&elem)==nValue
242
- && memcmp(zValue, blob_buffer(&elem), nValue)==0 ){
243
+ for(i=0; i<nElem; i++){
244
+ zH = htmlize((char*)azElem[i], aszElem[i]);
245
+ if( zValue && aszElem[i]==nValue
246
+ && memcmp(zValue, azElem[i], nValue)==0 ){
243247
z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH);
244248
}else{
245249
z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
246250
}
247251
free(zH);
248252
sendText(z, -1, 0);
249253
free(z);
250254
}
251255
sendText("</select>", -1, 0);
252
- blob_reset(&list);
256
+ Th_Free(interp, azElem);
253257
}
254258
return TH_OK;
255259
}
256260
257261
/*
@@ -262,14 +266,14 @@
262266
*/
263267
static int linecntCmd(
264268
Th_Interp *interp,
265269
void *p,
266270
int argc,
267
- const unsigned char **argv,
271
+ const char **argv,
268272
int *argl
269273
){
270
- const uchar *z;
274
+ const char *z;
271275
int size, n, i;
272276
int iMin, iMax;
273277
if( argc!=4 ){
274278
return Th_WrongNumArgs(interp, "linecount STRING MAX MIN");
275279
}
@@ -323,20 +327,20 @@
323327
** Store a string value in a variable in the interpreter.
324328
*/
325329
void Th_Store(const char *zName, const char *zValue){
326330
Th_FossilInit();
327331
if( zValue ){
328
- Th_SetVar(g.interp, (uchar*)zName, -1, (uchar*)zValue, strlen(zValue));
332
+ Th_SetVar(g.interp, (char*)zName, -1, (char*)zValue, strlen(zValue));
329333
}
330334
}
331335
332336
/*
333337
** Unset a variable.
334338
*/
335339
void Th_Unstore(const char *zName){
336340
if( g.interp ){
337
- Th_UnsetVar(g.interp, (uchar*)zName, -1);
341
+ Th_UnsetVar(g.interp, (char*)zName, -1);
338342
}
339343
}
340344
341345
/*
342346
** Retrieve a string value from the interpreter. If no such
@@ -343,11 +347,11 @@
343347
** variable exists, return NULL.
344348
*/
345349
char *Th_Fetch(const char *zName, int *pSize){
346350
int rc;
347351
Th_FossilInit();
348
- rc = Th_GetVar(g.interp, (uchar*)zName, -1);
352
+ rc = Th_GetVar(g.interp, (char*)zName, -1);
349353
if( rc==TH_OK ){
350354
return (char*)Th_GetResult(g.interp, pSize);
351355
}else{
352356
return 0;
353357
}
@@ -421,11 +425,11 @@
421425
*/
422426
int Th_Render(const char *z){
423427
int i = 0;
424428
int n;
425429
int rc = TH_OK;
426
- uchar *zResult;
430
+ char *zResult;
427431
Th_FossilInit();
428432
while( z[i] ){
429433
if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
430434
const char *zVar;
431435
int nVar;
@@ -437,20 +441,20 @@
437441
}else{
438442
/* Variables of the form $aaa */
439443
zVar = &z[i+1];
440444
nVar = n;
441445
}
442
- rc = Th_GetVar(g.interp, (uchar*)zVar, nVar);
446
+ rc = Th_GetVar(g.interp, (char*)zVar, nVar);
443447
z += i+1+n;
444448
i = 0;
445
- zResult = (uchar*)Th_GetResult(g.interp, &n);
449
+ zResult = (char*)Th_GetResult(g.interp, &n);
446450
sendText((char*)zResult, n, n>nVar);
447451
}else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
448452
sendText(z, i, 0);
449453
z += i+5;
450454
for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
451
- rc = Th_Eval(g.interp, 0, (const uchar*)z, i);
455
+ rc = Th_Eval(g.interp, 0, (const char*)z, i);
452456
if( rc!=TH_OK ) break;
453457
z += i;
454458
if( z[0] ){ z += 6; }
455459
i = 0;
456460
}else{
@@ -457,11 +461,11 @@
457461
i++;
458462
}
459463
}
460464
if( rc==TH_ERROR ){
461465
sendText("<hr><p><font color=\"red\"><b>ERROR: ", -1, 0);
462
- zResult = (uchar*)Th_GetResult(g.interp, &n);
466
+ zResult = (char*)Th_GetResult(g.interp, &n);
463467
sendText((char*)zResult, n, 1);
464468
sendText("</b></font></p>", -1, 0);
465469
}else{
466470
sendText(z, i, 0);
467471
}
468472
--- src/th_main.c
+++ src/th_main.c
@@ -65,11 +65,11 @@
65 */
66 static int enableOutputCmd(
67 Th_Interp *interp,
68 void *p,
69 int argc,
70 const unsigned char **argv,
71 int *argl
72 ){
73 if( argc!=2 ){
74 return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
75 }
@@ -104,11 +104,11 @@
104 */
105 static int putsCmd(
106 Th_Interp *interp,
107 void *pConvert,
108 int argc,
109 const unsigned char **argv,
110 int *argl
111 ){
112 if( argc!=2 ){
113 return Th_WrongNumArgs(interp, "puts STRING");
114 }
@@ -123,11 +123,11 @@
123 */
124 static int wikiCmd(
125 Th_Interp *interp,
126 void *p,
127 int argc,
128 const unsigned char **argv,
129 int *argl
130 ){
131 if( argc!=2 ){
132 return Th_WrongNumArgs(interp, "wiki STRING");
133 }
@@ -148,19 +148,19 @@
148 */
149 static int htmlizeCmd(
150 Th_Interp *interp,
151 void *p,
152 int argc,
153 const unsigned char **argv,
154 int *argl
155 ){
156 char *zOut;
157 if( argc!=2 ){
158 return Th_WrongNumArgs(interp, "htmlize STRING");
159 }
160 zOut = htmlize((char*)argv[1], argl[1]);
161 Th_SetResult(interp, (unsigned char*)zOut, -1);
162 free(zOut);
163 return TH_OK;
164 }
165
166 /*
@@ -170,15 +170,15 @@
170 */
171 static int dateCmd(
172 Th_Interp *interp,
173 void *p,
174 int argc,
175 const unsigned char **argv,
176 int *argl
177 ){
178 char *zOut = db_text("??", "SELECT datetime('now')");
179 Th_SetResult(interp, (unsigned char*)zOut, -1);
180 free(zOut);
181 return TH_OK;
182 }
183
184 /*
@@ -188,11 +188,11 @@
188 */
189 static int hascapCmd(
190 Th_Interp *interp,
191 void *p,
192 int argc,
193 const unsigned char **argv,
194 int *argl
195 ){
196 if( argc!=2 ){
197 return Th_WrongNumArgs(interp, "hascap STRING");
198 }
@@ -212,46 +212,50 @@
212 */
213 static int comboboxCmd(
214 Th_Interp *interp,
215 void *p,
216 int argc,
217 const unsigned char **argv,
218 int *argl
219 ){
220 if( argc!=4 ){
221 return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES");
222 }
223 if( enableOutput ){
224 int height;
225 Blob list, elem, name;
226 int nValue;
227 const char *zValue;
228 char *z, *zH;
 
 
 
 
229
230 if( Th_ToInt(interp, argv[3], argl[3], &height) ) return TH_ERROR;
231 blob_init(&list, (char*)argv[2], argl[2]);
232 blob_init(&name, (char*)argv[1], argl[1]);
233 zValue = Th_Fetch(blob_str(&name), &nValue);
234 z = mprintf("<select name=\"%z\" size=\"%d\">",
235 htmlize(blob_buffer(&name), blob_size(&name)), height);
236 sendText(z, -1, 0);
237 free(z);
238 blob_reset(&name);
239 while( blob_token(&list, &elem) ){
240 zH = htmlize(blob_buffer(&elem), blob_size(&elem));
241 if( zValue && blob_size(&elem)==nValue
242 && memcmp(zValue, blob_buffer(&elem), nValue)==0 ){
243 z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH);
244 }else{
245 z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
246 }
247 free(zH);
248 sendText(z, -1, 0);
249 free(z);
250 }
251 sendText("</select>", -1, 0);
252 blob_reset(&list);
253 }
254 return TH_OK;
255 }
256
257 /*
@@ -262,14 +266,14 @@
262 */
263 static int linecntCmd(
264 Th_Interp *interp,
265 void *p,
266 int argc,
267 const unsigned char **argv,
268 int *argl
269 ){
270 const uchar *z;
271 int size, n, i;
272 int iMin, iMax;
273 if( argc!=4 ){
274 return Th_WrongNumArgs(interp, "linecount STRING MAX MIN");
275 }
@@ -323,20 +327,20 @@
323 ** Store a string value in a variable in the interpreter.
324 */
325 void Th_Store(const char *zName, const char *zValue){
326 Th_FossilInit();
327 if( zValue ){
328 Th_SetVar(g.interp, (uchar*)zName, -1, (uchar*)zValue, strlen(zValue));
329 }
330 }
331
332 /*
333 ** Unset a variable.
334 */
335 void Th_Unstore(const char *zName){
336 if( g.interp ){
337 Th_UnsetVar(g.interp, (uchar*)zName, -1);
338 }
339 }
340
341 /*
342 ** Retrieve a string value from the interpreter. If no such
@@ -343,11 +347,11 @@
343 ** variable exists, return NULL.
344 */
345 char *Th_Fetch(const char *zName, int *pSize){
346 int rc;
347 Th_FossilInit();
348 rc = Th_GetVar(g.interp, (uchar*)zName, -1);
349 if( rc==TH_OK ){
350 return (char*)Th_GetResult(g.interp, pSize);
351 }else{
352 return 0;
353 }
@@ -421,11 +425,11 @@
421 */
422 int Th_Render(const char *z){
423 int i = 0;
424 int n;
425 int rc = TH_OK;
426 uchar *zResult;
427 Th_FossilInit();
428 while( z[i] ){
429 if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
430 const char *zVar;
431 int nVar;
@@ -437,20 +441,20 @@
437 }else{
438 /* Variables of the form $aaa */
439 zVar = &z[i+1];
440 nVar = n;
441 }
442 rc = Th_GetVar(g.interp, (uchar*)zVar, nVar);
443 z += i+1+n;
444 i = 0;
445 zResult = (uchar*)Th_GetResult(g.interp, &n);
446 sendText((char*)zResult, n, n>nVar);
447 }else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
448 sendText(z, i, 0);
449 z += i+5;
450 for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
451 rc = Th_Eval(g.interp, 0, (const uchar*)z, i);
452 if( rc!=TH_OK ) break;
453 z += i;
454 if( z[0] ){ z += 6; }
455 i = 0;
456 }else{
@@ -457,11 +461,11 @@
457 i++;
458 }
459 }
460 if( rc==TH_ERROR ){
461 sendText("<hr><p><font color=\"red\"><b>ERROR: ", -1, 0);
462 zResult = (uchar*)Th_GetResult(g.interp, &n);
463 sendText((char*)zResult, n, 1);
464 sendText("</b></font></p>", -1, 0);
465 }else{
466 sendText(z, i, 0);
467 }
468
--- src/th_main.c
+++ src/th_main.c
@@ -65,11 +65,11 @@
65 */
66 static int enableOutputCmd(
67 Th_Interp *interp,
68 void *p,
69 int argc,
70 const char **argv,
71 int *argl
72 ){
73 if( argc!=2 ){
74 return Th_WrongNumArgs(interp, "enable_output BOOLEAN");
75 }
@@ -104,11 +104,11 @@
104 */
105 static int putsCmd(
106 Th_Interp *interp,
107 void *pConvert,
108 int argc,
109 const char **argv,
110 int *argl
111 ){
112 if( argc!=2 ){
113 return Th_WrongNumArgs(interp, "puts STRING");
114 }
@@ -123,11 +123,11 @@
123 */
124 static int wikiCmd(
125 Th_Interp *interp,
126 void *p,
127 int argc,
128 const char **argv,
129 int *argl
130 ){
131 if( argc!=2 ){
132 return Th_WrongNumArgs(interp, "wiki STRING");
133 }
@@ -148,19 +148,19 @@
148 */
149 static int htmlizeCmd(
150 Th_Interp *interp,
151 void *p,
152 int argc,
153 const char **argv,
154 int *argl
155 ){
156 char *zOut;
157 if( argc!=2 ){
158 return Th_WrongNumArgs(interp, "htmlize STRING");
159 }
160 zOut = htmlize((char*)argv[1], argl[1]);
161 Th_SetResult(interp, zOut, -1);
162 free(zOut);
163 return TH_OK;
164 }
165
166 /*
@@ -170,15 +170,15 @@
170 */
171 static int dateCmd(
172 Th_Interp *interp,
173 void *p,
174 int argc,
175 const char **argv,
176 int *argl
177 ){
178 char *zOut = db_text("??", "SELECT datetime('now')");
179 Th_SetResult(interp, zOut, -1);
180 free(zOut);
181 return TH_OK;
182 }
183
184 /*
@@ -188,11 +188,11 @@
188 */
189 static int hascapCmd(
190 Th_Interp *interp,
191 void *p,
192 int argc,
193 const char **argv,
194 int *argl
195 ){
196 if( argc!=2 ){
197 return Th_WrongNumArgs(interp, "hascap STRING");
198 }
@@ -212,46 +212,50 @@
212 */
213 static int comboboxCmd(
214 Th_Interp *interp,
215 void *p,
216 int argc,
217 const char **argv,
218 int *argl
219 ){
220 if( argc!=4 ){
221 return Th_WrongNumArgs(interp, "combobox NAME TEXT-LIST NUMLINES");
222 }
223 if( enableOutput ){
224 int height;
225 Blob name;
226 int nValue;
227 const char *zValue;
228 char *z, *zH;
229 int nElem;
230 int *aszElem;
231 char **azElem;
232 int i;
233
234 if( Th_ToInt(interp, argv[3], argl[3], &height) ) return TH_ERROR;
235 Th_SplitList(interp, argv[2], argl[2], &azElem, &aszElem, &nElem);
236 blob_init(&name, (char*)argv[1], argl[1]);
237 zValue = Th_Fetch(blob_str(&name), &nValue);
238 z = mprintf("<select name=\"%z\" size=\"%d\">",
239 htmlize(blob_buffer(&name), blob_size(&name)), height);
240 sendText(z, -1, 0);
241 free(z);
242 blob_reset(&name);
243 for(i=0; i<nElem; i++){
244 zH = htmlize((char*)azElem[i], aszElem[i]);
245 if( zValue && aszElem[i]==nValue
246 && memcmp(zValue, azElem[i], nValue)==0 ){
247 z = mprintf("<option value=\"%s\" selected>%s</option>", zH, zH);
248 }else{
249 z = mprintf("<option value=\"%s\">%s</option>", zH, zH);
250 }
251 free(zH);
252 sendText(z, -1, 0);
253 free(z);
254 }
255 sendText("</select>", -1, 0);
256 Th_Free(interp, azElem);
257 }
258 return TH_OK;
259 }
260
261 /*
@@ -262,14 +266,14 @@
266 */
267 static int linecntCmd(
268 Th_Interp *interp,
269 void *p,
270 int argc,
271 const char **argv,
272 int *argl
273 ){
274 const char *z;
275 int size, n, i;
276 int iMin, iMax;
277 if( argc!=4 ){
278 return Th_WrongNumArgs(interp, "linecount STRING MAX MIN");
279 }
@@ -323,20 +327,20 @@
327 ** Store a string value in a variable in the interpreter.
328 */
329 void Th_Store(const char *zName, const char *zValue){
330 Th_FossilInit();
331 if( zValue ){
332 Th_SetVar(g.interp, (char*)zName, -1, (char*)zValue, strlen(zValue));
333 }
334 }
335
336 /*
337 ** Unset a variable.
338 */
339 void Th_Unstore(const char *zName){
340 if( g.interp ){
341 Th_UnsetVar(g.interp, (char*)zName, -1);
342 }
343 }
344
345 /*
346 ** Retrieve a string value from the interpreter. If no such
@@ -343,11 +347,11 @@
347 ** variable exists, return NULL.
348 */
349 char *Th_Fetch(const char *zName, int *pSize){
350 int rc;
351 Th_FossilInit();
352 rc = Th_GetVar(g.interp, (char*)zName, -1);
353 if( rc==TH_OK ){
354 return (char*)Th_GetResult(g.interp, pSize);
355 }else{
356 return 0;
357 }
@@ -421,11 +425,11 @@
425 */
426 int Th_Render(const char *z){
427 int i = 0;
428 int n;
429 int rc = TH_OK;
430 char *zResult;
431 Th_FossilInit();
432 while( z[i] ){
433 if( z[i]=='$' && (n = validVarName(&z[i+1]))>0 ){
434 const char *zVar;
435 int nVar;
@@ -437,20 +441,20 @@
441 }else{
442 /* Variables of the form $aaa */
443 zVar = &z[i+1];
444 nVar = n;
445 }
446 rc = Th_GetVar(g.interp, (char*)zVar, nVar);
447 z += i+1+n;
448 i = 0;
449 zResult = (char*)Th_GetResult(g.interp, &n);
450 sendText((char*)zResult, n, n>nVar);
451 }else if( z[i]=='<' && isBeginScriptTag(&z[i]) ){
452 sendText(z, i, 0);
453 z += i+5;
454 for(i=0; z[i] && (z[i]!='<' || !isEndScriptTag(&z[i])); i++){}
455 rc = Th_Eval(g.interp, 0, (const char*)z, i);
456 if( rc!=TH_OK ) break;
457 z += i;
458 if( z[0] ){ z += 6; }
459 i = 0;
460 }else{
@@ -457,11 +461,11 @@
461 i++;
462 }
463 }
464 if( rc==TH_ERROR ){
465 sendText("<hr><p><font color=\"red\"><b>ERROR: ", -1, 0);
466 zResult = (char*)Th_GetResult(g.interp, &n);
467 sendText((char*)zResult, n, 1);
468 sendText("</b></font></p>", -1, 0);
469 }else{
470 sendText(z, i, 0);
471 }
472
+1 -1
--- src/tkt.c
+++ src/tkt.c
@@ -270,11 +270,11 @@
270270
*/
271271
void ticket_init(void){
272272
const char *zConfig;
273273
Th_FossilInit();
274274
zConfig = ticket_common_code();
275
- Th_Eval(g.interp, 0, (const uchar*)zConfig, -1);
275
+ Th_Eval(g.interp, 0, zConfig, -1);
276276
}
277277
278278
/*
279279
** Recreate the ticket table.
280280
*/
281281
--- src/tkt.c
+++ src/tkt.c
@@ -270,11 +270,11 @@
270 */
271 void ticket_init(void){
272 const char *zConfig;
273 Th_FossilInit();
274 zConfig = ticket_common_code();
275 Th_Eval(g.interp, 0, (const uchar*)zConfig, -1);
276 }
277
278 /*
279 ** Recreate the ticket table.
280 */
281
--- src/tkt.c
+++ src/tkt.c
@@ -270,11 +270,11 @@
270 */
271 void ticket_init(void){
272 const char *zConfig;
273 Th_FossilInit();
274 zConfig = ticket_common_code();
275 Th_Eval(g.interp, 0, zConfig, -1);
276 }
277
278 /*
279 ** Recreate the ticket table.
280 */
281

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button