Jim Tcl

Check-in [40c6c81560]
Login

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

Overview
Comment:Build fixes, better Jim_EvalFile()

*: make-c-ext is now make-c-ext.tcl *: build doc/Tcl.html with asciidoc *: Jim_SetIntResult -> Jim_SetResultInt *: Jim_EvalFile() now reads the file contents in one go

Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 40c6c815603849b23d5de6a92ced8b57dcbe974b
User & Date: steveb@workware.net.au 2010-10-15 00:11:02.975
Original User & Date: steveb@workware.net.au 2010-10-15 00:11:03.000
Context
2010-10-15
00:11
Remove declarations for some functions which are gone check-in: fed669cceb user: steveb@workware.net.au tags: trunk
00:11
Build fixes, better Jim_EvalFile()

*: make-c-ext is now make-c-ext.tcl *: build doc/Tcl.html with asciidoc *: Jim_SetIntResult -> Jim_SetResultInt *: Jim_EvalFile() now reads the file contents in one go check-in: 40c6c81560 user: steveb@workware.net.au tags: trunk

00:11
Fit into the broad project build check-in: b2142bf7aa user: steveb@workware.net.au tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to Makefile.in.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
EXTENSIONS_OBJS := $(patsubst %,jim-%.o,$(EXTENSIONS))

.PRECIOUS: jim-%.c

# Create C extensions from pure Tcl extensions
jim-%.c: %.tcl
	echo $@ >>.clean
	tclsh make-c-ext $*.tcl

# Emulate tinytcl
LIBJIM := libtcl6.a

ifdef jim_nofork
	CFLAGS += -DNO_FORK
endif







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
EXTENSIONS_OBJS := $(patsubst %,jim-%.o,$(EXTENSIONS))

.PRECIOUS: jim-%.c

# Create C extensions from pure Tcl extensions
jim-%.c: %.tcl
	echo $@ >>.clean
	tclsh make-c-ext.tcl $@ $*.tcl

# Emulate tinytcl
LIBJIM := libtcl6.a

ifdef jim_nofork
	CFLAGS += -DNO_FORK
endif
Changes to doc/jim_man.txt.


















1
2
3
4
5
6
7


















# what: jim commands, description, points to ponder

jim 
	set var [value]

	dict

>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







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
Jim(n)
======

NAME
----
Jim - a better Tcl

SYNOPSIS
--------

  cc <source> -ltcl6

or

  jimsh <script>

INTRODUCTION
------------
# what: jim commands, description, points to ponder

jim 
	set var [value]

	dict

Changes to jim-bio.c.
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

    if (ferror(outfilePtr->f)) {
        Jim_AppendResult(interp, "error writing \"", argv[0], "\": ", Jim_UnixError(interp), 0);
        clearerr(outfilePtr->f);
        return TCL_ERROR;
    }

    Jim_SetIntResult(interp, count);

    return JIM_OK;
}
#endif

static int bio_cmd_write(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{







|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189

    if (ferror(outfilePtr->f)) {
        Jim_AppendResult(interp, "error writing \"", argv[0], "\": ", Jim_UnixError(interp), 0);
        clearerr(outfilePtr->f);
        return TCL_ERROR;
    }

    Jim_SetResultInt(interp, count);

    return JIM_OK;
}
#endif

static int bio_cmd_write(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Changes to jim-file.c.
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
        return "link";
    } else if (S_ISSOCK(mode)) {
        return "socket";
    }
    return "unknown";
}

static void Jim_SetIntResult(Jim_Interp *interp, jim_wide wide)
{
    Jim_SetResult(interp, Jim_NewIntObj(interp, wide));
}

/*
 *----------------------------------------------------------------------
 *
 * StoreStatData --
 *
 *  This is a utility procedure that breaks out the fields of a
 *  "stat" structure and stores them in textual form into the







<
<
<
<
<







90
91
92
93
94
95
96





97
98
99
100
101
102
103
        return "link";
    } else if (S_ISSOCK(mode)) {
        return "socket";
    }
    return "unknown";
}






/*
 *----------------------------------------------------------------------
 *
 * StoreStatData --
 *
 *  This is a utility procedure that breaks out the fields of a
 *  "stat" structure and stores them in textual form into the
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
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
426
427
428
static int file_cmd_atime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;

    if (file_stat(interp, argv[0], &sb) != JIM_OK) {
        return JIM_ERR;
    }
    Jim_SetIntResult(interp, sb.st_atime);
    return JIM_OK;
}

static int file_cmd_mtime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;

    if (file_stat(interp, argv[0], &sb) != JIM_OK) {
    return JIM_ERR;
    }
    Jim_SetIntResult(interp, sb.st_mtime);
    return JIM_OK;
}

static int file_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;

    if (file_stat(interp, argv[0], &sb) != JIM_OK) {
    return JIM_ERR;
    }
    Jim_SetIntResult(interp, sb.st_size);
    return JIM_OK;
}

static int file_cmd_isdirectory(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;
    int ret = 0;

    if (file_stat(interp, argv[0], &sb) == JIM_OK) {
    ret = S_ISDIR(sb.st_mode);
    }
    Jim_SetIntResult(interp, ret);
    return JIM_OK;
}

static int file_cmd_isfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;
    int ret = 0;

    if (file_stat(interp, argv[0], &sb) == JIM_OK) {
    ret = S_ISREG(sb.st_mode);
    }
    Jim_SetIntResult(interp, ret);
    return JIM_OK;
}

static int file_cmd_owned(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;
    int ret = 0;

    if (file_stat(interp, argv[0], &sb) == JIM_OK) {
    ret = (geteuid() == sb.st_uid);
    }
    Jim_SetIntResult(interp, ret);
    return JIM_OK;
}

#ifdef S_IFLNK
static int file_cmd_readlink(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    const char *path = Jim_GetString(argv[0], NULL);







|










|










|











|











|











|







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
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
static int file_cmd_atime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;

    if (file_stat(interp, argv[0], &sb) != JIM_OK) {
        return JIM_ERR;
    }
    Jim_SetResultInt(interp, sb.st_atime);
    return JIM_OK;
}

static int file_cmd_mtime(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;

    if (file_stat(interp, argv[0], &sb) != JIM_OK) {
    return JIM_ERR;
    }
    Jim_SetResultInt(interp, sb.st_mtime);
    return JIM_OK;
}

static int file_cmd_size(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;

    if (file_stat(interp, argv[0], &sb) != JIM_OK) {
    return JIM_ERR;
    }
    Jim_SetResultInt(interp, sb.st_size);
    return JIM_OK;
}

static int file_cmd_isdirectory(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;
    int ret = 0;

    if (file_stat(interp, argv[0], &sb) == JIM_OK) {
    ret = S_ISDIR(sb.st_mode);
    }
    Jim_SetResultInt(interp, ret);
    return JIM_OK;
}

static int file_cmd_isfile(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;
    int ret = 0;

    if (file_stat(interp, argv[0], &sb) == JIM_OK) {
    ret = S_ISREG(sb.st_mode);
    }
    Jim_SetResultInt(interp, ret);
    return JIM_OK;
}

static int file_cmd_owned(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    struct stat sb;
    int ret = 0;

    if (file_stat(interp, argv[0], &sb) == JIM_OK) {
    ret = (geteuid() == sb.st_uid);
    }
    Jim_SetResultInt(interp, ret);
    return JIM_OK;
}

#ifdef S_IFLNK
static int file_cmd_readlink(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
    const char *path = Jim_GetString(argv[0], NULL);
Changes to jim-regexp.c.
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68

#include <regex.h>
#include <string.h>

#define JIM_EXTENSION
#include "jim.h"

/* REVISIT: Would be useful in jim.h */
static void Jim_SetIntResult(Jim_Interp *interp, jim_wide wide)
{
    Jim_SetResult(interp, Jim_NewIntObj(interp, wide));
}

/**
 * REVISIT: Should cache a number of compiled regexps for performance reasons.
 */
static regex_t * 
compile_regexp(Jim_Interp *interp, const char *pattern, int flags)
{
    int ret;







<
<
<
<
<
<







49
50
51
52
53
54
55






56
57
58
59
60
61
62

#include <regex.h>
#include <string.h>

#define JIM_EXTENSION
#include "jim.h"







/**
 * REVISIT: Should cache a number of compiled regexps for performance reasons.
 */
static regex_t * 
compile_regexp(Jim_Interp *interp, const char *pattern, int flags)
{
    int ret;
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282

    done:
    if (result == JIM_OK) {
        if (opt_inline) {
            Jim_SetResult(interp, resultListObj);
        }
        else {
            Jim_SetIntResult(interp, num_matches);
        }
    }

    Jim_Free(pmatch);
    regfree(regex);
    Jim_Free(regex);
    return result;







|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276

    done:
    if (result == JIM_OK) {
        if (opt_inline) {
            Jim_SetResult(interp, resultListObj);
        }
        else {
            Jim_SetResultInt(interp, num_matches);
        }
    }

    Jim_Free(pmatch);
    regfree(regex);
    Jim_Free(regex);
    return result;
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
     */
    Jim_AppendString(interp, resultObj, p, -1);

    /* And now set the result variable */
    result = Jim_SetVariable(interp, varname, resultObj);

    if (result == JIM_OK) {
        Jim_SetIntResult(interp, num_matches);
    }
    else {
        Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
        Jim_AppendStrings(interp, Jim_GetResult(interp), "couldn't set variable \"", Jim_GetString(varname, NULL), "\"", NULL);
        Jim_FreeObj(interp, resultObj);
    }








|







446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
     */
    Jim_AppendString(interp, resultObj, p, -1);

    /* And now set the result variable */
    result = Jim_SetVariable(interp, varname, resultObj);

    if (result == JIM_OK) {
        Jim_SetResultInt(interp, num_matches);
    }
    else {
        Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
        Jim_AppendStrings(interp, Jim_GetResult(interp), "couldn't set variable \"", Jim_GetString(varname, NULL), "\"", NULL);
        Jim_FreeObj(interp, resultObj);
    }

Changes to jim.c.
8457
8458
8459
8460
8461
8462
8463

8464
8465
8466
8467
8468
8469
8470
8471


8472
8473
8474
8475
8476
8477
8478
8479
8480
8481
8482
8483
8484
8485
8486
8487
8488
8489
8490
8491
8492
8493
8494


8495

8496
8497
8498
8499
8500
8501
8502
8503
8504
8505
8506
8507
        }
        Jim_DecrRefCount(interp, objv[0]);
        Jim_DecrRefCount(interp, objv[1]);
    }
    return retval;
}


/* REVISIT: Just load the file with a single malloc/fread then Jim_EvalObj() */
int Jim_EvalFile(Jim_Interp *interp, const char *filename)
{
    char *prg = NULL;
    FILE *fp;
    int nread, totread, maxlen, buflen;
    int retval;
    Jim_Obj *scriptObjPtr;


    
    if ((fp = fopen(filename, "r")) == NULL) {
        const int cwd_len=2048;
        char *cwd=malloc(cwd_len);
        Jim_SetResult(interp, Jim_NewEmptyStringObj(interp));
        if (getcwd( cwd, cwd_len ) != 0) {
            strcpy(cwd, "?");
        }
        Jim_AppendStrings(interp, Jim_GetResult(interp),
            "Error loading script \"", filename, "\"",
            " cwd: ", cwd,
            " err: ", strerror(errno), NULL);
        free(cwd);
        return JIM_ERR;
    }
    buflen = 1024;
    maxlen = totread = 0;
    while (1) {
        if (maxlen < totread+buflen+1) {
            maxlen = totread+buflen+1;
            prg = Jim_Realloc(prg, maxlen);
        }
        if ((nread = fread(prg+totread, 1, buflen, fp)) == 0) break;


        totread += nread;

    }
    prg[totread] = '\0';
    fclose(fp);

    scriptObjPtr = Jim_NewStringObjNoAlloc(interp, prg, totread);
    JimSetSourceInfo(interp, scriptObjPtr, filename, 1);
    Jim_IncrRefCount(scriptObjPtr);
    retval = Jim_EvalObj(interp, scriptObjPtr);
    Jim_DecrRefCount(interp, scriptObjPtr);
    return retval;
}








>
|


<

|
<

>
>
|
|
<
<
|
<
<
<


<

<


<
<
<
<
<
<
|
<
>
>
|
>

<
<

|







8457
8458
8459
8460
8461
8462
8463
8464
8465
8466
8467

8468
8469

8470
8471
8472
8473
8474


8475



8476
8477

8478

8479
8480






8481

8482
8483
8484
8485
8486


8487
8488
8489
8490
8491
8492
8493
8494
8495
        }
        Jim_DecrRefCount(interp, objv[0]);
        Jim_DecrRefCount(interp, objv[1]);
    }
    return retval;
}

#include <sys/stat.h>

int Jim_EvalFile(Jim_Interp *interp, const char *filename)
{

    FILE *fp;
    char *buf;

    Jim_Obj *scriptObjPtr;
    struct stat sb;
    int retval;

    if (stat(filename, &sb) != 0 || (fp = fopen(filename, "r")) == NULL) {


        Jim_SetResultString(interp, "", 0);



        Jim_AppendStrings(interp, Jim_GetResult(interp),
            "Error loading script \"", filename, "\"",

            " err: ", strerror(errno), NULL);

        return JIM_ERR;
    }








    buf = Jim_Alloc(sb.st_size + 1);
    if (buf == 0 || fread(buf, sb.st_size, 1, fp) != 1) {
        Jim_Free(buf);
        return JIM_ERR;
    }



    scriptObjPtr = Jim_NewStringObjNoAlloc(interp, buf, sb.st_size);
    JimSetSourceInfo(interp, scriptObjPtr, filename, 1);
    Jim_IncrRefCount(scriptObjPtr);
    retval = Jim_EvalObj(interp, scriptObjPtr);
    Jim_DecrRefCount(interp, scriptObjPtr);
    return retval;
}

Deleted make-c-ext.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/env tclsh

proc tcl_to_string {str} {
	set result {}
	foreach buf [split $str \n] {
		set trimmed [string trim $buf]
		if {[string match "#*" $trimmed] || $trimmed == ""} {
			continue
		}
		regsub -all {\\} $buf {\\\\} buf 
		regsub -all \" $buf "\\\"" buf
		append result {"} $buf {\n"} \n
	}
	return $result
}

foreach file $argv {
	if {![string match *.tcl $file]} {
		error "Not a tcl file: $file"
	}
	set tmp [file tail $file]
	set rootname [file rootname $tmp]
	set outfile jim-$rootname.c
	puts "$file -> $outfile"
	set f [open $file]
	set str [read $f]
	close $f
	set f [open $outfile w]
	puts $f {#include <jim.h>}
	puts $f "int Jim_${rootname}Init(Jim_Interp *interp)"
	puts $f "{"
	puts $f "\treturn Jim_EvalGlobal(interp, "
	puts -nonewline $f [tcl_to_string $str]
	puts $f ");\t}"
	close $f
}
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








































































Added make-c-ext.tcl.
















































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#!/usr/bin/env tclsh

proc tcl_to_string {str} {
	set result {}
	foreach buf [split $str \n] {
		set trimmed [string trim $buf]
		if {[string match "#*" $trimmed] || $trimmed == ""} {
			continue
		}
		regsub -all {\\} $buf {\\\\} buf 
		regsub -all \" $buf "\\\"" buf
		append result {"} $buf {\n"} \n
	}
	return $result
}

set outfile [lindex $argv 0]
set argv [lrange $argv 1 end]

foreach file $argv {
	if {![string match *.tcl $file]} {
		error "Not a tcl file: $file"
	}
	set tmp [file tail $file]
	set rootname [file rootname $tmp]
	if {0} {
	set outfile jim-$rootname.c
	}
	set f [open $file]
	set str [read $f]
	close $f
	set f [open $outfile w]
	puts $f {#include <jim.h>}
	puts $f "int Jim_${rootname}Init(Jim_Interp *interp)"
	puts $f "{"
	puts $f "\treturn Jim_EvalGlobal(interp, "
	puts -nonewline $f [tcl_to_string $str]
	puts $f ");\t}"
	close $f
}
Changes to make-load-extensions.sh.
1
2
3
4
5
6


7
8
9
10
11
12
13
14
15
16
17
18
#!/bin/sh

exec >$1

shift



echo '#include "jim.h"'
for i in "$@"; do
	name=`echo $i | sed -e 's@.*/\(.*\).c@\1@'`
	echo "extern int Jim_${name}Init(Jim_Interp *interp);"
done
echo "int Jim_InitStaticExtensions(Jim_Interp *interp) {"
for i in "$@"; do
	name=`echo $i | sed -e 's@.*/\(.*\).c@\1@'`
	echo "if (Jim_${name}Init(interp) != JIM_OK) return JIM_ERR;"
done
	echo "return JIM_OK;"
echo "}"






>
>

|
<



|
<




1
2
3
4
5
6
7
8
9
10

11
12
13
14

15
16
17
18
#!/bin/sh

exec >$1

shift

exts=$(echo "$@" | sed -e 's@[^ ]*jim-@@g' -e 's@[.]c@@g')

echo '#include "jim.h"'
for name in $exts; do

	echo "extern int Jim_${name}Init(Jim_Interp *interp);"
done
echo "int Jim_InitStaticExtensions(Jim_Interp *interp) {"
for name in $exts; do

	echo "if (Jim_${name}Init(interp) != JIM_OK) return JIM_ERR;"
done
	echo "return JIM_OK;"
echo "}"