Fossil

Check-in [d87454917c]
Login

Check-in [d87454917c]

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

Overview
Comment:Cleanup style and use Jim_Obj APIs when bridging commands from Tcl to Jim.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | jimtcl
Files: files | file ages | folders
SHA1: d87454917c587741e7e3eba070ba65e7819bf316
User & Date: mistachkin 2011-11-04 23:34:11.656
Context
2011-11-05
00:01
Skip over Jim commands to create if they have a NULL name or function pointer. ... (check-in: 389f9fca5d user: mistachkin tags: jimtcl)
2011-11-04
23:34
Cleanup style and use Jim_Obj APIs when bridging commands from Tcl to Jim. ... (check-in: d87454917c user: mistachkin tags: jimtcl)
21:57
Replace the TH1 interpreter with Jim Tcl. ... (check-in: 863e789e83 user: steveb tags: jimtcl)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/main.c.
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  int iErrPriority;       /* Priority of current error message */
  char *zErrMsg;          /* Text of an error message */
  int sslNotAvailable;    /* SSL is not available.  Do not redirect to https: */
  Blob cgiIn;             /* Input to an xfer www method */
  int cgiOutput;          /* Write error and status messages to CGI */
  int xferPanic;          /* Write error messages in XFER protocol */
  int fullHttpReply;      /* True for full HTTP reply.  False for CGI reply */
  Jim_Interp *interp;      /* The TH1 interpreter */
  FILE *httpIn;           /* Accept HTTP input from here */
  FILE *httpOut;          /* Send HTTP output here */
  int xlinkClusterOnly;   /* Set when cloning.  Only process clusters */
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */







|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
  int iErrPriority;       /* Priority of current error message */
  char *zErrMsg;          /* Text of an error message */
  int sslNotAvailable;    /* SSL is not available.  Do not redirect to https: */
  Blob cgiIn;             /* Input to an xfer www method */
  int cgiOutput;          /* Write error and status messages to CGI */
  int xferPanic;          /* Write error messages in XFER protocol */
  int fullHttpReply;      /* True for full HTTP reply.  False for CGI reply */
  Jim_Interp *interp;     /* The script interpreter */
  FILE *httpIn;           /* Accept HTTP input from here */
  FILE *httpOut;          /* Send HTTP output here */
  int xlinkClusterOnly;   /* Set when cloning.  Only process clusters */
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

  /* For defense against Cross-site Request Forgery attacks */
  char zCsrfToken[12];    /* Value of the anti-CSRF token */
  int okCsrf;             /* Anti-CSRF token is present and valid */

  int parseCnt[10];       /* Counts of artifacts parsed */
  FILE *fDebug;           /* Write debug information here, if the file exists */
  int thTrace;            /* True to enable TH1 debugging output */
  Blob thLog;             /* Text of the TH1 debugging output */

  int isHome;             /* True if rendering the "home" page */

  /* Storage for the aux() and/or option() SQL function arguments */
  int nAux;                    /* Number of distinct aux() or option() values */
  const char *azAuxName[MX_AUX]; /* Name of each aux() or option() value */
  char *azAuxParam[MX_AUX];      /* Param of each aux() or option() value */







|
|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193

  /* For defense against Cross-site Request Forgery attacks */
  char zCsrfToken[12];    /* Value of the anti-CSRF token */
  int okCsrf;             /* Anti-CSRF token is present and valid */

  int parseCnt[10];       /* Counts of artifacts parsed */
  FILE *fDebug;           /* Write debug information here, if the file exists */
  int thTrace;            /* True to enable script debugging output */
  Blob thLog;             /* Text of the script debugging output */

  int isHome;             /* True if rendering the "home" page */

  /* Storage for the aux() and/or option() SQL function arguments */
  int nAux;                    /* Number of distinct aux() or option() values */
  const char *azAuxName[MX_AUX]; /* Name of each aux() or option() value */
  char *azAuxParam[MX_AUX];      /* Param of each aux() or option() value */
Changes to src/th_main.c.
353
354
355
356
357
358
359
360
361
362
363
364
365

366
367
368
369
370
371
372
    g.interp = Jim_CreateInterp();
    Jim_RegisterCoreCommands(g.interp);

    /* Register static extensions */
    Jim_InitStaticExtensions(g.interp);

#ifdef FOSSIL_ENABLE_TCL
    if( getenv("TH1_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
      th_register_tcl(g.interp, &g.tcl);  /* Tcl integration commands. */
    }
#endif
    for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
      Jim_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc, NULL, NULL);

    }
  }
}

/*
** Store a string value in a variable in the interpreter.
*/







|
|



|
>







353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
    g.interp = Jim_CreateInterp();
    Jim_RegisterCoreCommands(g.interp);

    /* Register static extensions */
    Jim_InitStaticExtensions(g.interp);

#ifdef FOSSIL_ENABLE_TCL
    if( getenv("FOSSIL_ENABLE_TCL")!=0 || db_get_boolean("tcl", 0) ){
      register_tcl(g.interp, &g.tcl);  /* Tcl integration commands. */
    }
#endif
    for(i=0; i<sizeof(aCommand)/sizeof(aCommand[0]); i++){
      Jim_CreateCommand(g.interp, aCommand[i].zName, aCommand[i].xProc, NULL,
          NULL);
    }
  }
}

/*
** Store a string value in a variable in the interpreter.
*/
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  }else{
    sendText(z, i, 0);
  }
  return rc;
}

/*
** COMMAND: test-th-render
*/
void test_th_render(void){
  Blob in;
  if( g.argc<3 ){
    usage("FILE");
  }
  db_open_config(0); /* Needed for "tcl" setting. */
  blob_zero(&in);
  blob_read_from_file(&in, g.argv[2]);
  Th_Render(blob_str(&in));
}







|

|









538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
  }else{
    sendText(z, i, 0);
  }
  return rc;
}

/*
** COMMAND: test-script-render
*/
void test_script_render(void){
  Blob in;
  if( g.argc<3 ){
    usage("FILE");
  }
  db_open_config(0); /* Needed for "tcl" setting. */
  blob_zero(&in);
  blob_read_from_file(&in, g.argv[2]);
  Th_Render(blob_str(&in));
}
Changes to src/th_tcl.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
*******************************************************************************
** This file contains code used to bridge the TH1 and Tcl scripting languages.
*/

#include "config.h"

#ifdef FOSSIL_ENABLE_TCL

#include "jim.h"










|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/*
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)
**
** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
*******************************************************************************
** This file contains code used to bridge the Jim and Tcl scripting languages.
*/

#include "config.h"

#ifdef FOSSIL_ENABLE_TCL

#include "jim.h"
28
29
30
31
32
33
34
35
36
37
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
** Tcl_EvalObjv instead of invoking the objProc directly.
 */
#define USE_TCL_EVALOBJV   1
#endif

/*
** These macros are designed to reduce the redundant code required to marshal
** arguments from TH1 to Tcl.
 */
#define USE_ARGV_TO_OBJV() \
  int objc;                \
  Tcl_Obj **objv;          \
  int i;

#define COPY_ARGV_TO_OBJV()                                         \
  objc = argc-1;                                                    \
  objv = (Tcl_Obj **)ckalloc((unsigned)(objc * sizeof(Tcl_Obj *))); \
  for(i=1; i<argc; i++){                                            \
    objv[i-1] = Tcl_NewStringObj(Jim_String(argv[i]), Jim_Length(argv[i]));                 \
    Tcl_IncrRefCount(objv[i-1]);                                    \
  }

#define FREE_ARGV_TO_OBJV()      \
  for(i=1; i<argc; i++){         \
    Tcl_DecrRefCount(objv[i-1]); \
  }                              \
  ckfree((char *)objv);

/*
** Fetch the Tcl interpreter from the specified void pointer, cast to a Tcl
** context.
 */
#define GET_CTX_TCL_INTERP(ctx) \
  ((struct TclContext *)(ctx))->interp

/*
** Creates and initializes a Tcl interpreter for use with the specified TH1
** interpreter.  Stores the created Tcl interpreter in the Tcl context supplied
** by the caller.  This must be declared here because quite a few functions in
** this file need to use it before it can be defined.
 */
static int createTclInterp(Jim_Interp *interp, void *pContext);

/*







|






|
|
|
|
|
|
















|







28
29
30
31
32
33
34
35
36
37
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
** Tcl_EvalObjv instead of invoking the objProc directly.
 */
#define USE_TCL_EVALOBJV   1
#endif

/*
** These macros are designed to reduce the redundant code required to marshal
** arguments from Jim to Tcl.
 */
#define USE_ARGV_TO_OBJV() \
  int objc;                \
  Tcl_Obj **objv;          \
  int i;

#define COPY_ARGV_TO_OBJV()                                                 \
  objc = argc-1;                                                            \
  objv = (Tcl_Obj **)ckalloc((unsigned)(objc * sizeof(Tcl_Obj *)));         \
  for(i=1; i<argc; i++){                                                    \
    objv[i-1] = Tcl_NewStringObj(Jim_String(argv[i]), Jim_Length(argv[i])); \
    Tcl_IncrRefCount(objv[i-1]);                                            \
  }

#define FREE_ARGV_TO_OBJV()      \
  for(i=1; i<argc; i++){         \
    Tcl_DecrRefCount(objv[i-1]); \
  }                              \
  ckfree((char *)objv);

/*
** Fetch the Tcl interpreter from the specified void pointer, cast to a Tcl
** context.
 */
#define GET_CTX_TCL_INTERP(ctx) \
  ((struct TclContext *)(ctx))->interp

/*
** Creates and initializes a Tcl interpreter for use with the specified Jim
** interpreter.  Stores the created Tcl interpreter in the Tcl context supplied
** by the caller.  This must be declared here because quite a few functions in
** this file need to use it before it can be defined.
 */
static int createTclInterp(Jim_Interp *interp, void *pContext);

/*
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108



109
110
111
112
113
114
115
    if( pN ) *pN = 0;
    return 0;
  }
  return Tcl_GetStringFromObj(resultPtr, pN);
}

/*
** Tcl context information used by TH1.  This structure definition has been
** copied from and should be kept in sync with the one in "main.c".
*/
struct TclContext {
  int argc;
  char **argv;
  Tcl_Interp *interp;
};

/*
** Syntax:
**
**   tclEval arg ?arg ...?
*/
static int tclEval_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv



){
  Tcl_Interp *tclInterp;
  Tcl_Obj *objPtr;
  int rc;
  int nResult;
  const char *zResult;
  void *ctx = Jim_CmdPrivData(interp);







|













|
>
>
>







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    if( pN ) *pN = 0;
    return 0;
  }
  return Tcl_GetStringFromObj(resultPtr, pN);
}

/*
** Tcl context information used by Jim.  This structure definition has been
** copied from and should be kept in sync with the one in "main.c".
*/
struct TclContext {
  int argc;
  char **argv;
  Tcl_Interp *interp;
};

/*
** Syntax:
**
**   tclEval arg ?arg ...?
*/
static int tclEval_command(
  Jim_Interp *interp,
  int argc,
  Jim_Obj *const *argv
){
  Tcl_Interp *tclInterp;
  Tcl_Obj *objPtr;
  int rc;
  int nResult;
  const char *zResult;
  void *ctx = Jim_CmdPrivData(interp);
148
149
150
151
152
153
154
155



156
157
158
159
160
161
162
}

/*
** Syntax:
**
**   tclExpr arg ?arg ...?
*/
static int tclExpr_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv



){
  Tcl_Interp *tclInterp;
  Tcl_Obj *objPtr;
  Tcl_Obj *resultObjPtr;
  int rc;
  int nResult;
  const char *zResult;







|
>
>
>







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
}

/*
** Syntax:
**
**   tclExpr arg ?arg ...?
*/
static int tclExpr_command(
  Jim_Interp *interp,
  int argc,
  Jim_Obj *const *argv
){
  Tcl_Interp *tclInterp;
  Tcl_Obj *objPtr;
  Tcl_Obj *resultObjPtr;
  int rc;
  int nResult;
  const char *zResult;
201
202
203
204
205
206
207
208



209
210
211
212
213
214
215
}

/*
** Syntax:
**
**   tclInvoke command ?arg ...?
*/
static int tclInvoke_command(Jim_Interp *interp, int argc, Jim_Obj *const *argv



){
  Tcl_Interp *tclInterp;
#ifndef USE_TCL_EVALOBJV
  Tcl_Command command;
  Tcl_CmdInfo cmdInfo;
#endif
  int rc;







|
>
>
>







207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
}

/*
** Syntax:
**
**   tclInvoke command ?arg ...?
*/
static int tclInvoke_command(
  Jim_Interp *interp,
  int argc,
  Jim_Obj *const *argv
){
  Tcl_Interp *tclInterp;
#ifndef USE_TCL_EVALOBJV
  Tcl_Command command;
  Tcl_CmdInfo cmdInfo;
#endif
  int rc;
241
242
243
244
245
246
247
248

249
250
251
252
253
254
255
  if( !command || Tcl_GetCommandInfoFromToken(command,&cmdInfo)==0 ){
    Jim_SetResultFormatted(interp, "Tcl command not found: %#s", argv[1]);
    Tcl_DecrRefCount(objPtr);
    Tcl_Release((ClientData)tclInterp);
    return JIM_ERR;
  }
  if( !cmdInfo.objProc ){
    Jim_SetResultFormatted(interp, "Cannot invoke command not found: %#s", argv[1]);

    Tcl_DecrRefCount(objPtr);
    Tcl_Release((ClientData)tclInterp);
    return JIM_ERR;
  }
  Tcl_DecrRefCount(objPtr);
#endif
  COPY_ARGV_TO_OBJV();







|
>







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
  if( !command || Tcl_GetCommandInfoFromToken(command,&cmdInfo)==0 ){
    Jim_SetResultFormatted(interp, "Tcl command not found: %#s", argv[1]);
    Tcl_DecrRefCount(objPtr);
    Tcl_Release((ClientData)tclInterp);
    return JIM_ERR;
  }
  if( !cmdInfo.objProc ){
    Jim_SetResultFormatted(interp, "Cannot invoke command not found: %#s",
        argv[1]);
    Tcl_DecrRefCount(objPtr);
    Tcl_Release((ClientData)tclInterp);
    return JIM_ERR;
  }
  Tcl_DecrRefCount(objPtr);
#endif
  COPY_ARGV_TO_OBJV();
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283


284
285
286
287
288
289
290
291
292
293
294


295

296

297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326
327
328


329

330
331
332
333
334
335
336
337
338
339
340
341
342
343
344

345
346
347
348

349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
  Tcl_Release((ClientData)tclInterp);
  return rc;
}

/*
** Syntax:
**
**   th1Eval arg
*/
static int Th1EvalObjCmd(
  ClientData clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  Jim_Interp *th1Interp;
  int nArg;
  const char *arg;
  int rc;



  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "arg");
    return TCL_ERROR;
  }
  th1Interp = (Jim_Interp *)clientData;
  if( !th1Interp ){
    Tcl_AppendResult(interp, "invalid TH1 interpreter", NULL);
    return TCL_ERROR;
  }
  arg = Tcl_GetStringFromObj(objv[1], &nArg);


  rc = Jim_Eval(th1Interp, arg);

  arg = Jim_String(Jim_GetResult(th1Interp));

  Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, -1));
  return rc;
}

/*
** Syntax:
**
**   th1Expr arg
*/
static int Th1ExprObjCmd(
  ClientData clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  Jim_Interp *th1Interp;
  int nArg;
  const char *arg;
  int rc;
  Jim_Obj *exprResultObj;


  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "arg");
    return TCL_ERROR;
  }
  th1Interp = (Jim_Interp *)clientData;
  if( !th1Interp ){
    Tcl_AppendResult(interp, "invalid TH1 interpreter", NULL);
    return TCL_ERROR;
  }

  arg = Tcl_GetStringFromObj(objv[1], &nArg);


  rc = Jim_EvalExpression(th1Interp, Jim_NewStringObj(th1Interp, arg, -1), &exprResultObj);

  if (rc == JIM_OK) {
    arg = Jim_String(exprResultObj);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, -1));
  }

  return rc;
}

/*
** Array of Tcl integration commands.  Used when adding or removing the Tcl
** integration commands from TH1.
*/
static struct _Command {
  const char *zName;
  Jim_CmdProc xProc;

} aCommand[] = {
  {"tclEval",   tclEval_command  },
  {"tclExpr",   tclExpr_command  },
  {"tclInvoke", tclInvoke_command},

};

/*
** Called if the Tcl interpreter is deleted.  Removes the Tcl integration
** commands from the TH1 interpreter.
 */
static void Th1DeleteProc(
  ClientData clientData,
  Tcl_Interp *interp
){
  int i;
  Jim_Interp *th1Interp = (Jim_Interp *)clientData;
  if( !th1Interp ) return;
  /* Remove the Tcl integration commands. */
  for(i=0; i<(sizeof(aCommand)/sizeof(aCommand[0])); i++){
    Jim_DeleteCommand(th1Interp, aCommand[i].zName);
  }
}

/*
** Creates and initializes a Tcl interpreter for use with the specified TH1
** interpreter.  Stores the created Tcl interpreter in the Tcl context supplied
** by the caller.
 */
static int createTclInterp(
  Jim_Interp *interp,
  void *pContext
){







|

|





|



>
>





|
|
|



>
>
|
>
|
>
|






|

|





|



|
>





|
|
|


<

>
>
|
>

|
|

<





|




>

|
|
|
>




|

|




|
|


|




|







275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343

344
345
346
347
348
349
350
351
352

353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
  Tcl_Release((ClientData)tclInterp);
  return rc;
}

/*
** Syntax:
**
**   bridgeEval arg
*/
static int BridgeEvalObjCmd(
  ClientData clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  Jim_Interp *jimInterp;
  int nArg;
  const char *arg;
  int rc;
  Jim_Obj *argObj;
  Jim_Obj *resultObj;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "arg");
    return TCL_ERROR;
  }
  jimInterp = (Jim_Interp *)clientData;
  if( !jimInterp ){
    Tcl_AppendResult(interp, "invalid bridge interpreter", NULL);
    return TCL_ERROR;
  }
  arg = Tcl_GetStringFromObj(objv[1], &nArg);
  argObj = Jim_NewStringObj(jimInterp, arg, nArg);
  Jim_IncrRefCount(argObj);
  rc = Jim_EvalObj(jimInterp, argObj);
  Jim_DecrRefCount(jimInterp, argObj);
  resultObj = Jim_GetResult(jimInterp);
  arg = Jim_GetString(resultObj, &nArg);
  Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, nArg));
  return rc;
}

/*
** Syntax:
**
**   bridgeExpr arg
*/
static int BridgeExprObjCmd(
  ClientData clientData,
  Tcl_Interp *interp,
  int objc,
  Tcl_Obj *CONST objv[]
){
  Jim_Interp *jimInterp;
  int nArg;
  const char *arg;
  int rc;
  Jim_Obj *argObj;
  Jim_Obj *resultObj;

  if( objc!=2 ){
    Tcl_WrongNumArgs(interp, 1, objv, "arg");
    return TCL_ERROR;
  }
  jimInterp = (Jim_Interp *)clientData;
  if( !jimInterp ){
    Tcl_AppendResult(interp, "invalid bridge interpreter", NULL);
    return TCL_ERROR;
  }

  arg = Tcl_GetStringFromObj(objv[1], &nArg);
  argObj = Jim_NewStringObj(jimInterp, arg, nArg);
  Jim_IncrRefCount(argObj);
  rc = Jim_EvalExpression(jimInterp, argObj, &resultObj);
  Jim_DecrRefCount(jimInterp, argObj);
  if (rc == JIM_OK) {
    arg = Jim_GetString(resultObj, &nArg);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(arg, nArg));
  }

  return rc;
}

/*
** Array of Tcl integration commands.  Used when adding or removing the Tcl
** integration commands from Jim.
*/
static struct _Command {
  const char *zName;
  Jim_CmdProc xProc;
  void *pContext;
} aCommand[] = {
  {"tclEval",   tclEval_command,   0},
  {"tclExpr",   tclExpr_command,   0},
  {"tclInvoke", tclInvoke_command, 0},
  {0, 0, 0}
};

/*
** Called if the Tcl interpreter is deleted.  Removes the Tcl integration
** commands from the Jim interpreter.
 */
static void BridgeDeleteProc(
  ClientData clientData,
  Tcl_Interp *interp
){
  int i;
  Jim_Interp *jimInterp = (Jim_Interp *)clientData;
  if( !jimInterp ) return;
  /* Remove the Tcl integration commands. */
  for(i=0; i<(sizeof(aCommand)/sizeof(aCommand[0])); i++){
    Jim_DeleteCommand(jimInterp, aCommand[i].zName);
  }
}

/*
** Creates and initializes a Tcl interpreter for use with the specified Jim
** interpreter.  Stores the created Tcl interpreter in the Tcl context supplied
** by the caller.
 */
static int createTclInterp(
  Jim_Interp *interp,
  void *pContext
){
389
390
391
392
393
394
395
396

397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418

419

420
421
422
423
424
425
  }
  tclInterp = tclContext->interp = Tcl_CreateInterp();
  if( !tclInterp || Tcl_InterpDeleted(tclInterp) ){
    Jim_SetResultString(interp, "Could not create Tcl interpreter", -1);
    return JIM_ERR;
  }
  if( Tcl_Init(tclInterp)!=TCL_OK ){
    Jim_SetResultFormatted(interp, "Tcl initialization error: %s", Tcl_GetStringResult(tclInterp));

    Tcl_DeleteInterp(tclInterp);
    tclContext->interp = tclInterp = 0;
    return JIM_ERR;
  }
  /* Add the TH1 integration commands to Tcl. */
  Tcl_CallWhenDeleted(tclInterp, Th1DeleteProc, interp);
  Tcl_CreateObjCommand(tclInterp, "th1Eval", Th1EvalObjCmd, interp, NULL);
  Tcl_CreateObjCommand(tclInterp, "th1Expr", Th1ExprObjCmd, interp, NULL);
  return JIM_OK;
}

/*
** Register the Tcl language commands with interpreter interp.
** Usually this is called soon after interpreter creation.
*/
int th_register_tcl(
  Jim_Interp *interp,
  void *pContext
){
  int i;
  /* Add the Tcl integration commands to TH1. */
  for(i=0; i<(sizeof(aCommand)/sizeof(aCommand[0])); i++){

    /* Use Tcl interpreter for context? */

    Jim_CreateCommand(interp, aCommand[i].zName, aCommand[i].xProc, pContext, NULL);
  }
  return JIM_OK;
}

#endif /* FOSSIL_ENABLE_TCL */







|
>




|
|
|
|







|




|

>

>
|





409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
  }
  tclInterp = tclContext->interp = Tcl_CreateInterp();
  if( !tclInterp || Tcl_InterpDeleted(tclInterp) ){
    Jim_SetResultString(interp, "Could not create Tcl interpreter", -1);
    return JIM_ERR;
  }
  if( Tcl_Init(tclInterp)!=TCL_OK ){
    Jim_SetResultFormatted(interp, "Tcl initialization error: %s",
        Tcl_GetStringResult(tclInterp));
    Tcl_DeleteInterp(tclInterp);
    tclContext->interp = tclInterp = 0;
    return JIM_ERR;
  }
  /* Add the Jim integration commands to Tcl. */
  Tcl_CallWhenDeleted(tclInterp, BridgeDeleteProc, interp);
  Tcl_CreateObjCommand(tclInterp, "bridgeEval", BridgeEvalObjCmd, interp, NULL);
  Tcl_CreateObjCommand(tclInterp, "bridgeExpr", BridgeExprObjCmd, interp, NULL);
  return JIM_OK;
}

/*
** Register the Tcl language commands with interpreter interp.
** Usually this is called soon after interpreter creation.
*/
int register_tcl(
  Jim_Interp *interp,
  void *pContext
){
  int i;
  /* Add the Tcl integration commands to Jim. */
  for(i=0; i<(sizeof(aCommand)/sizeof(aCommand[0])); i++){
    void *ctx = aCommand[i].pContext;
    /* Use Tcl interpreter for context? */
    if( !ctx ) ctx = pContext;
    Jim_CreateCommand(interp, aCommand[i].zName, aCommand[i].xProc, ctx, NULL);
  }
  return JIM_OK;
}

#endif /* FOSSIL_ENABLE_TCL */
Changes to test/th1-tcl.test.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

###############################################################################

set env(TH1_ENABLE_TCL) 1; # Tcl integration must be enabled for this test.

###############################################################################

fossil test-th-render [file nativename [file join $dir th1-tcl1.txt]]

test th1-tcl-1 {[regexp -- {^\d+
\d+
\d+
via Tcl invoke
4
4







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

###############################################################################

set env(TH1_ENABLE_TCL) 1; # Tcl integration must be enabled for this test.

###############################################################################

fossil test-script-render [file nativename [file join $dir th1-tcl1.txt]]

test th1-tcl-1 {[regexp -- {^\d+
\d+
\d+
via Tcl invoke
4
4
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
\d+
one_word
three words now
$} [string map [list \r\n \n] $RESULT]]}

###############################################################################

fossil test-th-render [file nativename [file join $dir th1-tcl2.txt]]

test th1-tcl-2 {[regexp -- {^\d+
$} [string map [list \r\n \n] $RESULT]]}

###############################################################################

fossil test-th-render [file nativename [file join $dir th1-tcl3.txt]]

test th1-tcl-3 {$RESULT eq {<hr><p class="thmainError">ERROR:\
invalid command name &quot;bad_command&quot;</p>}}

###############################################################################

fossil test-th-render [file nativename [file join $dir th1-tcl4.txt]]

test th1-tcl-4 {$RESULT eq {<hr><p class="thmainError">ERROR:\
divide by zero</p>}}

###############################################################################

fossil test-th-render [file nativename [file join $dir th1-tcl5.txt]]

test th1-tcl-5 {$RESULT eq {<hr><p class="thmainError">ERROR:\
Tcl command not found: bad_command</p>} || $RESULT eq {<hr><p\
class="thmainError">ERROR: invalid command name &quot;bad_command&quot;</p>}}

###############################################################################

fossil test-th-render [file nativename [file join $dir th1-tcl6.txt]]

test th1-tcl-6 {$RESULT eq {<hr><p class="thmainError">ERROR:\
no such command:  bad_command</p>}}

###############################################################################

fossil test-th-render [file nativename [file join $dir th1-tcl7.txt]]

test th1-tcl-7 {$RESULT eq {<hr><p class="thmainError">ERROR:\
syntax error in expression: &quot;2**0&quot;</p>}}

###############################################################################

fossil test-th-render [file nativename [file join $dir th1-tcl8.txt]]

test th1-tcl-8 {$RESULT eq {<hr><p class="thmainError">ERROR:\
Cannot invoke Tcl command: tailcall</p>} || $RESULT eq {<hr><p\
class="thmainError">ERROR: tailcall can only be called from a proc or\
lambda</p>}}








|






|






|






|







|






|






|






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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
\d+
one_word
three words now
$} [string map [list \r\n \n] $RESULT]]}

###############################################################################

fossil test-script-render [file nativename [file join $dir th1-tcl2.txt]]

test th1-tcl-2 {[regexp -- {^\d+
$} [string map [list \r\n \n] $RESULT]]}

###############################################################################

fossil test-script-render [file nativename [file join $dir th1-tcl3.txt]]

test th1-tcl-3 {$RESULT eq {<hr><p class="thmainError">ERROR:\
invalid command name &quot;bad_command&quot;</p>}}

###############################################################################

fossil test-script-render [file nativename [file join $dir th1-tcl4.txt]]

test th1-tcl-4 {$RESULT eq {<hr><p class="thmainError">ERROR:\
divide by zero</p>}}

###############################################################################

fossil test-script-render [file nativename [file join $dir th1-tcl5.txt]]

test th1-tcl-5 {$RESULT eq {<hr><p class="thmainError">ERROR:\
Tcl command not found: bad_command</p>} || $RESULT eq {<hr><p\
class="thmainError">ERROR: invalid command name &quot;bad_command&quot;</p>}}

###############################################################################

fossil test-script-render [file nativename [file join $dir th1-tcl6.txt]]

test th1-tcl-6 {$RESULT eq {<hr><p class="thmainError">ERROR:\
no such command:  bad_command</p>}}

###############################################################################

fossil test-script-render [file nativename [file join $dir th1-tcl7.txt]]

test th1-tcl-7 {$RESULT eq {<hr><p class="thmainError">ERROR:\
syntax error in expression: &quot;2**0&quot;</p>}}

###############################################################################

fossil test-script-render [file nativename [file join $dir th1-tcl8.txt]]

test th1-tcl-8 {$RESULT eq {<hr><p class="thmainError">ERROR:\
Cannot invoke Tcl command: tailcall</p>} || $RESULT eq {<hr><p\
class="thmainError">ERROR: tailcall can only be called from a proc or\
lambda</p>}}

Changes to test/th1-tcl1.txt.
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
<th1>
  #
  # This is a "TH1 fragment" used to test the Tcl integration features of TH1.
  # The corresponding test file executes this file using the test-th-render
  # Fossil command.
  #
  set channel stdout; tclInvoke set channel $channel
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclEval clock seconds]
  doOut [tclEval {set x [clock seconds]}]
  tclEval {puts $channel "[clock seconds]"}
  tclInvoke puts $channel "via Tcl invoke"
  doOut [tclExpr 2+2]
  doOut [tclExpr 2 + 2]
  doOut [tclInvoke set x "two words"]
  doOut [tclInvoke eval set y one_word]
  doOut [tclInvoke eval {set z "three words now"}]
  doOut [set x [tclEval {set x [clock seconds]}]]
  doOut [tclInvoke th1Eval {set y "two words"}]
  doOut [set z [tclInvoke th1Expr {2+2}]]
  doOut $x
  doOut $y
  doOut $z
  doOut [tclEval set x]
  doOut [tclEval set y]
  doOut [tclEval set z]
</th1>


|
|
|













|
|







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
<th1>
  #
  # This is a "script fragment" used to test the Tcl integration features of
  # Fossil.  The corresponding test file executes this file using the
  # test-script-render Fossil command.
  #
  set channel stdout; tclInvoke set channel $channel
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclEval clock seconds]
  doOut [tclEval {set x [clock seconds]}]
  tclEval {puts $channel "[clock seconds]"}
  tclInvoke puts $channel "via Tcl invoke"
  doOut [tclExpr 2+2]
  doOut [tclExpr 2 + 2]
  doOut [tclInvoke set x "two words"]
  doOut [tclInvoke eval set y one_word]
  doOut [tclInvoke eval {set z "three words now"}]
  doOut [set x [tclEval {set x [clock seconds]}]]
  doOut [tclInvoke bridgeEval {set y "two words"}]
  doOut [set z [tclInvoke bridgeExpr {2+2}]]
  doOut $x
  doOut $y
  doOut $z
  doOut [tclEval set x]
  doOut [tclEval set y]
  doOut [tclEval set z]
</th1>
Changes to test/th1-tcl2.txt.
1
2
3
4
5
6
7
8
9
10
11
12
<th1>
  #
  # This is a "TH1 fragment" used to test the Tcl integration features of TH1.
  # The corresponding test file executes this file using the test-th-render
  # Fossil command.
  #
  # NOTE: This test requires that the SQLite package be available for the Tcl
  #       interpreter that is linked to the Fossil executable.
  #
  tclInvoke set repository_name [repository 1]
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclEval {


|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
<th1>
  #
  # This is a "script fragment" used to test the Tcl integration features of
  # Fossil.  The corresponding test file executes this file using the
  # test-script-render Fossil command.
  #
  # NOTE: This test requires that the SQLite package be available for the Tcl
  #       interpreter that is linked to the Fossil executable.
  #
  tclInvoke set repository_name [repository 1]
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclEval {
Changes to test/th1-tcl3.txt.
1
2
3
4
5
6
7
8
9
<th1>
  #
  # This is a "TH1 fragment" used to test the Tcl integration features of TH1.
  # The corresponding test file executes this file using the test-th-render
  # Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclEval bad_command]
</th1>


|
|
|




1
2
3
4
5
6
7
8
9
<th1>
  #
  # This is a "script fragment" used to test the Tcl integration features of
  # Fossil.  The corresponding test file executes this file using the
  # test-script-render Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclEval bad_command]
</th1>
Changes to test/th1-tcl4.txt.
1
2
3
4
5
6
7
8
9
<th1>
  #
  # This is a "TH1 fragment" used to test the Tcl integration features of TH1.
  # The corresponding test file executes this file using the test-th-render
  # Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclExpr 2/0]
</th1>


|
|
|




1
2
3
4
5
6
7
8
9
<th1>
  #
  # This is a "script fragment" used to test the Tcl integration features of
  # Fossil.  The corresponding test file executes this file using the
  # test-script-render Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclExpr 2/0]
</th1>
Changes to test/th1-tcl5.txt.
1
2
3
4
5
6
7
8
9
<th1>
  #
  # This is a "TH1 fragment" used to test the Tcl integration features of TH1.
  # The corresponding test file executes this file using the test-th-render
  # Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclInvoke bad_command]
</th1>


|
|
|




1
2
3
4
5
6
7
8
9
<th1>
  #
  # This is a "script fragment" used to test the Tcl integration features of
  # Fossil.  The corresponding test file executes this file using the
  # test-script-render Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclInvoke bad_command]
</th1>
Changes to test/th1-tcl6.txt.
1
2
3
4
5
6
7
8
9
<th1>
  #
  # This is a "TH1 fragment" used to test the Tcl integration features of TH1.
  # The corresponding test file executes this file using the test-th-render
  # Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclEval th1Eval bad_command]
</th1>


|
|
|


|

1
2
3
4
5
6
7
8
9
<th1>
  #
  # This is a "script fragment" used to test the Tcl integration features of
  # Fossil.  The corresponding test file executes this file using the
  # test-script-render Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}
  doOut [tclEval bridgeEval bad_command]
</th1>
Changes to test/th1-tcl7.txt.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<th1>
  #
  # This is a "TH1 fragment" used to test the Tcl integration features of TH1.
  # The corresponding test file executes this file using the test-th-render
  # Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}

  #
  # BUGBUG: Attempting to divide by zero will crash TH1 with the error:
  #         "child killed: floating-point exception"
  #
  # doOut [tclEval th1Expr 2/0]

  #
  # NOTE: For now, just cause an expression syntax error.
  #
  doOut [tclEval th1Expr 2**0]
</th1>


|
|
|







|




|

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<th1>
  #
  # This is a "script fragment" used to test the Tcl integration features of
  # Fossil.  The corresponding test file executes this file using the
  # test-script-render Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}

  #
  # BUGBUG: Attempting to divide by zero will crash TH1 with the error:
  #         "child killed: floating-point exception"
  #
  # doOut [tclEval bridgeExpr 2/0]

  #
  # NOTE: For now, just cause an expression syntax error.
  #
  doOut [tclEval bridgeExpr 2**0]
</th1>
Changes to test/th1-tcl8.txt.
1
2
3
4
5
6
7
8
9
10
11
12
<th1>
  #
  # This is a "TH1 fragment" used to test the Tcl integration features of TH1.
  # The corresponding test file executes this file using the test-th-render
  # Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}

  if {[tclInvoke set tcl_version] >= 8.6} {
    doOut [tclInvoke tailcall set x 1]
  } else {
    doOut "This test requires Tcl 8.6 or higher."


|
|
|







1
2
3
4
5
6
7
8
9
10
11
12
<th1>
  #
  # This is a "script fragment" used to test the Tcl integration features of
  # Fossil.  The corresponding test file executes this file using the
  # test-script-render Fossil command.
  #
  proc doOut {msg} {puts $msg; puts \n}

  if {[tclInvoke set tcl_version] >= 8.6} {
    doOut [tclInvoke tailcall set x 1]
  } else {
    doOut "This test requires Tcl 8.6 or higher."
Changes to win/Makefile.mingw.mistachkin.
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
	$(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h

EXTRAOBJ =  $(OBJDIR)/sqlite3.o  $(OBJDIR)/shell.o  $(OBJDIR)/th.o  $(OBJDIR)/th_lang.o

ifdef FOSSIL_ENABLE_TCL
EXTRAOBJ +=  $(OBJDIR)/th_tcl.o
endif

$(APPNAME):	$(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o
	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o







|







421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
# the repository after running the tests.
test:	$(OBJDIR) $(APPNAME)
	$(TCLSH) $(SRCDIR)/../test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
	$(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(SRCDIR)/../VERSION >$(OBJDIR)/VERSION.h

EXTRAOBJ =  $(OBJDIR)/sqlite3.o  $(OBJDIR)/shell.o  $(OBJDIR)/jimtcl.o

ifdef FOSSIL_ENABLE_TCL
EXTRAOBJ +=  $(OBJDIR)/th_tcl.o
endif

$(APPNAME):	$(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o
	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
setup: $(OBJDIR) $(APPNAME)
	$(MAKENSIS) ./fossil.nsi


$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
	$(MKINDEX) $(TRANS_SRC) >$@
$(OBJDIR)/headers:	$(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
	$(MAKEHEADERS)  $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
	echo Done >$(OBJDIR)/headers

$(OBJDIR)/headers: Makefile
Makefile:
$(OBJDIR)/add_.c:	$(SRCDIR)/add.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c








|







450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
setup: $(OBJDIR) $(APPNAME)
	$(MAKENSIS) ./fossil.nsi


$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
	$(MKINDEX) $(TRANS_SRC) >$@
$(OBJDIR)/headers:	$(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
	$(MAKEHEADERS)  $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/glob_.c:$(OBJDIR)/glob.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(OBJDIR)/VERSION.h
	echo Done >$(OBJDIR)/headers

$(OBJDIR)/headers: Makefile
Makefile:
$(OBJDIR)/add_.c:	$(SRCDIR)/add.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c

1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
zip.h:	$(OBJDIR)/headers
$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
	$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o

ifdef FOSSIL_ENABLE_TCL
$(OBJDIR)/th_tcl.o:	$(SRCDIR)/th_tcl.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o
endif








|
<
|
<
<






1035
1036
1037
1038
1039
1040
1041
1042

1043


1044
1045
1046
1047
1048
1049
zip.h:	$(OBJDIR)/headers
$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c $(SRCDIR)/sqlite3.h
	$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o

$(OBJDIR)/jimtcl.o:	$(SRCDIR)/../autosetup/jimsh0.c

	$(XTCC) -I$(SRCDIR) -DJIM_BOOTSTRAP_LIB_ONLY -c $(SRCDIR)/../autosetup/jimsh0.c -o $(OBJDIR)/jimtcl.o



ifdef FOSSIL_ENABLE_TCL
$(OBJDIR)/th_tcl.o:	$(SRCDIR)/th_tcl.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_tcl.c -o $(OBJDIR)/th_tcl.o
endif