Fossil SCM
Refactord ob api to only swap out the Vtab output state, as opposed to the whole Vtab state (which includes the allocator).
Commit
d9e0ee2f1e23408c91189f6af54e6774eabcd487
Parent
236cf1359400683…
2 files changed
+25
-13
+4
-8
M
src/th.c
+25
-13
| --- src/th.c | ||
| +++ src/th.c | ||
| @@ -13,11 +13,11 @@ | ||
| 13 | 13 | |
| 14 | 14 | extern void *fossil_realloc(void *p, size_t n); |
| 15 | 15 | static void * th_fossil_realloc(void *p, unsigned int n){ |
| 16 | 16 | return fossil_realloc( p, n ); |
| 17 | 17 | } |
| 18 | - | |
| 18 | +static int Th_output_f_ob( char const * zData, int len, void * pState ); | |
| 19 | 19 | typedef struct Th_Command Th_Command; |
| 20 | 20 | typedef struct Th_Frame Th_Frame; |
| 21 | 21 | typedef struct Th_Variable Th_Variable; |
| 22 | 22 | |
| 23 | 23 | /* |
| @@ -2827,14 +2827,26 @@ | ||
| 2827 | 2827 | #define Th_Ob_Man_empty_m { \ |
| 2828 | 2828 | NULL/*aBuf*/, \ |
| 2829 | 2829 | 0/*nBuf*/, \ |
| 2830 | 2830 | -1/*cursor*/, \ |
| 2831 | 2831 | NULL/*interp*/, \ |
| 2832 | - NULL/*aVtab*/ \ | |
| 2832 | + NULL/*aOutput*/ \ | |
| 2833 | +} | |
| 2834 | +#define Th_Vtab_Output_empty_m { \ | |
| 2835 | + Th_output_f_ob /*f*/, \ | |
| 2836 | + NULL /*pState*/,\ | |
| 2837 | + 1/*enabled*/\ | |
| 2838 | +} | |
| 2839 | +#define Th_Vtab_Output_ob_m { \ | |
| 2840 | + Th_output_f_ob /*f*/, \ | |
| 2841 | + NULL /*pState*/,\ | |
| 2842 | + 1/*enabled*/\ | |
| 2833 | 2843 | } |
| 2834 | 2844 | static const Th_Ob_Man Th_Ob_Man_empty = Th_Ob_Man_empty_m; |
| 2835 | 2845 | static Th_Ob_Man Th_Ob_Man_instance = Th_Ob_Man_empty_m; |
| 2846 | +static Th_Vtab_Output Th_Vtab_Output_ob = Th_Vtab_Output_ob_m; | |
| 2847 | +static Th_Vtab_Output Th_Vtab_Output_empty = Th_Vtab_Output_empty_m; | |
| 2836 | 2848 | #define Th_Ob_Man_KEY "Th_Ob_Man" |
| 2837 | 2849 | Th_Ob_Man * Th_ob_manager(Th_Interp *interp){ |
| 2838 | 2850 | void * rc = Th_Data_Get(interp, Th_Ob_Man_KEY ); |
| 2839 | 2851 | return rc |
| 2840 | 2852 | ? ((Th_GcEntry*)rc)->pData |
| @@ -2849,11 +2861,11 @@ | ||
| 2849 | 2861 | |
| 2850 | 2862 | /* |
| 2851 | 2863 | ** Th_output_f() impl which expects pState to be (Th_Ob_Man*). |
| 2852 | 2864 | ** (zData,len) are appended to pState's current output buffer. |
| 2853 | 2865 | */ |
| 2854 | -static int Th_output_f_ob( char const * zData, int len, void * pState ){ | |
| 2866 | +int Th_output_f_ob( char const * zData, int len, void * pState ){ | |
| 2855 | 2867 | Th_Ob_Man * pMan = (Th_Ob_Man*)pState; |
| 2856 | 2868 | Blob * b = Th_ob_current( pMan ); |
| 2857 | 2869 | assert( NULL != pMan ); |
| 2858 | 2870 | assert( b ); |
| 2859 | 2871 | blob_append( b, zData, len ); |
| @@ -2888,28 +2900,28 @@ | ||
| 2888 | 2900 | void * re = Th_Realloc( pMan->interp, pMan->aBuf, x * sizeof(Blob*) ); |
| 2889 | 2901 | if(NULL==re){ |
| 2890 | 2902 | goto error; |
| 2891 | 2903 | } |
| 2892 | 2904 | pMan->aBuf = (Blob **)re; |
| 2893 | - re = Th_Realloc( pMan->interp, pMan->aVtab, x * sizeof(Th_Vtab*) ); | |
| 2905 | + re = Th_Realloc( pMan->interp, pMan->aOutput, x * sizeof(Th_Vtab_Output) ); | |
| 2894 | 2906 | if(NULL==re){ |
| 2895 | 2907 | goto error; |
| 2896 | 2908 | } |
| 2897 | - pMan->aVtab = (Th_Vtab**)re; | |
| 2909 | + pMan->aOutput = (Th_Vtab_Output*)re; | |
| 2898 | 2910 | for( i = pMan->nBuf; i < x; ++i ){ |
| 2899 | - pMan->aVtab[i] = NULL; | |
| 2911 | + pMan->aOutput[i] = Th_Vtab_Output_empty; | |
| 2900 | 2912 | pMan->aBuf[i] = NULL; |
| 2901 | 2913 | } |
| 2902 | 2914 | pMan->nBuf = x; |
| 2903 | 2915 | } |
| 2904 | 2916 | assert( pMan->nBuf > pMan->cursor ); |
| 2905 | 2917 | assert( pMan->cursor >= -1 ); |
| 2906 | 2918 | ++pMan->cursor; |
| 2907 | 2919 | pMan->aBuf[pMan->cursor] = pBlob; |
| 2908 | - pMan->aVtab[pMan->cursor] = pMan->interp->pVtab; | |
| 2909 | - pMan->interp->pVtab = &Th_Vtab_Ob; | |
| 2910 | - Th_Vtab_Ob.out.pState = pMan; | |
| 2920 | + pMan->aOutput[pMan->cursor] = pMan->interp->pVtab->out; | |
| 2921 | + pMan->interp->pVtab->out = Th_Vtab_Ob.out; | |
| 2922 | + pMan->interp->pVtab->out.pState = pMan; | |
| 2911 | 2923 | if( pOut ){ |
| 2912 | 2924 | *pOut = pBlob; |
| 2913 | 2925 | } |
| 2914 | 2926 | return TH_OK; |
| 2915 | 2927 | error: |
| @@ -2927,16 +2939,16 @@ | ||
| 2927 | 2939 | }else{ |
| 2928 | 2940 | Blob * rc; |
| 2929 | 2941 | assert( pMan->nBuf > pMan->cursor ); |
| 2930 | 2942 | rc = pMan->aBuf[pMan->cursor]; |
| 2931 | 2943 | pMan->aBuf[pMan->cursor] = NULL; |
| 2932 | - pMan->interp->pVtab = pMan->aVtab[pMan->cursor]; | |
| 2933 | - pMan->aVtab[pMan->cursor] = NULL; | |
| 2944 | + pMan->interp->pVtab->out = pMan->aOutput[pMan->cursor]; | |
| 2945 | + pMan->aOutput[pMan->cursor] = Th_Vtab_Output_empty; | |
| 2934 | 2946 | if(-1 == --pMan->cursor){ |
| 2935 | 2947 | Th_Interp * interp = pMan->interp; |
| 2936 | 2948 | Th_Free( pMan->interp, pMan->aBuf ); |
| 2937 | - Th_Free( pMan->interp, pMan->aVtab ); | |
| 2949 | + Th_Free( pMan->interp, pMan->aOutput ); | |
| 2938 | 2950 | *pMan = Th_Ob_Man_empty; |
| 2939 | 2951 | pMan->interp = interp; |
| 2940 | 2952 | } |
| 2941 | 2953 | return rc; |
| 2942 | 2954 | } |
| @@ -3030,11 +3042,11 @@ | ||
| 3030 | 3042 | if( NULL == b ){ |
| 3031 | 3043 | Th_ErrorMessage( interp, "Not currently buffering.", NULL, 0 ); |
| 3032 | 3044 | return TH_ERROR; |
| 3033 | 3045 | } |
| 3034 | 3046 | oldVtab = interp->pVtab; |
| 3035 | - interp->pVtab = pMan->aVtab[pMan->cursor]; | |
| 3047 | + interp->pVtab->out = pMan->aOutput[pMan->cursor]; | |
| 3036 | 3048 | Th_output( interp, blob_str(b), b->nUsed ); |
| 3037 | 3049 | interp->pVtab = oldVtab; |
| 3038 | 3050 | blob_reset(b); |
| 3039 | 3051 | |
| 3040 | 3052 | if(!rc && argc>2){ |
| 3041 | 3053 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -13,11 +13,11 @@ | |
| 13 | |
| 14 | extern void *fossil_realloc(void *p, size_t n); |
| 15 | static void * th_fossil_realloc(void *p, unsigned int n){ |
| 16 | return fossil_realloc( p, n ); |
| 17 | } |
| 18 | |
| 19 | typedef struct Th_Command Th_Command; |
| 20 | typedef struct Th_Frame Th_Frame; |
| 21 | typedef struct Th_Variable Th_Variable; |
| 22 | |
| 23 | /* |
| @@ -2827,14 +2827,26 @@ | |
| 2827 | #define Th_Ob_Man_empty_m { \ |
| 2828 | NULL/*aBuf*/, \ |
| 2829 | 0/*nBuf*/, \ |
| 2830 | -1/*cursor*/, \ |
| 2831 | NULL/*interp*/, \ |
| 2832 | NULL/*aVtab*/ \ |
| 2833 | } |
| 2834 | static const Th_Ob_Man Th_Ob_Man_empty = Th_Ob_Man_empty_m; |
| 2835 | static Th_Ob_Man Th_Ob_Man_instance = Th_Ob_Man_empty_m; |
| 2836 | #define Th_Ob_Man_KEY "Th_Ob_Man" |
| 2837 | Th_Ob_Man * Th_ob_manager(Th_Interp *interp){ |
| 2838 | void * rc = Th_Data_Get(interp, Th_Ob_Man_KEY ); |
| 2839 | return rc |
| 2840 | ? ((Th_GcEntry*)rc)->pData |
| @@ -2849,11 +2861,11 @@ | |
| 2849 | |
| 2850 | /* |
| 2851 | ** Th_output_f() impl which expects pState to be (Th_Ob_Man*). |
| 2852 | ** (zData,len) are appended to pState's current output buffer. |
| 2853 | */ |
| 2854 | static int Th_output_f_ob( char const * zData, int len, void * pState ){ |
| 2855 | Th_Ob_Man * pMan = (Th_Ob_Man*)pState; |
| 2856 | Blob * b = Th_ob_current( pMan ); |
| 2857 | assert( NULL != pMan ); |
| 2858 | assert( b ); |
| 2859 | blob_append( b, zData, len ); |
| @@ -2888,28 +2900,28 @@ | |
| 2888 | void * re = Th_Realloc( pMan->interp, pMan->aBuf, x * sizeof(Blob*) ); |
| 2889 | if(NULL==re){ |
| 2890 | goto error; |
| 2891 | } |
| 2892 | pMan->aBuf = (Blob **)re; |
| 2893 | re = Th_Realloc( pMan->interp, pMan->aVtab, x * sizeof(Th_Vtab*) ); |
| 2894 | if(NULL==re){ |
| 2895 | goto error; |
| 2896 | } |
| 2897 | pMan->aVtab = (Th_Vtab**)re; |
| 2898 | for( i = pMan->nBuf; i < x; ++i ){ |
| 2899 | pMan->aVtab[i] = NULL; |
| 2900 | pMan->aBuf[i] = NULL; |
| 2901 | } |
| 2902 | pMan->nBuf = x; |
| 2903 | } |
| 2904 | assert( pMan->nBuf > pMan->cursor ); |
| 2905 | assert( pMan->cursor >= -1 ); |
| 2906 | ++pMan->cursor; |
| 2907 | pMan->aBuf[pMan->cursor] = pBlob; |
| 2908 | pMan->aVtab[pMan->cursor] = pMan->interp->pVtab; |
| 2909 | pMan->interp->pVtab = &Th_Vtab_Ob; |
| 2910 | Th_Vtab_Ob.out.pState = pMan; |
| 2911 | if( pOut ){ |
| 2912 | *pOut = pBlob; |
| 2913 | } |
| 2914 | return TH_OK; |
| 2915 | error: |
| @@ -2927,16 +2939,16 @@ | |
| 2927 | }else{ |
| 2928 | Blob * rc; |
| 2929 | assert( pMan->nBuf > pMan->cursor ); |
| 2930 | rc = pMan->aBuf[pMan->cursor]; |
| 2931 | pMan->aBuf[pMan->cursor] = NULL; |
| 2932 | pMan->interp->pVtab = pMan->aVtab[pMan->cursor]; |
| 2933 | pMan->aVtab[pMan->cursor] = NULL; |
| 2934 | if(-1 == --pMan->cursor){ |
| 2935 | Th_Interp * interp = pMan->interp; |
| 2936 | Th_Free( pMan->interp, pMan->aBuf ); |
| 2937 | Th_Free( pMan->interp, pMan->aVtab ); |
| 2938 | *pMan = Th_Ob_Man_empty; |
| 2939 | pMan->interp = interp; |
| 2940 | } |
| 2941 | return rc; |
| 2942 | } |
| @@ -3030,11 +3042,11 @@ | |
| 3030 | if( NULL == b ){ |
| 3031 | Th_ErrorMessage( interp, "Not currently buffering.", NULL, 0 ); |
| 3032 | return TH_ERROR; |
| 3033 | } |
| 3034 | oldVtab = interp->pVtab; |
| 3035 | interp->pVtab = pMan->aVtab[pMan->cursor]; |
| 3036 | Th_output( interp, blob_str(b), b->nUsed ); |
| 3037 | interp->pVtab = oldVtab; |
| 3038 | blob_reset(b); |
| 3039 | |
| 3040 | if(!rc && argc>2){ |
| 3041 |
| --- src/th.c | |
| +++ src/th.c | |
| @@ -13,11 +13,11 @@ | |
| 13 | |
| 14 | extern void *fossil_realloc(void *p, size_t n); |
| 15 | static void * th_fossil_realloc(void *p, unsigned int n){ |
| 16 | return fossil_realloc( p, n ); |
| 17 | } |
| 18 | static int Th_output_f_ob( char const * zData, int len, void * pState ); |
| 19 | typedef struct Th_Command Th_Command; |
| 20 | typedef struct Th_Frame Th_Frame; |
| 21 | typedef struct Th_Variable Th_Variable; |
| 22 | |
| 23 | /* |
| @@ -2827,14 +2827,26 @@ | |
| 2827 | #define Th_Ob_Man_empty_m { \ |
| 2828 | NULL/*aBuf*/, \ |
| 2829 | 0/*nBuf*/, \ |
| 2830 | -1/*cursor*/, \ |
| 2831 | NULL/*interp*/, \ |
| 2832 | NULL/*aOutput*/ \ |
| 2833 | } |
| 2834 | #define Th_Vtab_Output_empty_m { \ |
| 2835 | Th_output_f_ob /*f*/, \ |
| 2836 | NULL /*pState*/,\ |
| 2837 | 1/*enabled*/\ |
| 2838 | } |
| 2839 | #define Th_Vtab_Output_ob_m { \ |
| 2840 | Th_output_f_ob /*f*/, \ |
| 2841 | NULL /*pState*/,\ |
| 2842 | 1/*enabled*/\ |
| 2843 | } |
| 2844 | static const Th_Ob_Man Th_Ob_Man_empty = Th_Ob_Man_empty_m; |
| 2845 | static Th_Ob_Man Th_Ob_Man_instance = Th_Ob_Man_empty_m; |
| 2846 | static Th_Vtab_Output Th_Vtab_Output_ob = Th_Vtab_Output_ob_m; |
| 2847 | static Th_Vtab_Output Th_Vtab_Output_empty = Th_Vtab_Output_empty_m; |
| 2848 | #define Th_Ob_Man_KEY "Th_Ob_Man" |
| 2849 | Th_Ob_Man * Th_ob_manager(Th_Interp *interp){ |
| 2850 | void * rc = Th_Data_Get(interp, Th_Ob_Man_KEY ); |
| 2851 | return rc |
| 2852 | ? ((Th_GcEntry*)rc)->pData |
| @@ -2849,11 +2861,11 @@ | |
| 2861 | |
| 2862 | /* |
| 2863 | ** Th_output_f() impl which expects pState to be (Th_Ob_Man*). |
| 2864 | ** (zData,len) are appended to pState's current output buffer. |
| 2865 | */ |
| 2866 | int Th_output_f_ob( char const * zData, int len, void * pState ){ |
| 2867 | Th_Ob_Man * pMan = (Th_Ob_Man*)pState; |
| 2868 | Blob * b = Th_ob_current( pMan ); |
| 2869 | assert( NULL != pMan ); |
| 2870 | assert( b ); |
| 2871 | blob_append( b, zData, len ); |
| @@ -2888,28 +2900,28 @@ | |
| 2900 | void * re = Th_Realloc( pMan->interp, pMan->aBuf, x * sizeof(Blob*) ); |
| 2901 | if(NULL==re){ |
| 2902 | goto error; |
| 2903 | } |
| 2904 | pMan->aBuf = (Blob **)re; |
| 2905 | re = Th_Realloc( pMan->interp, pMan->aOutput, x * sizeof(Th_Vtab_Output) ); |
| 2906 | if(NULL==re){ |
| 2907 | goto error; |
| 2908 | } |
| 2909 | pMan->aOutput = (Th_Vtab_Output*)re; |
| 2910 | for( i = pMan->nBuf; i < x; ++i ){ |
| 2911 | pMan->aOutput[i] = Th_Vtab_Output_empty; |
| 2912 | pMan->aBuf[i] = NULL; |
| 2913 | } |
| 2914 | pMan->nBuf = x; |
| 2915 | } |
| 2916 | assert( pMan->nBuf > pMan->cursor ); |
| 2917 | assert( pMan->cursor >= -1 ); |
| 2918 | ++pMan->cursor; |
| 2919 | pMan->aBuf[pMan->cursor] = pBlob; |
| 2920 | pMan->aOutput[pMan->cursor] = pMan->interp->pVtab->out; |
| 2921 | pMan->interp->pVtab->out = Th_Vtab_Ob.out; |
| 2922 | pMan->interp->pVtab->out.pState = pMan; |
| 2923 | if( pOut ){ |
| 2924 | *pOut = pBlob; |
| 2925 | } |
| 2926 | return TH_OK; |
| 2927 | error: |
| @@ -2927,16 +2939,16 @@ | |
| 2939 | }else{ |
| 2940 | Blob * rc; |
| 2941 | assert( pMan->nBuf > pMan->cursor ); |
| 2942 | rc = pMan->aBuf[pMan->cursor]; |
| 2943 | pMan->aBuf[pMan->cursor] = NULL; |
| 2944 | pMan->interp->pVtab->out = pMan->aOutput[pMan->cursor]; |
| 2945 | pMan->aOutput[pMan->cursor] = Th_Vtab_Output_empty; |
| 2946 | if(-1 == --pMan->cursor){ |
| 2947 | Th_Interp * interp = pMan->interp; |
| 2948 | Th_Free( pMan->interp, pMan->aBuf ); |
| 2949 | Th_Free( pMan->interp, pMan->aOutput ); |
| 2950 | *pMan = Th_Ob_Man_empty; |
| 2951 | pMan->interp = interp; |
| 2952 | } |
| 2953 | return rc; |
| 2954 | } |
| @@ -3030,11 +3042,11 @@ | |
| 3042 | if( NULL == b ){ |
| 3043 | Th_ErrorMessage( interp, "Not currently buffering.", NULL, 0 ); |
| 3044 | return TH_ERROR; |
| 3045 | } |
| 3046 | oldVtab = interp->pVtab; |
| 3047 | interp->pVtab->out = pMan->aOutput[pMan->cursor]; |
| 3048 | Th_output( interp, blob_str(b), b->nUsed ); |
| 3049 | interp->pVtab = oldVtab; |
| 3050 | blob_reset(b); |
| 3051 | |
| 3052 | if(!rc && argc>2){ |
| 3053 |
M
src/th.h
+4
-8
| --- src/th.h | ||
| +++ src/th.h | ||
| @@ -343,19 +343,15 @@ | ||
| 343 | 343 | struct Th_Ob_Man { |
| 344 | 344 | Blob ** aBuf; /* Stack of Blobs */ |
| 345 | 345 | int nBuf; /* Number of blobs */ |
| 346 | 346 | int cursor; /* Current level (-1=not active) */ |
| 347 | 347 | Th_Interp * interp; /* The associated interpreter */ |
| 348 | - Th_Vtab ** aVtab; /* Stack of Vtabs (they get restored | |
| 349 | - when a buffering level is popped). | |
| 348 | + Th_Vtab_Output * aOutput | |
| 349 | + /* Stack of output routines corresponding | |
| 350 | + to the current buffering level. | |
| 350 | 351 | Has nBuf entries. |
| 351 | - | |
| 352 | - FIXME? Only swap out the "out" members, and | |
| 353 | - not xRealloc (that could get us into | |
| 354 | - trouble, but we currently only use one | |
| 355 | - realloc impl). | |
| 356 | - */ | |
| 352 | + */; | |
| 357 | 353 | }; |
| 358 | 354 | |
| 359 | 355 | typedef struct Th_Ob_Man Th_Ob_Man; |
| 360 | 356 | |
| 361 | 357 | /* |
| 362 | 358 |
| --- src/th.h | |
| +++ src/th.h | |
| @@ -343,19 +343,15 @@ | |
| 343 | struct Th_Ob_Man { |
| 344 | Blob ** aBuf; /* Stack of Blobs */ |
| 345 | int nBuf; /* Number of blobs */ |
| 346 | int cursor; /* Current level (-1=not active) */ |
| 347 | Th_Interp * interp; /* The associated interpreter */ |
| 348 | Th_Vtab ** aVtab; /* Stack of Vtabs (they get restored |
| 349 | when a buffering level is popped). |
| 350 | Has nBuf entries. |
| 351 | |
| 352 | FIXME? Only swap out the "out" members, and |
| 353 | not xRealloc (that could get us into |
| 354 | trouble, but we currently only use one |
| 355 | realloc impl). |
| 356 | */ |
| 357 | }; |
| 358 | |
| 359 | typedef struct Th_Ob_Man Th_Ob_Man; |
| 360 | |
| 361 | /* |
| 362 |
| --- src/th.h | |
| +++ src/th.h | |
| @@ -343,19 +343,15 @@ | |
| 343 | struct Th_Ob_Man { |
| 344 | Blob ** aBuf; /* Stack of Blobs */ |
| 345 | int nBuf; /* Number of blobs */ |
| 346 | int cursor; /* Current level (-1=not active) */ |
| 347 | Th_Interp * interp; /* The associated interpreter */ |
| 348 | Th_Vtab_Output * aOutput |
| 349 | /* Stack of output routines corresponding |
| 350 | to the current buffering level. |
| 351 | Has nBuf entries. |
| 352 | */; |
| 353 | }; |
| 354 | |
| 355 | typedef struct Th_Ob_Man Th_Ob_Man; |
| 356 | |
| 357 | /* |
| 358 |