Fossil

Check-in [d9e0ee2f]
Login

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

Overview
Comment:Refactord ob api to only swap out the Vtab output state, as opposed to the whole Vtab state (which includes the allocator).
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | th1-query-api
Files: files | file ages | folders
SHA1: d9e0ee2f1e23408c91189f6af54e6774eabcd487
User & Date: stephan 2012-07-15 11:16:04.745
Context
2012-07-15
12:27
Refactored th1/sqlite bits to use Th_Data_Get/Set(), removed sqlite data from Th_Interp class. Other minor cleanups. ... (check-in: 3167ff33 user: stephan tags: th1-query-api)
11:16
Refactord ob api to only swap out the Vtab output state, as opposed to the whole Vtab state (which includes the allocator). ... (check-in: d9e0ee2f user: stephan tags: th1-query-api)
11:04
minor doc additions. ... (check-in: 236cf135 user: stephan tags: th1-query-api)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/th.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifdef TH_USE_OUTBUF
#endif

extern void *fossil_realloc(void *p, size_t n);
static void * th_fossil_realloc(void *p, unsigned int n){
  return fossil_realloc( p, n );
}

typedef struct Th_Command   Th_Command;
typedef struct Th_Frame     Th_Frame;
typedef struct Th_Variable  Th_Variable;

/*
** Holds client-provided "garbage collected" data for
** a Th_Interp instance.







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#ifdef TH_USE_OUTBUF
#endif

extern void *fossil_realloc(void *p, size_t n);
static void * th_fossil_realloc(void *p, unsigned int n){
  return fossil_realloc( p, n );
}
static int Th_output_f_ob( char const * zData, int len, void * pState );
typedef struct Th_Command   Th_Command;
typedef struct Th_Frame     Th_Frame;
typedef struct Th_Variable  Th_Variable;

/*
** Holds client-provided "garbage collected" data for
** a Th_Interp instance.
2825
2826
2827
2828
2829
2830
2831
2832










2833
2834
2835


2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
   of buffers.
*/
#define Th_Ob_Man_empty_m { \
  NULL/*aBuf*/,           \
  0/*nBuf*/,            \
  -1/*cursor*/,       \
  NULL/*interp*/,     \
  NULL/*aVtab*/       \










}
static const Th_Ob_Man Th_Ob_Man_empty = Th_Ob_Man_empty_m;
static Th_Ob_Man Th_Ob_Man_instance = Th_Ob_Man_empty_m;


#define Th_Ob_Man_KEY "Th_Ob_Man"
Th_Ob_Man * Th_ob_manager(Th_Interp *interp){
  void * rc = Th_Data_Get(interp, Th_Ob_Man_KEY );
  return rc
    ? ((Th_GcEntry*)rc)->pData
    : NULL;
}


Blob * Th_ob_current( Th_Ob_Man * pMan ){
  return pMan->nBuf>0 ? pMan->aBuf[pMan->cursor] : 0;
}


/*
** Th_output_f() impl which expects pState to be (Th_Ob_Man*).
** (zData,len) are appended to pState's current output buffer.
*/
static int Th_output_f_ob( char const * zData, int len, void * pState ){
  Th_Ob_Man * pMan = (Th_Ob_Man*)pState;
  Blob * b = Th_ob_current( pMan );
  assert( NULL != pMan );
  assert( b );
  blob_append( b, zData, len );
  return len;
}







|
>
>
>
>
>
>
>
>
>
>



>
>


















|







2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
   of buffers.
*/
#define Th_Ob_Man_empty_m { \
  NULL/*aBuf*/,           \
  0/*nBuf*/,            \
  -1/*cursor*/,       \
  NULL/*interp*/,     \
  NULL/*aOutput*/       \
}
#define Th_Vtab_Output_empty_m { \
  Th_output_f_ob /*f*/, \
  NULL /*pState*/,\
  1/*enabled*/\
}
#define Th_Vtab_Output_ob_m {                \
  Th_output_f_ob /*f*/, \
  NULL /*pState*/,\
  1/*enabled*/\
}
static const Th_Ob_Man Th_Ob_Man_empty = Th_Ob_Man_empty_m;
static Th_Ob_Man Th_Ob_Man_instance = Th_Ob_Man_empty_m;
static Th_Vtab_Output Th_Vtab_Output_ob = Th_Vtab_Output_ob_m;
static Th_Vtab_Output Th_Vtab_Output_empty = Th_Vtab_Output_empty_m;
#define Th_Ob_Man_KEY "Th_Ob_Man"
Th_Ob_Man * Th_ob_manager(Th_Interp *interp){
  void * rc = Th_Data_Get(interp, Th_Ob_Man_KEY );
  return rc
    ? ((Th_GcEntry*)rc)->pData
    : NULL;
}


Blob * Th_ob_current( Th_Ob_Man * pMan ){
  return pMan->nBuf>0 ? pMan->aBuf[pMan->cursor] : 0;
}


/*
** Th_output_f() impl which expects pState to be (Th_Ob_Man*).
** (zData,len) are appended to pState's current output buffer.
*/
int Th_output_f_ob( char const * zData, int len, void * pState ){
  Th_Ob_Man * pMan = (Th_Ob_Man*)pState;
  Blob * b = Th_ob_current( pMan );
  assert( NULL != pMan );
  assert( b );
  blob_append( b, zData, len );
  return len;
}
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
      x = pMan->cursor + 5;
    }
    void * re = Th_Realloc( pMan->interp, pMan->aBuf, x * sizeof(Blob*) );
    if(NULL==re){
      goto error;
    }
    pMan->aBuf = (Blob **)re;
    re = Th_Realloc( pMan->interp, pMan->aVtab, x * sizeof(Th_Vtab*) );
    if(NULL==re){
      goto error;
    }
    pMan->aVtab = (Th_Vtab**)re;
    for( i = pMan->nBuf; i < x; ++i ){
      pMan->aVtab[i] = NULL;
      pMan->aBuf[i] = NULL;
    }
    pMan->nBuf = x;
  }
  assert( pMan->nBuf > pMan->cursor );
  assert( pMan->cursor >= -1 );
  ++pMan->cursor;
  pMan->aBuf[pMan->cursor] = pBlob;
  pMan->aVtab[pMan->cursor] = pMan->interp->pVtab;
  pMan->interp->pVtab = &Th_Vtab_Ob;
  Th_Vtab_Ob.out.pState = pMan;
  if( pOut ){
    *pOut = pBlob;
  }
  return TH_OK;
  error:
  if( pBlob ){
    Th_Free( pMan->interp, pBlob );







|



|

|








|
|
|







2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
      x = pMan->cursor + 5;
    }
    void * re = Th_Realloc( pMan->interp, pMan->aBuf, x * sizeof(Blob*) );
    if(NULL==re){
      goto error;
    }
    pMan->aBuf = (Blob **)re;
    re = Th_Realloc( pMan->interp, pMan->aOutput, x * sizeof(Th_Vtab_Output) );
    if(NULL==re){
      goto error;
    }
    pMan->aOutput = (Th_Vtab_Output*)re;
    for( i = pMan->nBuf; i < x; ++i ){
      pMan->aOutput[i] = Th_Vtab_Output_empty;
      pMan->aBuf[i] = NULL;
    }
    pMan->nBuf = x;
  }
  assert( pMan->nBuf > pMan->cursor );
  assert( pMan->cursor >= -1 );
  ++pMan->cursor;
  pMan->aBuf[pMan->cursor] = pBlob;
  pMan->aOutput[pMan->cursor] = pMan->interp->pVtab->out;
  pMan->interp->pVtab->out = Th_Vtab_Ob.out;
  pMan->interp->pVtab->out.pState = pMan;
  if( pOut ){
    *pOut = pBlob;
  }
  return TH_OK;
  error:
  if( pBlob ){
    Th_Free( pMan->interp, pBlob );
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
  if( pMan->cursor < 0 ){
    return NULL;
  }else{
    Blob * rc;
    assert( pMan->nBuf > pMan->cursor );
    rc = pMan->aBuf[pMan->cursor];
    pMan->aBuf[pMan->cursor] = NULL;
    pMan->interp->pVtab = pMan->aVtab[pMan->cursor];
    pMan->aVtab[pMan->cursor] = NULL;
    if(-1 == --pMan->cursor){
      Th_Interp * interp = pMan->interp;
      Th_Free( pMan->interp, pMan->aBuf );
      Th_Free( pMan->interp, pMan->aVtab );
      *pMan = Th_Ob_Man_empty;
      pMan->interp = interp;
    }
    return rc;
  }
}








|
|



|







2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
  if( pMan->cursor < 0 ){
    return NULL;
  }else{
    Blob * rc;
    assert( pMan->nBuf > pMan->cursor );
    rc = pMan->aBuf[pMan->cursor];
    pMan->aBuf[pMan->cursor] = NULL;
    pMan->interp->pVtab->out = pMan->aOutput[pMan->cursor];
    pMan->aOutput[pMan->cursor] = Th_Vtab_Output_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;
      pMan->interp = interp;
    }
    return rc;
  }
}

3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
  assert( pMan && (interp == pMan->interp) );
  b = Th_ob_current(pMan);
  if( NULL == b ){
    Th_ErrorMessage( interp, "Not currently buffering.", NULL, 0 );
    return TH_ERROR;
  }
  oldVtab = interp->pVtab;
  interp->pVtab = pMan->aVtab[pMan->cursor];
  Th_output( interp, blob_str(b), b->nUsed );
  interp->pVtab = oldVtab;
  blob_reset(b);

  if(!rc && argc>2){
    int argPos = 2;
    char const * sub = argv[argPos];







|







3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
  assert( pMan && (interp == pMan->interp) );
  b = Th_ob_current(pMan);
  if( NULL == b ){
    Th_ErrorMessage( interp, "Not currently buffering.", NULL, 0 );
    return TH_ERROR;
  }
  oldVtab = interp->pVtab;
  interp->pVtab->out = pMan->aOutput[pMan->cursor];
  Th_output( interp, blob_str(b), b->nUsed );
  interp->pVtab = oldVtab;
  blob_reset(b);

  if(!rc && argc>2){
    int argPos = 2;
    char const * sub = argv[argPos];
Changes to src/th.h.
341
342
343
344
345
346
347

348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
** Manager of a stack of Blob objects for output buffering.
*/
struct Th_Ob_Man {
  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 ** aVtab;    /* Stack of Vtabs (they get restored
                          when a buffering level is popped).
                          Has nBuf entries.

                          FIXME? Only swap out the "out" members, and
                          not xRealloc (that could get us into
                          trouble, but we currently only use one
                          realloc impl).
                       */
};

typedef struct Th_Ob_Man Th_Ob_Man;

/*
** Returns the ob manager for the given interpreter.
*/







>
|
|

<
<
<
<
<
|







341
342
343
344
345
346
347
348
349
350
351





352
353
354
355
356
357
358
359
** Manager of a stack of Blob objects for output buffering.
*/
struct Th_Ob_Man {
  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_Output * aOutput
                       /* Stack of output routines corresponding
                          to the current buffering level.
                          Has nBuf entries.





                       */;
};

typedef struct Th_Ob_Man Th_Ob_Man;

/*
** Returns the ob manager for the given interpreter.
*/