Fossil

Check-in [495f26a0]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:More minor internal consistency cleanups.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | th1-query-api
Files: files | file ages | folders
SHA1: 495f26a00eb7e4a5c2722a7583c7251197c0b382
User & Date: stephan 2012-07-16 19:21:43.526
Context
2012-07-16
19:35
Removed 2x extraneous #include "th.h". ... (check-in: 27dc9b0b user: stephan tags: th1-query-api)
19:21
More minor internal consistency cleanups. ... (check-in: 495f26a0 user: stephan tags: th1-query-api)
18:56
Cleanups requested by DRH, plus some incidental consistency/maintenance-related cleanups found along the way. ... (check-in: c25a5d19 user: stephan tags: th1-query-api)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/th.c.
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;
Changes to src/th.h.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
** This structure defines the output state associated with a
** Th_Vtab. It is intended that a given Vtab be able to swap out
** output back-ends during its lifetime, e.g. to form a stack of
** buffers.
*/
struct Th_Vtab_OutputMethods {
  Th_Output_f write;   /* output handler */
    void (*dispose)( void * pState ); /* Called when the framework is done with
                                         this output handler,passed this object's
                                         pState pointer.. */
  void * pState;   /* final argument for write() and dispose()*/
  char enabled;    /* if 0, Th_Output() does nothing. */
};
typedef struct Th_Vtab_OutputMethods Th_Vtab_OutputMethods;

/*
** Shared Th_Vtab_OutputMethods instance used for copy-initialization. This
** implementation uses Th_Output_f_FILE as its write() impl and







|
|


|







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
/*
** This structure defines the output state associated with a
** Th_Vtab. It is intended that a given Vtab be able to swap out
** output back-ends during its lifetime, e.g. to form a stack of
** buffers.
*/
struct Th_Vtab_OutputMethods {
  Th_Output_f xWrite;   /* output handler */
    void (*xDispose)( void * pState ); /* Called when the framework is done with
                                         this output handler,passed this object's
                                         pState pointer.. */
  void * pState;   /* final argument for xWrite() and xDispose()*/
  char enabled;    /* if 0, Th_Output() does nothing. */
};
typedef struct Th_Vtab_OutputMethods Th_Vtab_OutputMethods;

/*
** Shared Th_Vtab_OutputMethods instance used for copy-initialization. This
** implementation uses Th_Output_f_FILE as its write() impl and
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
** Opaque handle for interpeter.
*/
typedef struct Th_Interp Th_Interp;


/* 
** Creates a new interpreter instance using the given v-table. pVtab
** must outlive the returned object, and pVtab->out.dispose() will be
** called when the interpreter is cleaned up. The optional "ob" API
** swaps out Vtab::out instances, so pVtab->out might not be active
** for the entire lifetime of the interpreter.
**
** Potential TODO: we "should probably" add a dispose() method to the
** Th_Vtab interface.
*/







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
** Opaque handle for interpeter.
*/
typedef struct Th_Interp Th_Interp;


/* 
** Creates a new interpreter instance using the given v-table. pVtab
** must outlive the returned object, and pVtab->out.xDispose() will be
** called when the interpreter is cleaned up. The optional "ob" API
** swaps out Vtab::out instances, so pVtab->out might not be active
** for the entire lifetime of the interpreter.
**
** Potential TODO: we "should probably" add a dispose() method to the
** Th_Vtab interface.
*/
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
** A Th_Output_f() implementation which sends its output to either
** pState (which must be NULL or a (FILE*)) or stdout (if pState is
** NULL).
*/
int Th_Output_f_FILE( char const * zData, int len, void * pState );

/*
** A Th_Vtab_OutputMethods::dispose() impl for FILE handles. If pState is not
** one of the standard streams (stdin, stdout, stderr) then it is
** fclose()d.
*/
void Th_Output_dispose_FILE( void * pState );

/*
** A helper type for holding lists of function registration information.
** For use with Th_RegisterCommands().
*/







|

|







369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
** A Th_Output_f() implementation which sends its output to either
** pState (which must be NULL or a (FILE*)) or stdout (if pState is
** NULL).
*/
int Th_Output_f_FILE( char const * zData, int len, void * pState );

/*
** A Th_Vtab_OutputMethods::xDispose() impl for FILE handles. If pState is not
** one of the standard streams (stdin, stdout, stderr) then it is
** fclose()d by this call.
*/
void Th_Output_dispose_FILE( void * pState );

/*
** A helper type for holding lists of function registration information.
** For use with Th_RegisterCommands().
*/
442
443
444
445
446
447
448
449





450
451
452
453
454
455
456
** have a NULL zName field (that is the end-of-list marker).
** Returns TH_OK on success, "something else" on error.
*/
int Th_RegisterCommands( Th_Interp * interp, Th_Command_Reg const * pList );

#ifdef TH_ENABLE_OB
/*
** Output buffer stack manager for TH. Used/managed by the Th_ob_xxx() functions.





*/
struct Th_Ob_Manager {
  Blob ** aBuf;        /* Stack of Blobs */
  int nBuf;            /* Number of blobs */
  int cursor;          /* Current level (-1=not active) */
  Th_Interp * interp;  /* The associated interpreter */
  Th_Vtab_OutputMethods * aOutput







|
>
>
>
>
>







442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
** have a NULL zName field (that is the end-of-list marker).
** Returns TH_OK on success, "something else" on error.
*/
int Th_RegisterCommands( Th_Interp * interp, Th_Command_Reg const * pList );

#ifdef TH_ENABLE_OB
/*
** Output buffer stack manager for TH. Used/managed by the Th_ob_xxx()
** functions. This class manages Th_Interp::pVtab->out for a specific
** interpreter, swapping it in and out in order to redirect output
** generated via Th_Output() to internal buffers. The buffers can be
** pushed and popped from the stack, allowing clients to selectively
** capture output for a given block of TH1 code.
*/
struct Th_Ob_Manager {
  Blob ** aBuf;        /* Stack of Blobs */
  int nBuf;            /* Number of blobs */
  int cursor;          /* Current level (-1=not active) */
  Th_Interp * interp;  /* The associated interpreter */
  Th_Vtab_OutputMethods * aOutput
Changes to src/th_main.c.
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
    {"wiki",          wikiCmd,              0},

    {0, 0, 0}
  };
  if( g.interp==0 ){
    int i;
    if(g.cgiOutput){
      vtab.out.write = Th_Output_f_cgi_content;
    }else{
      vtab.out = Th_Vtab_OutputMethods_FILE;
      vtab.out.pState = stdout;
    }
    vtab.out.enabled = enableOutput;
    g.interp = Th_CreateInterp(&vtab);
    th_register_language(g.interp);       /* Basic scripting commands. */







|







2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
    {"wiki",          wikiCmd,              0},

    {0, 0, 0}
  };
  if( g.interp==0 ){
    int i;
    if(g.cgiOutput){
      vtab.out.xWrite = Th_Output_f_cgi_content;
    }else{
      vtab.out = Th_Vtab_OutputMethods_FILE;
      vtab.out.pState = stdout;
    }
    vtab.out.enabled = enableOutput;
    g.interp = Th_CreateInterp(&vtab);
    th_register_language(g.interp);       /* Basic scripting commands. */