1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
/*
** The implementation of the TH core. This file contains the parser, and
** the implementation of the interface in th.h.
*/
#include "th.h"
#include <string.h>
#include <assert.h>
#include <stdio.h> /* FILE class */
/*
** Th_Output_f() impl which redirects output to a Th_Ob_Manager.
*/
static int Th_Output_f_ob( char const * zData, int len, void * pState );
/*
** Th_Output::dispose() impl which requires pState to be-a Th_Ob_Manager.
*/
static void Th_Output_dispose_ob( void * pState );
typedef struct Th_Command Th_Command;
typedef struct Th_Frame Th_Frame;
typedef struct Th_Variable Th_Variable;
/*
** Shared instance. See th.h for the docs.
*/
const Th_Vtab_OutputMethods Th_Vtab_OutputMethods_FILE = {
Th_Output_f_FILE /* write() */,
Th_Output_dispose_FILE /* dispose() */,
NULL /*pState*/,
1/*enabled*/
};
/*
** Holds client-provided "garbage collected" data for
|
<
<
<
<
<
<
<
<
<
<
|
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
/*
** The implementation of the TH core. This file contains the parser, and
** the implementation of the interface in th.h.
*/
#include "th.h"
#include <string.h>
#include <assert.h>
#include <stdio.h> /* FILE class */
typedef struct Th_Command Th_Command;
typedef struct Th_Frame Th_Frame;
typedef struct Th_Variable Th_Variable;
/*
** Shared instance. See th.h for the docs.
*/
const Th_Vtab_OutputMethods Th_Vtab_OutputMethods_FILE = {
Th_Output_f_FILE /* xWrite() */,
Th_Output_dispose_FILE /* dispose() */,
NULL /*pState*/,
1/*enabled*/
};
/*
** Holds client-provided "garbage collected" data for
|
| ︙ | | | ︙ | |
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
|
void *Th_Realloc(Th_Interp *pInterp, void *z, int nByte){
void *p = pInterp->pVtab->xRealloc(z, nByte);
return p;
}
int Th_Vtab_Output( Th_Vtab *vTab, char const * zData, int nData ){
if(!vTab->out.write){
return -1;
}else if(!vTab->out.enabled){
return 0;
}else{
return vTab->out.write( zData, nData, vTab->out.pState );
}
}
int Th_Output( Th_Interp *pInterp, char const * zData, int nData ){
return Th_Vtab_Output( pInterp->pVtab, zData, nData );
}
|
|
|
|
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
|
void *Th_Realloc(Th_Interp *pInterp, void *z, int nByte){
void *p = pInterp->pVtab->xRealloc(z, nByte);
return p;
}
int Th_Vtab_Output( Th_Vtab *vTab, char const * zData, int nData ){
if(!vTab->out.xWrite){
return -1;
}else if(!vTab->out.enabled){
return 0;
}else{
return vTab->out.xWrite( zData, nData, vTab->out.pState );
}
}
int Th_Output( Th_Interp *pInterp, char const * zData, int nData ){
return Th_Vtab_Output( pInterp->pVtab, zData, nData );
}
|
| ︙ | | | ︙ | |
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
|
if( interp->paGc ){
Th_HashIterate(interp, interp->paGc, thFreeGc, (void *)interp);
Th_HashDelete(interp, interp->paGc);
interp->paGc = NULL;
}
/* Clean up the output abstraction. */
if( interp->pVtab && interp->pVtab->out.dispose ){
interp->pVtab->out.dispose( interp->pVtab->out.pState );
}
/* Delete the contents of the global frame. */
thPopFrame(interp);
/* Delete any result currently stored in the interpreter. */
Th_SetResult(interp, 0, 0);
|
|
|
|
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
|
if( interp->paGc ){
Th_HashIterate(interp, interp->paGc, thFreeGc, (void *)interp);
Th_HashDelete(interp, interp->paGc);
interp->paGc = NULL;
}
/* Clean up the output abstraction. */
if( interp->pVtab && interp->pVtab->out.xDispose ){
interp->pVtab->out.xDispose( interp->pVtab->out.pState );
}
/* Delete the contents of the global frame. */
thPopFrame(interp);
/* Delete any result currently stored in the interpreter. */
Th_SetResult(interp, 0, 0);
|
| ︙ | | | ︙ | |
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
|
/* Reminder: the ob code "really" belongs in th_lang.c or th_main.c,
but it needs access to Th_Interp::pVtab in order to swap out
Th_Vtab_OutputMethods parts for purposes of stacking layers of
buffers. We could add access to it via the public interface,
but that didn't seem appropriate.
*/
/* Empty-initialized Th_Ob_Manager instance. */
#define Th_Ob_Man_empty_m { \
NULL/*aBuf*/, \
0/*nBuf*/, \
-1/*cursor*/, \
NULL/*interp*/, \
|
>
>
>
>
>
>
>
>
>
>
|
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
|
/* Reminder: the ob code "really" belongs in th_lang.c or th_main.c,
but it needs access to Th_Interp::pVtab in order to swap out
Th_Vtab_OutputMethods parts for purposes of stacking layers of
buffers. We could add access to it via the public interface,
but that didn't seem appropriate.
*/
/*
** Th_Output_f() impl which redirects output to a Th_Ob_Manager.
** Requires that pState be a (Th_Ob_Man*).
*/
static int Th_Output_f_ob( char const * zData, int len, void * pState );
/*
** Th_Output::dispose() impl which requires pState to be-a Th_Ob_Manager.
*/
static void Th_Output_dispose_ob( void * pState );
/* Empty-initialized Th_Ob_Manager instance. */
#define Th_Ob_Man_empty_m { \
NULL/*aBuf*/, \
0/*nBuf*/, \
-1/*cursor*/, \
NULL/*interp*/, \
|
| ︙ | | | ︙ | |
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
|
Blob * b = Th_Ob_GetCurrentBuffer( pMan );
assert( NULL != pMan );
assert( b );
blob_append( b, zData, len );
return len;
}
static void Th_Output_dispose_ob( void * pState ){
/* possible todo: move the cleanup logic from
Th_Ob_Pop() to here? */
#if 0
Th_Ob_Manager * pMan = (Th_Ob_Manager*)pState;
Blob * b = Th_Ob_GetCurrentBuffer( pMan );
assert( NULL != pMan );
assert( b );
|
|
|
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
|
Blob * b = Th_Ob_GetCurrentBuffer( pMan );
assert( NULL != pMan );
assert( b );
blob_append( b, zData, len );
return len;
}
void Th_Output_dispose_ob( void * pState ){
/* possible todo: move the cleanup logic from
Th_Ob_Pop() to here? */
#if 0
Th_Ob_Manager * pMan = (Th_Ob_Manager*)pState;
Blob * b = Th_Ob_GetCurrentBuffer( pMan );
assert( NULL != pMan );
assert( b );
|
| ︙ | | | ︙ | |
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
|
}else{
Blob * rc;
Th_Vtab_OutputMethods * theOut;
assert( pMan->nBuf > pMan->cursor );
rc = pMan->aBuf[pMan->cursor];
pMan->aBuf[pMan->cursor] = NULL;
theOut = &pMan->aOutput[pMan->cursor];
if( theOut->dispose ){
theOut->dispose( theOut->pState );
}
pMan->interp->pVtab->out = *theOut;
pMan->aOutput[pMan->cursor] = Th_Vtab_OutputMethods_empty;
if(-1 == --pMan->cursor){
Th_Interp * interp = pMan->interp;
Th_Free( pMan->interp, pMan->aBuf );
Th_Free( pMan->interp, pMan->aOutput );
*pMan = Th_Ob_Man_empty;
|
>
>
>
>
>
>
>
|
|
>
|
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
|
}else{
Blob * rc;
Th_Vtab_OutputMethods * theOut;
assert( pMan->nBuf > pMan->cursor );
rc = pMan->aBuf[pMan->cursor];
pMan->aBuf[pMan->cursor] = NULL;
theOut = &pMan->aOutput[pMan->cursor];
#if 0
/* We need something like this (but not this!) if we extend the
support to use other (non-Blob) proxies. We will likely need
another callback function or two for that case, e.g. xStart()
and xEnd(), which would be called when they are pushed/popped
to/from the stack.
*/
if( theOut->xDispose ){
theOut->xDispose( theOut->pState );
}
#endif
pMan->interp->pVtab->out = *theOut;
pMan->aOutput[pMan->cursor] = Th_Vtab_OutputMethods_empty;
if(-1 == --pMan->cursor){
Th_Interp * interp = pMan->interp;
Th_Free( pMan->interp, pMan->aBuf );
Th_Free( pMan->interp, pMan->aOutput );
*pMan = Th_Ob_Man_empty;
|
| ︙ | | | ︙ | |