Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
| Comment: | Added PHP-like "ob" (output buffering) API to th1. Refactred Th_Vtab allocator to use a single realloc()-like interface. |
|---|---|
| Downloads: | Tarball | ZIP archive |
| Timelines: | family | ancestors | descendants | both | th1-query-api |
| Files: | files | file ages | folders |
| SHA1: |
b7930639549f7bcc987799e7f77e9403 |
| User & Date: | stephan 2012-07-14 18:32:42.720 |
Context
|
2012-07-14
| ||
| 18:44 | i think i fixed the th.c-needs-blob.h build problem (again). Merged in 9f83e033a2304a9. ... (check-in: 960576b961 user: stephan tags: th1-query-api) | |
| 18:32 | Added PHP-like "ob" (output buffering) API to th1. Refactred Th_Vtab allocator to use a single realloc()-like interface. ... (check-in: b793063954 user: stephan tags: th1-query-api) | |
| 14:02 | Refactored Th_ToXXX() to live on top of Th_TryXXX() to simplify some downstream code. ... (check-in: 7554072246 user: stephan tags: th1-query-api) | |
Changes
Changes to src/blob.c.
| ︙ | ︙ | |||
17 18 19 20 21 22 23 | ** ** A Blob is a variable-length containers for arbitrary string ** or binary data. */ #include "config.h" #include <zlib.h> #include "blob.h" | < > | 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
**
** A Blob is a variable-length containers for arbitrary string
** or binary data.
*/
#include "config.h"
#include <zlib.h>
#include "blob.h"
#if INTERFACE
typedef struct Blob Blob;
/*
** A Blob can hold a string or a binary object of arbitrary size. The
** size changes as necessary.
*/
struct Blob {
unsigned int nUsed; /* Number of bytes used in aData[] */
unsigned int nAlloc; /* Number of bytes allocated for aData[] */
|
| ︙ | ︙ | |||
47 48 49 50 51 52 53 | /* ** Seek whence parameter values */ #define BLOB_SEEK_SET 1 #define BLOB_SEEK_CUR 2 #define BLOB_SEEK_END 3 | < | 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | /* ** Seek whence parameter values */ #define BLOB_SEEK_SET 1 #define BLOB_SEEK_CUR 2 #define BLOB_SEEK_END 3 #endif /* INTERFACE */ /* ** Make sure a blob is initialized */ #define blob_is_init(x) \ assert((x)->xRealloc==blobReallocMalloc || (x)->xRealloc==blobReallocStatic) |
| ︙ | ︙ |
Changes to src/main.c.
| ︙ | ︙ | |||
677 678 679 680 681 682 683 |
if( p==0 ) fossil_panic("out of memory");
return p;
}
void fossil_free(void *p){
free(p);
}
void *fossil_realloc(void *p, size_t n){
| | | | | 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 |
if( p==0 ) fossil_panic("out of memory");
return p;
}
void fossil_free(void *p){
free(p);
}
void *fossil_realloc(void *p, size_t n){
void * re = realloc(p, n);
if( re==0 && n>0 ) fossil_panic("out of memory");
return (n > 0) ? re : 0;
}
/*
** This function implements a cross-platform "system()" interface.
*/
int fossil_system(const char *zOrigCmd){
int rc;
|
| ︙ | ︙ |
Changes to src/th.c.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | /* ** 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; /* ** Interpreter structure. | > > > > > > > > > > | 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 */
#ifdef TH_USE_OUTBUF
#ifndef INTERFACE
#include "blob.h"
#endif
#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;
/*
** Interpreter structure.
|
| ︙ | ︙ | |||
1375 1376 1377 1378 1379 1380 1381 |
}
/*
** Wrappers around the supplied malloc() and free()
*/
void *Th_Malloc(Th_Interp *pInterp, int nByte){
| | > > | > > > > | 1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 |
}
/*
** Wrappers around the supplied malloc() and free()
*/
void *Th_Malloc(Th_Interp *pInterp, int nByte){
void * p = pInterp->pVtab->xRealloc(NULL, nByte);
if( p ){
memset(p, 0, nByte);
}else{
assert( 0 == nByte );
}
return p;
}
void Th_Free(Th_Interp *pInterp, void *z){
if( z ){
pInterp->pVtab->xRealloc(z, 0);
}
}
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.f){
return -1;
}else if(!vTab->out.enabled){
|
| ︙ | ︙ | |||
1705 1706 1707 1708 1709 1710 1711 |
/*
** Create a new interpreter.
*/
Th_Interp * Th_CreateInterp(Th_Vtab *pVtab){
Th_Interp *p;
/* Allocate and initialise the interpreter and the global frame */
| | | 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 |
/*
** Create a new interpreter.
*/
Th_Interp * Th_CreateInterp(Th_Vtab *pVtab){
Th_Interp *p;
/* Allocate and initialise the interpreter and the global frame */
p = pVtab->xRealloc(NULL, sizeof(Th_Interp) + sizeof(Th_Frame));
memset(p, 0, sizeof(Th_Interp));
p->pVtab = pVtab;
p->paCmd = Th_HashNew(p);
thPushFrame(p, (Th_Frame *)&p[1]);
return p;
}
|
| ︙ | ︙ | |||
2381 2382 2383 2384 2385 2386 2387 |
int th_isalnum(char c){
return (aCharProp[(unsigned char)c] & 0x0A);
}
#ifndef LONGDOUBLE_TYPE
# define LONGDOUBLE_TYPE long double
#endif
| | | 2397 2398 2399 2400 2401 2402 2403 2404 2405 2406 2407 2408 2409 2410 2411 |
int th_isalnum(char c){
return (aCharProp[(unsigned char)c] & 0x0A);
}
#ifndef LONGDOUBLE_TYPE
# define LONGDOUBLE_TYPE long double
#endif
/*typedef char u8;*/
/*
** Return TRUE if z is a pure numeric string. Return FALSE if the
** string contains any character which is not part of a number. If
** the string is numeric and contains the '.' character, set *realnum
** to TRUE (otherwise FALSE).
|
| ︙ | ︙ | |||
2684 2685 2686 2687 2688 2689 2690 | *z = '\0'; return Th_SetResult(interp, zBuf, -1); } #ifdef TH_USE_SQLITE | < | 2700 2701 2702 2703 2704 2705 2706 2707 2708 2709 2710 2711 2712 2713 |
*z = '\0';
return Th_SetResult(interp, zBuf, -1);
}
#ifdef TH_USE_SQLITE
int Th_AddStmt(Th_Interp *interp, sqlite3_stmt * pStmt){
int i, x;
sqlite3_stmt * s;
sqlite3_stmt ** list = interp->stmt.aStmt;
for( i = 0; i < interp->stmt.nStmt; ++i ){
s = list[i];
if(NULL==s){
|
| ︙ | ︙ | |||
2731 2732 2733 2734 2735 2736 2737 |
return ((stmtId<1) || (stmtId > interp->stmt.nStmt))
? NULL
: interp->stmt.aStmt[stmtId-1];
}
#endif
/* end TH_USE_SQLITE */
| > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 2746 2747 2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 2773 2774 2775 2776 2777 2778 2779 2780 2781 2782 2783 2784 2785 2786 2787 2788 2789 2790 2791 2792 2793 2794 2795 2796 2797 2798 2799 2800 2801 2802 2803 2804 2805 2806 2807 2808 2809 2810 2811 2812 2813 2814 2815 2816 2817 2818 2819 2820 2821 2822 2823 2824 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 2874 2875 2876 2877 2878 2879 2880 2881 2882 2883 2884 2885 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 2918 2919 2920 2921 2922 2923 2924 2925 2926 2927 2928 2929 2930 2931 2932 2933 2934 2935 2936 2937 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 2963 2964 2965 2966 2967 2968 2969 2970 2971 2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 |
return ((stmtId<1) || (stmtId > interp->stmt.nStmt))
? NULL
: interp->stmt.aStmt[stmtId-1];
}
#endif
/* end TH_USE_SQLITE */
#ifdef TH_USE_OUTBUF
struct Th_Ob_Man {
Blob ** aBuf;
int nBuf;
int cursor;
Th_Interp * interp;
Th_Vtab ** aVtab;
};
typedef struct Th_Ob_Man Th_Ob_Man;
#define Th_Ob_Man_empty_m { NULL, 0, -1, NULL, NULL }
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 Blob * Th_ob_current( Th_Ob_Man * pMan ){
return pMan->nBuf>0 ? pMan->aBuf[pMan->cursor] : 0;
}
static int Th_output_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;
}
static Th_Vtab Th_Vtab_Ob = { th_fossil_realloc,
{
Th_output_ob,
NULL,
1
}
};
#if 0
#define OB_MALLOC(I,N) malloc((N))
#define OB_REALLOC(I,P,N) realloc((P),(N))
#define OB_FREE(I,P) free((P))
#else
#define OB_MALLOC(I,N) Th_Malloc((I),(N))
#define OB_REALLOC(I,P,N) Th_Realloc((I),(P),(N))
#define OB_FREE(I,P) Th_Free((I),(P))
#endif
int Th_ob_push( Th_Ob_Man * pMan, Blob ** pOut ){
Blob * pBlob;
int x, i;
assert( NULL != pMan->interp );
pBlob = (Blob *)OB_MALLOC(pMan->interp, sizeof(Blob));
*pBlob = empty_blob;
if( pMan->cursor <= pMan->nBuf ){
/* expand if needed */
x = (pMan->cursor>0 ? pMan->cursor : 1) * 2;
/*fprintf(stderr,"OB EXPAND x=%d\n",x);*/
void * re = OB_REALLOC( pMan->interp, pMan->aBuf, x * sizeof(Blob*) );
if(NULL==re){
goto error;
}
pMan->aBuf = (Blob **)re;
re = OB_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;
}
/*fprintf(stderr,"OB PUSH: %p\n", pBlob);*/
return TH_OK;
error:
if( pBlob ){
OB_FREE( pMan->interp, pBlob );
}
return TH_ERROR;
}
Blob * Th_ob_pop( Th_Ob_Man * pMan ){
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){
OB_FREE( pMan->interp, pMan->aBuf );
OB_FREE( pMan->interp, pMan->aVtab );
*pMan = Th_Ob_Man_empty;
}
/*fprintf(stderr,"OB pop: %p level=%d\n", rc, pMan->cursor-1);*/
return rc;
}
}
static int ob_clean_command( Th_Interp *interp, void *ctx,
int argc, const char **argv, int *argl
){
Th_Ob_Man * pMan = (Th_Ob_Man *)ctx;
Blob * b;
assert( pMan && (interp == pMan->interp) );
b = pMan ? Th_ob_current(pMan) : NULL;
if(!b){
Th_ErrorMessage( interp, "Not currently buffering.", NULL, 0 );
return TH_ERROR;
}else{
blob_reset(b);
}
return TH_OK;
}
static int ob_end_command( Th_Interp *interp, void *ctx,
int argc, const char **argv, int *argl ){
Th_Ob_Man * pMan = (Th_Ob_Man *)ctx;
Blob * b;
assert( pMan && (interp == pMan->interp) );
b = Th_ob_pop(pMan);
if(!b){
Th_ErrorMessage( interp, "Not currently buffering.", NULL, 0 );
return TH_ERROR;
}else{
blob_reset(b);
OB_FREE( interp, b );
}
return TH_OK;
}
static int ob_flush_command( Th_Interp *interp, void *ctx,
int argc, const char **argv, int *argl ){
Th_Ob_Man * pMan = (Th_Ob_Man *)ctx;
Blob * b = NULL;
Th_Vtab * oldVtab;
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);
return TH_OK;
}
static int ob_get_command( Th_Interp *interp, void *ctx,
int argc, const char **argv, int *argl){
Th_Ob_Man * pMan = (Th_Ob_Man *)ctx;
Blob * b = NULL;
assert( pMan && (interp == pMan->interp) );
b = Th_ob_current(pMan);
if( NULL == b ){
Th_ErrorMessage( interp, "Not currently buffering.", NULL, 0 );
return TH_ERROR;
}else{
int argPos = 2;
char const * sub;
int subL;
int rc = TH_OK;
Th_SetResult( interp, blob_str(b), b->nUsed );
if(argc>=argPos){
sub = argv[argPos];
subL = argl[argPos];
/* "ob get clean" */
if(!rc && th_strlen(sub)==5 && 0==memcmp("clean", sub, subL)){
rc |= ob_clean_command(interp, ctx, argc-1, argv+1, argl+1);
}/* "ob get end" */
else if(!rc && th_strlen(sub)==3 && 0==memcmp("end", sub, subL)){
rc |= ob_end_command(interp, ctx, argc-1, argv+1, argl+1);
}
}
return rc;
}
}
static int ob_start_command( Th_Interp *interp, void *ctx,
int argc, const char **argv, int *argl
){
Th_Ob_Man * pMan = (Th_Ob_Man *)ctx;
Blob * b = NULL;
int rc;
assert( pMan && (interp == pMan->interp) );
rc = Th_ob_push(pMan, &b);
if( TH_OK != rc ){
assert( NULL == b );
return rc;
}
assert( NULL != b );
/*fprintf(stderr,"OB STARTED: %p level=%d\n", b, pMan->cursor);*/
Th_SetResultInt( interp, pMan->cursor );
return TH_OK;
}
static int ob_cmd(
Th_Interp *interp,
void *ignored,
int argc,
const char **argv,
int *argl
){
static Th_Ob_Man * pMan = &Th_Ob_Man_instance;
Th_SubCommand aSub[] = {
{ "clean", ob_clean_command },
{ "end", ob_end_command },
{ "flush", ob_flush_command },
{ "get", ob_get_command },
{ "start", ob_start_command },
{ 0, 0 }
};
if(NULL == pMan->interp){
pMan->interp = interp;
/*
FIXME: add rudamentary at-finalization GC to Th_Interp and clean
this up there.
*/
}
return Th_CallSubCommand(interp, pMan, argc, argv, argl, aSub);
}
int th_register_ob(Th_Interp * interp){
static Th_Command_Reg aCommand[] = {
{"ob", ob_cmd, 0},
{0,0,0}
};
return Th_register_commands( interp, aCommand );
}
#undef OB_MALLOC
#undef OB_REALLOC
#undef OB_FREE
#endif
/* end TH_USE_OUTBUF */
|
Changes to src/th.h.
1 |
| > < < < < < > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include "config.h" #define TH_USE_SQLITE #ifdef TH_USE_SQLITE #include "sqlite3.h" #endif /* ** TH_USE_OUTBUF, if defined, enables the "ob" family of functions. */ #define TH_USE_OUTBUF /*#undef TH_USE_OUTBUF*/ /* This header file defines the external interface to the custom Scripting ** Language (TH) interpreter. TH is very similar to TCL but is not an ** exact clone. */ /* |
| ︙ | ︙ | |||
34 35 36 37 38 39 40 |
/*
** Before creating an interpreter, the application must allocate and
** populate an instance of the following structure. It must remain valid
** for the lifetime of the interpreter.
*/
struct Th_Vtab {
| | < | 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 |
/*
** Before creating an interpreter, the application must allocate and
** populate an instance of the following structure. It must remain valid
** for the lifetime of the interpreter.
*/
struct Th_Vtab {
void *(*xRealloc)(void *, unsigned int);
Th_Vtab_Output out;
};
typedef struct Th_Vtab Th_Vtab;
/*
** Opaque handle for interpeter.
|
| ︙ | ︙ | |||
149 150 151 152 153 154 155 | /* ** Access the memory management functions associated with the specified ** interpreter. */ void *Th_Malloc(Th_Interp *, int); void Th_Free(Th_Interp *, void *); | | | 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 | /* ** Access the memory management functions associated with the specified ** interpreter. */ void *Th_Malloc(Th_Interp *, int); void Th_Free(Th_Interp *, void *); void *Th_Realloc(Th_Interp *, void *, int); /* ** Functions for handling TH lists. */ int Th_ListAppend(Th_Interp *, char **, int *, const char *, int); int Th_SplitList(Th_Interp *, const char *, int, char ***, int **, int *); int Th_StringAppend(Th_Interp *, char **, int *, const char *, int); |
| ︙ | ︙ | |||
187 188 189 190 191 192 193 | */ int th_register_language(Th_Interp *interp); /* th_lang.c */ int th_register_sqlite(Th_Interp *interp); /* th_main.c */ int th_register_argv(Th_Interp *interp); /* th_main.c */ int th_register_vfs(Th_Interp *interp); /* th_vfs.c */ int th_register_testvfs(Th_Interp *interp); /* th_testvfs.c */ int th_register_tcl(Th_Interp *interp, void *pContext); /* th_tcl.c */ | | | 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 |
*/
int th_register_language(Th_Interp *interp); /* th_lang.c */
int th_register_sqlite(Th_Interp *interp); /* th_main.c */
int th_register_argv(Th_Interp *interp); /* th_main.c */
int th_register_vfs(Th_Interp *interp); /* th_vfs.c */
int th_register_testvfs(Th_Interp *interp); /* th_testvfs.c */
int th_register_tcl(Th_Interp *interp, void *pContext); /* th_tcl.c */
int th_register_ob(Th_Interp * interp); /* th.c */
/*
** General purpose hash table from th_lang.c.
*/
typedef struct Th_Hash Th_Hash;
typedef struct Th_HashEntry Th_HashEntry;
struct Th_HashEntry {
void *pData;
|
| ︙ | ︙ | |||
259 260 261 262 263 264 265 | ** pointer to an array of Th_Command_Reg objects, the last one of which MUST ** have a NULL zName field (that is the end-of-list marker). ** Returns TH_OK on success, "something else" on error. */ int Th_register_commands( Th_Interp * interp, Th_Command_Reg const * pList ); #ifdef TH_USE_SQLITE | < < | 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | ** pointer to an array of Th_Command_Reg objects, the last one of which MUST ** have a NULL zName field (that is the end-of-list marker). ** Returns TH_OK on success, "something else" on error. */ int Th_register_commands( Th_Interp * interp, Th_Command_Reg const * pList ); #ifdef TH_USE_SQLITE /* ** Adds the given prepared statement to the interpreter. Returns the ** statements opaque identifier (a positive value). Ownerships of ** pStmt is transfered to interp and it must be cleaned up by the ** client by calling Th_FinalizeStmt(), passing it the value returned ** by this function. |
| ︙ | ︙ |
Changes to src/th_lang.c.
| ︙ | ︙ | |||
1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 |
}
/*
** Register the built-in th1 language commands with interpreter interp.
** Usually this is called soon after interpreter creation.
*/
int th_register_language(Th_Interp *interp){
/* Array of built-in commands. */
struct Th_Command_Reg aCommand[] = {
{"catch", catch_command, 0},
{"expr", expr_command, 0},
{"for", for_command, 0},
{"if", if_command, 0},
{"info", info_command, 0},
| > | 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 |
}
/*
** Register the built-in th1 language commands with interpreter interp.
** Usually this is called soon after interpreter creation.
*/
int th_register_language(Th_Interp *interp){
int rc;
/* Array of built-in commands. */
struct Th_Command_Reg aCommand[] = {
{"catch", catch_command, 0},
{"expr", expr_command, 0},
{"for", for_command, 0},
{"if", if_command, 0},
{"info", info_command, 0},
|
| ︙ | ︙ | |||
1062 1063 1064 1065 1066 1067 1068 |
{"return", return_command, 0},
{"break", simple_command, (void *)TH_BREAK},
{"continue", simple_command, (void *)TH_CONTINUE},
{"error", simple_command, (void *)TH_ERROR},
{0, 0, 0}
};
| | > > > > | 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 |
{"return", return_command, 0},
{"break", simple_command, (void *)TH_BREAK},
{"continue", simple_command, (void *)TH_CONTINUE},
{"error", simple_command, (void *)TH_ERROR},
{0, 0, 0}
};
rc = Th_register_commands(interp, aCommand);
#ifdef TH_USE_OUTBUF
rc |= th_register_ob(interp);
#endif
return rc;
}
|
Changes to src/th_main.c.
| ︙ | ︙ | |||
38 39 40 41 42 43 44 |
}
return p;
}
static void xFree(void *p){
if( p ){
nOutstandingMalloc--;
}
| > > > > > | > > > > > > > > | | > | | | | | 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
}
return p;
}
static void xFree(void *p){
if( p ){
nOutstandingMalloc--;
}
fossil_free(p);
}
static void *xRealloc(void * p, unsigned int n){
if(0 == n){
xFree(p);
return NULL;
}else if(NULL == p){
return xMalloc(n);
}else{
return fossil_realloc(p, n)
/* FIXME: try to find some reasonable nOutstandingMalloc
heuristics, e.g. if !p then ++, if !n then --, etc.
*/;
}
}
static Th_Vtab vtab = { xRealloc, {
NULL,
NULL,
1
}
};
/*
** Generate a TH1 trace message if debugging is enabled.
*/
void Th_Trace(const char *zFormat, ...){
|
| ︙ | ︙ | |||
725 726 727 728 729 730 731 732 733 734 735 736 737 738 | Th_register_commands( interp, aCommand ); } #endif /* end TH_USE_ARGV */ #ifdef TH_USE_SQLITE /* ** TH Syntax: ** ** query_prepare SQL ** ** Returns an opaque statement identifier. */ | > | 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 | Th_register_commands( interp, aCommand ); } #endif /* end TH_USE_ARGV */ #ifdef TH_USE_SQLITE /* ** TH Syntax: ** ** query_prepare SQL ** ** Returns an opaque statement identifier. */ |
| ︙ | ︙ |