Fossil

Diff
Login

Differences From Artifact [4abae97ee0]:

To Artifact [ac5baa6da5]:


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;