├── AUTHORS ├── BUGS ├── COPYING ├── ChangeLog ├── LICENSE ├── Makefile ├── Makefile.vc ├── README ├── STYLE ├── TODO ├── bench.tcl ├── doc ├── AIO-Extension.txt ├── Embedder-HOWTO.txt ├── Sqlite-Extension.txt └── jim_man.txt ├── ecos ├── ecos.db ├── language │ └── tcl │ │ └── jim │ │ └── current │ │ ├── ChangeLog │ │ ├── cdl │ │ └── jimtcl.cdl │ │ ├── doc │ │ └── jimtcl.sgml │ │ ├── include │ │ ├── jim-eventloop.h │ │ └── jim.h │ │ └── src │ │ ├── jim-aio.c │ │ ├── jim-eventloop.c │ │ └── jim.c ├── pkgconf │ └── rules.mak ├── readme.txt └── update.sh ├── freebsd ├── andrew.txt ├── clemens.txt ├── duane.txt ├── oharboe.txt ├── pat.txt ├── salvatore.txt └── uwe.txt ├── jim-aio.c ├── jim-array-1.0.tcl ├── jim-eventloop.c ├── jim-eventloop.h ├── jim-glob-1.0.tcl ├── jim-hwio.c ├── jim-hwio.inoutblock.h ├── jim-posix.c ├── jim-readdir.c ├── jim-readline.c ├── jim-regexp.c ├── jim-rlprompt-1.0.tcl ├── jim-sdl.c ├── jim-sqlite.c ├── jim-sqlite3.c ├── jim-stdlib-1.0.tcl ├── jim-win32.c ├── jim-win32api.c ├── jim-win32com.c ├── jim.c ├── jim.h ├── jimsh.c ├── regtest.tcl ├── test.tcl └── tools └── benchtable.tcl /AUTHORS: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antirez/Jim/a1a87f72fc61cc085680019eef45312fb2a52d13/AUTHORS -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | Known bugs: 2 | 3 | EXPR: || and && are not lazy. ?: is not implemented. Double math not 4 | implemented. Functions like sin(), cos(), not implemented. 5 | 6 | [subst] ingores special meaning of JIM_BREAK and alike. 7 | 8 | [list #] should generate {#} and not #, this was also broken in Tcl 8.4, fixed in 9 | 8.5. 10 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antirez/Jim/a1a87f72fc61cc085680019eef45312fb2a52d13/COPYING -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antirez/Jim/a1a87f72fc61cc085680019eef45312fb2a52d13/LICENSE -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Jim makefile 2 | # 3 | # This is a simple Makefile as it is expected that most users are likely 4 | # to embed Jim directly into their current build system. Jim is able to 5 | # make use of dynamically loaded extensions on unix provided you have the 6 | # dl library available. If not, set JIM_LIBS= on the make command line. 7 | # 8 | # make CC=gcc jim builds a standard Jim binary using gcc. 9 | # make CC=gcc LIBS= jim avoids attempts to link in libdl.a 10 | # 11 | # 12 | 13 | .SUFFIXES: 14 | .SUFFIXES: .c .so .xo .o .dll 15 | .PHONY: jim-aio-1.0.so 16 | 17 | SHELL = /bin/sh 18 | RM = rm -f 19 | OPT = -Os 20 | LDFLAGS = $(PROFILE) 21 | CFLAGS = -Wall -Wwrite-strings -W $(OPT) -g $(PROFILE) 22 | AR = /usr/bin/ar 23 | RANLIB = /usr/bin/ranlib 24 | LIBPATH =-L. 25 | INSTALL = /usr/bin/install 26 | INSTALL_PROGRAM= $(INSTALL) 27 | INSTALL_DATA= $(INSTALL) -m 644 28 | DESTDIR = /usr/local/bin/ 29 | 30 | PROGRAMS = jim jim.exe 31 | JIM_OBJECTS = jim.o jimsh.o 32 | LIBS = -ldl 33 | 34 | stopit: 35 | @echo "Use:" 36 | @echo "make jim - to build the Jim interpreter" 37 | @echo "---" 38 | @echo "make eventloop - to build only the event loop extension (.SO)" 39 | @echo "make aio - to build only the ANSI I/O extension (.SO)" 40 | @echo "make aio-dll - to build only the ANSI I/O extension (.DLL)" 41 | @echo "---" 42 | @echo "make unix-ext - to build the AIO, POSIX and SDL extensions" 43 | @echo "make posix - to build only the POSIX extension" 44 | @echo "make hwio - to build only Hardware IO extension" 45 | @echo "make sdl - to build only the SDL extension" 46 | @echo "make readline - to build only the READLINE extension" 47 | @echo "---" 48 | @echo "make win32-ext - to build the WIN32 and WIN32COM extensions" 49 | @echo "make win32 - to build only the WIN32 extension" 50 | @echo "make win32com - to build only the WIN32COM extension" 51 | @echo "" 52 | @echo "Note, if 'make jim' does not work try 'make jim LIBS=\"\"'" 53 | @echo "" 54 | @echo "For default Jim is compiled with -Os, if you need more" 55 | @echo "speed try: 'make OPT=\"-O3 -fomit-frame-pointer\"' but" 56 | @echo "this will result in a much larger binary." 57 | 58 | all: $(DEFAULT_BUILD) 59 | 60 | profile: 61 | @$(MAKE) clean jim PROFILE=-pg 62 | 63 | .c.o: 64 | $(CC) -I. $(CFLAGS) $(DEFS) -c $< -o $@ 65 | 66 | .c.xo: 67 | $(CC) -I. $(CFLAGS) $(DEFS) -fPIC -c $< -o $@ 68 | 69 | jim-win32-1.0.dll: im-win32.o 70 | $(CC) -shared -o $@ $< 71 | 72 | jim-aio-1.0.dll: jim-aio.o 73 | $(CC) -shared -o $@ $< 74 | 75 | jim-win32com-1.0.dll: jim-win32com.o 76 | $(CC) -shared -o $@ $< -lole32 -luuid -loleaut32 77 | 78 | jim-aio-1.0.so: jim-aio.xo 79 | $(LD) -G -z text -o $@ $< $(LIBS) -lc 80 | 81 | jim-posix-1.0.so: jim-posix.xo 82 | $(LD) -G -z text -o $@ $< $(LIBS) -lc 83 | 84 | jim-hwio-1.0.so: jim-hwio.xo 85 | $(LD) -G -z text -o $@ $< $(LIBS) -lc 86 | 87 | jim-eventloop-1.0.so: jim-eventloop.xo 88 | $(LD) -G -z text -o $@ $< $(LIBS) -lc 89 | 90 | jim-udp-1.0.so: jim-udp.xo 91 | $(LD) -G -z text -o $@ $< $(LIBS) -lc 92 | 93 | jim-sqlite-1.0.so: jim-sqlite.xo 94 | $(LD) -G -z text -o $@ $< $(LIBS) -lc -lsqlite 95 | 96 | jim-readline-1.0.so: jim-readline.xo 97 | $(LD) -G -z text -o $@ $< $(LIBS) -lc -lreadline 98 | 99 | jim-sdl.xo: jim-sdl.c 100 | $(CC) `sdl-config --cflags` -I. $(CFLAGS) $(DEFS) -fPIC -c $< -o $@ 101 | 102 | jim-sdl-1.0.so: jim-sdl.xo 103 | rm -f $@ 104 | $(LD) -G -z text -o $@ $< $(LIBS) -lc -L/usr/local/lib -lSDL -lSDL_gfx -lpthread 105 | 106 | jim: $(JIM_OBJECTS) 107 | $(CC) $(LDFLAGS) -o jim $(JIM_OBJECTS) $(LIBS) 108 | 109 | readline: jim-readline-1.0.so 110 | posix: jim-posix-1.0.so 111 | hwio: jim-hwio-1.0.so 112 | eventloop: jim-eventloop-1.0.so 113 | udp: jim-udp-1.0.so 114 | sqlite: jim-sqlite-1.0.so 115 | aio: jim-aio-1.0.so 116 | aio-dll: jim-aio-1.0.dll 117 | sdl: jim-sdl-1.0.so 118 | win32: jim-win32-1.0.dll 119 | win32com: jim-win32com-1.0.dll 120 | unix-extensions: posix aio sdl hwio 121 | win32-extensions: win32 win32com 122 | 123 | clean: 124 | $(RM) *.o *.so *.dll *.xo core .depend .*.swp gmon.out $(PROGRAMS) 125 | 126 | test: jim 127 | ./jim test.tcl 128 | ./jim regtest.tcl 129 | 130 | bench: jim 131 | ./jim bench.tcl 132 | 133 | dep: 134 | gcc -MM *.[ch] 2> /dev/null 135 | 136 | TAGS: jim.h jim.c jim-posix.c jim-hwio.c jim-win32.c jim-win32com.c 137 | etags -o $@ $^ 138 | 139 | wc: 140 | wc -l jim.[ch] 141 | wc -l *.[ch] 142 | 143 | clog: 144 | cvs2cl 145 | 146 | commit: 147 | cvs2cl 148 | cvs commit 149 | 150 | update: 151 | cvs update 152 | cvs2cl 153 | 154 | bak: 155 | cp -f jim.c jim.c.orig 156 | cp -f jimsh.c jimsh.c.orig 157 | cp -f jim.h jim.h.orig 158 | 159 | # Dependences 160 | jim-aio.o: jim-aio.c jim.h 161 | jim-posix.o: jim-posix.c jim.h 162 | jim-hwio.o: jim-hwio.c jim-hwio.inoutblock.h jim.h 163 | jim-sdl.o: jim-sdl.c jim.h 164 | jim-win32com.o: jim-win32com.c jim.h 165 | jim.o: jim.c jim.h 166 | jimsh.o: jimsh.c jim.h 167 | 168 | 169 | -------------------------------------------------------------------------------- /Makefile.vc: -------------------------------------------------------------------------------- 1 | # -*- Makefile -*- 2 | # 3 | # This is a Microsoft Visual C NMAKE makefile to use in building the 4 | # Jim interpreter. 5 | # 6 | # Usage: 7 | # nmake -f Makefile.vc clean all 8 | # 9 | # To build a debug build, add DEBUG=1 to the command line. To build 10 | # for profiling, add PROFILE=1. eg: 11 | # nmake -f Makefile.vc DEBUG=1 clean all 12 | # 13 | # 14 | # Copyright (C) 2005 Pat Thoyts 15 | # 16 | 17 | SRCDIR =. 18 | 19 | !ifndef DEBUG 20 | DEBUG =0 21 | !endif 22 | !ifndef PROFILE 23 | PROFILE =0 24 | !endif 25 | !ifndef SYMBOLS 26 | SYMBOLS = 0 27 | !endif 28 | !ifndef CC 29 | CC=cl 30 | !endif 31 | !ifndef LINK 32 | LINK=link 33 | !endif 34 | 35 | # If you have sqlite3 installed and want to build the extension add 36 | # SQLITE3DIR=c:\path\to\sqlite3 37 | # 38 | !ifndef SQLITE3DIR 39 | SQLITE3 =0 40 | !else 41 | SQLITE3 =1 42 | SQLITE_INC=-I$(SQLITE3DIR) 43 | SQLITE_LIB=-libpath:$(SQLITE3DIR) libsqlite3.lib 44 | !endif 45 | 46 | #------------------------------------------------------------------------- 47 | # There should be no need to edit below this point. 48 | #------------------------------------------------------------------------- 49 | 50 | !if $(DEBUG) 51 | OUTDIR =Debug 52 | CFLAGS =-Od -Zi -GZ -MDd -D_DEBUG 53 | LDFLAGS=-debug:full -debugtype:cv 54 | !else 55 | OUTDIR =Release 56 | !if $(SYMBOLS) 57 | CFLAGS =-Od -Zi -Op -Gs -MD -DNDEBUG 58 | LDFLAGS=-debug -opt:ref -opt:icf,3 59 | !else 60 | CFLAGS =-O2 -Otip -Gs -MD -DNDEBUG 61 | LDFLAGS=-release -opt:ref -opt:icf,3 62 | !endif 63 | !endif 64 | 65 | !if $(PROFILE) 66 | CFLAGS =$(CFLAGS) -Zi 67 | LDFLAGS=$(LDFLAGS) -profile -map 68 | !endif 69 | 70 | !if "$(OS)" == "Windows_NT" 71 | RMDIR = rmdir /s /q >NUL 72 | !else 73 | RMDIR = deltree /y 74 | !endif 75 | DEL = del /f /q 76 | 77 | TMPDIR =$(OUTDIR)\Objects 78 | 79 | CC =$(CC) -nologo 80 | LD =$(LINK) -nologo 81 | 82 | CFLAGS =$(CFLAGS) -W3 -YX -Fp$(TMPDIR)^\ 83 | INC = 84 | DEFS =-DWIN32 85 | LIBS = 86 | 87 | all: jim aio win32 win32com win32api dll #sqlite3 eventloop 88 | jim: setup $(OUTDIR)\jim.exe 89 | jimwish: setup $(OUTDIR)\jimwish.exe 90 | dll: setup $(OUTDIR)\jim.dll 91 | aio: setup $(OUTDIR)\jim-aio-1.0.dll 92 | sqlite3: setup $(OUTDIR)\jim-sqlite3-1.0.dll 93 | eventloop: setup $(OUTDIR)\jim-eventloop-1.0.dll 94 | win32: setup $(OUTDIR)\jim-win32-1.0.dll 95 | win32api: setup $(OUTDIR)\jim-win32api-1.0.dll 96 | win32com: setup $(OUTDIR)\jim-win32com-1.0.dll 97 | 98 | $(OUTDIR)\jim.exe: $(TMPDIR)\jim.obj $(TMPDIR)\jimsh.obj 99 | @$(LD) $(LDFLAGS) -out:$@ $** $(LIBS) 100 | 101 | $(OUTDIR)\jim.dll: $(TMPDIR)\jim.dll.obj 102 | @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS) 103 | @if exist $(@:.dll=.exp) $(DEL) $(@:.dll=.exp) 104 | 105 | $(OUTDIR)\jim-win32-1.0.dll: $(TMPDIR)\jim-win32.obj 106 | @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS) >NUL 107 | @if exist $(@:.dll=.exp) $(DEL) $(@:.dll=.exp) 108 | 109 | $(OUTDIR)\jim-win32api-1.0.dll: $(TMPDIR)\jim-win32api.obj 110 | @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS) >NUL 111 | @if exist $(@:.dll=.exp) $(DEL) $(@:.dll=.exp) 112 | 113 | $(OUTDIR)\jim-win32com-1.0.dll: $(TMPDIR)\jim-win32com.obj 114 | @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS) >NUL 115 | @if exist $(@:.dll=.exp) $(DEL) $(@:.dll=.exp) 116 | 117 | $(OUTDIR)\jim-aio-1.0.dll: $(TMPDIR)\jim-aio.obj 118 | @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS) >NUL 119 | @if exist $(@:.dll=.exp) $(DEL) $(@:.dll=.exp) 120 | 121 | $(OUTDIR)\jim-eventloop-1.0.dll: $(TMPDIR)\jim-eventloop.obj 122 | @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS) >NUL 123 | @if exist $(@:.dll=.exp) $(DEL) $(@:.dll=.exp) 124 | 125 | $(OUTDIR)\jim-sqlite3-1.0.dll: $(TMPDIR)\jim-sqlite3.obj 126 | !if $(SQLITE3) 127 | @$(LD) $(LDFLAGS) -dll -out:$@ $** $(LIBS) $(SQLITE_LIB) >NUL 128 | @if exist $(@:.dll=.exp) $(DEL) $(@:.dll=.exp) 129 | !else 130 | @echo cannot build sqlite3 extension - SQLITE3DIR not defined 131 | !endif 132 | 133 | $(OUTDIR)\jimwish.exe: $(TMPDIR)\jim.obj $(TMPDIR)\jimwish.obj 134 | @$(LD) $(LDFLAGS) -out:$@ $** $(LIBS) user32.lib 135 | 136 | .PHONY: all jim dll win32 win32api win32com jim jimwish aio sqlite3 137 | 138 | #------------------------------------------------------------------------- 139 | setup: 140 | @if not exist $(OUTDIR) mkdir $(OUTDIR) 141 | @if not exist $(TMPDIR) mkdir $(TMPDIR) 142 | 143 | test: jim 144 | $(OUTDIR)\jim.exe test.tcl 145 | 146 | clean: 147 | @if exist $(TMPDIR)\NUL $(RMDIR) $(TMPDIR) >NUL 148 | 149 | realclean: clean 150 | @if exist $(OUTDIR)\NUL $(RMDIR) $(OUTDIR) >NUL 151 | 152 | #------------------------------------------------------------------------- 153 | 154 | .SUFFIXES:.c .cpp 155 | 156 | {$(SRCDIR)}.c{$(TMPDIR)}.obj:: 157 | @$(CC) $(CFLAGS) $(DEFS) $(INC) -Fo$(TMPDIR)\ -c @<< 158 | $< 159 | << 160 | 161 | {$(SRCDIR)}.cpp{$(TMPDIR)}.obj:: 162 | @$(CC) $(CFLAGS) $(DEFS) $(INC) -Fo$(TMPDIR)\ -c @<< 163 | $< 164 | << 165 | 166 | $(TMPDIR)\jim.obj: $(SRCDIR)\jim.c $(SRCDIR)\jim.h 167 | $(TMPDIR)\jim-aio.obj: $(SRCDIR)\jim-aio.c $(SRCDIR)\jim.h 168 | $(TMPDIR)\jim-eventloop.obj: $(SRCDIR)\jim-eventloop.c $(SRCDIR)\jim.h 169 | $(TMPDIR)\jim-win32.obj: $(SRCDIR)\jim-win32.c $(SRCDIR)\jim.h 170 | $(TMPDIR)\jim-win32api.obj: $(SRCDIR)\jim-win32api.c $(SRCDIR)\jim.h 171 | $(TMPDIR)\jim-win32com.obj: $(SRCDIR)\jim-win32com.c $(SRCDIR)\jim.h 172 | $(TMPDIR)\jim.dll.obj: $(SRCDIR)\jim.c $(SRCDIR)\jim.h 173 | @$(CC) -DBUILD_Jim $(CFLAGS) $(DEFS) $(INC) -Fo$@ -c $(SRCDIR)\jim.c 174 | $(TMPDIR)\jim-sqlite3.obj: $(SRCDIR)\jim-sqlite3.c $(SRCDIR)\jim.h 175 | !if $(SQLITE3) 176 | @$(CC) $(CFLAGS) $(DEFS) $(INC) $(SQLITE_INC) -Fo$(TMPDIR)\ -c $(SRCDIR)\jim-sqlite3.c 177 | !else 178 | @echo cannot build sqlite3 extension - SQLITE3DIR not defined 179 | !endif 180 | 181 | #------------------------------------------------------------------------- 182 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | The Jim Interpreter 2 | A small-footprint implementation of the Tcl programming language. 3 | 4 | -------------------------------------------------------------------------------- 5 | WHAT IS JIM? 6 | -------------------------------------------------------------------------------- 7 | 8 | Jim is a small footprint implementation of the Tcl programming language 9 | written from scratch. Currently it's a work in progress, but already 10 | capable to run non-trivial scripts (see the benchmark.tcl file for 11 | an example). There are many Tcl core commands not implemented, but the 12 | language itself offers already interesting features like {expand} and 13 | [dict], that are features that will appear on Tcl8.5, [lambda] with 14 | garbage collection, and a general GC/references system to build linked 15 | data structure with automatic memory management. Arrays in Jim are 16 | not collection of variables, but instead syntax sugar for [dict]tionaries. 17 | 18 | Other common features of the Tcl programming language are present, like 19 | the "everything is a string" behaviour, implemented internally as 20 | dual ported objects to ensure that the execution time does not reflect 21 | the semantic of the language :) 22 | 23 | -------------------------------------------------------------------------------- 24 | WHEN JIM CAN BE USEFUL? 25 | -------------------------------------------------------------------------------- 26 | 27 | 1) If you are writing an application, and want to make it scriptable, with 28 | Jim you have a way to do it that does not require to link your application 29 | with a big system. You can just put jim.c and jim.h files in your project 30 | and use the Jim API to write the glue code that makes your application 31 | scriptable in Jim, with the following advantages: 32 | 33 | - Jim is not the next "little language", but it's a Tcl implementation. 34 | You can reuse your knowledge if you already Tcl skills, or enjoy 35 | the availability of documentation, books, web resources, ... 36 | (for example check my online Tcl book at http://www.invece.org/tclwise) 37 | 38 | - Jim is simple, 10k lines of code. If you want to adapt it you can hack 39 | the source code to feet the needs of your application. It makes you 40 | able to have scripting for default, and avoid external dependences. 41 | 42 | Having scripting support *inside*, and in a way that a given version 43 | of your program always gets shipped a given version of Jim, you can 44 | write part of your application in Jim itself. Like it happens for 45 | Emacs/Elisp, or Gimp/Scheme, both this applications have the interpreter 46 | inside. 47 | 48 | - Jim is Tcl, and Tcl looks like a configuration file if you want. So 49 | if you use Jim you have also a flexible syntax for your config file. 50 | This is a valid Tcl script: 51 | 52 | set MyFeature on 53 | ifssl { 54 | set SslPort 45000 55 | use compression 56 | } 57 | 58 | It looks like a configuration file, but if you implement the [ifssl] 59 | and [use] commands, it's a valid Tcl script. 60 | 61 | - Tcl scales with the user. Not all know it, but Tcl is so powerful that 62 | you can reprogram the language in itself. Jim support this features 63 | of the Tcl programming language. You can write new control structures, 64 | use the flexible data types it offers (Lists are a central data structure, 65 | with Dictionaries that are also lists). Still Tcl is simpler for the 66 | casual programmer, especially if compared to other languages offering 67 | small footprint implementations (like Scheme and FORTH). 68 | 69 | - Because of the Tcl semantic (pass by value, everything is a command 70 | since there are no reserved words), there is a nice API to glue 71 | your application with Jim. See under the 'docs' directory to find 72 | examples and documentation about it. 73 | 74 | - Jim is supported. If you need commercial software, contact the author 75 | writing an email to 'antirez@gmail.com'. 76 | 77 | 2) The other "field" where Jim can be useful is obviously embedded systems. 78 | 79 | 3) We are working to make Jim as feature-complete as possible, thanks to 80 | dynamically loaded extensions it may stay as little as it is today 81 | but able to do interesting things for you. So it's not excluded that 82 | in the future Jim will be an option as general purpose language. 83 | But don't mind, for this there is already the mainstream Tcl 84 | implementation ;). 85 | 86 | -------------------------------------------------------------------------------- 87 | HOW BIG IS IT? 88 | -------------------------------------------------------------------------------- 89 | 90 | Jim compiled with -Os is 85k currently. Still it lacks core commands 91 | that will make it a little bigger, but not too much... only what's 92 | strictly required will end inside the core, the rest will be implemented 93 | as extensions. 94 | 95 | Note that the actual Jim core is much smaller, if you strip away commands. 96 | If you can do without [expr] (that's big about code size), and some 97 | other command you may probably end with a 40k executable. 98 | 99 | -------------------------------------------------------------------------------- 100 | HOW FAST IS IT? 101 | -------------------------------------------------------------------------------- 102 | 103 | Jim is in most code faster than Tcl7.6p2 (latest 7.x version), 104 | and slower than Tcl 8.4.x. You can expect pretty decent performances 105 | for such a little interpreter. 106 | 107 | If you want a more precise measure, there is 'bench.tcl' inside this 108 | distribution that will run both under Jim and Tcl, so just execute 109 | it with both the interpreters and see what you get :) 110 | 111 | -------------------------------------------------------------------------------- 112 | HOW TO COMPILE 113 | -------------------------------------------------------------------------------- 114 | 115 | Jim was tested under Linux, FreeBSD, MacosX, Windows XP (mingw, MVC). 116 | 117 | To compile jim itself try: 118 | 119 | make jim 120 | 121 | In non-linux systems you may have to complile without "-ldl" because 122 | it's not needed but will cause a compilation error (no configure for 123 | now... applications embedding Jim will probably have one already). 124 | 125 | In order to avoid to link against 'dl' just use: 126 | 127 | make LIBS="" jim 128 | 129 | For instructions about how to compile extensions just try 'make' 130 | and see the available options. Check also the next section of this file. 131 | 132 | -------------------------------------------------------------------------------- 133 | HOW TO COMPILE IN SYSTEMS WITH JUST ANSI-C SUPPORT 134 | -------------------------------------------------------------------------------- 135 | 136 | Try: 137 | 138 | make LIBS="" DEFS="-DJIM_ANSIC" jim 139 | 140 | This should compile Jim almost everywhere there is a decent ANSI-C compiler. 141 | 142 | -------------------------------------------------------------------------------- 143 | EXTENSIONS 144 | -------------------------------------------------------------------------------- 145 | 146 | POSIX 147 | ===== 148 | 149 | This is the start of a library that should export to Jim useful bits of the 150 | POSIX API. For now there are just a few utility functions, but it's 151 | an example on how to write a simple library for Jim. 152 | 153 | WIN32 154 | ===== 155 | 156 | This is the start of a library that should export to Jim useful bits of the 157 | WIN32 API. Currently there is just one function that is used to call windows 158 | applications. For example run jim and try the extension with: 159 | 160 | package require win32 161 | win32.shellexecute open notepad 162 | 163 | You should see a notepad application running. 164 | 165 | ANSI-I/O, SQLITE 166 | ================ 167 | 168 | There is documentation under the "doc" dictory about the "ANSI I/O" 169 | and "SQLITE" extensions. 170 | 171 | SDL 172 | === 173 | 174 | The SDL extension is currently undocumented (work in progress), but 175 | there is enought to start to play. That's an example script: 176 | 177 | package require sdl 178 | 179 | set xres 800 180 | set yres 800 181 | set s [sdl.screen $xres $yres] 182 | 183 | set i 0 184 | while 1 { 185 | set x1 [rand $xres] 186 | set y1 [rand $yres] 187 | set x2 [rand $xres] 188 | set y2 [rand $yres] 189 | set rad [rand 40] 190 | set r [rand 256] 191 | set g [rand 256] 192 | set b [rand 256] 193 | $s fcircle $x1 $y1 $rad $r $g $b 200 194 | incr i 195 | if {$i > 2000} {$s flip} 196 | if {$i == 3000} exit 197 | } 198 | 199 | -------------------------------------------------------------------------------- 200 | HOW TO EMBED JIM INTO APPLICATIONS / HOW TO WRITE EXTENSIONS FOR JIM 201 | -------------------------------------------------------------------------------- 202 | 203 | See the documentation under the "doc" directory (work in progress). 204 | 205 | -------------------------------------------------------------------------------- 206 | COPYRIGHT and LICENSE 207 | -------------------------------------------------------------------------------- 208 | 209 | Copyright (C) 2005 Salvatore Sanfilippo 210 | All Rights Reserved 211 | 212 | Licensed under the Apache License, Version 2.0 (the "License"); 213 | you may not use this file except in compliance with the License. 214 | You may obtain a copy of the License at 215 | 216 | http://www.apache.org/licenses/LICENSE-2.0 217 | 218 | A copy of the license is also included in the source distribution 219 | of Jim, as a TXT file name called LICENSE. 220 | 221 | Unless required by applicable law or agreed to in writing, software 222 | distributed under the License is distributed on an "AS IS" BASIS, 223 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 224 | See the License for the specific language governing permissions and 225 | limitations under the License. 226 | 227 | -------------------------------------------------------------------------------- 228 | HISTORY 229 | -------------------------------------------------------------------------------- 230 | 231 | "first Jim goal: to vent my need to hack on Tcl." 232 | 233 | And actually this is exactly why I started Jim, in the first days 234 | of Jenuary 2005. After a month of hacking Jim was able to run 235 | simple scripts, now, after two months it started to be clear to 236 | me that it was not just the next toy to throw away but something 237 | that may evolve into a real interpreter. In the same time 238 | Pat Thoyts and Clemens Hintze started to contribute code, so that 239 | the development of new core commands was faster, and also more 240 | people hacking on the same code had as result fixes in the API, 241 | C macros, and so on. 242 | 243 | Currently we are at the point that the core interpreter is almost finished 244 | and it is entering the Beta stage. There is to add some other core command, 245 | to do a code review to ensure quality of all the parts and to write 246 | documentation. 247 | 248 | We already started to work on extensions like OOP, event loop, 249 | I/O, networking, regexp. Some extensions are already ready for 250 | prime time, like the Sqlite extension and the ANSI I/O. 251 | 252 | ------------------------------------------------------------------------------ 253 | Thanks to... 254 | ------------------------------------------------------------------------------ 255 | 256 | - First of all, thanks to every guy that are listed in the AUTHORS file, 257 | that directly helped with code and ideas. Also check the ChangeLog 258 | file for additional credits about patches or bug reports. 259 | - Elisa Manara that helped me to select this ill conceived name for 260 | an interpreter. 261 | - Many people on the Tclers Chat that helped me to explore issues 262 | about the use and the implementation of the Tcl programming language. 263 | - David Welton for the tech info sharing and our chats about 264 | programming languages design and the ability of software to "scale down". 265 | - Martin S. Weber for the great help with Solaris issues, debugging of 266 | problems with [load] on this arch, 64bit tests. 267 | - The authors of "valgrind", for this wonderful tool, that helped me a 268 | lot to fix bugs in minutes instead of hours. 269 | 270 | 271 | ---- 272 | Enjoy! 273 | Salvatore Sanfilippo 274 | 10 Mar 2005 275 | 276 | 277 | -------------------------------------------------------------------------------- /STYLE: -------------------------------------------------------------------------------- 1 | This file summarizes the C style used for Jim. 2 | Copyright (C) 2005 Salvatore Sanfilippo. 3 | 4 | ----------- 5 | INDENTATION 6 | ----------- 7 | 8 | Indentation is 4 spaces, no smart-tabs are used (i.e. 9 | two indentation steps of 4 spaces will not be converted 10 | into a real tab, but 8 spaces). 11 | 12 | --------------- 13 | FUNCTIONS NAMES 14 | --------------- 15 | 16 | Functions names of exported functions are in the form: 17 | 18 | Jim_ExportedFunctionName() 19 | 20 | The prefix is "Jim_", every word composing the function name 21 | is capitalized. 22 | 23 | Not exported functions that are of general interest for the Jim 24 | core, like JimFreeInterp() are capitalized the same way, but the 25 | prefix used for this functions is "Jim" instead of "Jim_". 26 | Another example is: 27 | 28 | JimNotExportedFunction() 29 | 30 | Not exported functions that are not general, like functions 31 | implementing hashtables or Jim objects methods can be named 32 | in any prefix as long as capitalization rules are followed, 33 | like in: 34 | 35 | ListSetIndex() 36 | 37 | --------------- 38 | VARIABLES NAMES 39 | --------------- 40 | 41 | Global variables follow the same names convention of functions. 42 | 43 | Local variables have usually short names. A counter is just 'i', or 'j', 44 | or something like this. When a longer name is required, composed of 45 | more words, capitalization is used, but the first word starts in 46 | lowcase: 47 | 48 | thisIsALogVarName 49 | 50 | ---- 51 | GOTO 52 | ---- 53 | 54 | Goto is allowed every time it makes the code cleaner, like in complex 55 | functions that need to handle exceptions, there is often an "err" label 56 | at the end of the function where allocated resources are freed before to exit 57 | with an error. Goto is also used in order to excape multiple nexted loops. 58 | 59 | ---------- 60 | C FEATURES 61 | ---------- 62 | 63 | Only C89 ANSI C is allowed. C99 features can't be used currently. 64 | GCC extensions are not allowed. 65 | 66 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | CORE LANGUAGE FEATURES 2 | 3 | - Proc default arguments 4 | - Traces 5 | - [static] command 6 | 7 | CORE COMMANDS 8 | 9 | - All the missing standard core commands not related to I/O, namespaces, ... 10 | - The current [expr] needs a lot of work, expecially operators && and || 11 | are not lazy. Math functions are not present but probably will never 12 | be added as expr functions, but as Tcl commands, like [sin], [cos] and 13 | so on. 14 | - [onleave] command, executing something as soon as the current procedure 15 | returns. With no arguments it returns the script set, with one appends 16 | the onleave script. There should be a way to reset. 17 | - [proc] without arguments may return a list of all the procedures 18 | (no C commands). While with a single argument (the name of a proc) 19 | may return [list $args $statics $body]. 20 | 21 | OTHER COMMANDS NOT IN TCL BUT THAT SHOULD BE IN JIM 22 | 23 | - Set commands: [lunion], [lintersect], and [ldifference] 24 | 25 | EXTENSIONS LOADING 26 | 27 | - Avoid that the same extension can be loaded multiple times inside the 28 | same interpreter. The extension should return its name on initialization 29 | together with the version so that Jim_InitExtension will fail if the 30 | extension with the same name is already loaded. 31 | 32 | EXTENSIONS 33 | 34 | - Regexp extension 35 | - OOP system 36 | - Event loop 37 | - Files 38 | - Sockets 39 | - Cryptography: hash functions, block ciphers, strim ciphers, PRNGs. 40 | - Tuplespace extension (http://wiki.tcl.tk/3947) (using sqlite as backend) 41 | - Zlib 42 | - Gdlib 43 | - CGI (interface compatible with ncgi, but possibly written in C for speed) 44 | 45 | SPEED OPTIMIZATIONS 46 | 47 | - Find a way to avoid interpolation/reparsing in "foo($bar)" tokens. 48 | See the "sieve" and "ary" bench performances, result of this problem. 49 | (to compare with sieve_dict is also useful.) 50 | - Experiment with better ways to do literal sharing. 51 | - Organize the 'script' object so that a single data structure is 52 | used for a full command, and interpolation is done using an 53 | 'interpolation token type' like JIM_TT_VAR and so on. 54 | This way there is no need to run the array if integer objects 55 | with the command structure. Also should help for better cache usage. 56 | - Generate .c from Jim programs, as calls to the Jim API to avoid 57 | the performance penality of Jim_EvalObj() overhead. In the future 58 | try to generate the calls like a JIT emitting assembler from 59 | Jim directly. 60 | - Jim_GetDouble() should check if the object type is an integer into 61 | a range that a double can represent without any loss, and directly 62 | return the double value converting the integer one instead to pass 63 | for the string repr. 64 | 65 | IMPLEMENTATION ISSUES 66 | 67 | - Objects lazy free. 68 | - Rewrite all the commands accepting a set of options to use Jim_GetEnum(). 69 | - Every time an extension is loaded Jim should put the dlopen() (or win32 70 | equivalent) handle in a list inside the interpreter structure. When 71 | the interpreter is freed all this handles should be closed with dlclose(). 72 | - *AssocData() function should allow to specify a delProc C function like 73 | in the Tcl API. When the interpreter is destroied all the delProc functions 74 | should be called to free the memory before to free the interpreter. 75 | - Convert dicts from lists directly without to pass from the string repr. 76 | 77 | ERROR MESSAGES 78 | 79 | - Display the procedure relative file number where the error happened. 80 | Like: 81 | 82 | In procedure 'check' line 11, called at file "test.tcl", line 1024 83 | 84 | instead of just: 85 | 86 | In procedure 'check' called at file "test.tcl", line 1024 87 | 88 | REFERENCES SYSTEM 89 | 90 | - Unify ref/getref/setref/collect/finalize under an unique [ref] command. 91 | - Add a 'call' attribute to references in order to call a given procedure 92 | if the name of a reference is used as command name. 93 | 94 | API FUNCTIONS TO EXPORT 95 | 96 | - Jim_FormatString() 97 | 98 | RANDOM THINGS TO DO ASAP 99 | 100 | - .jimrc loading, using the ENV variable 101 | -------------------------------------------------------------------------------- /bench.tcl: -------------------------------------------------------------------------------- 1 | set batchmode 0 2 | set benchmarks {} 3 | 4 | proc bench {title script} { 5 | global benchmarks batchmode 6 | 7 | set Title [string range "$title " 0 20] 8 | 9 | set failed [catch {time $script} res] 10 | if {$failed} { 11 | if {!$batchmode} {puts "$Title - This test can't run on this interpreter"} 12 | lappend benchmarks $title F 13 | } else { 14 | set t [lindex $res 0] 15 | lappend benchmarks $title $t 16 | set ts " $t" 17 | set ts [string range $ts [expr {[string length $ts]-10}] end] 18 | if {!$batchmode} {puts "$Title -$ts microseconds per iteration"} 19 | } 20 | } 21 | 22 | ### BUSY LOOP ################################################################## 23 | 24 | proc whilebusyloop {} { 25 | set i 0 26 | while {$i < 1850000} { 27 | incr i 28 | } 29 | } 30 | 31 | proc forbusyloop {} { 32 | for {set i 0} {$i < 1850000} {incr i} {} 33 | } 34 | 35 | ### FIBONACCI ################################################################## 36 | 37 | proc fibonacci {x} { 38 | if {$x <= 1} { 39 | expr 1 40 | } else { 41 | expr {[fibonacci [expr {$x-1}]] + [fibonacci [expr {$x-2}]]} 42 | } 43 | } 44 | 45 | ### HEAPSORT ################################################################### 46 | 47 | set IM 139968 48 | set IA 3877 49 | set IC 29573 50 | 51 | set last 42 52 | 53 | proc make_gen_random {} { 54 | global IM IA IC 55 | set params [list IM $IM IA $IA IC $IC] 56 | set body [string map $params { 57 | global last 58 | expr {($max * [set last [expr {($last * IA + IC) % IM}]]) / IM} 59 | }] 60 | proc gen_random {max} $body 61 | } 62 | 63 | proc heapsort {ra_name} { 64 | upvar 1 $ra_name ra 65 | set n [llength $ra] 66 | set l [expr {$n / 2}] 67 | set ir [expr {$n - 1}] 68 | while 1 { 69 | if {$l} { 70 | set rra [lindex $ra [incr l -1]] 71 | } else { 72 | set rra [lindex $ra $ir] 73 | lset ra $ir [lindex $ra 0] 74 | if {[incr ir -1] == 0} { 75 | lset ra 0 $rra 76 | break 77 | } 78 | } 79 | set i $l 80 | set j [expr {(2 * $l) + 1}] 81 | while {$j <= $ir} { 82 | set tmp [lindex $ra $j] 83 | if {$j < $ir} { 84 | if {$tmp < [lindex $ra [expr {$j + 1}]]} { 85 | set tmp [lindex $ra [incr j]] 86 | } 87 | } 88 | if {$rra >= $tmp} { 89 | break 90 | } 91 | lset ra $i $tmp 92 | incr j [set i $j] 93 | } 94 | lset ra $i $rra 95 | } 96 | } 97 | 98 | proc heapsort_main {} { 99 | set n 6100 100 | make_gen_random 101 | 102 | set data {} 103 | for {set i 1} {$i <= $n} {incr i} { 104 | lappend data [gen_random 1.0] 105 | } 106 | heapsort data 107 | } 108 | 109 | ### SIEVE ###################################################################### 110 | 111 | proc sieve {num} { 112 | while {$num > 0} { 113 | incr num -1 114 | set count 0 115 | for {set i 2} {$i <= 8192} {incr i} { 116 | set flags($i) 1 117 | } 118 | for {set i 2} {$i <= 8192} {incr i} { 119 | if {$flags($i) == 1} { 120 | # remove all multiples of prime: i 121 | for {set k [expr {$i+$i}]} {$k <= 8192} {incr k $i} { 122 | set flags($k) 0 123 | } 124 | incr count 125 | } 126 | } 127 | } 128 | return $count 129 | } 130 | 131 | proc sieve_dict {num} { 132 | while {$num > 0} { 133 | incr num -1 134 | set count 0 135 | for {set i 2} {$i <= 8192} {incr i} { 136 | dict set flags $i 1 137 | } 138 | for {set i 2} {$i <= 8192} {incr i} { 139 | if {[dict get $flags $i] == 1} { 140 | # remove all multiples of prime: i 141 | for {set k [expr {$i+$i}]} {$k <= 8192} {incr k $i} { 142 | dict set flags $k 0 143 | } 144 | incr count 145 | } 146 | } 147 | } 148 | return $count 149 | } 150 | 151 | ### ARY ######################################################################## 152 | 153 | proc ary n { 154 | for {set i 0} {$i < $n} {incr i} { 155 | set x($i) $i 156 | } 157 | set last [expr {$n - 1}] 158 | for {set j $last} {$j >= 0} {incr j -1} { 159 | set y($j) $x($j) 160 | } 161 | } 162 | 163 | ### REPEAT ##################################################################### 164 | 165 | proc repeat {n body} { 166 | for {set i 0} {$i < $n} {incr i} { 167 | uplevel 1 $body 168 | } 169 | } 170 | 171 | proc use_repeat {} { 172 | set x 0 173 | repeat {1000000} {incr x} 174 | } 175 | 176 | ### UPVAR ###################################################################### 177 | 178 | proc myincr varname { 179 | upvar 1 $varname x 180 | incr x 181 | } 182 | 183 | proc upvartest {} { 184 | set y 0 185 | for {set x 0} {$x < 100000} {myincr x} { 186 | myincr y 187 | } 188 | } 189 | 190 | ### NESTED LOOPS ############################################################### 191 | 192 | proc nestedloops {} { 193 | set n 10 194 | set x 0 195 | incr n 1 196 | set a $n 197 | while {[incr a -1]} { 198 | set b $n 199 | while {[incr b -1]} { 200 | set c $n 201 | while {[incr c -1]} { 202 | set d $n 203 | while {[incr d -1]} { 204 | set e $n 205 | while {[incr e -1]} { 206 | set f $n 207 | while {[incr f -1]} { 208 | incr x 209 | } 210 | } 211 | } 212 | } 213 | } 214 | } 215 | } 216 | 217 | ### ROTATE ##################################################################### 218 | 219 | proc rotate {count} { 220 | set v 1 221 | for {set n 0} {$n < $count} {incr n} { 222 | set v [expr {$v <<< 1}] 223 | } 224 | } 225 | 226 | ### DYNAMICALLY GENERATED CODE ################################################# 227 | 228 | proc dyncode {} { 229 | for {set i 0} {$i < 100000} {incr i} { 230 | set script "lappend foo $i" 231 | eval $script 232 | } 233 | } 234 | 235 | proc dyncode_list {} { 236 | for {set i 0} {$i < 100000} {incr i} { 237 | set script [list lappend foo $i] 238 | eval $script 239 | } 240 | } 241 | 242 | ### PI DIGITS ################################################################## 243 | 244 | proc pi_digits {} { 245 | set N 300 246 | set LEN [expr {10*$N/3}] 247 | set result "" 248 | 249 | set a [string repeat " 2" $LEN] 250 | set nines 0 251 | set predigit 0 252 | set nines {} 253 | 254 | set i0 [expr {$LEN+1}] 255 | set quot0 [expr {2*$LEN+1}] 256 | for {set j 0} {$j<$N} {incr j} { 257 | set q 0 258 | set i $i0 259 | set quot $quot0 260 | set pos -1 261 | foreach apos $a { 262 | set x [expr {10*$apos + $q * [incr i -1]}] 263 | lset a [incr pos] [expr {$x % [incr quot -2]}] 264 | set q [expr {$x / $quot}] 265 | } 266 | lset a end [expr {$q % 10}] 267 | set q [expr {$q / 10}] 268 | if {$q < 8} { 269 | append result $predigit $nines 270 | set nines {} 271 | set predigit $q 272 | } elseif {$q == 9} { 273 | append nines 9 274 | } else { 275 | append result [expr {$predigit+1}][string map {9 0} $nines] 276 | set nines {} 277 | set predigit 0 278 | } 279 | } 280 | #puts $result$predigit 281 | } 282 | 283 | ### EXPAND ##################################################################### 284 | 285 | proc expand {} { 286 | for {set i 0} {$i < 100000} {incr i} { 287 | set a [list a b c d e f] 288 | lappend b {expand}$a 289 | } 290 | } 291 | 292 | ### MINLOOPS ################################################################### 293 | 294 | proc miniloops {} { 295 | for {set i 0} {$i < 100000} {incr i} { 296 | set sum 0 297 | for {set j 0} {$j < 10} {incr j} { 298 | # something of more or less real 299 | incr sum $j 300 | } 301 | } 302 | } 303 | 304 | ### wiki.tcl.tk/8566 ########################################################### 305 | 306 | # Internal procedure that indexes into the 2-dimensional array t, 307 | # which corresponds to the sequence y, looking for the (i,j)th element. 308 | 309 | proc Index { t y i j } { 310 | set indx [expr { ([llength $y] + 1) * ($i + 1) + ($j + 1) }] 311 | return [lindex $t $indx] 312 | } 313 | 314 | # Internal procedure that implements Levenshtein to derive the longest 315 | # common subsequence of two lists x and y. 316 | 317 | proc ComputeLCS { x y } { 318 | set t [list] 319 | for { set i -1 } { $i < [llength $y] } { incr i } { 320 | lappend t 0 321 | } 322 | for { set i 0 } { $i < [llength $x] } { incr i } { 323 | lappend t 0 324 | for { set j 0 } { $j < [llength $y] } { incr j } { 325 | if { [string equal [lindex $x $i] [lindex $y $j]] } { 326 | set lastT [Index $t $y [expr { $i - 1 }] [expr {$j - 1}]] 327 | set nextT [expr {$lastT + 1}] 328 | } else { 329 | set lastT1 [Index $t $y $i [expr { $j - 1 }]] 330 | set lastT2 [Index $t $y [expr { $i - 1 }] $j] 331 | if { $lastT1 > $lastT2 } { 332 | set nextT $lastT1 333 | } else { 334 | set nextT $lastT2 335 | } 336 | } 337 | lappend t $nextT 338 | } 339 | } 340 | return $t 341 | } 342 | 343 | # Internal procedure that traces through the array built by ComputeLCS 344 | # and finds a longest common subsequence -- specifically, the one that 345 | # is lexicographically first. 346 | 347 | proc TraceLCS { t x y } { 348 | set trace {} 349 | set i [expr { [llength $x] - 1 }] 350 | set j [expr { [llength $y] - 1 }] 351 | set k [expr { [Index $t $y $i $j] - 1 }] 352 | while { $i >= 0 && $j >= 0 } { 353 | set im1 [expr { $i - 1 }] 354 | set jm1 [expr { $j - 1 }] 355 | if { [Index $t $y $i $j] == [Index $t $y $im1 $jm1] + 1 356 | && [string equal [lindex $x $i] [lindex $y $j]] } { 357 | lappend trace xy [list $i $j] 358 | set i $im1 359 | set j $jm1 360 | } elseif { [Index $t $y $im1 $j] > [Index $t $y $i $jm1] } { 361 | lappend trace x $i 362 | set i $im1 363 | } else { 364 | lappend trace y $j 365 | set j $jm1 366 | } 367 | } 368 | while { $i >= 0 } { 369 | lappend trace x $i 370 | incr i -1 371 | } 372 | while { $j >= 0 } { 373 | lappend trace y $j 374 | incr j -1 375 | } 376 | return $trace 377 | } 378 | 379 | # list::longestCommonSubsequence::compare -- 380 | # 381 | # Compare two lists for the longest common subsequence 382 | # 383 | # Arguments: 384 | # x, y - Two lists of strings to compare 385 | # matched - Callback to execute on matched elements, see below 386 | # unmatchedX - Callback to execute on unmatched elements from the 387 | # first list, see below. 388 | # unmatchedY - Callback to execute on unmatched elements from the 389 | # second list, see below. 390 | # 391 | # Results: 392 | # None. 393 | # 394 | # Side effects: 395 | # Whatever the callbacks do. 396 | # 397 | # The 'compare' procedure compares the two lists of strings, x and y. 398 | # It finds a longest common subsequence between the two. It then walks 399 | # the lists in order and makes the following callbacks: 400 | # 401 | # For an element that is common to both lists, it appends the index in 402 | # the first list, the index in the second list, and the string value of 403 | # the element as three parameters to the 'matched' callback, and executes 404 | # the result. 405 | # 406 | # For an element that is in the first list but not the second, it appends 407 | # the index in the first list and the string value of the element as two 408 | # parameters to the 'unmatchedX' callback and executes the result. 409 | # 410 | # For an element that is in the second list but not the first, it appends 411 | # the index in the second list and the string value of the element as two 412 | # parameters to the 'unmatchedY' callback and executes the result. 413 | 414 | proc compare { x y 415 | matched 416 | unmatchedX unmatchedY } { 417 | set t [ComputeLCS $x $y] 418 | set trace [TraceLCS $t $x $y] 419 | set i [llength $trace] 420 | while { $i > 0 } { 421 | set indices [lindex $trace [incr i -1]] 422 | set type [lindex $trace [incr i -1]] 423 | switch -exact -- $type { 424 | xy { 425 | set c $matched 426 | eval lappend c $indices 427 | lappend c [lindex $x [lindex $indices 0]] 428 | uplevel 1 $c 429 | } 430 | x { 431 | set c $unmatchedX 432 | lappend c $indices 433 | lappend c [lindex $x $indices] 434 | uplevel 1 $c 435 | } 436 | y { 437 | set c $unmatchedY 438 | lappend c $indices 439 | lappend c [lindex $y $indices] 440 | uplevel 1 $c 441 | } 442 | } 443 | } 444 | return 445 | } 446 | 447 | proc umx { index value } { 448 | global lastx 449 | global xlines 450 | append xlines "< " $value \n 451 | set lastx $index 452 | } 453 | 454 | proc umy { index value } { 455 | global lasty 456 | global ylines 457 | append ylines "> " $value \n 458 | set lasty $index 459 | } 460 | 461 | proc matched { index1 index2 value } { 462 | global lastx 463 | global lasty 464 | global xlines 465 | global ylines 466 | if { [info exists lastx] && [info exists lasty] } { 467 | #puts "[expr { $lastx + 1 }],${index1}c[expr {$lasty + 1 }],${index2}" 468 | #puts -nonewline $xlines 469 | #puts "----" 470 | #puts -nonewline $ylines 471 | } elseif { [info exists lastx] } { 472 | #puts "[expr { $lastx + 1 }],${index1}d${index2}" 473 | #puts -nonewline $xlines 474 | } elseif { [info exists lasty] } { 475 | #puts "${index1}a[expr {$lasty + 1 }],${index2}" 476 | #puts -nonewline $ylines 477 | } 478 | catch { unset lastx } 479 | catch { unset xlines } 480 | catch { unset lasty } 481 | catch { unset ylines } 482 | } 483 | 484 | # Really, we should read the first file in like this: 485 | # set f0 [open [lindex $argv 0] r] 486 | # set x [split [read $f0] \n] 487 | # close $f0 488 | # But I'll just provide some sample lines: 489 | 490 | proc commonsub_test {} { 491 | set x {} 492 | for { set i 0 } { $i < 20 } { incr i } { 493 | lappend x a r a d e d a b r a x 494 | } 495 | 496 | # The second file, too, should be read in like this: 497 | # set f1 [open [lindex $argv 1] r] 498 | # set y [split [read $f1] \n] 499 | # close $f1 500 | # Once again, I'll just do some sample lines. 501 | 502 | set y {} 503 | for { set i 0 } { $i < 20 } { incr i } { 504 | lappend y a b r a c a d a b r a 505 | } 506 | 507 | compare $x $y matched umx umy 508 | matched [llength $x] [llength $y] {} 509 | } 510 | 511 | ### MANDEL ##################################################################### 512 | 513 | proc mandel {xres yres infx infy supx supy} { 514 | set incremx [expr {(0.0+$supx-$infx)/$xres}] 515 | set incremy [expr {(0.0+$supy-$infy)/$yres}] 516 | 517 | for {set j 0} {$j < $yres} {incr j} { 518 | set cim [expr {$infy+($incremy*$j)}] 519 | set line {} 520 | for {set i 0} {$i < $xres} {incr i} { 521 | set counter 0 522 | set zim 0 523 | set zre 0 524 | set cre [expr {$infx+($incremx*$i)}] 525 | while {$counter < 255} { 526 | set dam [expr {$zre*$zre-$zim*$zim+$cre}] 527 | set zim [expr {2*$zim*$zre+$cim}] 528 | set zre $dam 529 | if {$zre*$zre+$zim*$zim > 4} break 530 | incr counter 531 | } 532 | # output pixel $i $j 533 | } 534 | } 535 | } 536 | 537 | ### RUN ALL #################################################################### 538 | 539 | if {[string compare [lindex $argv 0] "-batch"] == 0} { 540 | set batchmode 1 541 | } 542 | 543 | bench {[while] busy loop} {whilebusyloop} 544 | bench {[for] busy loop} {forbusyloop} 545 | bench {mini loops} {miniloops} 546 | bench {fibonacci(25)} {fibonacci 25} 547 | bench {heapsort} {heapsort_main} 548 | bench {sieve} {sieve 10} 549 | bench {sieve [dict]} {sieve_dict 10} 550 | bench {ary} {ary 100000} 551 | bench {repeat} {use_repeat} 552 | bench {upvar} {upvartest} 553 | bench {nested loops} {nestedloops} 554 | bench {rotate} {rotate 100000} 555 | bench {dynamic code} {dyncode} 556 | bench {dynamic code (list)} {dyncode_list} 557 | bench {PI digits} {pi_digits} 558 | bench {expand} {expand} 559 | bench {wiki.tcl.tk/8566} {commonsub_test} 560 | bench {mandel} {mandel 60 60 -2 -1.5 1 1.5} 561 | 562 | proc istcl {} { 563 | return [expr {![catch {info tclversion}]}] 564 | } 565 | 566 | if {$batchmode} { 567 | if {[catch {info patchlevel} ver]} { 568 | set ver Jim[info version] 569 | } 570 | puts [list $ver $benchmarks] 571 | } 572 | -------------------------------------------------------------------------------- /doc/AIO-Extension.txt: -------------------------------------------------------------------------------- 1 | ANSI I/O extensiond documentation 2 | 3 | Overview 4 | ~~~~~~~~ 5 | 6 | The AIO (ANSI I/O) extension implements an I/O interface for Jim using only 7 | ANSI-C capabilities. The goal of the extension is to make Jim able to 8 | work with files in environments where the only assumption that can be 9 | done is that there is an ANSI-C compiler, or where the binary size matters 10 | (the AIO extension is very small compared to size that the real Tcl-alike 11 | channels implementation will have). 12 | 13 | Goals 14 | ~~~~~ 15 | 16 | The AIO extension was developed in order to be able to experiment with 17 | two ideas. 18 | 19 | The first is the idea to build a replacement for autoconf/automake 20 | using the fact that Jim is small and ANSI-C, so the build process may 21 | build Jim with the assumption of an ANSI-C compiler, and a Jim script will 22 | check what exists in the system and will generate the Makefile and config.h. 23 | Autconf/make is such a crap that it's worth to experiment with this idea... 24 | 25 | The second idea is to create a micro starkit runtime, using a very small 26 | implementation of zlib called muzcat, and AIO. 27 | 28 | Usage 29 | ~~~~~ 30 | 31 | The AIO extension exports an Object Based interface for files. In order 32 | to open a file use: 33 | 34 | set f [aio.open filename] 35 | 36 | this will open the file in read-only. It's possible to specify the mode: 37 | 38 | set f [aio.open filename w+] 39 | 40 | The [aio.open] command returns a file handle, that is a command name that 41 | can be used to perform operations on the file. A real example: 42 | 43 | Welcome to Jim version 0, Copyright (c) 2005 Salvatore Sanfilippo 44 | 0 jim> package require aio 45 | 1.0 46 | 0 jim> set f [aio.open /etc/passwd] 47 | aio.handle0 48 | 0 jim> $f gets line 49 | 30 50 | 0 jim> puts $line 51 | root:x:0:0:root:/root:/bin/zsh 52 | 53 | The "methods" of an AIO file object are an exact copy of the usual 54 | Tcl commands for file I/O. In order to have the full list of 55 | the methods currenty supported, pass a bad method as argument, 56 | like in the example (but don't trust the example, the extension is 57 | in active development so probably there will be more functionality when 58 | you are reading this document): 59 | 60 | 0 jim> $f helpme 61 | Runtime error, file "?", line 1: 62 | bad AIO method "helpme": must be close, seek, tell, gets, puts, or flush 63 | 64 | In order to close the file, use the 'close' method that will have as side effect 65 | to close the file and that the command associated with the file will be removed. 66 | 67 | Standard files 68 | ~~~~~~~~~~~~~~ 69 | 70 | The AIO library is able to return handles about the standard C channels 71 | stdin, stdout and stderr. In order to do so just use: 72 | 73 | set f [aio.open standard input] 74 | 75 | Valid standard file names are "input", "output", "error". 76 | 77 | For standard files, the close method will just remove the command associated 78 | with the handle, without to really close the file. 79 | 80 | 81 | -------------------------------------------------------------------------------- /doc/Embedder-HOWTO.txt: -------------------------------------------------------------------------------- 1 | Embedder HOWTO 2 | -------------- 3 | 4 | This document explains how to embed Jim into an existing application, in 5 | order to make the application scriptable, to write parts of the application 6 | in Jim on top of a C core, or just to use Jim as a configuration file format. 7 | 8 | STEP 1 9 | ------ 10 | 11 | Copy jim.c and jim.h into your project, and modify the Makefile in 12 | order to compile jim.c and link jim.o into your application. 13 | 14 | STEP 2 15 | ------ 16 | 17 | Include the file "jim.h" in your application, in the file where you 18 | defined your main() function. Before to include jim.h, only for this 19 | file you have to define JIM_EMBEDDED. So the two lines to add are: 20 | 21 | #define JIM_EMBEDDED 22 | #include "jim.h" 23 | 24 | Then add the call to Jim_InitEmbedded(); into your main() function. 25 | This call need to be placed before any other call to the Jim API. 26 | Example: 27 | 28 | int main(int argc, char **argv) { 29 | .... 30 | Jim_InitEmbedded(); 31 | ... 32 | 33 | /* Here is possible to call other Jim API functions */ 34 | } 35 | 36 | NOTE: If you require to call the Jim API from other files of your project 37 | you have just to include "jim.h" WITHOUT to define JIM_EMBEDDED. 38 | This definition is only useful inside the file that calls Jim_InitEmbedded(), 39 | i.e. in the file containing your main() function. 40 | 41 | STEP 3 42 | ------ 43 | 44 | Use the Jim API in order to glue your program with Jim. First of all you 45 | probably want to create an interpreter, add some command, and use 46 | Jim_Eval() to execute Jim scripts from your application: 47 | 48 | #define JIM_EMBEDDED 49 | #include "jim.h" 50 | 51 | #include 52 | 53 | static int foobarJimHelloCommand(Jim_Interp *interp, int argc, 54 | Jim_Obj *const *argv) 55 | { 56 | printf("Hello World!\n"); 57 | return JIM_OK; 58 | } 59 | 60 | int main(void) 61 | { 62 | Jim_Interp *interp; 63 | 64 | Jim_InitEmbedded(); 65 | printf("Welcome to The FooBar Application\n"); 66 | 67 | /* Create an interpreter */ 68 | interp = Jim_CreateInterp(); 69 | /* Add all the Jim core commands */ 70 | Jim_RegisterCoreCommands(interp); 71 | /* Add a new foobar.hello command to Jim */ 72 | Jim_CreateCommand(interp, "foobar.hello", foobarJimHelloCommand, NULL); 73 | /* Eval some Jim code. */ 74 | Jim_Eval(interp, "for {set i 0} {$i < 10} {incr i} {foobar.hello}"); 75 | return 0; 76 | } 77 | 78 | STEP 4 79 | ------ 80 | 81 | To test this example complile with: 82 | 83 | gcc main.c jim.c -ldl 84 | 85 | (you need to link against the 'dl' lib because Jim supports dynamic loading 86 | of extensions) 87 | 88 | The run the example with ./a.out. The output should be: 89 | 90 | Welcome to The FooBar Application 91 | Hello World! 92 | Hello World! 93 | Hello World! 94 | Hello World! 95 | Hello World! 96 | Hello World! 97 | Hello World! 98 | Hello World! 99 | Hello World! 100 | Hello World! 101 | 102 | Check the API reference for more information. 103 | 104 | 105 | -------------------------------------------------------------------------------- /doc/Sqlite-Extension.txt: -------------------------------------------------------------------------------- 1 | Jim Sqlite extension documentation. 2 | Copyright 2005 Salvatore Sanfilippo 3 | 4 | 5 | Overview 6 | ~~~~~~~~ 7 | 8 | The Sqlite extension makes possible to work with sqlite (http://www.sqlite.org) 9 | databases from Jim. SQLite is a small C library that implements a 10 | self-contained, embeddable, zero-configuration SQL database engine. This 11 | means it is perfect for embedded systems, and for stand-alone applications 12 | that need the power of SQL without to use an external server like Mysql. 13 | 14 | Basic usage 15 | ~~~~~~~~~~~ 16 | 17 | The Sqlite extension exports an Object Based interface for databases. In order 18 | to open a database use: 19 | 20 | set f [sqlite.open dbname] 21 | 22 | The [sqlite.open] command returns a db handle, that is a command name that 23 | can be used to perform operations on the database. A real example: 24 | 25 | . set db [sqlite.open test.db] 26 | sqlite.handle0 27 | . $db query "SELECT * from tbl1" 28 | {one hello! two 10} {one goodbye two 20} 29 | 30 | In the second line the handle is used as a command name, followed 31 | by the 'method' or 'subcommand' ("query" in the example), and the arguments. 32 | 33 | The query method 34 | ~~~~~~~~~~~~~~~~ 35 | 36 | The query method has the following signature: 37 | 38 | $db query SqlQuery ?args? 39 | 40 | The sql query may contain occurrences of "%s" that are substituted 41 | in the actual query with the following arguments, quoted in order 42 | to make sure that the query is correct even if this arguments contain 43 | "'" characters. So for example it is possible to write: 44 | 45 | . $db query "SELECT * from tbl1 WHERE one='%s'" hello! 46 | {one hello! two 10} 47 | 48 | Instead of hello! it is possible to use a string with embedded "'": 49 | 50 | . $db query "SELECT * from tbl1 WHERE one='%s'" a'b 51 | (no matches - the empty list is returned) 52 | 53 | This does not work instead using the Tcl variable expansion in the string: 54 | 55 | . $db query "SELECT * from tbl1 WHERE one='$foo'" 56 | Runtime error, file "?", line 1: 57 | near "b": syntax error 58 | 59 | In order to obtain an actual '%' character in the query, there is just 60 | to use two, like in "foo %% bar". This is the same as the [format] argument. 61 | 62 | Specification of query results 63 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 64 | 65 | In one of the above examples, the following query was used: 66 | 67 | . $db query "SELECT * from tbl1" 68 | {one hello! two 10} {one goodbye two 20} 69 | 70 | As you can see the result of a query is a list of lists. Every 71 | element of the list represents a row, as a list of key/value pairs, 72 | so actually every row is a Jim dictionary. 73 | 74 | The following example and generated output show how to take advantage 75 | of this representation: 76 | 77 | . set res [$db query "SELECT * from tbl1"] 78 | {one hello! two 10} {one goodbye two 20} 79 | . foreach row $res {puts "One: $row(one), Two: $row(two)"} 80 | One: hello!, Two: 10 81 | One: goodbye, Two: 20 82 | 83 | To access every row sequentially is very simple, and field of a row 84 | can be accessed using the $row(field) syntax. 85 | 86 | The close method 87 | ~~~~~~~~~~~~~~~~ 88 | 89 | In order to close the db, use the 'close' method that will have as side effect 90 | to close the db and to remove the command associated with the db. 91 | Just use: 92 | 93 | $db close 94 | 95 | Handling NULL values 96 | ~~~~~~~~~~~~~~~~~~~~ 97 | 98 | In the SQL language there is a special value NULL that is not the empty 99 | string, so how to represent it in a typeless language like Tcl? 100 | For default this extension will use the empty string, but it is possible 101 | to specify a different string for the NULL value. 102 | 103 | In the above example there were two rows in the 'tbl1' table. Now 104 | we can add usign the "sqlite" command line client another one with 105 | a NULL value: 106 | 107 | sqlite> INSERT INTO tbl1 VALUES(NULL,30); 108 | sqlite> .exit 109 | 110 | That's what the sqlite extension will return for default: 111 | 112 | . $db query "SELECT * from tbl1" 113 | {one hello! two 10} {one goodbye two 20} {one {} two 30} 114 | 115 | As you can see in the last row, the NULL is represented as {}, that's 116 | the empty string. Using the -null option of the 'query' command we 117 | can change this default, and tell the sqlite extension to represent 118 | the NULL value as a different string: 119 | 120 | . $db query -null <> "SELECT * from tbl1" 121 | {one hello! two 10} {one goodbye two 20} {one <> two 30} 122 | 123 | This way if the emtpy string has some semantical value for your 124 | dataset you can change it. 125 | 126 | Finding the ID of the last inserted row 127 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 128 | 129 | This is as simple as: 130 | 131 | . $db lastid 132 | 10 133 | 134 | Number of rows changed by the most recent query 135 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 136 | 137 | This is also very simple, there is just to use the 'changes' method 138 | without arugments. 139 | 140 | . $db changes 141 | 5 142 | 143 | Note that if you drop an entire table the number of changes will 144 | be reported as zero, because of details of the sqlite implementation. 145 | 146 | That's all, 147 | Enjoy! 148 | Salvatore Sanfilippo 149 | 150 | p.s. this extension is just the work of some hour thanks to the cool 151 | clean C API that sqlite exports. Thanks to the author of sqlite for this 152 | great work. 153 | 154 | In memory databases 155 | ~~~~~~~~~~~~~~~~~~~ 156 | 157 | SQLite is able to create in-memory databases instead to use files. 158 | This is of course faster and does not need the ability to write 159 | to the filesystem. Of course this databases are only useful for 160 | temp data. 161 | 162 | In-memory DBs are used just like regular databases, just the name used to 163 | open the database is :memory:. That's an example that does not use the 164 | filesystem at all to create and work with the db. 165 | 166 | package require sqlite 167 | set db [sqlite.open :memory:] 168 | $db query {CREATE TABLE plays (id, author, title)} 169 | $db query {INSERT INTO plays (id, author, title) VALUES (1, 'Goethe', 'Faust');} 170 | $db query {INSERT INTO plays (id, author, title) VALUES (2, 'Shakespeare', 'Hamlet');} 171 | $db query {INSERT INTO plays (id, author, title) VALUES (3, 'Sophocles', 'Oedipus Rex');} 172 | set res [$db query "SELECT * FROM plays"] 173 | $db close 174 | foreach r $res {puts $r(author)} 175 | 176 | Of course once the Jim process is destroyed the database will no longer 177 | exists. 178 | -------------------------------------------------------------------------------- /doc/jim_man.txt: -------------------------------------------------------------------------------- 1 | # what: jim commands, description, points to ponder 2 | 3 | jim 4 | set var [value] 5 | 6 | dict 7 | 8 | array [get | set ] 9 | set $array($elem) $val 10 | the array command and array syntax $array($elem) is 11 | an wrapper around dict! 12 | 13 | 14 | package eventloop 15 | after time/ms script 16 | the script is mandatory! a blocking wait is not implemented ( good!? ) 17 | returns event_handle 18 | open: after cancel and remaining time query. ( stubs in C exist UK) 19 | 20 | vwait variable 21 | work the eventloop until variable is accessed. 22 | currently works only on change of variable content!! 23 | returns ?variable value? 24 | 25 | package aio 26 | aio.open 27 | returns handle ?aio.file? 28 | 29 | aio.socket | 30 | socketspec may be stream, stream.server ( TODO : dgram , domain, ..... ) 31 | serverspec may be [ANY|]: 32 | remotehostspec may be : 33 | returns handle ?aio.socket? | aio. 34 | 35 | $aio.handle 36 | close 37 | tell 38 | seek 39 | gets 40 | read 41 | write 42 | ndelay [1|0] 43 | readable [ {} | [ ] ] 44 | noargs: return the scripts for readable event, optional eof event script. 45 | returns {} on not setup 46 | [ list ] 47 | arg {} : remove event 48 | arg : setup script or read event, fold eof into this script 49 | arg same as above, eof is handled separately. 50 | 51 | writable 52 | same for writable, no eof though 53 | onexception 54 | same for out-of-band data 55 | 56 | accept 57 | applys only to server sockets and should be used in a fileevent. 58 | returns a new socket handle for the accepted connection. 59 | 60 | 61 | package posix 62 | signal [ ] 63 | tell signal action for signal $signame or if given set action to $sigaction 64 | $sigaction can be either default, ignore , debug or ( TODO: an action script 65 | that works like a fileevent ) 66 | in all cases the previous action is returned. 67 | 68 | sleep 69 | sleep number of seconds 70 | 71 | usleep [ ] 72 | call usleep/nanosleep with given value 73 | bare or time as float plus unit ( one of s ms us ns ) 74 | 75 | pit 76 | return unix second ( since epoch ) as a float(double) 77 | Jpit 78 | return Julian Date in days as a float(double)! 79 | see http://en.wikipedia.org/wiki/Julian_Date 80 | 81 | -------------------------------------------------------------------------------- /ecos/ecos.db: -------------------------------------------------------------------------------- 1 | #============================================================================= 2 | # 3 | # ecos.db 4 | # 5 | # repository which contains only athttpd 6 | # 7 | #============================================================================= 8 | #####ECOSGPLCOPYRIGHTBEGIN#### 9 | ## ------------------------------------------- 10 | ## This file is part of eCos, the Embedded Configurable Operating System. 11 | ## Copyright (C) 2004, 2005 eCosCentric Limited 12 | ## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. 13 | ## 14 | ## eCos is free software; you can redistribute it and/or modify it under 15 | ## the terms of the GNU General Public License as published by the Free 16 | ## Software Foundation; either version 2 or (at your option) any later version. 17 | ## 18 | ## eCos is distributed in the hope that it will be useful, but WITHOUT ANY 19 | ## WARRANTY; without even the implied warranty of MERCHANTABILITY or 20 | ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 21 | ## for more details. 22 | ## 23 | ## You should have received a copy of the GNU General Public License along 24 | ## with eCos; if not, write to the Free Software Foundation, Inc., 25 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 26 | ## 27 | ## As a special exception, if other files instantiate templates or use macros 28 | ## or inline functions from this file, or you compile this file and link it 29 | ## with other works to produce a work based on this file, this file does not 30 | ## by itself cause the resulting work to be covered by the GNU General Public 31 | ## License. However the source code for this file must still be made available 32 | ## in accordance with section (3) of the GNU General Public License. 33 | ## 34 | ## This exception does not invalidate any other reasons why a work based on 35 | ## this file might be covered by the GNU General Public License. 36 | ## ------------------------------------------- 37 | #####ECOSGPLCOPYRIGHTEND#### 38 | #============================================================================= 39 | ######DESCRIPTIONBEGIN#### 40 | # 41 | # Author(s): bartv 42 | # Date: 1999-06-13 43 | # 44 | # This file contains three lots of information. It details the packages 45 | # in the component repository, the target boards supported by those 46 | # packages, and a set of templates that can be used to instantiate 47 | # configuration. 48 | # 49 | #####DESCRIPTIONEND#### 50 | #=============================================================================== 51 | 52 | package CYGPKG_JIMTCL { 53 | alias { "Jim Tcl" jimtcl } 54 | directory language/tcl/jim 55 | script jimtcl.cdl 56 | description "Jim Tcl a lightweight Tcl implementation. Lacks all the create comforts libraries of a PC implementation, but otherwise complete." 57 | } 58 | -------------------------------------------------------------------------------- /ecos/language/tcl/jim/current/ChangeLog: -------------------------------------------------------------------------------- 1 | 2008-01-05 Oyvind Harboe 2 | 3 | * src/jim.c: translate malloc(0) & realloc(ptr, 0) => malloc(1) & realloc(ptr, 1) 4 | to avoid problems with differing implementations. 5 | 6 | 2008-01-04 Oyvind Harboe 7 | 8 | * Split out jim from athttpd. athttpd can be subsequently updated to 9 | use this module 10 | * src/jim.c: fixed bug in parsing hex in expr. This patch has been submitted 11 | to jim-devel 12 | 13 | //=========================================================================== 14 | //####ECOSGPLCOPYRIGHTBEGIN#### 15 | // ------------------------------------------- 16 | // This file is part of eCos, the Embedded Configurable Operating System. 17 | // Copyright (C) 2005, 2006 eCosCentric Ltd. 18 | // 19 | // eCos is free software; you can redistribute it and/or modify it under 20 | // the terms of the GNU General Public License as published by the Free 21 | // Software Foundation; either version 2 or (at your option) any later version. 22 | // 23 | // eCos is distributed in the hope that it will be useful, but WITHOUT ANY 24 | // WARRANTY; without even the implied warranty of MERCHANTABILITY or 25 | // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 26 | // for more details. 27 | // 28 | // You should have received a copy of the GNU General Public License along 29 | // with eCos; if not, write to the Free Software Foundation, Inc., 30 | // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 31 | // 32 | // As a special exception, if other files instantiate templates or use macros 33 | // or inline functions from this file, or you compile this file and link it 34 | // with other works to produce a work based on this file, this file does not 35 | // by itself cause the resulting work to be covered by the GNU General Public 36 | // License. However the source code for this file must still be made available 37 | // in accordance with section (3) of the GNU General Public License. 38 | // 39 | // This exception does not invalidate any other reasons why a work based on 40 | // this file might be covered by the GNU General Public License. 41 | // 42 | // ------------------------------------------- 43 | //####ECOSGPLCOPYRIGHTEND#### 44 | //=========================================================================== 45 | -------------------------------------------------------------------------------- /ecos/language/tcl/jim/current/cdl/jimtcl.cdl: -------------------------------------------------------------------------------- 1 | # ==================================================================== 2 | # 3 | # jimtcl.cdl 4 | # 5 | # HTTP server configuration data 6 | # 7 | # ==================================================================== 8 | #####ECOSGPLCOPYRIGHTBEGIN#### 9 | ## ------------------------------------------- 10 | ## This file is part of eCos, the Embedded Configurable Operating System. 11 | ## Copyright (C) 2005 eCosCentric Ltd. 12 | ## 13 | ## eCos is free software; you can redistribute it and/or modify it under 14 | ## the terms of the GNU General Public License as published by the Free 15 | ## Software Foundation; either version 2 or (at your option) any later version. 16 | ## 17 | ## eCos is distributed in the hope that it will be useful, but WITHOUT ANY 18 | ## WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 | ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 | ## for more details. 21 | ## 22 | ## You should have received a copy of the GNU General Public License along 23 | ## with eCos; if not, write to the Free Software Foundation, Inc., 24 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 25 | ## 26 | ## As a special exception, if other files instantiate templates or use macros 27 | ## or inline functions from this file, or you compile this file and link it 28 | ## with other works to produce a work based on this file, this file does not 29 | ## by itself cause the resulting work to be covered by the GNU General Public 30 | ## License. However the source code for this file must still be made available 31 | ## in accordance with section (3) of the GNU General Public License. 32 | ## 33 | ## This exception does not invalidate any other reasons why a work based on 34 | ## this file might be covered by the GNU General Public License. 35 | ## 36 | ## ------------------------------------------- 37 | #####ECOSGPLCOPYRIGHTEND#### 38 | # ==================================================================== 39 | ######DESCRIPTIONBEGIN#### 40 | # 41 | # Author(s): Anthony Tonizzo (atonizzo@gmail.com) 42 | # Contributors: Lars Povlsen (lpovlsen@vitesse.com) 43 | # Date: 2006-06-09 44 | # 45 | #####DESCRIPTIONEND#### 46 | # 47 | # ==================================================================== 48 | 49 | cdl_package CYGPKG_JIMTCL { 50 | display "Jim Tcl" 51 | description "Core Tcl implementation upon which commands pretinent to deeply embedded application can be added." 52 | include_dir cyg/jimtcl 53 | include_files jim.h 54 | include_files jim-eventloop.h 55 | compile jim.c jim-aio.c jim-eventloop.c 56 | 57 | requires CYGINT_ISO_STDIO_STREAMS 58 | requires CYGINT_ISO_STDIO_FILEACCESS 59 | requires CYGINT_ISO_STDIO_FORMATTED_IO 60 | requires CYGINT_ISO_STRING_MEMFUNCS 61 | requires CYGINT_ISO_STRING_STRFUNCS 62 | requires CYGINT_ISO_STRING_BSD_FUNCS 63 | requires CYGINT_ISO_C_CLOCK_FUNCS 64 | requires CYGINT_ISO_MALLOC 65 | requires CYGINT_ISO_CTYPE 66 | define JIM_ANSIC 67 | define JIM_STATICEXT 68 | 69 | cdl_component CYGPKG_JIMTCL_OPTIONS { 70 | display "Jim Tcl build options" 71 | flavor none 72 | no_define 73 | 74 | 75 | 76 | cdl_option CYGPKG_JIMTCL_CFLAGS_ADD { 77 | display "Additional compiler flags" 78 | flavor data 79 | no_define 80 | default_value { "-D__ECOS" } 81 | description " 82 | This option modifies the set of compiler flags for 83 | building the HTTP server package. 84 | These flags are used in addition 85 | to the set of global flags." 86 | } 87 | 88 | cdl_option CYGPKG_JIMTCL_CFLAGS_REMOVE { 89 | display "Suppressed compiler flags" 90 | flavor data 91 | no_define 92 | default_value { "" } 93 | description " 94 | This option modifies the set of compiler flags for 95 | building the HTTP server package. These flags are removed from 96 | the set of global flags if present." 97 | } 98 | } 99 | } 100 | 101 | # ==================================================================== 102 | # EOF jimtcl.cdl 103 | -------------------------------------------------------------------------------- /ecos/language/tcl/jim/current/include/jim-eventloop.h: -------------------------------------------------------------------------------- 1 | /* Jim - A small embeddable Tcl interpreter 2 | * 3 | * Copyright 2005 Salvatore Sanfilippo 4 | * Copyright 2005 Clemens Hintze 5 | * Copyright 2005 patthoyts - Pat Thoyts 6 | * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com 7 | * Copyright 2008 Andrew Lunn 8 | * Copyright 2008 Duane Ellis 9 | * Copyright 2008 Uwe Klein 10 | * 11 | * The FreeBSD license 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions 15 | * are met: 16 | * 17 | * 1. Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 2. Redistributions in binary form must reproduce the above 20 | * copyright notice, this list of conditions and the following 21 | * disclaimer in the documentation and/or other materials 22 | * provided with the distribution. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY 25 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 26 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 | * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 35 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | * 37 | * The views and conclusions contained in the software and documentation 38 | * are those of the authors and should not be interpreted as representing 39 | * official policies, either expressed or implied, of the Jim Tcl Project. 40 | **/ 41 | /* ------ USAGE ------- 42 | * 43 | * In order to use this file from other extensions include it in every 44 | * file where you need to call the eventloop API, also in the init 45 | * function of your extension call Jim_ImportEventloopAPI(interp) 46 | * after the Jim_InitExtension() call. 47 | * 48 | * See the UDP extension as example. 49 | */ 50 | 51 | 52 | #ifndef __JIM_EVENTLOOP_H__ 53 | #define __JIM_EVENTLOOP_H__ 54 | 55 | typedef int Jim_FileProc(Jim_Interp *interp, void *clientData, int mask); 56 | typedef int Jim_SignalProc(Jim_Interp *interp, void *clientData, void *msg); 57 | typedef void Jim_TimeProc(Jim_Interp *interp, void *clientData); 58 | typedef void Jim_EventFinalizerProc(Jim_Interp *interp, void *clientData); 59 | 60 | /* File event structure */ 61 | #define JIM_EVENT_READABLE 1 62 | #define JIM_EVENT_WRITABLE 2 63 | #define JIM_EVENT_EXCEPTION 4 64 | #define JIM_EVENT_FEOF 8 65 | 66 | #define JIM_API(x) x 67 | #define JIM_STATIC 68 | 69 | JIM_STATIC int Jim_EventLoopOnLoad(Jim_Interp *interp); 70 | 71 | /* --- POSIX version of Jim_ProcessEvents, for now the only available --- */ 72 | #define JIM_FILE_EVENTS 1 73 | #define JIM_TIME_EVENTS 2 74 | #define JIM_ALL_EVENTS (JIM_FILE_EVENTS | JIM_TIME_EVENTS) 75 | #define JIM_DONT_WAIT 4 76 | 77 | JIM_STATIC void JIM_API(Jim_CreateFileHandler) (Jim_Interp *interp, 78 | void *handle, int mask, 79 | Jim_FileProc *proc, void *clientData, 80 | Jim_EventFinalizerProc *finalizerProc); 81 | JIM_STATIC void JIM_API(Jim_DeleteFileHandler) (Jim_Interp *interp, 82 | void *handle); 83 | JIM_STATIC jim_wide JIM_API(Jim_CreateTimeHandler) (Jim_Interp *interp, 84 | jim_wide milliseconds, 85 | Jim_TimeProc *proc, void *clientData, 86 | Jim_EventFinalizerProc *finalizerProc); 87 | JIM_STATIC jim_wide JIM_API(Jim_DeleteTimeHandler) (Jim_Interp *interp, jim_wide id); 88 | JIM_STATIC int JIM_API(Jim_ProcessEvents) (Jim_Interp *interp, int flags); 89 | 90 | #undef JIM_STATIC 91 | #undef JIM_API 92 | 93 | #ifndef __JIM_EVENTLOOP_CORE__ 94 | 95 | #define JIM_GET_API(name) \ 96 | Jim_GetApi(interp, "Jim_" #name, ((void *)&Jim_ ## name)) 97 | 98 | #undef JIM_GET_API 99 | #endif /* __JIM_EVENTLOOP_CORE__ */ 100 | 101 | #endif /* __JIM_EVENTLOOP_H__ */ 102 | -------------------------------------------------------------------------------- /ecos/language/tcl/jim/current/src/jim-aio.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antirez/Jim/a1a87f72fc61cc085680019eef45312fb2a52d13/ecos/language/tcl/jim/current/src/jim-aio.c -------------------------------------------------------------------------------- /ecos/pkgconf/rules.mak: -------------------------------------------------------------------------------- 1 | #============================================================================= 2 | # 3 | # rules.mak 4 | # 5 | # Generic rules for inclusion by all package makefiles. 6 | # 7 | #============================================================================= 8 | #####ECOSGPLCOPYRIGHTBEGIN#### 9 | ## ------------------------------------------- 10 | ## This file is part of eCos, the Embedded Configurable Operating System. 11 | ## Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc. 12 | ## 13 | ## eCos is free software; you can redistribute it and/or modify it under 14 | ## the terms of the GNU General Public License as published by the Free 15 | ## Software Foundation; either version 2 or (at your option) any later version. 16 | ## 17 | ## eCos is distributed in the hope that it will be useful, but WITHOUT ANY 18 | ## WARRANTY; without even the implied warranty of MERCHANTABILITY or 19 | ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 20 | ## for more details. 21 | ## 22 | ## You should have received a copy of the GNU General Public License along 23 | ## with eCos; if not, write to the Free Software Foundation, Inc., 24 | ## 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 25 | ## 26 | ## As a special exception, if other files instantiate templates or use macros 27 | ## or inline functions from this file, or you compile this file and link it 28 | ## with other works to produce a work based on this file, this file does not 29 | ## by itself cause the resulting work to be covered by the GNU General Public 30 | ## License. However the source code for this file must still be made available 31 | ## in accordance with section (3) of the GNU General Public License. 32 | ## 33 | ## This exception does not invalidate any other reasons why a work based on 34 | ## this file might be covered by the GNU General Public License. 35 | ## 36 | ## Alternative licenses for eCos may be arranged by contacting Red Hat, Inc. 37 | ## at http://sources.redhat.com/ecos/ecos-license/ 38 | ## ------------------------------------------- 39 | #####ECOSGPLCOPYRIGHTEND#### 40 | #============================================================================= 41 | #####DESCRIPTIONBEGIN#### 42 | # 43 | # Author(s): jld 44 | # Contributors: bartv 45 | # Date: 1999-11-04 46 | # Purpose: Generic rules for inclusion by all package makefiles 47 | # Description: 48 | # 49 | #####DESCRIPTIONEND#### 50 | #============================================================================= 51 | 52 | # FIXME: This definition belongs in the top-level makefile. 53 | export HOST_CC := gcc 54 | 55 | .PHONY: default build clean tests headers mlt_headers 56 | 57 | # include any dependency rules generated previously 58 | ifneq ($(wildcard *.deps),) 59 | include $(wildcard *.deps) 60 | endif 61 | 62 | # GCC since 2.95 does -finit-priority by default so remove it from old HALs 63 | CFLAGS := $(subst -finit-priority,,$(CFLAGS)) 64 | 65 | # -fvtable-gc is known to be broken in all recent GCC. 66 | CFLAGS := $(subst -fvtable-gc,,$(CFLAGS)) 67 | 68 | # To support more recent GCC whilst preserving existing behaviour, we need 69 | # to increase the inlining limit globally from the default 600. Note this 70 | # will break GCC 2.95 based tools and earlier. You must use "make OLDGCC=1" 71 | # to avoid this. 72 | ifneq ($(OLDGCC),1) 73 | CFLAGS := -finline-limit=7000 $(CFLAGS) 74 | endif 75 | 76 | # Separate C++ flags out from C flags. 77 | ACTUAL_CFLAGS = $(CFLAGS) 78 | ACTUAL_CFLAGS := $(subst -fno-rtti,,$(ACTUAL_CFLAGS)) 79 | ACTUAL_CFLAGS := $(subst -frtti,,$(ACTUAL_CFLAGS)) 80 | ACTUAL_CFLAGS := $(subst -Woverloaded-virtual,,$(ACTUAL_CFLAGS)) 81 | ACTUAL_CFLAGS := $(subst -fvtable-gc,,$(ACTUAL_CFLAGS)) 82 | 83 | ACTUAL_CXXFLAGS = $(subst -Wstrict-prototypes,,$(CFLAGS)) 84 | 85 | # pattern matching rules to generate a library object from source code 86 | # object filenames are prefixed to avoid name clashes 87 | # a single dependency rule is generated (file extension = ".o.d") 88 | %.o.d : %.c 89 | ifeq ($(HOST),CYGWIN) 90 | @mkdir -p `cygpath -w "$(dir $@)" | sed "s@\\\\\\\\@/@g"` 91 | else 92 | @mkdir -p $(dir $@) 93 | endif 94 | $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(ACTUAL_CFLAGS) -Wp,-MD,$(@:.o.d=.tmp) -o $(dir $@)$(OBJECT_PREFIX)_$(notdir $(@:.o.d=.o)) $< 95 | @sed -e '/^ *\\/d' -e "s#.*: #$@: #" $(@:.o.d=.tmp) > $@ 96 | @rm $(@:.o.d=.tmp) 97 | 98 | %.o.d : %.cxx 99 | ifeq ($(HOST),CYGWIN) 100 | @mkdir -p `cygpath -w "$(dir $@)" | sed "s@\\\\\\\\@/@g"` 101 | else 102 | @mkdir -p $(dir $@) 103 | endif 104 | $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(ACTUAL_CXXFLAGS) -Wp,-MD,$(@:.o.d=.tmp) -o $(dir $@)$(OBJECT_PREFIX)_$(notdir $(@:.o.d=.o)) $< 105 | @sed -e '/^ *\\/d' -e "s#.*: #$@: #" $(@:.o.d=.tmp) > $@ 106 | @rm $(@:.o.d=.tmp) 107 | 108 | %.o.d : %.cpp 109 | ifeq ($(HOST),CYGWIN) 110 | @mkdir -p `cygpath -w "$(dir $@)" | sed "s@\\\\\\\\@/@g"` 111 | else 112 | @mkdir -p $(dir $@) 113 | endif 114 | $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(ACTUAL_CXXFLAGS) -Wp,-MD,$(@:.o.d=.tmp) -o $(dir $@)$(OBJECT_PREFIX)_$(notdir $(@:.o.d=.o)) $< 115 | @sed -e '/^ *\\/d' -e "s#.*: #$@: #" $(@:.o.d=.tmp) > $@ 116 | @rm $(@:.o.d=.tmp) 117 | 118 | %.o.d : %.S 119 | ifeq ($(HOST),CYGWIN) 120 | @mkdir -p `cygpath -w "$(dir $@)" | sed "s@\\\\\\\\@/@g"` 121 | else 122 | @mkdir -p $(dir $@) 123 | endif 124 | $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(ACTUAL_CFLAGS) -Wp,-MD,$(@:.o.d=.tmp) -o $(dir $@)$(OBJECT_PREFIX)_$(notdir $(@:.o.d=.o)) $< 125 | @sed -e '/^ *\\/d' -e "s#.*: #$@: #" $(@:.o.d=.tmp) > $@ 126 | @rm $(@:.o.d=.tmp) 127 | 128 | # pattern matching rules to generate a test object from source code 129 | # object filenames are not prefixed 130 | # a single dependency rule is generated (file extension = ".d") 131 | %.d : %.c 132 | ifeq ($(HOST),CYGWIN) 133 | @mkdir -p `cygpath -w "$(dir $@)" | sed "s@\\\\\\\\@/@g"` 134 | else 135 | @mkdir -p $(dir $@) 136 | endif 137 | $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(ACTUAL_CFLAGS) -Wp,-MD,$(@:.d=.tmp) -o $(@:.d=.o) $< 138 | @sed -e '/^ *\\/d' -e "s#.*: #$@: #" $(@:.d=.tmp) > $@ 139 | @rm $(@:.d=.tmp) 140 | 141 | %.d : %.cxx 142 | ifeq ($(HOST),CYGWIN) 143 | @mkdir -p `cygpath -w "$(dir $@)" | sed "s@\\\\\\\\@/@g"` 144 | else 145 | @mkdir -p $(dir $@) 146 | endif 147 | $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(ACTUAL_CXXFLAGS) -Wp,-MD,$(@:.d=.tmp) -o $(@:.d=.o) $< 148 | @sed -e '/^ *\\/d' -e "s#.*: #$@: #" $(@:.d=.tmp) > $@ 149 | @rm $(@:.d=.tmp) 150 | 151 | %.d : %.cpp 152 | ifeq ($(HOST),CYGWIN) 153 | @mkdir -p `cygpath -w "$(dir $@)" | sed "s@\\\\\\\\@/@g"` 154 | else 155 | @mkdir -p $(dir $@) 156 | endif 157 | $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(ACTUAL_CXXFLAGS) -Wp,-MD,$(@:.d=.tmp) -o $(@:.d=.o) $< 158 | @sed -e '/^ *\\/d' -e "s#.*: #$@: #" $(@:.d=.tmp) > $@ 159 | @rm $(@:.d=.tmp) 160 | 161 | %.d : %.S 162 | ifeq ($(HOST),CYGWIN) 163 | @mkdir -p `cygpath -w "$(dir $@)" | sed "s@\\\\\\\\@/@g"` 164 | else 165 | @mkdir -p $(dir $@) 166 | endif 167 | $(CC) -c $(INCLUDE_PATH) -I$(dir $<) $(ACTUAL_CFLAGS) -Wp,-MD,$(@:.d=.tmp) -o $(@:.d=.o) $< 168 | @sed -e '/^ *\\/d' -e "s#.*: #$@: #" $(@:.d=.tmp) > $@ 169 | @rm $(@:.d=.tmp) 170 | 171 | # rule to generate a test executable from object code 172 | $(PREFIX)/tests/$(PACKAGE)/%$(EXEEXT): %.d $(wildcard $(PREFIX)/lib/target.ld) $(wildcard $(PREFIX)/lib/*.[ao]) 173 | ifeq ($(HOST),CYGWIN) 174 | @mkdir -p `cygpath -w "$(dir $@)" | sed "s@\\\\\\\\@/@g"` 175 | else 176 | @mkdir -p $(dir $@) 177 | endif 178 | ifneq ($(IGNORE_LINK_ERRORS),) 179 | -$(CC) -L$(PREFIX)/lib -Ttarget.ld -o $@ $(<:.d=.o) $(LDFLAGS) 180 | else 181 | $(CC) -L$(PREFIX)/lib -Ttarget.ld -o $@ $(<:.d=.o) $(LDFLAGS) 182 | endif 183 | 184 | # rule to generate all tests and create a dependency file "tests.deps" by 185 | # concatenating the individual dependency rule files (file extension = ".d") 186 | # generated during compilation 187 | tests: tests.stamp 188 | 189 | TESTS := $(TESTS:.cpp=) 190 | TESTS := $(TESTS:.cxx=) 191 | TESTS := $(TESTS:.c=) 192 | TESTS := $(TESTS:.S=) 193 | tests.stamp: $(foreach target,$(TESTS),$(target).d $(PREFIX)/tests/$(PACKAGE)/$(target)$(EXEEXT)) 194 | ifneq ($(strip $(TESTS)),) 195 | @cat $(TESTS:%=%.d) > $(@:.stamp=.deps) 196 | endif 197 | @touch $@ 198 | 199 | # rule to clean the build tree 200 | clean: 201 | @find . -type f -print | grep -v makefile | xargs rm -f 202 | 203 | # rule to copy MLT files 204 | mlt_headers: $(foreach x,$(MLT),$(PREFIX)/include/pkgconf/$(notdir $x)) 205 | 206 | $(foreach x,$(MLT),$(PREFIX)/include/pkgconf/$(notdir $x)): $(MLT) 207 | @cp $(dir $<)/$(notdir $@) $(PREFIX)/include/pkgconf 208 | @chmod u+w $(PREFIX)/include/pkgconf/$(notdir $@) 209 | 210 | # end of file 211 | -------------------------------------------------------------------------------- /ecos/readme.txt: -------------------------------------------------------------------------------- 1 | Work in progress 2 | 3 | Run update.sh to update 4 | 5 | Build eCos repository structure by copying files 6 | from jim into this directory. A jim distribution 7 | under CVS if you like. 8 | 9 | Committed from ecosforge as-was, so it can 10 | be merged with the original jim to make update.sh 11 | work without any manual intervention 12 | -------------------------------------------------------------------------------- /ecos/update.sh: -------------------------------------------------------------------------------- 1 | # Copy files from original places into eCos repository structure 2 | cp ../jim.c language/tcl/jim/current/src 3 | cp ../jim-aio.c language/tcl/jim/current/src 4 | cp ../jim-eventloop.c language/tcl/jim/current/src 5 | cp ../jim.h language/tcl/jim/current/include 6 | cp ../jim-eventloop.h language/tcl/jim/current/include 7 | 8 | -------------------------------------------------------------------------------- /freebsd/andrew.txt: -------------------------------------------------------------------------------- 1 | Delivered-To: oyvindharboe@gmail.com 2 | Received: by 10.100.7.20 with SMTP id 20cs86142ang; 3 | Wed, 16 Jul 2008 00:45:59 -0700 (PDT) 4 | Received: by 10.142.238.12 with SMTP id l12mr5009290wfh.204.1216194359186; 5 | Wed, 16 Jul 2008 00:45:59 -0700 (PDT) 6 | Return-Path: 7 | Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) 8 | by mx.google.com with ESMTP id 31si6762736wff.16.2008.07.16.00.45.57; 9 | Wed, 16 Jul 2008 00:45:59 -0700 (PDT) 10 | Received-SPF: fail (google.com: domain of andrew@lunn.ch does not designate 209.85.100.29 as permitted sender) client-ip=209.85.100.29; 11 | Authentication-Results: mx.google.com; spf=hardfail (google.com: domain of andrew@lunn.ch does not designate 209.85.100.29 as permitted sender) smtp.mail=andrew@lunn.ch 12 | Received: from londo.lunn.ch ([80.238.139.98]:48839 ident=mail) 13 | by cpanel5.proisp.no with esmtp (Exim 4.69) 14 | (envelope-from ) 15 | id 1KJ1ht-00085G-Ng 16 | for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 09:45:52 +0200 17 | Received: from lunn by londo.lunn.ch with local (Exim 3.36 #1 (Debian)) 18 | id 1KJ1hq-0005ss-00; Wed, 16 Jul 2008 09:45:46 +0200 19 | Date: Wed, 16 Jul 2008 09:45:46 +0200 20 | From: Andrew Lunn 21 | To: ?yvind Harboe 22 | Cc: jim-devel@lists.berlios.de, antirez@gmail.com, patthoyts@users.sf.net, 23 | andrew@lunn.ch, openocd@duaneellis.com, uklein@klein-messgeraete.de, 24 | ml-jim@qiao.in-berlin.de 25 | Subject: Re: Change Jim Tcl license 26 | Message-ID: <20080716074546.GC24771@lunn.ch> 27 | References: 28 | MIME-Version: 1.0 29 | Content-Type: text/plain; charset=us-ascii 30 | Content-Disposition: inline 31 | In-Reply-To: 32 | User-Agent: Mutt/1.5.18 (2008-05-17) 33 | X-Spam-Status: No, score=-2.6 34 | X-Spam-Score: -25 35 | X-Spam-Bar: -- 36 | X-Spam-Flag: NO 37 | X-AntiAbuse: This header was added to track abuse, please include it with any abuse report 38 | X-AntiAbuse: Primary Hostname - cpanel5.proisp.no 39 | X-AntiAbuse: Original Domain - zylin.com 40 | X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] 41 | X-AntiAbuse: Sender Address Domain - lunn.ch 42 | X-Source: 43 | X-Source-Args: 44 | X-Source-Dir: 45 | 46 | On Wed, Jul 16, 2008 at 09:34:14AM +0200, ?yvind Harboe wrote: 47 | > Hi all, 48 | > 49 | > I'm currently the maintainer of Jim Tcl trying as best as I can 50 | > to fill Salvatore's shoes. 51 | > 52 | > Short story: 53 | > 54 | > If you have contributed to Jim Tcl, please reply to this email 55 | > that you agree that we can switch Jim Tcl to a FreeBSD license. 56 | 57 | I've no problems with this, but my contributions are very minimal. 58 | 59 | Do you want this written down, in blood, to keep the lawyers happy? 60 | 61 | At a minimum i think everybody's agreement needs to be posted to a 62 | public email list which is publicly archived etc so there is a 63 | record of the agreement... 64 | 65 | Andrew 66 | -------------------------------------------------------------------------------- /freebsd/clemens.txt: -------------------------------------------------------------------------------- 1 | 2 | Delivered-To: oyvindharboe@gmail.com 3 | Received: by 10.100.7.20 with SMTP id 20cs114742ang; 4 | Wed, 16 Jul 2008 08:58:18 -0700 (PDT) 5 | Received: by 10.114.137.2 with SMTP id k2mr325372wad.95.1216223896673; 6 | Wed, 16 Jul 2008 08:58:16 -0700 (PDT) 7 | Return-Path: 8 | Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) 9 | by mx.google.com with ESMTP id m28si10145125waf.16.2008.07.16.08.58.15; 10 | Wed, 16 Jul 2008 08:58:16 -0700 (PDT) 11 | Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of ml-jim@qiao.in-berlin.de) client-ip=209.85.100.29; 12 | Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of ml-jim@qiao.in-berlin.de) smtp.mail=ml-jim@qiao.in-berlin.de 13 | Received: from gnu.in-berlin.de ([192.109.42.4]:58401) 14 | by cpanel5.proisp.no with esmtps (TLSv1:AES256-SHA:256) 15 | (Exim 4.69) 16 | (envelope-from ) 17 | id 1KJ9OG-0006Hf-8y 18 | for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 17:58:07 +0200 19 | X-Envelope-From: ml-jim@qiao.in-berlin.de 20 | X-Envelope-To: 21 | Received: from qiao.in-berlin.de (qiao.in-berlin.de [217.197.85.72]) 22 | by gnu.in-berlin.de (8.13.8/8.13.8/Debian-2) with ESMTP id m6GFvxio009504 23 | for ; Wed, 16 Jul 2008 17:58:02 +0200 24 | Received: from [192.168.0.10] ([::ffff:192.168.0.10]) 25 | by qiao.in-berlin.de with esmtp; Wed, 16 Jul 2008 18:00:04 +0200 26 | id 0001D68D.487E1B04.000042E7 27 | In-Reply-To: 28 | References: 29 | Mime-Version: 1.0 (Apple Message framework v753.1) 30 | Content-Type: text/plain; charset=ISO-8859-1; delsp=yes; format=flowed 31 | Message-Id: 32 | Cc: jim-devel@lists.berlios.de, antirez@gmail.com, patthoyts@users.sf.net, 33 | andrew@lunn.ch, openocd@duaneellis.com, uklein@klein-messgeraete.de 34 | Content-Transfer-Encoding: quoted-printable 35 | From: Clemens Hintze 36 | Subject: Re: Change Jim Tcl license 37 | Date: Wed, 16 Jul 2008 17:58:14 +0200 38 | To: "=?ISO-8859-1?Q?\"=D8yvind_Harboe\"?=" 39 | X-Mailer: Apple Mail (2.753.1) 40 | X-Spam-Score: (0.101) BAYES_50,RDNS_NONE 41 | X-Scanned-By: MIMEDefang_at_IN-Berlin_e.V. on 192.109.42.4 42 | X-Spam-Status: No, score=-2.6 43 | X-Spam-Score: -25 44 | X-Spam-Bar: -- 45 | X-Spam-Flag: NO 46 | X-AntiAbuse: This header was added to track abuse, please include it with any abuse report 47 | X-AntiAbuse: Primary Hostname - cpanel5.proisp.no 48 | X-AntiAbuse: Original Domain - zylin.com 49 | X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] 50 | X-AntiAbuse: Sender Address Domain - qiao.in-berlin.de 51 | X-Source: 52 | X-Source-Args: 53 | X-Source-Dir: 54 | 55 | 56 | Am 16.07.2008 um 09:34 schrieb =D8yvind Harboe: 57 | 58 | > Hi all, 59 | 60 | Hi =D8yvind, 61 | 62 | (...) 63 | 64 | > If you have contributed to Jim Tcl, please reply to this email 65 | > that you agree that we can switch Jim Tcl to a FreeBSD license. 66 | > 67 | > Once I have a record of all contributors agreeing to switch 68 | > to a FreeBSD license, I'll update CVS. 69 | 70 | No problem with me: I agree to permit my contributions to the Jim =20 71 | project to be 72 | re-licensed under a BSD compatible license. 73 | 74 | (...) 75 | 76 | > Please let me know if any of the emails below are wrong(chi is 77 | > missing) or the list is not complete. 78 | 79 | After consultation with the voices in my head, I can ensure you, =20 80 | 'chi' is also agreeing with the re-licensing, because its me too ;-) 81 | 82 | Thank you very much to revive Jim! :-) 83 | 84 | Best regards, 85 | Clemens Hintze. 86 | 87 | (...)= 88 | -------------------------------------------------------------------------------- /freebsd/duane.txt: -------------------------------------------------------------------------------- 1 | Delivered-To: oyvindharboe@gmail.com 2 | Received: by 10.100.7.20 with SMTP id 20cs93801ang; 3 | Wed, 16 Jul 2008 03:40:02 -0700 (PDT) 4 | Received: by 10.142.148.10 with SMTP id v10mr5070849wfd.317.1216204801306; 5 | Wed, 16 Jul 2008 03:40:01 -0700 (PDT) 6 | Return-Path: 7 | Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) 8 | by mx.google.com with ESMTP id 27si9313433wff.3.2008.07.16.03.40.00; 9 | Wed, 16 Jul 2008 03:40:01 -0700 (PDT) 10 | Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of openocd@duaneellis.com) client-ip=209.85.100.29; 11 | Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of openocd@duaneellis.com) smtp.mail=openocd@duaneellis.com 12 | Received: from smtpout10-04.prod.mesa1.secureserver.net ([64.202.165.238]:48803 helo=smtpout10.prod.mesa1.secureserver.net) 13 | by cpanel5.proisp.no with smtp (Exim 4.69) 14 | (envelope-from ) 15 | id 1KJ4QL-0005cq-GB 16 | for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 12:39:54 +0200 17 | Received: (qmail 2305 invoked from network); 16 Jul 2008 10:39:56 -0000 18 | Received: from unknown (68.37.53.103) 19 | by smtpout10-04.prod.mesa1.secureserver.net (64.202.165.238) with ESMTP; 16 Jul 2008 10:39:55 -0000 20 | Message-ID: <487DCFEC.4010104@duaneellis.com> 21 | Date: Wed, 16 Jul 2008 06:39:40 -0400 22 | From: Duane Ellis 23 | Reply-To: openocd@duaneellis.com 24 | User-Agent: Thunderbird 2.0.0.14 (Windows/20080421) 25 | MIME-Version: 1.0 26 | To: =?ISO-8859-1?Q?=D8yvind_Harboe?= 27 | CC: jim-devel@lists.berlios.de, antirez@gmail.com, 28 | patthoyts@users.sf.net, andrew@lunn.ch, uklein@klein-messgeraete.de, 29 | ml-jim@qiao.in-berlin.de 30 | Subject: Re: Change Jim Tcl license 31 | References: 32 | In-Reply-To: 33 | Content-Type: text/plain; charset=ISO-8859-1; format=flowed 34 | Content-Transfer-Encoding: 8bit 35 | X-Spam-Status: No, score=-2.6 36 | X-Spam-Score: -25 37 | X-Spam-Bar: -- 38 | X-Spam-Flag: NO 39 | X-AntiAbuse: This header was added to track abuse, please include it with any abuse report 40 | X-AntiAbuse: Primary Hostname - cpanel5.proisp.no 41 | X-AntiAbuse: Original Domain - zylin.com 42 | X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] 43 | X-AntiAbuse: Sender Address Domain - duaneellis.com 44 | X-Source: 45 | X-Source-Args: 46 | X-Source-Dir: 47 | 48 | Oyvind Harboe wrote: 49 | > Short story: 50 | > 51 | > If you have contributed to Jim Tcl, please reply to this email 52 | > that you agree that we can switch Jim Tcl to a FreeBSD license. 53 | > 54 | > Once I have a record of all contributors agreeing to switch 55 | > to a FreeBSD license, I'll update CVS. 56 | > 57 | > 58 | OK - from me 59 | 60 | --Duane. 61 | 62 | -Duane. 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /freebsd/oharboe.txt: -------------------------------------------------------------------------------- 1 | 2 | Received: by 10.100.7.20 with HTTP; Wed, 16 Jul 2008 10:12:05 -0700 (PDT) 3 | Message-ID: 4 | Date: Wed, 16 Jul 2008 19:12:05 +0200 5 | From: "=?ISO-8859-1?Q?=D8yvind_Harboe?=" 6 | Sender: oyvindharboe@gmail.com 7 | To: jim-devel@lists.berlios.de 8 | Subject: Re: Change Jim Tcl license 9 | In-Reply-To: 10 | MIME-Version: 1.0 11 | Content-Type: text/plain; charset=ISO-8859-1 12 | Content-Transfer-Encoding: quoted-printable 13 | Content-Disposition: inline 14 | References: 15 | Delivered-To: oyvindharboe@gmail.com 16 | X-Google-Sender-Auth: fc18e85532eee8f2 17 | 18 | For the record: 19 | 20 | I would like my contributions to Jim Tcl to be under a FreeBSD license too= 21 | . 22 | 23 | On Wed, Jul 16, 2008 at 9:34 AM, =D8yvind Harboe = 24 | wrote: 25 | > Hi all, 26 | > 27 | > I'm currently the maintainer of Jim Tcl trying as best as I can 28 | > to fill Salvatore's shoes. 29 | > 30 | > Short story: 31 | > 32 | > If you have contributed to Jim Tcl, please reply to this email 33 | > that you agree that we can switch Jim Tcl to a FreeBSD license. 34 | > 35 | > Once I have a record of all contributors agreeing to switch 36 | > to a FreeBSD license, I'll update CVS. 37 | > 38 | > Long story: 39 | > 40 | > The current Jim Tcl license has a problem with GPL. If you 41 | > link GPL code and Jim Tcl, the result is no license at all. 42 | > 43 | > This prevents Jim Tcl from being used in GPL projects. 44 | > 45 | > Lately Jim Tcl has been used with OpenOCD, a GPL project, 46 | > and the license issue must be resolved one way or another. 47 | > 48 | > Upon conferring with Jonathan Larmour , who 49 | > has kindly helped out with his knowledge on the topic, I have 50 | > concluded that the best way to rectify this is to change the 51 | > Jim Tcl license to a FreeBSD license. See OpenOCD mailing 52 | > list for a discussion on this if you want details. 53 | > 54 | > http://www.fsf.org/licensing/licenses/index_html#FreeBSD 55 | > 56 | > As far as I can determine, below is the complete list of contributors. 57 | > 58 | > 59 | > antirez - Salvatore Sanfilippo 60 | > patthoyts - ?? Pat Thoyts 61 | > oharboe - =D8yvind Harboe - soyvind.harboe@zylin.com 62 | > chi - ?? 63 | > Andrew Lunn 64 | > Duane Ellis 65 | > Uwe Klein 66 | > Clemens Hintze ml-jim@qiao.in-berlin.de 67 | > 68 | > Please let me know if any of the emails below are wrong(chi is 69 | > missing) or the list is not complete. 70 | > 71 | > 72 | > -- 73 | > =D8yvind Harboe 74 | > http://www.zylin.com/zy1000.html 75 | > ARM7 ARM9 XScale Cortex 76 | > JTAG debugger and flash programmer 77 | > 78 | 79 | 80 | 81 | --=20 82 | =D8yvind Harboe 83 | http://www.zylin.com/zy1000.html 84 | ARM7 ARM9 XScale Cortex 85 | JTAG debugger and flash programmer 86 | -------------------------------------------------------------------------------- /freebsd/pat.txt: -------------------------------------------------------------------------------- 1 | 2 | Delivered-To: oyvindharboe@gmail.com 3 | Received: by 10.100.7.20 with SMTP id 20cs108097ang; 4 | Wed, 16 Jul 2008 07:49:02 -0700 (PDT) 5 | Received: by 10.142.232.20 with SMTP id e20mr80874wfh.138.1216219741865; 6 | Wed, 16 Jul 2008 07:49:01 -0700 (PDT) 7 | Return-Path: 8 | Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) 9 | by mx.google.com with ESMTP id 30si10551683wff.18.2008.07.16.07.49.01; 10 | Wed, 16 Jul 2008 07:49:01 -0700 (PDT) 11 | Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of patthoyts@users.sourceforge.net) client-ip=209.85.100.29; 12 | Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by best guess record for domain of patthoyts@users.sourceforge.net) smtp.mail=patthoyts@users.sourceforge.net 13 | Received: from smtp-out4.blueyonder.co.uk ([195.188.213.7]:38596) 14 | by cpanel5.proisp.no with esmtp (Exim 4.69) 15 | (envelope-from ) 16 | id 1KJ8JH-0000Vd-OT 17 | for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 16:48:52 +0200 18 | Received: from [172.23.170.141] (helo=anti-virus02-08) 19 | by smtp-out4.blueyonder.co.uk with smtp (Exim 4.52) 20 | id 1KJ8JO-0007r0-Cy; Wed, 16 Jul 2008 15:48:58 +0100 21 | Received: from [77.102.249.21] (helo=badger.patthoyts.tk) 22 | by asmtp-out4.blueyonder.co.uk with esmtp (Exim 4.52) 23 | id 1KJ8J6-0000gY-VY; Wed, 16 Jul 2008 15:48:41 +0100 24 | Received: by badger.patthoyts.tk (Postfix, from userid 1000) 25 | id 810535184F; Wed, 16 Jul 2008 15:48:40 +0100 (BST) 26 | Sender: pat@badger.patthoyts.tk 27 | To: =?iso-8859-1?q?=D8yvind_Harboe?= 28 | Cc: jim-devel@lists.berlios.de 29 | Subject: Re: Change Jim Tcl license 30 | References: 31 | X-Face: .`d#euqz@6H{";Ysmx2IVe_7M3vA+2w1X[QLk?ZO&QRauXQL{*L'$3getx}9+zK.-KWDx3. 32 | qrlR)76MFb`6bgoGvLpLtcQKB=X~;* 36 | Date: 16 Jul 2008 15:48:39 +0100 37 | In-Reply-To: 38 | Message-ID: <87fxq97um0.fsf@badger.patthoyts.tk> 39 | Lines: 27 40 | User-Agent: Gnus/5.09 (Gnus v5.9.0) Emacs/21.3 41 | MIME-Version: 1.0 42 | Content-Type: text/plain; charset=iso-8859-1 43 | Content-Transfer-Encoding: quoted-printable 44 | X-Spam-Status: No, score=-2.6 45 | X-Spam-Score: -25 46 | X-Spam-Bar: -- 47 | X-Spam-Flag: NO 48 | X-AntiAbuse: This header was added to track abuse, please include it with any abuse report 49 | X-AntiAbuse: Primary Hostname - cpanel5.proisp.no 50 | X-AntiAbuse: Original Domain - zylin.com 51 | X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] 52 | X-AntiAbuse: Sender Address Domain - users.sourceforge.net 53 | X-Source: 54 | X-Source-Args: 55 | X-Source-Dir: 56 | 57 | -----BEGIN PGP SIGNED MESSAGE----- 58 | Hash: SHA1 59 | 60 | "=D8yvind Harboe" writes: 61 | 62 | >If you have contributed to Jim Tcl, please reply to this email 63 | >that you agree that we can switch Jim Tcl to a FreeBSD license. 64 | > 65 | >Once I have a record of all contributors agreeing to switch 66 | >to a FreeBSD license, I'll update CVS. 67 | 68 | I hereby agree to permit my contributions to the Jim project to be 69 | re-licensed under a BSD compatible license. 70 | 71 | - --=20 72 | Pat Thoyts http://www.patthoyts.tk/ 73 | PGP fingerprint 2C 6E 98 07 2C 59 C8 97 10 CE 11 E6 04 E0 B9 DD 74 | -----BEGIN PGP SIGNATURE----- 75 | Version: GnuPG v1.4.8 (SunOS) 76 | Comment: Processed by Mailcrypt 3.5.8 77 | 78 | iQCVAwUBSH4KO2B90JXwhOSJAQKtqQP9ERwSXpbP69l4JSrunG29Rhu2F3r83zu3 79 | GAKpFu4HwkVnIStLQ4o3tsqG9uKrVDbRMa187eSwHmlXXIMwDlkCKNsDFxvdLDZz 80 | kbTYDibspYSw6CjwOUSTXifK9P7ho4Q7PtsRnJ8T1IMlGJlwg39Rxd+mpEO/if3q 81 | ExIwM1aBbAs=3D 82 | =3Du8si 83 | -----END PGP SIGNATURE----- 84 | 85 | -------------------------------------------------------------------------------- /freebsd/salvatore.txt: -------------------------------------------------------------------------------- 1 | 2 | Delivered-To: oyvindharboe@gmail.com 3 | Received: by 10.100.7.20 with SMTP id 20cs113143ang; 4 | Wed, 16 Jul 2008 08:41:11 -0700 (PDT) 5 | Received: by 10.142.140.15 with SMTP id n15mr127048wfd.84.1216222870242; 6 | Wed, 16 Jul 2008 08:41:10 -0700 (PDT) 7 | Return-Path: 8 | Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) 9 | by mx.google.com with ESMTP id 29si7397124wfg.0.2008.07.16.08.41.08; 10 | Wed, 16 Jul 2008 08:41:10 -0700 (PDT) 11 | Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by domain of antirez@gmail.com) client-ip=209.85.100.29; 12 | Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by domain of antirez@gmail.com) smtp.mail=antirez@gmail.com; dkim=pass (test mode) header.i=@gmail.com 13 | Received: from fg-out-1718.google.com ([72.14.220.155]:16058) 14 | by cpanel5.proisp.no with esmtp (Exim 4.69) 15 | (envelope-from ) 16 | id 1KJ97g-0004yX-1W 17 | for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 17:40:59 +0200 18 | Received: by fg-out-1718.google.com with SMTP id l27so3985052fgb.19 19 | for ; Wed, 16 Jul 2008 08:40:59 -0700 (PDT) 20 | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; 21 | d=gmail.com; s=gamma; 22 | h=domainkey-signature:received:received:message-id:date:from:to 23 | :subject:cc:in-reply-to:mime-version:content-type 24 | :content-transfer-encoding:content-disposition:references; 25 | bh=/aWDZQfgMBPqomYWZ2AUKOhhGMju+bwnSBbKL8MBonA=; 26 | b=i0P3OKDopn/vHfa5ZrUvBjuPBnj43GMw8FOXKjxM/IfvywJParYqBS2Vmlw8RTndFg 27 | J5wwxXf5056cZu/GbKbj8xLfylFfSInVaO7OnDutA3CeX1iU35my1DU6l9W6ILkLiT1P 28 | Azi3L27rFQrzau/s53VU/UVELc3WckWdu1a1k= 29 | DomainKey-Signature: a=rsa-sha1; c=nofws; 30 | d=gmail.com; s=gamma; 31 | h=message-id:date:from:to:subject:cc:in-reply-to:mime-version 32 | :content-type:content-transfer-encoding:content-disposition 33 | :references; 34 | b=ww2MIz9svJttgS8mTRBhEX8Isveugn2hl3sMcgh0hZ1+ln8YbiysxYxZkdddewWm02 35 | WXsWgSgwy7MIPAUK1tNjzgkZ2l789SdrAtBCmqmRWJJI+ESTqbHMz8cqW+QRVP/A9Dfm 36 | 8+AR85DHi7SOB0mdHtq9fsavZReUdaSIgy6F4= 37 | Received: by 10.86.80.5 with SMTP id d5mr2284433fgb.19.1216222858224; 38 | Wed, 16 Jul 2008 08:40:58 -0700 (PDT) 39 | Received: by 10.86.50.18 with HTTP; Wed, 16 Jul 2008 08:40:58 -0700 (PDT) 40 | Message-ID: 41 | Date: Wed, 16 Jul 2008 17:40:58 +0200 42 | From: "Salvatore Sanfilippo" 43 | To: "=?ISO-8859-1?Q?=D8yvind_Harboe?=" 44 | Subject: Re: Change Jim Tcl license 45 | Cc: jim-devel@lists.berlios.de, patthoyts@users.sf.net, andrew@lunn.ch, 46 | openocd@duaneellis.com, uklein@klein-messgeraete.de, 47 | ml-jim@qiao.in-berlin.de 48 | In-Reply-To: 49 | MIME-Version: 1.0 50 | Content-Type: text/plain; charset=ISO-8859-1 51 | Content-Transfer-Encoding: 7bit 52 | Content-Disposition: inline 53 | References: 54 | X-Spam-Status: No, score=-2.6 55 | X-Spam-Score: -25 56 | X-Spam-Bar: -- 57 | X-Spam-Flag: NO 58 | X-AntiAbuse: This header was added to track abuse, please include it with any abuse report 59 | X-AntiAbuse: Primary Hostname - cpanel5.proisp.no 60 | X-AntiAbuse: Original Domain - zylin.com 61 | X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] 62 | X-AntiAbuse: Sender Address Domain - gmail.com 63 | X-Source: 64 | X-Source-Args: 65 | X-Source-Dir: 66 | 67 | I agree to permit my contributions to the Jim project to be 68 | re-licensed under a BSD compatible license. 69 | 70 | Since I'm currently the top contributor if it's safer from 71 | the legal point of view I can also put a tar.gz of the current 72 | Jim source code with a BSD "LICENSE" file on my website. 73 | 74 | Otherwise I can sign by hand a letter and send a digitalized 75 | image here. 76 | 77 | Ciao, 78 | Salvatore 79 | 80 | -- 81 | Salvatore 'antirez' Sanfilippo 82 | http://antirez.com 83 | 84 | Organizations which design systems are constrained to produce designs 85 | which are copies of the communication structures of these 86 | organizations. 87 | 88 | Conway's Law 89 | -------------------------------------------------------------------------------- /freebsd/uwe.txt: -------------------------------------------------------------------------------- 1 | Delivered-To: oyvindharboe@gmail.com 2 | Received: by 10.100.7.20 with SMTP id 20cs89014ang; 3 | Wed, 16 Jul 2008 01:58:32 -0700 (PDT) 4 | Received: by 10.142.125.9 with SMTP id x9mr5028534wfc.123.1216198711465; 5 | Wed, 16 Jul 2008 01:58:31 -0700 (PDT) 6 | Return-Path: 7 | Received: from cpanel5.proisp.no (cpanel5.proisp.no [209.85.100.29]) 8 | by mx.google.com with ESMTP id 30si6756166wfa.10.2008.07.16.01.58.29; 9 | Wed, 16 Jul 2008 01:58:31 -0700 (PDT) 10 | Received-SPF: neutral (google.com: 209.85.100.29 is neither permitted nor denied by domain of wiederling@googlemail.com) client-ip=209.85.100.29; 11 | Authentication-Results: mx.google.com; spf=neutral (google.com: 209.85.100.29 is neither permitted nor denied by domain of wiederling@googlemail.com) smtp.mail=wiederling@googlemail.com; dkim=pass (test mode) header.i=@googlemail.com 12 | Received: from wr-out-0506.google.com ([64.233.184.233]:51225) 13 | by cpanel5.proisp.no with esmtp (Exim 4.69) 14 | (envelope-from ) 15 | id 1KJ2q7-00057b-IR 16 | for oyvind.harboe@zylin.com; Wed, 16 Jul 2008 10:58:24 +0200 17 | Received: by wr-out-0506.google.com with SMTP id c8so2209154wra.27 18 | for ; Wed, 16 Jul 2008 01:58:25 -0700 (PDT) 19 | DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; 20 | d=googlemail.com; s=gamma; 21 | h=domainkey-signature:received:received:message-id:date:from:to 22 | :subject:cc:in-reply-to:mime-version:content-type 23 | :content-transfer-encoding:content-disposition:references; 24 | bh=VxcH0g2H5iLUo27gqJiqrlY4uVbN1NFE4skyMKqysPM=; 25 | b=JPK53r6LQ6GqBCG1kfVYyTPuPuVhlBrbzQ8oSBwpwuwwB7t3CSv+c75jRjb/n3y8mi 26 | gN1r6noZucK9ZpRZiHxYZpHVhYFcWbZ+ZXM75H2qIFfl4YDzfgg/Ub7CzoR2LskuBsRk 27 | DMH2LnyAYf+Om2YAKJdkoMnGbPMDMFSrNHeIc= 28 | DomainKey-Signature: a=rsa-sha1; c=nofws; 29 | d=googlemail.com; s=gamma; 30 | h=message-id:date:from:to:subject:cc:in-reply-to:mime-version 31 | :content-type:content-transfer-encoding:content-disposition 32 | :references; 33 | b=VAGlxpb1YGbex/eaS0tQgWvH/lWHzgD5R/rxjshVSwZJOStwqMA1F5jNQgybQFIn1F 34 | zWoiAV81uWMzBEGYab7SGsStWLxovcBSgi9NL+XqwAkhBdrWjgFPvpBHn5PvgOOXEhGH 35 | EGhjrY8qp2LSxhFcW3/DvgObhBBKtY1J+qzvA= 36 | Received: by 10.90.115.17 with SMTP id n17mr1231758agc.90.1216198705850; 37 | Wed, 16 Jul 2008 01:58:25 -0700 (PDT) 38 | Received: by 10.90.105.18 with HTTP; Wed, 16 Jul 2008 01:58:25 -0700 (PDT) 39 | Message-ID: <1af31b6f0807160158o295303adh43abdd34fbe8ec99@mail.gmail.com> 40 | Date: Wed, 16 Jul 2008 10:58:25 +0200 41 | From: "Uwe Klein" 42 | To: "=?ISO-8859-1?Q?=D8yvind_Harboe?=" 43 | Subject: Re: [Jim-devel] Change Jim Tcl license 44 | Cc: jim-devel@lists.berlios.de, patthoyts@users.sf.net, andrew@lunn.ch, 45 | uklein@klein-messgeraete.de, antirez@gmail.com, 46 | openocd@duaneellis.com, ml-jim@qiao.in-berlin.de 47 | In-Reply-To: 48 | MIME-Version: 1.0 49 | Content-Type: text/plain; charset=ISO-8859-1 50 | Content-Transfer-Encoding: 7bit 51 | Content-Disposition: inline 52 | References: 53 | X-Spam-Status: No, score=-2.6 54 | X-Spam-Score: -25 55 | X-Spam-Bar: -- 56 | X-Spam-Flag: NO 57 | X-AntiAbuse: This header was added to track abuse, please include it with any abuse report 58 | X-AntiAbuse: Primary Hostname - cpanel5.proisp.no 59 | X-AntiAbuse: Original Domain - zylin.com 60 | X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] 61 | X-AntiAbuse: Sender Address Domain - googlemail.com 62 | X-Source: 63 | X-Source-Args: 64 | X-Source-Dir: 65 | 66 | > If you have contributed to Jim Tcl, please reply to this email 67 | > that you agree that we can switch Jim Tcl to a FreeBSD license. 68 | 69 | For Uwe Klein 70 | 71 | This is OK with me. 72 | 73 | uwe 74 | -------------------------------------------------------------------------------- /jim-aio.c: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/antirez/Jim/a1a87f72fc61cc085680019eef45312fb2a52d13/jim-aio.c -------------------------------------------------------------------------------- /jim-array-1.0.tcl: -------------------------------------------------------------------------------- 1 | # (c) 2008 Steve Bennett 2 | # 3 | # Implements a Tcl-compatible array command based on dict 4 | # 5 | # The FreeBSD license 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions 9 | # are met: 10 | # 11 | # 1. Redistributions of source code must retain the above copyright 12 | # notice, this list of conditions and the following disclaimer. 13 | # 2. Redistributions in binary form must reproduce the above 14 | # copyright notice, this list of conditions and the following 15 | # disclaimer in the documentation and/or other materials 16 | # provided with the distribution. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY 19 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 21 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | # JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 | # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | # 31 | # The views and conclusions contained in the software and documentation 32 | # are those of the authors and should not be interpreted as representing 33 | # official policies, either expressed or implied, of the Jim Tcl Project. 34 | 35 | package provide array 1.0 36 | 37 | proc array {subcmd arrayname args} { 38 | # $name is the name of the array in the caller's context 39 | upvar $arrayname name 40 | 41 | if {$subcmd eq "exists"} { 42 | return [info exists name] 43 | } 44 | 45 | if {![info exists name]} { 46 | set name [dict create] 47 | } 48 | 49 | switch $subcmd { 50 | set { 51 | # The argument should be a list, but we also 52 | # support name value pairs 53 | if {[llength $args] == 1} { 54 | set args [lindex $args 0] 55 | } 56 | foreach {key value} $args { 57 | dict set name $key $value 58 | } 59 | return $name 60 | } 61 | size { 62 | return [/ [llength $name] 2] 63 | } 64 | } 65 | 66 | # The remaining options take a pattern 67 | if {[llength $args] > 0} { 68 | set pattern [lindex $args 0] 69 | } else { 70 | set pattern * 71 | } 72 | 73 | switch $subcmd { 74 | names { 75 | set keys {} 76 | foreach {key value} $name { 77 | if {[string match $pattern $key]} { 78 | lappend keys $key 79 | } 80 | } 81 | return $keys 82 | } 83 | get { 84 | set list {} 85 | foreach {key value} $name { 86 | if {[string match $pattern $key]} { 87 | lappend list $key $value 88 | } 89 | } 90 | return $list 91 | } 92 | unset { 93 | foreach {key value} $name { 94 | if {[string match $pattern $key]} { 95 | dict unset name $key 96 | } 97 | } 98 | return 99 | } 100 | } 101 | 102 | # Tcl-compatible error message 103 | error "bad option \"$subcmd\": must be exists, get, names, set, size, or unset" 104 | } 105 | -------------------------------------------------------------------------------- /jim-eventloop.h: -------------------------------------------------------------------------------- 1 | /* Jim - A small embeddable Tcl interpreter 2 | * 3 | * Copyright 2005 Salvatore Sanfilippo 4 | * Copyright 2005 Clemens Hintze 5 | * Copyright 2005 patthoyts - Pat Thoyts 6 | * Copyright 2008 oharboe - Øyvind Harboe - oyvind.harboe@zylin.com 7 | * Copyright 2008 Andrew Lunn 8 | * Copyright 2008 Duane Ellis 9 | * Copyright 2008 Uwe Klein 10 | * 11 | * The FreeBSD license 12 | * 13 | * Redistribution and use in source and binary forms, with or without 14 | * modification, are permitted provided that the following conditions 15 | * are met: 16 | * 17 | * 1. Redistributions of source code must retain the above copyright 18 | * notice, this list of conditions and the following disclaimer. 19 | * 2. Redistributions in binary form must reproduce the above 20 | * copyright notice, this list of conditions and the following 21 | * disclaimer in the documentation and/or other materials 22 | * provided with the distribution. 23 | * 24 | * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY 25 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 26 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 27 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 28 | * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 29 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 30 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 31 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 32 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 33 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 34 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 35 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 36 | * 37 | * The views and conclusions contained in the software and documentation 38 | * are those of the authors and should not be interpreted as representing 39 | * official policies, either expressed or implied, of the Jim Tcl Project. 40 | **/ 41 | /* ------ USAGE ------- 42 | * 43 | * In order to use this file from other extensions include it in every 44 | * file where you need to call the eventloop API, also in the init 45 | * function of your extension call Jim_ImportEventloopAPI(interp) 46 | * after the Jim_InitExtension() call. 47 | * 48 | * See the UDP extension as example. 49 | */ 50 | 51 | 52 | #ifndef __JIM_EVENTLOOP_H__ 53 | #define __JIM_EVENTLOOP_H__ 54 | 55 | typedef int Jim_FileProc(Jim_Interp *interp, void *clientData, int mask); 56 | typedef int Jim_SignalProc(Jim_Interp *interp, void *clientData, void *msg); 57 | typedef void Jim_TimeProc(Jim_Interp *interp, void *clientData); 58 | typedef void Jim_EventFinalizerProc(Jim_Interp *interp, void *clientData); 59 | 60 | /* File event structure */ 61 | #define JIM_EVENT_READABLE 1 62 | #define JIM_EVENT_WRITABLE 2 63 | #define JIM_EVENT_EXCEPTION 4 64 | #define JIM_EVENT_FEOF 8 65 | 66 | #define JIM_API(x) x 67 | #define JIM_STATIC 68 | 69 | JIM_STATIC int Jim_EventLoopOnLoad(Jim_Interp *interp); 70 | 71 | /* --- POSIX version of Jim_ProcessEvents, for now the only available --- */ 72 | #define JIM_FILE_EVENTS 1 73 | #define JIM_TIME_EVENTS 2 74 | #define JIM_ALL_EVENTS (JIM_FILE_EVENTS | JIM_TIME_EVENTS) 75 | #define JIM_DONT_WAIT 4 76 | 77 | JIM_STATIC void JIM_API(Jim_CreateFileHandler) (Jim_Interp *interp, 78 | void *handle, int mask, 79 | Jim_FileProc *proc, void *clientData, 80 | Jim_EventFinalizerProc *finalizerProc); 81 | JIM_STATIC void JIM_API(Jim_DeleteFileHandler) (Jim_Interp *interp, 82 | void *handle); 83 | JIM_STATIC jim_wide JIM_API(Jim_CreateTimeHandler) (Jim_Interp *interp, 84 | jim_wide milliseconds, 85 | Jim_TimeProc *proc, void *clientData, 86 | Jim_EventFinalizerProc *finalizerProc); 87 | JIM_STATIC jim_wide JIM_API(Jim_DeleteTimeHandler) (Jim_Interp *interp, jim_wide id); 88 | JIM_STATIC int JIM_API(Jim_ProcessEvents) (Jim_Interp *interp, int flags); 89 | 90 | #undef JIM_STATIC 91 | #undef JIM_API 92 | 93 | #ifndef __JIM_EVENTLOOP_CORE__ 94 | 95 | #define JIM_GET_API(name) \ 96 | Jim_GetApi(interp, "Jim_" #name, ((void *)&Jim_ ## name)) 97 | 98 | #undef JIM_GET_API 99 | #endif /* __JIM_EVENTLOOP_CORE__ */ 100 | 101 | #endif /* __JIM_EVENTLOOP_H__ */ 102 | -------------------------------------------------------------------------------- /jim-glob-1.0.tcl: -------------------------------------------------------------------------------- 1 | # (c) 2008 Steve Bennett 2 | # 3 | # Implements a Tcl-compatible glob command based on readdir 4 | # 5 | # The FreeBSD license 6 | # 7 | # Redistribution and use in source and binary forms, with or without 8 | # modification, are permitted provided that the following conditions 9 | # are met: 10 | # 11 | # 1. Redistributions of source code must retain the above copyright 12 | # notice, this list of conditions and the following disclaimer. 13 | # 2. Redistributions in binary form must reproduce the above 14 | # copyright notice, this list of conditions and the following 15 | # disclaimer in the documentation and/or other materials 16 | # provided with the distribution. 17 | # 18 | # THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY 19 | # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 20 | # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 21 | # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 | # JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 23 | # INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 | # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 | # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 | # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 27 | # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 | # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 | # ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | # 31 | # The views and conclusions contained in the software and documentation 32 | # are those of the authors and should not be interpreted as representing 33 | # official policies, either expressed or implied, of the Jim Tcl Project. 34 | 35 | package provide glob 1.0 36 | package require readdir 1.0 37 | 38 | # If $dir is a directory, return a list of all entries 39 | # it contains which match $pattern 40 | # 41 | proc _glob_readdir_pattern {dir pattern} { 42 | set result {} 43 | 44 | # readdir doesn't return . or .., so simulate it here 45 | if {$pattern eq "." || $pattern eq ".."} { 46 | return $pattern 47 | } 48 | # Use -nocomplain here to return nothing if $dir is not a directory 49 | foreach name [readdir -nocomplain $dir] { 50 | if {[string match $pattern $name]} { 51 | lappend result $name 52 | } 53 | } 54 | 55 | return $result 56 | } 57 | 58 | # glob entries in directory $dir and pattern $rem 59 | # 60 | proc _glob_do {dir rem} { 61 | # Take one level from rem 62 | # Avoid regexp here 63 | set i [string first / $rem] 64 | if {$i < 0} { 65 | set pattern $rem 66 | set rempattern "" 67 | } else { 68 | set j $i 69 | incr j 70 | incr i -1 71 | set pattern [string range $rem 0 $i] 72 | set rempattern [string range $rem $j end] 73 | } 74 | 75 | # Determine the appropriate separator and globbing dir 76 | set sep / 77 | set globdir $dir 78 | if {[string match "*/" $dir]} { 79 | set sep "" 80 | } elseif {$dir eq ""} { 81 | set globdir . 82 | set sep "" 83 | } 84 | 85 | set result {} 86 | 87 | # Use readdir and select all files which match the pattern 88 | foreach f [_glob_readdir_pattern $globdir $pattern] { 89 | if {$rempattern eq ""} { 90 | # This is a terminal entry, so add it 91 | lappend result $dir$sep$f 92 | } else { 93 | # Expany any entries at this level and add them 94 | lappend result {expand}[_glob_do $dir$sep$f $rempattern] 95 | } 96 | } 97 | return $result 98 | } 99 | 100 | # Implements the Tcl glob command 101 | # 102 | # Usage: glob ?-nocomplain? pattern ... 103 | # 104 | # Patterns use string match pattern matching for each 105 | # directory level. 106 | # 107 | # e.g. glob te[a-e]*/*.tcl 108 | # 109 | proc glob {args} { 110 | set nocomplain 0 111 | 112 | if {[lindex $args 0] eq "-nocomplain"} { 113 | set nocomplain 1 114 | set args [lrange $args 1 end] 115 | } 116 | 117 | set result {} 118 | foreach pattern $args { 119 | if {$pattern eq "/"} { 120 | lappend result / 121 | } elseif {[string match "/*" $pattern]} { 122 | lappend result {expand}[_glob_do / [string range $pattern 1 end]] 123 | } else { 124 | lappend result {expand}[_glob_do "" $pattern] 125 | } 126 | } 127 | 128 | if {$nocomplain == 0 && [llength $result] == 0} { 129 | error "no files matched glob patterns" 130 | } 131 | 132 | return $result 133 | } 134 | -------------------------------------------------------------------------------- /jim-hwio.inoutblock.h: -------------------------------------------------------------------------------- 1 | /* Jim - POSIX extension 2 | * Copyright 2005 Salvatore Sanfilippo 3 | * Copyright 2007 Uwe Klein Habertwedt 4 | * 5 | * $Id: jim-hwio.inoutblock.h,v 1.3 2008/02/11 17:09:39 macc Exp macc $ 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * A copy of the license is also included in the source distribution 14 | * of Jim, as a TXT file name called LICENSE. 15 | * 16 | * Unless required by applicable law or agreed to in writing, software 17 | * distributed under the License is distributed on an "AS IS" BASIS, 18 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 | * See the License for the specific language governing permissions and 20 | * limitations under the License. 21 | */ 22 | 23 | static int INOUT_IN_CMDNAME(Jim_Interp *interp, int argc, 24 | Jim_Obj *const *argv) 25 | { 26 | int idx ; 27 | int addrval; 28 | int *plast = NULL; 29 | 30 | Jim_Obj *ret = Jim_NewListObj(interp, 0, 0); 31 | 32 | 33 | for (idx=1;(idx < argc);idx++) { 34 | if (HwIo_getIntsfromList(interp, argv[idx],INOUT_SIZE,plast,&addrval) != JIM_OK) { 35 | Jim_WrongNumArgs(interp, 1, argv, "Format!"); 36 | return JIM_ERR; 37 | } 38 | inb(0x80); 39 | Jim_ListAppendElement(interp,ret,Jim_NewIntObj(interp, INOUT_IN_OP(addrval))); 40 | inb(0x80); 41 | plast = &addrval; 42 | } 43 | Jim_SetResult(interp, ret); 44 | return JIM_OK; 45 | } 46 | 47 | static int INOUT_OUT_CMDNAME(Jim_Interp *interp, int argc, 48 | Jim_Obj *const *argv) 49 | { 50 | int idx ; 51 | int addrval; 52 | int *plast = NULL; 53 | long outval; 54 | int cnt = 0; 55 | 56 | for (idx=1;(idx < argc);idx++) { 57 | // fprintf(stderr,"argc %d idx %d\n",argc,idx); 58 | if (HwIo_getIntsfromList(interp, argv[idx],INOUT_SIZE,plast,&addrval) != JIM_OK) { 59 | Jim_WrongNumArgs(interp, 1, argv, "Format!"); 60 | return JIM_ERR; 61 | } 62 | plast = &addrval; 63 | idx++; 64 | if (idx == argc) 65 | fprintf(stderr,"uneven number args @ %d\n",idx); 66 | if (Jim_GetLong(interp, argv[idx], &outval) == JIM_OK) { 67 | inb(0x80); 68 | INOUT_OUT_OP(outval,addrval); 69 | inb(0x80); 70 | // fprintf(stderr,"outb:%ld @ %d\n",outval,addrval); 71 | cnt++; 72 | } else 73 | return JIM_ERR; 74 | // fprintf(stderr,"argc %d idx %d\n",argc,idx); 75 | } 76 | Jim_SetResult(interp, Jim_NewIntObj(interp, cnt)); 77 | return JIM_OK; 78 | } 79 | #undef INOUT_SIZE 80 | #undef INOUT_IN_OP 81 | #undef INOUT_OUT_OP 82 | #undef INOUT_IN_CMDNAME 83 | #undef INOUT_OUT_CMDNAME 84 | //end 85 | -------------------------------------------------------------------------------- /jim-posix.c: -------------------------------------------------------------------------------- 1 | /* Jim - POSIX extension 2 | * Copyright 2005 Salvatore Sanfilippo 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * A copy of the license is also included in the source distribution 11 | * of Jim, as a TXT file name called LICENSE. 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #define JIM_EXTENSION 28 | #include "jim.h" 29 | 30 | static void Jim_PosixSetError(Jim_Interp *interp) 31 | { 32 | Jim_SetResultString(interp, strerror(errno), -1); 33 | } 34 | 35 | static int Jim_PosixForkCommand(Jim_Interp *interp, int argc, 36 | Jim_Obj *const *argv) 37 | { 38 | pid_t pid; 39 | JIM_NOTUSED(argv); 40 | 41 | if (argc != 1) { 42 | Jim_WrongNumArgs(interp, 1, argv, ""); 43 | return JIM_ERR; 44 | } 45 | if ((pid = fork()) == -1) { 46 | Jim_SetResultString(interp, strerror(errno), -1); 47 | return JIM_ERR; 48 | } 49 | Jim_SetResult(interp, Jim_NewIntObj(interp, (jim_wide)pid)); 50 | return JIM_OK; 51 | } 52 | 53 | static int Jim_PosixSleepCommand(Jim_Interp *interp, int argc, 54 | Jim_Obj *const *argv) 55 | { 56 | long longValue; 57 | 58 | if (argc != 2) { 59 | Jim_WrongNumArgs(interp, 1, argv, "?seconds?"); 60 | return JIM_ERR; 61 | } 62 | if (Jim_GetLong(interp, argv[1], &longValue) != JIM_OK) 63 | return JIM_ERR; 64 | sleep(longValue); 65 | return JIM_OK; 66 | } 67 | 68 | static int Jim_PosixGetidsCommand(Jim_Interp *interp, int argc, 69 | Jim_Obj *const *argv) 70 | { 71 | Jim_Obj *objv[8]; 72 | if (argc != 1) { 73 | Jim_WrongNumArgs(interp, 1, argv, ""); 74 | return JIM_ERR; 75 | } 76 | objv[0] = Jim_NewStringObj(interp, "uid", -1); 77 | objv[1] = Jim_NewIntObj(interp, getuid()); 78 | objv[2] = Jim_NewStringObj(interp, "euid", -1); 79 | objv[3] = Jim_NewIntObj(interp, geteuid()); 80 | objv[4] = Jim_NewStringObj(interp, "gid", -1); 81 | objv[5] = Jim_NewIntObj(interp, getgid()); 82 | objv[6] = Jim_NewStringObj(interp, "egid", -1); 83 | objv[7] = Jim_NewIntObj(interp, getegid()); 84 | Jim_SetResult(interp, Jim_NewListObj(interp, objv, 8)); 85 | return JIM_OK; 86 | } 87 | 88 | #define JIM_HOST_NAME_MAX 1024 89 | static int Jim_PosixGethostnameCommand(Jim_Interp *interp, int argc, 90 | Jim_Obj *const *argv) 91 | { 92 | char buf[JIM_HOST_NAME_MAX]; 93 | 94 | if (argc != 1) { 95 | Jim_WrongNumArgs(interp, 1, argv, ""); 96 | return JIM_ERR; 97 | } 98 | if (gethostname(buf, JIM_HOST_NAME_MAX) == -1) { 99 | Jim_PosixSetError(interp); 100 | return JIM_ERR; 101 | } 102 | Jim_SetResultString(interp, buf, -1); 103 | return JIM_OK; 104 | } 105 | 106 | static int Jim_PosixSethostnameCommand(Jim_Interp *interp, int argc, 107 | Jim_Obj *const *argv) 108 | { 109 | const char *hostname; 110 | int len; 111 | 112 | if (argc != 2) { 113 | Jim_WrongNumArgs(interp, 1, argv, "hostname"); 114 | return JIM_ERR; 115 | } 116 | hostname = Jim_GetString(argv[1], &len); 117 | if (sethostname(hostname, len) == -1) { 118 | Jim_PosixSetError(interp); 119 | return JIM_ERR; 120 | } 121 | return JIM_OK; 122 | } 123 | // added Commands, some linux specific 124 | 125 | // uses POSIX.1b 126 | #define S_NS 1000000000 127 | #define S_US 1000000 128 | #define MSNS 1000000 129 | #define USNS 1000 130 | #define NSNS 1 131 | 132 | static int Jim_LinuxUSleepCommand(Jim_Interp *interp, int argc, 133 | Jim_Obj *const *argv) 134 | { 135 | int mult = NSNS ; 136 | double floatValue ; 137 | const char *units ; 138 | long long delay ; 139 | int len ; 140 | struct timespec tv; 141 | 142 | switch (argc) { 143 | case 3: 144 | units = Jim_GetString(argv[2], &len); 145 | if (units == NULL) 146 | return JIM_ERR; 147 | switch (*units) { 148 | case 's': mult = S_NS; break; 149 | case 'm': mult = MSNS; break; 150 | case 'u': mult = USNS; break; 151 | case 'n': mult = NSNS; break; 152 | default: 153 | Jim_WrongNumArgs(interp, 1, argv, "arg3: ms us ns or empty"); 154 | return JIM_ERR; 155 | } 156 | // fallthrough 157 | case 2: if (Jim_GetDouble(interp, argv[1], &floatValue) != JIM_OK) 158 | return JIM_ERR; 159 | delay = (long long)(floatValue * mult); 160 | break; 161 | default: 162 | Jim_WrongNumArgs(interp, 1, argv, "?useconds?"); 163 | return JIM_ERR; 164 | } 165 | tv.tv_sec = delay / S_NS; 166 | tv.tv_nsec = delay % S_NS; 167 | fprintf(stderr,"delay: %lld mult: %d sec: %ld ns: %ld\n", delay, mult, tv.tv_sec,tv.tv_nsec ); 168 | nanosleep(&tv,NULL); 169 | return JIM_OK; 170 | } 171 | 172 | static int Jim_PointInTimeCommand(Jim_Interp *interp, int argc, 173 | Jim_Obj *const *argv) 174 | { 175 | struct timezone tz = { 0, 0 }; 176 | double pit ; 177 | struct timeval tv; 178 | 179 | gettimeofday(&tv,&tz); 180 | pit = (double)tv.tv_usec; 181 | pit /= (double)S_US; 182 | pit +=(double)tv.tv_sec; 183 | 184 | Jim_SetResult(interp, Jim_NewDoubleObj(interp, pit)); 185 | return JIM_OK; 186 | } 187 | 188 | static int Jim_PointInTimeJulianCommand(Jim_Interp *interp, int argc, 189 | Jim_Obj *const *argv) 190 | { 191 | struct timezone tz = { 0, 0 }; 192 | double pit ; 193 | struct timeval tv; 194 | 195 | gettimeofday(&tv,&tz); 196 | pit = (double)tv.tv_usec; 197 | pit /= (double)S_US; 198 | pit += (double)tv.tv_sec; 199 | pit /= (double)( 60 * 60 * 24 ); 200 | pit += 2440587.5; 201 | 202 | Jim_SetResult(interp, Jim_NewDoubleObj(interp, pit)); 203 | return JIM_OK; 204 | } 205 | 206 | // signal stuff 207 | // signal 208 | 209 | static const char *signames[] = { 210 | "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", 211 | "SIGABRT", "SIGFPE", "SIGKILL", "SIGSEGV", 212 | "SIGPIPE", "SIGALRM", "SIGTERM", 213 | "SIGUSR1", "SIGUSR2", 214 | "SIGCHLD", "SIGCONT", "SIGSTOP", 215 | "SIGTSTP", "SIGTTIN" "SIGTTOU", 216 | "SIGBUS", "SIGPOLL", "SIGPROF", "SIGSYS", 217 | "SIGTRAP", "SIGURG", "SIGVTALRM", "SIGXCPU", 218 | "SIGXFSZ", 219 | "SIGIOT", 220 | #ifdef SIGEMT 221 | "SIGEMT", 222 | #endif 223 | "SIGSTKFLT", "SIGIO", 224 | "SIGCLD", "SIGPWR", 225 | #ifdef SIGINFO 226 | "SIGINFO", 227 | #endif 228 | #ifdef SIGLOST 229 | "SIGLOST", 230 | #endif 231 | "SIGWINCH", "SIGUNUSED", 232 | "SIGRT32", "SIGRT33", "SIGRT34", "SIGRT35", 233 | "SIGRT36", "SIGRT37", "SIGRT38", "SIGRT39", 234 | NULL 235 | } ; 236 | static int signums[] = { 237 | SIGHUP, SIGINT, SIGQUIT, SIGILL, 238 | SIGABRT, SIGFPE, SIGKILL, SIGSEGV, 239 | SIGPIPE, SIGALRM, SIGTERM, 240 | SIGUSR1, SIGUSR2, 241 | SIGCHLD, SIGCONT, SIGSTOP, 242 | SIGTSTP, SIGTTIN, SIGTTOU, 243 | SIGBUS, SIGPOLL, SIGPROF, SIGSYS, 244 | SIGTRAP, SIGURG, SIGVTALRM, SIGXCPU, 245 | SIGXFSZ, 246 | SIGIOT, 247 | #ifdef SIGEMT 248 | SIGEMT, 249 | #endif 250 | SIGSTKFLT, SIGIO, 251 | SIGCLD, SIGPWR, 252 | #ifdef SIGINFO 253 | SIGINFO, 254 | #endif 255 | #ifdef SIGLOST 256 | SIGLOST, 257 | #endif 258 | SIGWINCH, SIGUNUSED, 259 | #ifdef SIGRT 260 | SIGRT32, SIGRT33, SIGRT34, SIGRT35, 261 | SIGRT36, SIGRT37, SIGRT38, SIGRT39, 262 | #endif 263 | 0 264 | } ; 265 | enum { 266 | HUP, INT, QUIT, ILL, 267 | ABRT, FPE, KILL, SEGV, 268 | PIPE, ALRM, TERM, 269 | USR1, USR2, 270 | CHLD, CONT, STOP, 271 | TSTP, TTIN, TTOU, 272 | BUS, POLL, PROF, SYS, 273 | TRAP, URG, VTALRM, XCPU, 274 | XFSZ, 275 | IOT, 276 | #ifdef SIGEMT 277 | EMT, 278 | #endif 279 | STKFLT, IO, 280 | CLD, PWR, 281 | #ifdef SIGINFO 282 | INFO, 283 | #endif 284 | #ifdef SIGLOST 285 | LOST, 286 | #endif 287 | WINCH, UNUSED, 288 | #ifdef SIGRT 289 | RT32, RT33, RT34, RT35, 290 | RT36, RT37, RT38, RT39, 291 | #endif 292 | ISEND 293 | } ; 294 | static void Jim_Posix_SigHandler(int signal) 295 | { 296 | int i; 297 | for (i=0; ((i 3 | * 4 | * Tcl readdir command. 5 | * 6 | * The FreeBSD license 7 | * 8 | * Redistribution and use in source and binary forms, with or without 9 | * modification, are permitted provided that the following conditions 10 | * are met: 11 | * 12 | * 1. Redistributions of source code must retain the above copyright 13 | * notice, this list of conditions and the following disclaimer. 14 | * 2. Redistributions in binary form must reproduce the above 15 | * copyright notice, this list of conditions and the following 16 | * disclaimer in the documentation and/or other materials 17 | * provided with the distribution. 18 | * 19 | * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY 20 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 22 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 23 | * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 24 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 26 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 27 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 28 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 30 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | * 32 | * The views and conclusions contained in the software and documentation 33 | * are those of the authors and should not be interpreted as representing 34 | * official policies, either expressed or implied, of the Jim Tcl Project. 35 | * 36 | * Based on original work by: 37 | *----------------------------------------------------------------------------- 38 | * Copyright 1991-1994 Karl Lehenbauer and Mark Diekhans. 39 | * 40 | * Permission to use, copy, modify, and distribute this software and its 41 | * documentation for any purpose and without fee is hereby granted, provided 42 | * that the above copyright notice appear in all copies. Karl Lehenbauer and 43 | * Mark Diekhans make no representations about the suitability of this 44 | * software for any purpose. It is provided "as is" without express or 45 | * implied warranty. 46 | *----------------------------------------------------------------------------- 47 | */ 48 | 49 | #include 50 | #include 51 | #include 52 | #include 53 | 54 | #define JIM_EXTENSION 55 | #include "jim.h" 56 | 57 | /* 58 | *----------------------------------------------------------------------------- 59 | * 60 | * Jim_ReaddirCmd -- 61 | * Implements the rename TCL command: 62 | * readdir ?-nocomplain? dirPath 63 | * 64 | * Results: 65 | * Standard TCL result. 66 | *----------------------------------------------------------------------------- 67 | */ 68 | int 69 | Jim_ReaddirCmd (Jim_Interp *interp, int argc, Jim_Obj *const *argv) 70 | { 71 | const char *dirPath; 72 | DIR *dirPtr; 73 | struct dirent *entryPtr; 74 | int nocomplain = 0; 75 | 76 | if (argc == 3 && Jim_CompareStringImmediate(interp, argv[1], "-nocomplain")) { 77 | nocomplain = 1; 78 | } 79 | if (argc != 2 && !nocomplain) { 80 | Jim_WrongNumArgs(interp, 1, argv, "?-nocomplain? dirPath"); 81 | return JIM_ERR; 82 | } 83 | 84 | dirPath = Jim_GetString(argv[1 + nocomplain], NULL); 85 | 86 | dirPtr = opendir (dirPath); 87 | if (dirPtr == NULL) { 88 | if (nocomplain) { 89 | return JIM_OK; 90 | } 91 | Jim_SetResultString(interp, strerror(errno), -1); 92 | return JIM_ERR; 93 | } 94 | Jim_SetResultString(interp, strerror(errno), -1); 95 | 96 | Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0)); 97 | 98 | while ((entryPtr = readdir (dirPtr)) != NULL) { 99 | if (entryPtr->d_name [0] == '.') { 100 | if (entryPtr->d_name [1] == '\0') { 101 | continue; 102 | } 103 | if ((entryPtr->d_name [1] == '.') && 104 | (entryPtr->d_name [2] == '\0')) 105 | continue; 106 | } 107 | Jim_ListAppendElement(interp, Jim_GetResult(interp), Jim_NewStringObj(interp, entryPtr->d_name, -1)); 108 | } 109 | closedir (dirPtr); 110 | 111 | return JIM_OK; 112 | } 113 | 114 | int Jim_OnLoad(Jim_Interp *interp) 115 | { 116 | Jim_InitExtension(interp); 117 | if (Jim_PackageProvide(interp, "readdir", "1.0", JIM_ERRMSG) != JIM_OK) { 118 | return JIM_ERR; 119 | } 120 | Jim_CreateCommand(interp, "readdir", Jim_ReaddirCmd, NULL, NULL); 121 | return JIM_OK; 122 | } 123 | -------------------------------------------------------------------------------- /jim-readline.c: -------------------------------------------------------------------------------- 1 | /* Jim - Readline bindings for Jim 2 | * Copyright 2005 Salvatore Sanfilippo 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * A copy of the license is also included in the source distribution 11 | * of Jim, as a TXT file name called LICENSE. 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #define JIM_EXTENSION 21 | #include "jim.h" 22 | 23 | #include 24 | #include 25 | 26 | static int JimRlReadlineCommand(Jim_Interp *interp, int argc, 27 | Jim_Obj *const *argv) 28 | { 29 | char *line; 30 | 31 | if (argc != 2) { 32 | Jim_WrongNumArgs(interp, 1, argv, "prompt"); 33 | return JIM_ERR; 34 | } 35 | line = readline(Jim_GetString(argv[1], NULL)); 36 | Jim_SetResult(interp, Jim_NewStringObj(interp, line, -1)); 37 | return JIM_OK; 38 | } 39 | 40 | static int JimRlAddHistoryCommand(Jim_Interp *interp, int argc, 41 | Jim_Obj *const *argv) 42 | { 43 | if (argc != 2) { 44 | Jim_WrongNumArgs(interp, 1, argv, "string"); 45 | return JIM_ERR; 46 | } 47 | add_history(Jim_GetString(argv[1], NULL)); 48 | return JIM_OK; 49 | } 50 | 51 | int Jim_OnLoad(Jim_Interp *interp) 52 | { 53 | Jim_InitExtension(interp); 54 | if (Jim_PackageProvide(interp, "readline", "1.0", JIM_ERRMSG) != JIM_OK) 55 | return JIM_ERR; 56 | Jim_CreateCommand(interp, "readline.readline", JimRlReadlineCommand, NULL, 57 | NULL); 58 | Jim_CreateCommand(interp, "readline.addhistory", JimRlAddHistoryCommand, 59 | NULL, NULL); 60 | return JIM_OK; 61 | } 62 | -------------------------------------------------------------------------------- /jim-regexp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * (c) 2008 Steve Bennett 3 | * 4 | * Implements the regexp and regsub commands for Jim 5 | * 6 | * Uses C library regcomp()/regexec() for the matching. 7 | * 8 | * The FreeBSD license 9 | * 10 | * Redistribution and use in source and binary forms, with or without 11 | * modification, are permitted provided that the following conditions 12 | * are met: 13 | * 14 | * 1. Redistributions of source code must retain the above copyright 15 | * notice, this list of conditions and the following disclaimer. 16 | * 2. Redistributions in binary form must reproduce the above 17 | * copyright notice, this list of conditions and the following 18 | * disclaimer in the documentation and/or other materials 19 | * provided with the distribution. 20 | * 21 | * THIS SOFTWARE IS PROVIDED BY THE JIM TCL PROJECT ``AS IS'' AND ANY 22 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 23 | * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A 24 | * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 | * JIM TCL PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 26 | * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 27 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 30 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 32 | * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 | * 34 | * The views and conclusions contained in the software and documentation 35 | * are those of the authors and should not be interpreted as representing 36 | * official policies, either expressed or implied, of the Jim Tcl Project. 37 | * 38 | * Based on code originally from Tcl 6.7: 39 | * 40 | * Copyright 1987-1991 Regents of the University of California 41 | * Permission to use, copy, modify, and distribute this 42 | * software and its documentation for any purpose and without 43 | * fee is hereby granted, provided that the above copyright 44 | * notice appear in all copies. The University of California 45 | * makes no representations about the suitability of this 46 | * software for any purpose. It is provided "as is" without 47 | * express or implied warranty. 48 | */ 49 | 50 | #include 51 | #include 52 | 53 | #define JIM_EXTENSION 54 | #include "jim.h" 55 | 56 | /* REVISIT: Would be useful in jim.h */ 57 | static void Jim_SetIntResult(Jim_Interp *interp, jim_wide wide) 58 | { 59 | Jim_SetResult(interp, Jim_NewIntObj(interp, wide)); 60 | } 61 | 62 | /** 63 | * REVISIT: Should cache a number of compiled regexps for performance reasons. 64 | */ 65 | static regex_t * 66 | compile_regexp(Jim_Interp *interp, const char *pattern, int flags) 67 | { 68 | int ret; 69 | 70 | regex_t *result = (regex_t *)Jim_Alloc(sizeof(*result)); 71 | 72 | if ((ret = regcomp(result, pattern, REG_EXTENDED | flags)) != 0) { 73 | char buf[100]; 74 | regerror(ret, result, buf, sizeof(buf)); 75 | Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); 76 | Jim_AppendStrings(interp, Jim_GetResult(interp), "couldn't compile regular expression pattern: ", buf, NULL); 77 | Jim_Free(result); 78 | return NULL; 79 | } 80 | return result; 81 | } 82 | 83 | int Jim_RegexpCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) 84 | { 85 | int opt_indices = 0; 86 | int opt_all = 0; 87 | int opt_inline = 0; 88 | regex_t *regex; 89 | int match, i, j; 90 | long offset = 0; 91 | regmatch_t *pmatch = NULL; 92 | int source_len; 93 | int result = JIM_OK; 94 | const char *pattern; 95 | const char *source_str; 96 | int num_matches = 0; 97 | int num_vars; 98 | Jim_Obj *resultListObj = NULL; 99 | int regcomp_flags = 0; 100 | 101 | if (argc < 3) { 102 | wrongNumArgs: 103 | Jim_WrongNumArgs(interp, 1, argv, "?-nocase? ?-line? ?-indices? ?-start offset? ?-all? ?-inline? exp string ?matchVar? ?subMatchVar ...?"); 104 | return JIM_ERR; 105 | } 106 | 107 | for (i = 1; i < argc; i++) { 108 | if (Jim_CompareStringImmediate(interp, argv[i], "-indices")) { 109 | opt_indices = 1; 110 | } 111 | else if (Jim_CompareStringImmediate(interp, argv[i], "-nocase")) { 112 | regcomp_flags |= REG_ICASE; 113 | } 114 | else if (Jim_CompareStringImmediate(interp, argv[i], "-line")) { 115 | regcomp_flags |= REG_NEWLINE; 116 | } 117 | else if (Jim_CompareStringImmediate(interp, argv[i], "-all")) { 118 | opt_all = 1; 119 | } 120 | else if (Jim_CompareStringImmediate(interp, argv[i], "-inline")) { 121 | opt_inline = 1; 122 | } 123 | else if (Jim_CompareStringImmediate(interp, argv[i], "-start")) { 124 | if (++i == argc) { 125 | goto wrongNumArgs; 126 | } 127 | if (Jim_GetLong(interp, argv[i], &offset) != JIM_OK) { 128 | return JIM_ERR; 129 | } 130 | } 131 | else if (Jim_CompareStringImmediate(interp, argv[i], "--")) { 132 | i++; 133 | break; 134 | } 135 | else { 136 | const char *opt = Jim_GetString(argv[i], NULL); 137 | if (*opt == '-') { 138 | /* Bad option */ 139 | goto wrongNumArgs; 140 | } 141 | break; 142 | } 143 | } 144 | if (argc - i < 2) { 145 | goto wrongNumArgs; 146 | } 147 | 148 | pattern = Jim_GetString(argv[i], NULL); 149 | regex = compile_regexp(interp, pattern, regcomp_flags); 150 | if (regex == NULL) { 151 | return JIM_ERR; 152 | } 153 | 154 | source_str = Jim_GetString(argv[i + 1], &source_len); 155 | 156 | num_vars = argc - i - 2; 157 | 158 | if (opt_inline) { 159 | if (num_vars) { 160 | Jim_SetResultString(interp, "regexp match variables not allowed when using -inline", -1); 161 | result = JIM_ERR; 162 | goto done; 163 | } 164 | /* REVISIT: Ugly! */ 165 | num_vars = 100; 166 | } 167 | 168 | pmatch = Jim_Alloc((num_vars + 1) * sizeof(*pmatch)); 169 | 170 | /* If an offset has been specified, adjust for that now. 171 | * If it points past the end of the string, point to the terminating null 172 | */ 173 | if (offset) { 174 | if (offset > source_len) { 175 | source_str += source_len; 176 | } else if (offset > 0) { 177 | source_str += offset; 178 | } 179 | } 180 | 181 | if (opt_inline) { 182 | resultListObj = Jim_NewListObj(interp, NULL, 0); 183 | } 184 | 185 | next_match: 186 | match = regexec(regex, source_str, num_vars + 1, pmatch, 0); 187 | if (match >= REG_BADPAT) { 188 | char buf[100]; 189 | regerror(match, regex, buf, sizeof(buf)); 190 | Jim_SetResultString(interp, "", 0); 191 | Jim_AppendStrings(interp, Jim_GetResult(interp), "error while matching pattern: ", buf, NULL); 192 | result = JIM_ERR; 193 | goto done; 194 | } 195 | 196 | if (match == REG_NOMATCH) { 197 | goto done; 198 | } 199 | 200 | num_matches++; 201 | 202 | if (opt_all && !opt_inline) { 203 | /* Just count the number of matches, so skip the substitution h*/ 204 | goto try_next_match; 205 | } 206 | 207 | /* 208 | * If additional variable names have been specified, return 209 | * index information in those variables. 210 | */ 211 | 212 | //fprintf(stderr, "source_str=%s, [0].rm_eo=%d\n", source_str, pmatch[0].rm_eo); 213 | 214 | j = 0; 215 | for (i += 2; opt_inline ? pmatch[j].rm_so != -1 : i < argc; i++, j++) { 216 | Jim_Obj *resultObj; 217 | 218 | if (opt_indices) { 219 | resultObj = Jim_NewListObj(interp, NULL, 0); 220 | } 221 | else { 222 | resultObj = Jim_NewStringObj(interp, "", 0); 223 | } 224 | 225 | if (pmatch[j].rm_so == -1) { 226 | if (opt_indices) { 227 | Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); 228 | Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, -1)); 229 | } 230 | } else { 231 | int len = pmatch[j].rm_eo - pmatch[j].rm_so; 232 | if (opt_indices) { 233 | Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, offset + pmatch[j].rm_so)); 234 | Jim_ListAppendElement(interp, resultObj, Jim_NewIntObj(interp, offset + pmatch[j].rm_so + len - 1)); 235 | } else { 236 | Jim_AppendString(interp, resultObj, source_str + pmatch[j].rm_so, len); 237 | } 238 | } 239 | 240 | if (opt_inline) { 241 | Jim_ListAppendElement(interp, resultListObj, resultObj); 242 | } 243 | else { 244 | /* And now set the result variable */ 245 | result = Jim_SetVariable(interp, argv[i], resultObj); 246 | 247 | if (result != JIM_OK) { 248 | Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); 249 | Jim_AppendStrings(interp, Jim_GetResult(interp), "couldn't set variable \"", Jim_GetString(argv[i], NULL), "\"", NULL); 250 | Jim_FreeObj(interp, resultObj); 251 | break; 252 | } 253 | } 254 | } 255 | 256 | try_next_match: 257 | if (opt_all && pattern[0] != '^' && *source_str) { 258 | if (pmatch[0].rm_eo) { 259 | source_str += pmatch[0].rm_eo; 260 | } 261 | else { 262 | source_str++; 263 | } 264 | if (*source_str) { 265 | goto next_match; 266 | } 267 | } 268 | 269 | done: 270 | if (result == JIM_OK) { 271 | if (opt_inline) { 272 | Jim_SetResult(interp, resultListObj); 273 | } 274 | else { 275 | Jim_SetIntResult(interp, num_matches); 276 | } 277 | } 278 | 279 | Jim_Free(pmatch); 280 | regfree(regex); 281 | Jim_Free(regex); 282 | return result; 283 | } 284 | 285 | #define MAX_SUB_MATCHES 10 286 | 287 | int Jim_RegsubCmd(Jim_Interp *interp, int argc, Jim_Obj *const *argv) 288 | { 289 | int regcomp_flags = 0; 290 | int opt_all = 0; 291 | long offset = 0; 292 | regex_t *regex; 293 | const char *p; 294 | int result = JIM_ERR; 295 | regmatch_t pmatch[MAX_SUB_MATCHES + 1]; 296 | int num_matches = 0; 297 | 298 | int i; 299 | Jim_Obj *varname; 300 | Jim_Obj *resultObj; 301 | const char *source_str; 302 | int source_len; 303 | const char *replace_str; 304 | const char *pattern; 305 | 306 | if (argc < 5) { 307 | wrongNumArgs: 308 | Jim_WrongNumArgs(interp, 1, argv, "?-nocase? ?-all? exp string subSpec varName"); 309 | return JIM_ERR; 310 | } 311 | 312 | for (i = 1; i < argc; i++) { 313 | if (Jim_CompareStringImmediate(interp, argv[i], "-nocase")) { 314 | regcomp_flags |= REG_ICASE; 315 | } 316 | else if (Jim_CompareStringImmediate(interp, argv[i], "-line")) { 317 | regcomp_flags |= REG_NEWLINE; 318 | } 319 | else if (Jim_CompareStringImmediate(interp, argv[i], "-all")) { 320 | opt_all = 1; 321 | } 322 | else if (Jim_CompareStringImmediate(interp, argv[i], "-start")) { 323 | if (++i == argc) { 324 | goto wrongNumArgs; 325 | } 326 | if (Jim_GetLong(interp, argv[i], &offset) != JIM_OK) { 327 | return JIM_ERR; 328 | } 329 | } 330 | else if (Jim_CompareStringImmediate(interp, argv[i], "--")) { 331 | i++; 332 | break; 333 | } 334 | else { 335 | const char *opt = Jim_GetString(argv[i], NULL); 336 | if (*opt == '-') { 337 | /* Bad option */ 338 | goto wrongNumArgs; 339 | } 340 | break; 341 | } 342 | } 343 | if (argc - i != 4) { 344 | goto wrongNumArgs; 345 | } 346 | 347 | pattern = Jim_GetString(argv[i], NULL); 348 | regex = compile_regexp(interp, pattern, regcomp_flags); 349 | if (regex == NULL) { 350 | return JIM_ERR; 351 | } 352 | 353 | source_str = Jim_GetString(argv[i + 1], &source_len); 354 | replace_str = Jim_GetString(argv[i + 2], NULL); 355 | varname = argv[i + 3]; 356 | 357 | /* Create the result string */ 358 | resultObj = Jim_NewStringObj(interp, "", 0); 359 | 360 | /* If an offset has been specified, adjust for that now. 361 | * If it points past the end of the string, point to the terminating null 362 | */ 363 | if (offset) { 364 | if (offset > source_len) { 365 | offset = source_len; 366 | } else if (offset < 0) { 367 | offset = 0; 368 | } 369 | } 370 | 371 | /* Copy the part before -start */ 372 | Jim_AppendString(interp, resultObj, source_str, offset); 373 | 374 | /* 375 | * The following loop is to handle multiple matches within the 376 | * same source string; each iteration handles one match and its 377 | * corresponding substitution. If "-all" hasn't been specified 378 | * then the loop body only gets executed once. 379 | */ 380 | 381 | for (p = source_str + offset; *p != 0; ) { 382 | const char *src; 383 | int match = regexec(regex, p, MAX_SUB_MATCHES, pmatch, 0); 384 | if (match >= REG_BADPAT) { 385 | char buf[100]; 386 | regerror(match, regex, buf, sizeof(buf)); 387 | Jim_SetResultString(interp, "", 0); 388 | Jim_AppendStrings(interp, Jim_GetResult(interp), "error while matching pattern: ", buf, NULL); 389 | goto done; 390 | } 391 | if (match == REG_NOMATCH) { 392 | break; 393 | } 394 | 395 | num_matches++; 396 | 397 | /* 398 | * Copy the portion of the source string before the match to the 399 | * result variable. 400 | */ 401 | Jim_AppendString(interp, resultObj, p, pmatch[0].rm_so); 402 | 403 | /* 404 | * Append the subSpec (replace_str) argument to the variable, making appropriate 405 | * substitutions. This code is a bit hairy because of the backslash 406 | * conventions and because the code saves up ranges of characters in 407 | * subSpec to reduce the number of calls to Jim_SetVar. 408 | */ 409 | 410 | for (src = replace_str; *src; src++) { 411 | int index; 412 | int c = *src; 413 | 414 | if (c == '&') { 415 | index = 0; 416 | } 417 | else if (c == '\\') { 418 | c = *++src; 419 | if ((c >= '0') && (c <= '9')) { 420 | index = c - '0'; 421 | } 422 | else if ((c == '\\') || (c == '&')) { 423 | Jim_AppendString(interp, resultObj, src, 1); 424 | continue; 425 | } 426 | else { 427 | Jim_AppendString(interp, resultObj, src - 1, 2); 428 | continue; 429 | } 430 | } 431 | else { 432 | Jim_AppendString(interp, resultObj, src, 1); 433 | continue; 434 | } 435 | if ((index < MAX_SUB_MATCHES) && pmatch[index].rm_so != -1 && pmatch[index].rm_eo != -1) { 436 | Jim_AppendString(interp, resultObj, p + pmatch[index].rm_so, pmatch[index].rm_eo - pmatch[index].rm_so); 437 | } 438 | } 439 | 440 | p += pmatch[0].rm_eo; 441 | 442 | if (!opt_all || pmatch[0].rm_eo == 0 || pattern[0] == '^') { 443 | /* If we are doing a single match, or we haven't moved with this match 444 | * or this is an anchored match, we stop */ 445 | break; 446 | } 447 | } 448 | 449 | /* 450 | * Copy the portion of the string after the last match to the 451 | * result variable. 452 | */ 453 | Jim_AppendString(interp, resultObj, p, -1); 454 | 455 | /* And now set the result variable */ 456 | result = Jim_SetVariable(interp, varname, resultObj); 457 | 458 | if (result == JIM_OK) { 459 | Jim_SetIntResult(interp, num_matches); 460 | } 461 | else { 462 | Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); 463 | Jim_AppendStrings(interp, Jim_GetResult(interp), "couldn't set variable \"", Jim_GetString(varname, NULL), "\"", NULL); 464 | Jim_FreeObj(interp, resultObj); 465 | } 466 | 467 | done: 468 | regfree(regex); 469 | Jim_Free(regex); 470 | return result; 471 | } 472 | 473 | int Jim_OnLoad(Jim_Interp *interp) 474 | { 475 | Jim_InitExtension(interp); 476 | if (Jim_PackageProvide(interp, "regexp", "1.0", JIM_ERRMSG) != JIM_OK) { 477 | return JIM_ERR; 478 | } 479 | Jim_CreateCommand(interp, "regexp", Jim_RegexpCmd, NULL, NULL); 480 | Jim_CreateCommand(interp, "regsub", Jim_RegsubCmd, NULL, NULL); 481 | return JIM_OK; 482 | } 483 | -------------------------------------------------------------------------------- /jim-rlprompt-1.0.tcl: -------------------------------------------------------------------------------- 1 | # Readline-based interactive shell for Jim 2 | # Copyright(C) 2005 Salvatore Sanfilippo 3 | # 4 | # In order to automatically have readline-editing features 5 | # put this in your $HOME/.jimrc 6 | # 7 | # if {$jim_interactive} { 8 | # if {[catch {package require rlprompt}] == 0} { 9 | # rlprompt.shell 10 | # } 11 | # } 12 | 13 | package require readline 14 | package provide rlprompt 1.0 15 | 16 | proc rlprompt.shell {} { 17 | puts "Readline shell loaded" 18 | puts "Welcome to Jim [info version]!" 19 | set prompt ". " 20 | while 1 { 21 | set line [readline.readline $prompt] 22 | if {[string length $line] == 0} { 23 | continue 24 | } 25 | readline.addhistory $line 26 | set errCode [catch {uplevel #0 $line} err] 27 | if {$err ne {}} { 28 | puts $err 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /jim-sdl.c: -------------------------------------------------------------------------------- 1 | /* Jim - SDL extension 2 | * Copyright 2005 Salvatore Sanfilippo 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * A copy of the license is also included in the source distribution 11 | * of Jim, as a TXT file name called LICENSE. 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | 27 | #define JIM_EXTENSION 28 | #include "jim.h" 29 | 30 | #define AIO_CMD_LEN 128 31 | 32 | typedef struct JimSdlSurface { 33 | SDL_Surface *screen; 34 | } JimSdlSurface; 35 | 36 | static void JimSdlSetError(Jim_Interp *interp) 37 | { 38 | Jim_SetResultString(interp, SDL_GetError(), -1); 39 | } 40 | 41 | static void JimSdlDelProc(Jim_Interp *interp, void *privData) 42 | { 43 | JimSdlSurface *jss = privData; 44 | JIM_NOTUSED(interp); 45 | 46 | SDL_FreeSurface(jss->screen); 47 | Jim_Free(jss); 48 | } 49 | 50 | /* Calls to commands created via [sdl.surface] are implemented by this 51 | * C command. */ 52 | static int JimSdlHandlerCommand(Jim_Interp *interp, int argc, 53 | Jim_Obj *const *argv) 54 | { 55 | JimSdlSurface *jss = Jim_CmdPrivData(interp); 56 | int option; 57 | const char *options[] = { 58 | "free", "flip", "pixel", "rectangle", "box", "line", "aaline", 59 | "circle", "aacircle", "fcircle", NULL 60 | }; 61 | enum {OPT_FREE, OPT_FLIP, OPT_PIXEL, OPT_RECTANGLE, OPT_BOX, OPT_LINE, 62 | OPT_AALINE, OPT_CIRCLE, OPT_AACIRCLE, OPT_FCIRCLE}; 63 | 64 | if (argc < 2) { 65 | Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?"); 66 | return JIM_ERR; 67 | } 68 | if (Jim_GetEnum(interp, argv[1], options, &option, "SDL surface method", 69 | JIM_ERRMSG) != JIM_OK) 70 | return JIM_ERR; 71 | if (option == OPT_PIXEL) { 72 | /* PIXEL */ 73 | long x, y, red, green, blue, alpha = 255; 74 | 75 | if (argc != 7 && argc != 8) { 76 | Jim_WrongNumArgs(interp, 2, argv, "x y red green blue ?alpha?"); 77 | return JIM_ERR; 78 | } 79 | if (Jim_GetLong(interp, argv[2], &x) != JIM_OK || 80 | Jim_GetLong(interp, argv[3], &y) != JIM_OK || 81 | Jim_GetLong(interp, argv[4], &red) != JIM_OK || 82 | Jim_GetLong(interp, argv[5], &green) != JIM_OK || 83 | Jim_GetLong(interp, argv[6], &blue) != JIM_OK) 84 | { 85 | return JIM_ERR; 86 | } 87 | if (argc == 8 && Jim_GetLong(interp, argv[7], &alpha) != JIM_OK) 88 | return JIM_ERR; 89 | pixelRGBA(jss->screen, x, y, red, green, blue, alpha); 90 | return JIM_OK; 91 | } else if (option == OPT_RECTANGLE || option == OPT_BOX || 92 | option == OPT_LINE || option == OPT_AALINE) 93 | { 94 | /* RECTANGLE, BOX, LINE, AALINE */ 95 | long x1, y1, x2, y2, red, green, blue, alpha = 255; 96 | 97 | if (argc != 9 && argc != 10) { 98 | Jim_WrongNumArgs(interp, 2, argv, "x y red green blue ?alpha?"); 99 | return JIM_ERR; 100 | } 101 | if (Jim_GetLong(interp, argv[2], &x1) != JIM_OK || 102 | Jim_GetLong(interp, argv[3], &y1) != JIM_OK || 103 | Jim_GetLong(interp, argv[4], &x2) != JIM_OK || 104 | Jim_GetLong(interp, argv[5], &y2) != JIM_OK || 105 | Jim_GetLong(interp, argv[6], &red) != JIM_OK || 106 | Jim_GetLong(interp, argv[7], &green) != JIM_OK || 107 | Jim_GetLong(interp, argv[8], &blue) != JIM_OK) 108 | { 109 | return JIM_ERR; 110 | } 111 | if (argc == 10 && Jim_GetLong(interp, argv[9], &alpha) != JIM_OK) 112 | return JIM_ERR; 113 | switch(option) { 114 | case OPT_RECTANGLE: 115 | rectangleRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha); 116 | break; 117 | case OPT_BOX: 118 | boxRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha); 119 | break; 120 | case OPT_LINE: 121 | lineRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha); 122 | break; 123 | case OPT_AALINE: 124 | aalineRGBA(jss->screen, x1, y1, x2, y2, red, green, blue, alpha); 125 | break; 126 | } 127 | return JIM_OK; 128 | } else if (option == OPT_CIRCLE || option == OPT_AACIRCLE || 129 | option == OPT_FCIRCLE) 130 | { 131 | /* CIRCLE, AACIRCLE, FCIRCLE */ 132 | long x, y, radius, red, green, blue, alpha = 255; 133 | 134 | if (argc != 8 && argc != 9) { 135 | Jim_WrongNumArgs(interp, 2, argv, 136 | "x y radius red green blue ?alpha?"); 137 | return JIM_ERR; 138 | } 139 | if (Jim_GetLong(interp, argv[2], &x) != JIM_OK || 140 | Jim_GetLong(interp, argv[3], &y) != JIM_OK || 141 | Jim_GetLong(interp, argv[4], &radius) != JIM_OK || 142 | Jim_GetLong(interp, argv[5], &red) != JIM_OK || 143 | Jim_GetLong(interp, argv[6], &green) != JIM_OK || 144 | Jim_GetLong(interp, argv[7], &blue) != JIM_OK) 145 | { 146 | return JIM_ERR; 147 | } 148 | if (argc == 9 && Jim_GetLong(interp, argv[8], &alpha) != JIM_OK) 149 | return JIM_ERR; 150 | switch(option) { 151 | case OPT_CIRCLE: 152 | circleRGBA(jss->screen, x, y, radius, red, green, blue, alpha); 153 | break; 154 | case OPT_AACIRCLE: 155 | aacircleRGBA(jss->screen, x, y, radius, red, green, blue, alpha); 156 | break; 157 | case OPT_FCIRCLE: 158 | filledCircleRGBA(jss->screen, x, y, radius, red, green, blue, 159 | alpha); 160 | break; 161 | } 162 | return JIM_OK; 163 | } else if (option == OPT_FREE) { 164 | /* FREE */ 165 | if (argc != 2) { 166 | Jim_WrongNumArgs(interp, 2, argv, ""); 167 | return JIM_ERR; 168 | } 169 | Jim_DeleteCommand(interp, Jim_GetString(argv[0], NULL)); 170 | return JIM_OK; 171 | } else if (option == OPT_FLIP) { 172 | /* FLIP */ 173 | if (argc != 2) { 174 | Jim_WrongNumArgs(interp, 2, argv, ""); 175 | return JIM_ERR; 176 | } 177 | SDL_Flip(jss->screen); 178 | return JIM_OK; 179 | } 180 | return JIM_OK; 181 | } 182 | 183 | static int JimSdlSurfaceCommand(Jim_Interp *interp, int argc, 184 | Jim_Obj *const *argv) 185 | { 186 | JimSdlSurface *jss; 187 | char buf[AIO_CMD_LEN]; 188 | Jim_Obj *objPtr; 189 | long screenId, xres, yres; 190 | SDL_Surface *screen; 191 | 192 | if (argc != 3) { 193 | Jim_WrongNumArgs(interp, 1, argv, "xres yres"); 194 | return JIM_ERR; 195 | } 196 | if (Jim_GetLong(interp, argv[1], &xres) != JIM_OK || 197 | Jim_GetLong(interp, argv[2], &yres) != JIM_OK) 198 | return JIM_ERR; 199 | 200 | /* Try to create the surface */ 201 | screen = SDL_SetVideoMode(xres, yres, 32, SDL_SWSURFACE|SDL_ANYFORMAT); 202 | if (screen == NULL) { 203 | JimSdlSetError(interp); 204 | return JIM_ERR; 205 | } 206 | /* Get the next file id */ 207 | if (Jim_EvalGlobal(interp, 208 | "if {[catch {incr sdl.surfaceId}]} {set sdl.surfaceId 0}") != JIM_OK) 209 | return JIM_ERR; 210 | objPtr = Jim_GetVariableStr(interp, "sdl.surfaceId", JIM_ERRMSG); 211 | if (objPtr == NULL) return JIM_ERR; 212 | if (Jim_GetLong(interp, objPtr, &screenId) != JIM_OK) return JIM_ERR; 213 | 214 | /* Create the SDL screen command */ 215 | jss = Jim_Alloc(sizeof(*jss)); 216 | jss->screen = screen; 217 | sprintf(buf, "sdl.surface%ld", screenId); 218 | Jim_CreateCommand(interp, buf, JimSdlHandlerCommand, jss, JimSdlDelProc); 219 | Jim_SetResultString(interp, buf, -1); 220 | return JIM_OK; 221 | } 222 | 223 | int Jim_OnLoad(Jim_Interp *interp) 224 | { 225 | Jim_InitExtension(interp); 226 | if (Jim_PackageProvide(interp, "sdl", "1.0", JIM_ERRMSG) != JIM_OK) 227 | return JIM_ERR; 228 | if (SDL_Init(SDL_INIT_VIDEO) < 0) { 229 | JimSdlSetError(interp); 230 | return JIM_ERR; 231 | } 232 | atexit(SDL_Quit); 233 | Jim_CreateCommand(interp, "sdl.screen", JimSdlSurfaceCommand, NULL, NULL); 234 | return JIM_OK; 235 | } 236 | -------------------------------------------------------------------------------- /jim-sqlite.c: -------------------------------------------------------------------------------- 1 | /* Jim - Sqlite bindings 2 | * Copyright 2005 Salvatore Sanfilippo 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * A copy of the license is also included in the source distribution 11 | * of Jim, as a TXT file name called LICENSE. 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #define JIM_EXTENSION 25 | #include "jim.h" 26 | 27 | #define SQLITE_CMD_LEN 128 28 | 29 | typedef struct JimSqliteHandle { 30 | sqlite *db; 31 | } JimSqliteHandle; 32 | 33 | static void JimSqliteDelProc(Jim_Interp *interp, void *privData) 34 | { 35 | JimSqliteHandle *sh = privData; 36 | JIM_NOTUSED(interp); 37 | 38 | sqlite_close(sh->db); 39 | Jim_Free(sh); 40 | } 41 | 42 | static char *JimSqliteQuoteString(const char *str, int len, int *newLenPtr) 43 | { 44 | int i, newLen, c = 0; 45 | const char *s; 46 | char *d, *buf; 47 | 48 | for (i = 0; i < len; i++) 49 | if (str[i] == '\'') 50 | c++; 51 | newLen = len+c; 52 | s = str; 53 | d = buf = Jim_Alloc(newLen); 54 | while (len--) { 55 | if (*s == '\'') 56 | *d++ = '\''; 57 | *d++ = *s++; 58 | } 59 | *newLenPtr = newLen; 60 | return buf; 61 | } 62 | 63 | static Jim_Obj *JimSqliteFormatQuery(Jim_Interp *interp, Jim_Obj *fmtObjPtr, 64 | int objc, Jim_Obj *const *objv) 65 | { 66 | const char *fmt; 67 | int fmtLen; 68 | Jim_Obj *resObjPtr; 69 | 70 | fmt = Jim_GetString(fmtObjPtr, &fmtLen); 71 | resObjPtr = Jim_NewStringObj(interp, "", 0); 72 | while (fmtLen) { 73 | const char *p = fmt; 74 | char spec[2]; 75 | 76 | while (*fmt != '%' && fmtLen) { 77 | fmt++; fmtLen--; 78 | } 79 | Jim_AppendString(interp, resObjPtr, p, fmt-p); 80 | if (fmtLen == 0) 81 | break; 82 | fmt++; fmtLen--; /* skip '%' */ 83 | if (*fmt != '%') { 84 | if (objc == 0) { 85 | Jim_FreeNewObj(interp, resObjPtr); 86 | Jim_SetResultString(interp, 87 | "not enough arguments for all format specifiers", -1); 88 | return NULL; 89 | } else { 90 | objc--; 91 | } 92 | } 93 | switch(*fmt) { 94 | case 's': 95 | { 96 | const char *str; 97 | char *quoted; 98 | int len, newLen; 99 | 100 | str = Jim_GetString(objv[0], &len); 101 | quoted = JimSqliteQuoteString(str, len, &newLen); 102 | Jim_AppendString(interp, resObjPtr, quoted, newLen); 103 | Jim_Free(quoted); 104 | } 105 | objv++; 106 | break; 107 | case '%': 108 | Jim_AppendString(interp, resObjPtr, "%" , 1); 109 | break; 110 | default: 111 | spec[1] = *fmt; spec[2] = '\0'; 112 | Jim_FreeNewObj(interp, resObjPtr); 113 | Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); 114 | Jim_AppendStrings(interp, Jim_GetResult(interp), 115 | "bad field specifier \"", spec, "\", ", 116 | "only %%s and %%%% are validd", NULL); 117 | return NULL; 118 | } 119 | fmt++; 120 | fmtLen--; 121 | } 122 | return resObjPtr; 123 | } 124 | 125 | /* Calls to [sqlite.open] create commands that are implemented by this 126 | * C command. */ 127 | static int JimSqliteHandlerCommand(Jim_Interp *interp, int argc, 128 | Jim_Obj *const *argv) 129 | { 130 | JimSqliteHandle *sh = Jim_CmdPrivData(interp); 131 | int option; 132 | const char *options[] = { 133 | "close", "query", "lastid", "changes", NULL 134 | }; 135 | enum {OPT_CLOSE, OPT_QUERY, OPT_LASTID, OPT_CHANGES}; 136 | 137 | if (argc < 2) { 138 | Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?"); 139 | return JIM_ERR; 140 | } 141 | if (Jim_GetEnum(interp, argv[1], options, &option, "Sqlite method", 142 | JIM_ERRMSG) != JIM_OK) 143 | return JIM_ERR; 144 | /* CLOSE */ 145 | if (option == OPT_CLOSE) { 146 | if (argc != 2) { 147 | Jim_WrongNumArgs(interp, 2, argv, ""); 148 | return JIM_ERR; 149 | } 150 | Jim_DeleteCommand(interp, Jim_GetString(argv[0], NULL)); 151 | return JIM_OK; 152 | } else if (option == OPT_QUERY) { 153 | /* QUERY */ 154 | Jim_Obj *objPtr, *rowsListPtr; 155 | sqlite_vm *vm; 156 | char *errMsg; 157 | const char *query, *tail, **values, **names; 158 | int columns, rows; 159 | char *nullstr; 160 | 161 | if (argc >= 4 && Jim_CompareStringImmediate(interp, argv[2], "-null")) { 162 | nullstr = Jim_StrDup(Jim_GetString(argv[3], NULL)); 163 | argv += 2; 164 | argc -= 2; 165 | } else { 166 | nullstr = Jim_StrDup(""); 167 | } 168 | if (argc < 3) { 169 | Jim_WrongNumArgs(interp, 2, argv, "query ?args?"); 170 | Jim_Free(nullstr); 171 | return JIM_ERR; 172 | } 173 | objPtr = JimSqliteFormatQuery(interp, argv[2], argc-3, argv+3); 174 | if (objPtr == NULL) { 175 | Jim_Free(nullstr); 176 | return JIM_ERR; 177 | } 178 | query = Jim_GetString(objPtr, NULL); 179 | Jim_IncrRefCount(objPtr); 180 | /* Compile the query into VM code */ 181 | if (sqlite_compile(sh->db, query, &tail, &vm, &errMsg) != SQLITE_OK) { 182 | Jim_DecrRefCount(interp, objPtr); 183 | Jim_SetResultString(interp, errMsg, -1); 184 | sqlite_freemem(errMsg); 185 | Jim_Free(nullstr); 186 | return JIM_ERR; 187 | } 188 | Jim_DecrRefCount(interp, objPtr); /* query no longer needed. */ 189 | /* Build a list of rows (that are lists in turn) */ 190 | rowsListPtr = Jim_NewListObj(interp, NULL, 0); 191 | Jim_IncrRefCount(rowsListPtr); 192 | rows = 0; 193 | while (sqlite_step(vm, &columns, &values, &names) == SQLITE_ROW) { 194 | int i; 195 | 196 | objPtr = Jim_NewListObj(interp, NULL, 0); 197 | for (i = 0; i < columns; i++) { 198 | Jim_ListAppendElement(interp, objPtr, 199 | Jim_NewStringObj(interp, names[i], -1)); 200 | Jim_ListAppendElement(interp, objPtr, 201 | Jim_NewStringObj(interp, 202 | values[i] != NULL ? values[i] : nullstr, -1)); 203 | } 204 | Jim_ListAppendElement(interp, rowsListPtr, objPtr); 205 | rows++; 206 | } 207 | /* Finalize */ 208 | Jim_Free(nullstr); 209 | if (sqlite_finalize(vm, &errMsg) != SQLITE_OK) { 210 | Jim_DecrRefCount(interp, rowsListPtr); 211 | Jim_SetResultString(interp, errMsg, -1); 212 | sqlite_freemem(errMsg); 213 | return JIM_ERR; 214 | } 215 | Jim_SetResult(interp, rowsListPtr); 216 | Jim_DecrRefCount(interp, rowsListPtr); 217 | } else if (option == OPT_LASTID) { 218 | if (argc != 2) { 219 | Jim_WrongNumArgs(interp, 2, argv, ""); 220 | return JIM_ERR; 221 | } 222 | Jim_SetResult(interp, Jim_NewIntObj(interp, 223 | sqlite_last_insert_rowid(sh->db))); 224 | return JIM_OK; 225 | } else if (option == OPT_CHANGES) { 226 | if (argc != 2) { 227 | Jim_WrongNumArgs(interp, 2, argv, ""); 228 | return JIM_ERR; 229 | } 230 | Jim_SetResult(interp, Jim_NewIntObj(interp, 231 | sqlite_changes(sh->db))); 232 | return JIM_OK; 233 | } 234 | return JIM_OK; 235 | } 236 | 237 | static int JimSqliteOpenCommand(Jim_Interp *interp, int argc, 238 | Jim_Obj *const *argv) 239 | { 240 | sqlite *db; 241 | JimSqliteHandle *sh; 242 | char buf[SQLITE_CMD_LEN], *errMsg; 243 | Jim_Obj *objPtr; 244 | long dbId; 245 | 246 | if (argc != 2) { 247 | Jim_WrongNumArgs(interp, 1, argv, "dbname"); 248 | return JIM_ERR; 249 | } 250 | db = sqlite_open(Jim_GetString(argv[1], NULL), 0, &errMsg); 251 | if (db == NULL) { 252 | Jim_SetResultString(interp, errMsg, -1); 253 | sqlite_freemem(errMsg); 254 | return JIM_ERR; 255 | } 256 | /* Get the next file id */ 257 | if (Jim_EvalGlobal(interp, 258 | "if {[catch {incr sqlite.dbId}]} {set sqlite.dbId 0}") != JIM_OK) 259 | return JIM_ERR; 260 | objPtr = Jim_GetVariableStr(interp, "sqlite.dbId", JIM_ERRMSG); 261 | if (objPtr == NULL) return JIM_ERR; 262 | if (Jim_GetLong(interp, objPtr, &dbId) != JIM_OK) return JIM_ERR; 263 | 264 | /* Create the file command */ 265 | sh = Jim_Alloc(sizeof(*sh)); 266 | sh->db = db; 267 | sprintf(buf, "sqlite.handle%ld", dbId); 268 | Jim_CreateCommand(interp, buf, JimSqliteHandlerCommand, sh, 269 | JimSqliteDelProc); 270 | Jim_SetResultString(interp, buf, -1); 271 | return JIM_OK; 272 | } 273 | 274 | int Jim_OnLoad(Jim_Interp *interp) 275 | { 276 | Jim_InitExtension(interp); 277 | if (Jim_PackageProvide(interp, "sqlite", "1.0", JIM_ERRMSG) != JIM_OK) 278 | return JIM_ERR; 279 | Jim_CreateCommand(interp, "sqlite.open", JimSqliteOpenCommand, NULL, NULL); 280 | return JIM_OK; 281 | } 282 | -------------------------------------------------------------------------------- /jim-sqlite3.c: -------------------------------------------------------------------------------- 1 | /* Jim - Sqlite bindings 2 | * Copyright 2005 Salvatore Sanfilippo 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * A copy of the license is also included in the source distribution 11 | * of Jim, as a TXT file name called LICENSE. 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | */ 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #define JIM_EXTENSION 25 | #include "jim.h" 26 | 27 | #define SQLITE_CMD_LEN 128 28 | 29 | typedef struct JimSqliteHandle { 30 | sqlite3 *db; 31 | } JimSqliteHandle; 32 | 33 | static void JimSqliteDelProc(Jim_Interp *interp, void *privData) 34 | { 35 | JimSqliteHandle *sh = privData; 36 | JIM_NOTUSED(interp); 37 | 38 | sqlite3_close(sh->db); 39 | Jim_Free(sh); 40 | } 41 | 42 | static char *JimSqliteQuoteString(const char *str, int len, int *newLenPtr) 43 | { 44 | int i, newLen, c = 0; 45 | const char *s; 46 | char *d, *buf; 47 | 48 | for (i = 0; i < len; i++) 49 | if (str[i] == '\'') 50 | c++; 51 | newLen = len+c; 52 | s = str; 53 | d = buf = Jim_Alloc(newLen); 54 | while (len--) { 55 | if (*s == '\'') 56 | *d++ = '\''; 57 | *d++ = *s++; 58 | } 59 | *newLenPtr = newLen; 60 | return buf; 61 | } 62 | 63 | static Jim_Obj *JimSqliteFormatQuery(Jim_Interp *interp, Jim_Obj *fmtObjPtr, 64 | int objc, Jim_Obj *const *objv) 65 | { 66 | const char *fmt; 67 | int fmtLen; 68 | Jim_Obj *resObjPtr; 69 | 70 | fmt = Jim_GetString(fmtObjPtr, &fmtLen); 71 | resObjPtr = Jim_NewStringObj(interp, "", 0); 72 | while (fmtLen) { 73 | const char *p = fmt; 74 | char spec[2]; 75 | 76 | while (*fmt != '%' && fmtLen) { 77 | fmt++; fmtLen--; 78 | } 79 | Jim_AppendString(interp, resObjPtr, p, fmt-p); 80 | if (fmtLen == 0) 81 | break; 82 | fmt++; fmtLen--; /* skip '%' */ 83 | if (*fmt != '%') { 84 | if (objc == 0) { 85 | Jim_FreeNewObj(interp, resObjPtr); 86 | Jim_SetResultString(interp, 87 | "not enough arguments for all format specifiers", -1); 88 | return NULL; 89 | } else { 90 | objc--; 91 | } 92 | } 93 | switch(*fmt) { 94 | case 's': 95 | { 96 | const char *str; 97 | char *quoted; 98 | int len, newLen; 99 | 100 | str = Jim_GetString(objv[0], &len); 101 | quoted = JimSqliteQuoteString(str, len, &newLen); 102 | Jim_AppendString(interp, resObjPtr, quoted, newLen); 103 | Jim_Free(quoted); 104 | } 105 | objv++; 106 | break; 107 | case '%': 108 | Jim_AppendString(interp, resObjPtr, "%" , 1); 109 | break; 110 | default: 111 | spec[1] = *fmt; spec[2] = '\0'; 112 | Jim_FreeNewObj(interp, resObjPtr); 113 | Jim_SetResult(interp, Jim_NewEmptyStringObj(interp)); 114 | Jim_AppendStrings(interp, Jim_GetResult(interp), 115 | "bad field specifier \"", spec, "\", ", 116 | "only %%s and %%%% are validd", NULL); 117 | return NULL; 118 | } 119 | fmt++; 120 | fmtLen--; 121 | } 122 | return resObjPtr; 123 | } 124 | 125 | /* Calls to [sqlite.open] create commands that are implemented by this 126 | * C command. */ 127 | static int JimSqliteHandlerCommand(Jim_Interp *interp, int argc, 128 | Jim_Obj *const *argv) 129 | { 130 | JimSqliteHandle *sh = Jim_CmdPrivData(interp); 131 | int option; 132 | const char *options[] = { 133 | "close", "query", "lastid", "changes", NULL 134 | }; 135 | enum {OPT_CLOSE, OPT_QUERY, OPT_LASTID, OPT_CHANGES}; 136 | 137 | if (argc < 2) { 138 | Jim_WrongNumArgs(interp, 1, argv, "method ?args ...?"); 139 | return JIM_ERR; 140 | } 141 | if (Jim_GetEnum(interp, argv[1], options, &option, "Sqlite method", 142 | JIM_ERRMSG) != JIM_OK) 143 | return JIM_ERR; 144 | /* CLOSE */ 145 | if (option == OPT_CLOSE) { 146 | if (argc != 2) { 147 | Jim_WrongNumArgs(interp, 2, argv, ""); 148 | return JIM_ERR; 149 | } 150 | Jim_DeleteCommand(interp, Jim_GetString(argv[0], NULL)); 151 | return JIM_OK; 152 | } else if (option == OPT_QUERY) { 153 | /* QUERY */ 154 | Jim_Obj *objPtr, *rowsListPtr; 155 | sqlite3_stmt *stmt; 156 | const char *query, *tail; 157 | int columns, rows, len; 158 | char *nullstr; 159 | 160 | if (argc >= 4 && Jim_CompareStringImmediate(interp, argv[2], "-null")) { 161 | nullstr = Jim_StrDup(Jim_GetString(argv[3], NULL)); 162 | argv += 2; 163 | argc -= 2; 164 | } else { 165 | nullstr = Jim_StrDup(""); 166 | } 167 | if (argc < 3) { 168 | Jim_WrongNumArgs(interp, 2, argv, "query ?args?"); 169 | Jim_Free(nullstr); 170 | return JIM_ERR; 171 | } 172 | objPtr = JimSqliteFormatQuery(interp, argv[2], argc-3, argv+3); 173 | if (objPtr == NULL) { 174 | Jim_Free(nullstr); 175 | return JIM_ERR; 176 | } 177 | query = Jim_GetString(objPtr, &len); 178 | Jim_IncrRefCount(objPtr); 179 | /* Compile the query into VM code */ 180 | if (sqlite3_prepare(sh->db, query, len, &stmt, &tail) != SQLITE_OK) { 181 | Jim_DecrRefCount(interp, objPtr); 182 | Jim_SetResultString(interp, sqlite3_errmsg(sh->db), -1); 183 | Jim_Free(nullstr); 184 | return JIM_ERR; 185 | } 186 | Jim_DecrRefCount(interp, objPtr); /* query no longer needed. */ 187 | /* Build a list of rows (that are lists in turn) */ 188 | rowsListPtr = Jim_NewListObj(interp, NULL, 0); 189 | Jim_IncrRefCount(rowsListPtr); 190 | rows = 0; 191 | columns = sqlite3_column_count(stmt); 192 | while (sqlite3_step(stmt) == SQLITE_ROW) { 193 | int i; 194 | 195 | objPtr = Jim_NewListObj(interp, NULL, 0); 196 | for (i = 0; i < columns; i++) { 197 | Jim_Obj *vObj = NULL; 198 | Jim_ListAppendElement(interp, objPtr, 199 | Jim_NewStringObj(interp, sqlite3_column_name(stmt, i), -1)); 200 | switch (sqlite3_column_type(stmt, i)) { 201 | case SQLITE_NULL: 202 | vObj = Jim_NewStringObj(interp, nullstr, -1); 203 | break; 204 | case SQLITE_INTEGER: 205 | vObj = Jim_NewIntObj(interp, sqlite3_column_int(stmt, i)); 206 | break; 207 | case SQLITE_FLOAT: 208 | vObj = Jim_NewDoubleObj(interp, sqlite3_column_double(stmt, i)); 209 | break; 210 | case SQLITE_TEXT: 211 | case SQLITE_BLOB: 212 | vObj = Jim_NewStringObj(interp, 213 | (const unsigned char *)sqlite3_column_blob(stmt, i), 214 | sqlite3_column_bytes(stmt, i)); 215 | break; 216 | } 217 | Jim_ListAppendElement(interp, objPtr, vObj); 218 | } 219 | Jim_ListAppendElement(interp, rowsListPtr, objPtr); 220 | rows++; 221 | } 222 | /* Finalize */ 223 | Jim_Free(nullstr); 224 | if (sqlite3_finalize(stmt) != SQLITE_OK) { 225 | Jim_DecrRefCount(interp, rowsListPtr); 226 | Jim_SetResultString(interp, sqlite3_errmsg(sh->db), -1); 227 | return JIM_ERR; 228 | } 229 | Jim_SetResult(interp, rowsListPtr); 230 | Jim_DecrRefCount(interp, rowsListPtr); 231 | } else if (option == OPT_LASTID) { 232 | if (argc != 2) { 233 | Jim_WrongNumArgs(interp, 2, argv, ""); 234 | return JIM_ERR; 235 | } 236 | Jim_SetResult(interp, Jim_NewIntObj(interp, 237 | sqlite3_last_insert_rowid(sh->db))); 238 | return JIM_OK; 239 | } else if (option == OPT_CHANGES) { 240 | if (argc != 2) { 241 | Jim_WrongNumArgs(interp, 2, argv, ""); 242 | return JIM_ERR; 243 | } 244 | Jim_SetResult(interp, Jim_NewIntObj(interp, 245 | sqlite3_changes(sh->db))); 246 | return JIM_OK; 247 | } 248 | return JIM_OK; 249 | } 250 | 251 | static int JimSqliteOpenCommand(Jim_Interp *interp, int argc, 252 | Jim_Obj *const *argv) 253 | { 254 | sqlite3 *db; 255 | JimSqliteHandle *sh; 256 | char buf[SQLITE_CMD_LEN]; 257 | Jim_Obj *objPtr; 258 | long dbId; 259 | int r; 260 | 261 | if (argc != 2) { 262 | Jim_WrongNumArgs(interp, 1, argv, "dbname"); 263 | return JIM_ERR; 264 | } 265 | r = sqlite3_open(Jim_GetString(argv[1], NULL), &db); 266 | if (r != SQLITE_OK) { 267 | Jim_SetResultString(interp, sqlite3_errmsg(db), -1); 268 | sqlite3_close(db); 269 | return JIM_ERR; 270 | } 271 | /* Get the next file id */ 272 | if (Jim_EvalGlobal(interp, 273 | "if {[catch {incr sqlite.dbId}]} {set sqlite.dbId 0}") != JIM_OK) 274 | return JIM_ERR; 275 | objPtr = Jim_GetVariableStr(interp, "sqlite.dbId", JIM_ERRMSG); 276 | if (objPtr == NULL) return JIM_ERR; 277 | if (Jim_GetLong(interp, objPtr, &dbId) != JIM_OK) return JIM_ERR; 278 | 279 | /* Create the file command */ 280 | sh = Jim_Alloc(sizeof(*sh)); 281 | sh->db = db; 282 | sprintf(buf, "sqlite.handle%ld", dbId); 283 | Jim_CreateCommand(interp, buf, JimSqliteHandlerCommand, sh, 284 | JimSqliteDelProc); 285 | Jim_SetResultString(interp, buf, -1); 286 | return JIM_OK; 287 | } 288 | 289 | DLLEXPORT int 290 | Jim_OnLoad(Jim_Interp *interp) 291 | { 292 | Jim_InitExtension(interp); 293 | if (Jim_PackageProvide(interp, "sqlite3", "1.0", JIM_ERRMSG) != JIM_OK) 294 | return JIM_ERR; 295 | Jim_CreateCommand(interp, "sqlite3.open", JimSqliteOpenCommand, NULL, NULL); 296 | return JIM_OK; 297 | } 298 | -------------------------------------------------------------------------------- /jim-stdlib-1.0.tcl: -------------------------------------------------------------------------------- 1 | # Jim stdlib - a pure-Jim extension library for Jim 2 | # 3 | # Copyright 2005 Salvatore Sanfilippo 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # A copy of the license is also included in the source distribution 12 | # of Jim, as a TXT file name called LICENSE. 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | 20 | # To use this library just do [package require stdlib] 21 | # Make sure this file is in one directory specified in $jim_libpath 22 | 23 | package provide stdlib 1.0 24 | 25 | ### Functional programming ### 26 | 27 | proc curry {cmd args} { 28 | lambda args [list cmd [list pref $args]] { 29 | uplevel 1 [list $cmd {expand}$pref {expand}$args] 30 | } 31 | } 32 | 33 | proc memoize {} {{Memo {}}} { 34 | set cmd [info level -1] 35 | if {[info level] > 2 && [lindex [info level -2] 0] eq "memoize"} return 36 | if {![info exists Memo($cmd)]} {set Memo($cmd) [eval $cmd]} 37 | return -code return $Memo($cmd) 38 | } 39 | 40 | ### Control structures ### 41 | 42 | proc repeat {n body} { 43 | for {set i 0} {$i < $n} {incr i} { 44 | uplevel 1 $body 45 | } 46 | } 47 | 48 | ### List procedures ### 49 | 50 | proc first {list} {lindex $list 0} 51 | proc rest {list} {lrange $list 1 end} 52 | proc last {list} {lindex $list end} 53 | 54 | ### EOF ### 55 | -------------------------------------------------------------------------------- /jim-win32api.c: -------------------------------------------------------------------------------- 1 | /* WIN32 API extension 2 | * 3 | * Copyright (C) 2005 Pat Thoyts 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * A copy of the license is also included in the source distribution 12 | * of Jim, as a TXT file name called LICENSE. 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #define STRICT 22 | #define WIN32_LEAN_AND_MEAN 23 | #include 24 | #include 25 | #include 26 | 27 | #include 28 | 29 | #define JIM_EXTENSION 30 | #include "jim.h" 31 | 32 | #if _MSC_VER >= 1000 33 | #pragma comment(lib, "shell32") 34 | #pragma comment(lib, "user32") 35 | #pragma comment(lib, "advapi32") 36 | #endif /* _MSC_VER >= 1000 */ 37 | 38 | static const char win32api_type_hash[] = "win32api:typemap"; 39 | 40 | __declspec(dllexport) int Jim_OnLoad(Jim_Interp *interp); 41 | 42 | /* ---------------------------------------------------------------------- 43 | * Convert Win32 error codes into an error message string object. 44 | */ 45 | 46 | static Jim_Obj * 47 | Win32ErrorObj(Jim_Interp *interp, const char * szPrefix, DWORD dwError) 48 | { 49 | Jim_Obj *msgObj = NULL; 50 | char * lpBuffer = NULL; 51 | DWORD dwLen = 0; 52 | 53 | dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER 54 | | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwError, LANG_NEUTRAL, 55 | (char *)&lpBuffer, 0, NULL); 56 | if (dwLen < 1) { 57 | dwLen = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER 58 | | FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ARGUMENT_ARRAY, 59 | "code 0x%1!08X!%n", 0, LANG_NEUTRAL, 60 | (char *)&lpBuffer, 0, (va_list *)&dwError); 61 | } 62 | 63 | msgObj = Jim_NewStringObj(interp, szPrefix, -1); 64 | if (dwLen > 0) { 65 | char *p = lpBuffer + dwLen - 1; /* remove cr-lf at end */ 66 | for ( ; p && *p && isspace(*p); p--) 67 | ; 68 | *++p = 0; 69 | Jim_AppendString(interp, msgObj, ": ", 2); 70 | Jim_AppendString(interp, msgObj, lpBuffer, -1); 71 | } 72 | LocalFree((HLOCAL)lpBuffer); 73 | return msgObj; 74 | } 75 | 76 | /* ---------------------------------------------------------------------- 77 | * Information recorded for API calls that we can call. 78 | */ 79 | 80 | typedef struct Win32ApiDeclaration { 81 | HMODULE module; /* Reference counted handle to the library */ 82 | LPSTR symbol; /* The function name as used in the library */ 83 | FARPROC lpfn; /* Generic function pointer for the API */ 84 | LPSTR rtype; /* The return type */ 85 | Jim_Obj *typeList; /* List of parameters as type name type ... */ 86 | } Win32ApiDeclaration; 87 | 88 | 89 | /* ---------------------------------------------------------------------- 90 | * Type hash table 91 | * 92 | * This is generic string:thing* hash. 93 | * Keys are a typename. Values are pointers Win32ApiTypeInfo structs 94 | */ 95 | 96 | typedef struct Win32ApiTypeInfo { 97 | size_t type_size; /* The size of the type in bytes (not used yet) */ 98 | char type_spec[]; /* packing details for the type */ 99 | } Win32ApiTypeInfo; 100 | 101 | static unsigned int Win32ApiTypeInfoHashTableHash(const void *key) 102 | { 103 | /*return Jim_DjbHashFunction(key, strlen(key));*/ 104 | unsigned int h = 5381; 105 | size_t len = strlen(key); 106 | while(len--) 107 | h = (h + (h << 5)) ^ *((const char *)key)++; 108 | return h; 109 | } 110 | 111 | static const void *Win32ApiTypeInfoHashTableCopyKey(void *privdata, const void *key) 112 | { 113 | JIM_NOTUSED(privdata); 114 | return Jim_StrDup(key); 115 | } 116 | 117 | static int Win32ApiTypeInfoHashTableCompare(void *privdata, const void *key1, const void *key2) 118 | { 119 | JIM_NOTUSED(privdata); 120 | return strcmp(key1, key2) == 0; 121 | } 122 | 123 | static void Win32ApiTypeInfoHashTableDestroyKey(void *privdata, const void *key) 124 | { 125 | JIM_NOTUSED(privdata); 126 | Jim_Free((void*)key); 127 | } 128 | 129 | static void Win32ApiTypeInfoHashTableDestroyValue(void *interp, void *val) 130 | { 131 | Win32ApiTypeInfo *entryPtr = (Win32ApiTypeInfo *)val; 132 | JIM_NOTUSED(interp); 133 | Jim_Free((void*)entryPtr); 134 | } 135 | 136 | static Jim_HashTableType Win32ApiTypeHashTableType = { 137 | Win32ApiTypeInfoHashTableHash, /* hash function */ 138 | Win32ApiTypeInfoHashTableCopyKey, /* key dup */ 139 | NULL, /* val dup */ 140 | Win32ApiTypeInfoHashTableCompare, /* key compare */ 141 | Win32ApiTypeInfoHashTableDestroyKey, /* key destructor */ 142 | Win32ApiTypeInfoHashTableDestroyValue /* val destructor */ 143 | }; 144 | 145 | /* ---------------------------------------------------------------------- 146 | * The typedef object type is a caching internal rep to avoid repeat 147 | * lookups into the hash table. 148 | */ 149 | 150 | Jim_ObjType typedefObjType = { 151 | "win32.typedef", 152 | NULL, 153 | NULL, 154 | NULL, 155 | JIM_TYPE_REFERENCES, 156 | }; 157 | 158 | int 159 | TypedefSetFromAny(Jim_Interp *interp, Jim_Obj *objPtr) 160 | { 161 | if (objPtr->typePtr != &typedefObjType) { 162 | const char *tname = Jim_GetString(objPtr, NULL); 163 | Jim_HashTable *hashPtr = Jim_GetAssocData(interp, win32api_type_hash); 164 | Jim_HashEntry *entryPtr = Jim_FindHashEntry(hashPtr, tname); 165 | if (entryPtr == NULL) { 166 | Jim_Obj *errObj = Jim_NewEmptyStringObj(interp); 167 | Jim_AppendStrings(interp, errObj, "type \"", tname, "\" is not defined", NULL); 168 | Jim_SetResult(interp, errObj); 169 | return JIM_ERR; 170 | } 171 | 172 | Jim_FreeIntRep(interp, objPtr); 173 | objPtr->internalRep.ptr = entryPtr; 174 | objPtr->typePtr = &typedefObjType; 175 | } 176 | return JIM_OK; 177 | } 178 | 179 | /* ---------------------------------------------------------------------- */ 180 | 181 | /* Clean up the package's interp associated data */ 182 | static void 183 | Win32_PackageDeleteProc(Jim_Interp *interp, void *clientData) 184 | { 185 | Jim_HashTable *hashPtr = (Jim_HashTable *)clientData; 186 | Jim_FreeHashTable(hashPtr); 187 | Jim_Free(clientData); 188 | } 189 | 190 | /* Update and introspect the type table 191 | * 192 | * Perls pack supports... 193 | a char binary data (null padded) u uuencoded string 194 | A cha binary data (space padded) U unicode char 195 | Z asciiz 196 | c char s int16 i int l int32 n be u_int16 v le uint16 q int64 f float p pointer (null term) 197 | C uchar S u_int16 I u_int L uint_32 N be u_int32 V le uint32 Q u_int64 d double P block pointer 198 | */ 199 | static int 200 | Win32_Typedef(Jim_Interp *interp, int objc, Jim_Obj *const objv[]) 201 | { 202 | enum {OPT_NULL, OPT_TYPE_NAMES, OPT_TYPE_GET, OPT_TYPE_SET}; 203 | Jim_HashTable *hashPtr = (Jim_HashTable *)Jim_CmdPrivData(interp); 204 | Win32ApiTypeInfo *typePtr; 205 | const char *name = NULL, *spec = NULL; 206 | int name_len, spec_len, n, r = JIM_OK; 207 | struct def { char c; unsigned char n; } defs[] = { 208 | 'c', 1, 'C', 1, 's', 2, 'S', 2, 'i', 4, 'I', 4, 209 | 'l', 4, 'L', 4, 'n', 4, 'N', 4, 'v', 4, 'V', 4, 210 | 'q', 8, 'Q', 8, 'f', 4, 'd', 8, 'p', 4, 'P', 4, 211 | 'a', 1, 'A', 1, 'Z', 0, 'U', 2, 0, 0}; 212 | struct def *sp; 213 | const char *p; 214 | size_t size, m = 0; 215 | 216 | if (objc > 3) { 217 | Jim_WrongNumArgs(interp, 1, objv, "typename ?pack_spec?"); 218 | return JIM_ERR; 219 | } 220 | 221 | switch (objc) { 222 | /* Assign a new type. We validate the pack format and calculate the type size at the same time */ 223 | case OPT_TYPE_SET: { 224 | name = Jim_GetString(objv[1], &name_len); 225 | spec = Jim_GetString(objv[2], &spec_len); 226 | 227 | size = 0; 228 | p = spec; 229 | while (p && *p) { 230 | for (sp = defs; sp->c != 0; sp++) { 231 | if (sp->c == *p) 232 | break; 233 | } 234 | if (sp->c == 0) { 235 | Jim_Obj *errObj = Jim_NewStringObj(interp, "invalid pack character \"0\"", -1); 236 | errObj->bytes[24] = *p; /* NOTE: if you change the text in the above string this must be fixed */ 237 | Jim_AppendStrings(interp, errObj, " while defining type \"", name, "\"", NULL); 238 | Jim_SetResult(interp, errObj); 239 | return JIM_ERR; 240 | } 241 | if (isdigit(*(p+1))) { 242 | char *pe = NULL; 243 | m = strtol(p+1, &pe, 0); 244 | p = pe; 245 | } else { 246 | m = 1; 247 | p++; 248 | } 249 | size += (sp->n * m); 250 | } 251 | 252 | n = name_len + spec_len + 1; 253 | typePtr = (Win32ApiTypeInfo *)Jim_Alloc(n); 254 | typePtr->type_size = size; 255 | strcpy(typePtr->type_spec, spec); 256 | Jim_AddHashEntry(hashPtr, name, typePtr); 257 | Jim_SetResultString(interp, name, name_len); 258 | break; 259 | } 260 | case OPT_TYPE_GET: { 261 | Jim_HashEntry *entryPtr; 262 | name = Jim_GetString(objv[1], &name_len); 263 | if ((entryPtr = Jim_FindHashEntry(hashPtr, name)) == NULL) { 264 | Jim_Obj *resObj = Jim_NewEmptyStringObj(interp); 265 | Jim_AppendStrings(interp, resObj, "type \"", name, "\" not found", NULL); 266 | Jim_SetResult(interp, resObj); 267 | r = JIM_ERR; 268 | } else { 269 | typePtr = entryPtr->val; 270 | Jim_SetResultString(interp, typePtr->type_spec, -1); 271 | } 272 | break; 273 | } 274 | case OPT_TYPE_NAMES: { 275 | Jim_Obj *listPtr; 276 | Jim_HashEntry *entryPtr; 277 | Jim_HashTableIterator *it = Jim_GetHashTableIterator(hashPtr); 278 | listPtr = Jim_NewListObj(interp, NULL, 0); 279 | while ((entryPtr = Jim_NextHashEntry(it)) != NULL) { 280 | Jim_ListAppendElement(interp, listPtr, Jim_NewStringObj(interp, entryPtr->key, -1)); 281 | } 282 | Jim_SetResult(interp, listPtr); 283 | break; 284 | } 285 | } 286 | return r; 287 | } 288 | 289 | /* ---------------------------------------------------------------------- */ 290 | 291 | 292 | static void 293 | Win32_ApiCleanup(Jim_Interp *interp, void *clientData) 294 | { 295 | Win32ApiDeclaration *declPtr = (Win32ApiDeclaration *)clientData; 296 | FreeLibrary(declPtr->module); 297 | Jim_Free((void *)declPtr->symbol); 298 | Jim_Free((void *)declPtr->rtype); 299 | Jim_DecrRefCount(interp, declPtr->typeList); 300 | } 301 | 302 | static int 303 | Win32_ApiHandler(Jim_Interp *interp, int objc, Jim_Obj *const objv[]) 304 | { 305 | Win32ApiDeclaration *declPtr = (Win32ApiDeclaration *)Jim_CmdPrivData(interp); 306 | Jim_HashTable *hashPtr; 307 | int nargs = 0, n, np, r; 308 | long lval; 309 | double dblval; 310 | float fltval; 311 | struct { 312 | unsigned long params[16]; 313 | } param; 314 | 315 | Jim_ListLength(interp, declPtr->typeList, &nargs); 316 | if (objc-1 != nargs/2) { 317 | int tlen = 0; 318 | const char *types = Jim_GetString(declPtr->typeList, &tlen); 319 | char *sz = (char *)_alloca(tlen + 3); 320 | sprintf(sz, "(%s)", types); 321 | Jim_WrongNumArgs(interp, 1, objv, sz); 322 | return JIM_ERR; 323 | } 324 | 325 | ZeroMemory(¶m, sizeof(param)); 326 | hashPtr = Jim_GetAssocData(interp, win32api_type_hash); 327 | 328 | for (n = 1, np = 0; n < objc; n++) { 329 | Jim_HashEntry *entryPtr; 330 | Jim_Obj *tnameObj, *pnameObj; 331 | const char *tname, *pname; 332 | 333 | r = Jim_ListIndex(interp, declPtr->typeList, (np*2), &tnameObj, JIM_ERRMSG); 334 | tname = Jim_GetString(tnameObj, NULL); 335 | r = Jim_ListIndex(interp, declPtr->typeList, (np*2)+1, &pnameObj, JIM_ERRMSG); 336 | pname = Jim_GetString(pnameObj, NULL); 337 | 338 | entryPtr = Jim_FindHashEntry(hashPtr, tname); 339 | switch (((Win32ApiTypeInfo *)entryPtr->val)->type_spec[0]) { 340 | case 'q': case 'Q': 341 | Jim_GetWide(interp, objv[n], (jim_wide *)¶m.params[np]); 342 | np += 2; 343 | break; 344 | case 's': case 'v': 345 | Jim_GetLong(interp, objv[n], &lval); 346 | param.params[np] = (unsigned short)lval; 347 | np++; 348 | break; 349 | case 'd': 350 | Jim_GetDouble(interp, objv[n], &dblval); 351 | memcpy(¶m.params[np], &dblval, 8); 352 | np+=2; 353 | break; 354 | case 'f': 355 | Jim_GetDouble(interp, objv[n], &dblval); 356 | fltval = (float)dblval; 357 | memcpy(¶m.params[np], &fltval, 4); 358 | np+=2; 359 | break; 360 | case 'l': case 'L': case 'i': case 'I': case 'V': 361 | default: 362 | Jim_GetLong(interp, objv[n], ¶m.params[np]); 363 | np++; 364 | break; 365 | } 366 | } 367 | 368 | if (nargs == 0) 369 | r = declPtr->lpfn(); 370 | else 371 | r = declPtr->lpfn(param); 372 | 373 | Jim_SetResult(interp, Jim_NewIntObj(interp, r)); 374 | return JIM_OK; 375 | } 376 | 377 | static int 378 | Win32_Declare(Jim_Interp *interp, int objc, Jim_Obj *const objv[]) 379 | { 380 | Jim_HashTable *hashPtr = (Jim_HashTable *)Jim_CmdPrivData(interp); /* type hash map */ 381 | Win32ApiDeclaration *declPtr; 382 | HMODULE hLib = NULL; 383 | FARPROC lpfn = NULL; 384 | const char *lib, *rtype, *name; 385 | Jim_Obj *cmdObj = NULL; 386 | 387 | if (objc != 5) { 388 | Jim_WrongNumArgs(interp, 1, objv, "lib return_type name typelist"); 389 | return JIM_ERR; 390 | } 391 | 392 | lib = Jim_GetString(objv[1], NULL); 393 | rtype = Jim_GetString(objv[2], NULL); 394 | name = Jim_GetString(objv[3], NULL); 395 | hLib = LoadLibraryA(lib); 396 | if (hLib == NULL) { 397 | Jim_SetResultString(interp, "failed to load library", -1); 398 | return JIM_ERR; 399 | } 400 | 401 | if ((lpfn = GetProcAddress(hLib, name)) == NULL) { 402 | Jim_Obj *errObj = Jim_NewEmptyStringObj(interp); 403 | FreeLibrary(hLib); 404 | Jim_AppendStrings(interp, errObj, "could not load \"", name, "\" from \"", lib, "\"", NULL); 405 | Jim_SetResult(interp, errObj); 406 | return JIM_ERR; 407 | } 408 | 409 | declPtr = (Win32ApiDeclaration *)Jim_Alloc(sizeof(Win32ApiDeclaration)); 410 | declPtr->module = hLib; 411 | declPtr->lpfn = lpfn; 412 | declPtr->symbol = Jim_StrDup(name); 413 | declPtr->rtype = Jim_StrDup(rtype); 414 | declPtr->typeList = Jim_DuplicateObj(interp, objv[4]); 415 | Jim_IncrRefCount(declPtr->typeList); 416 | 417 | cmdObj = Jim_NewStringObj(interp, "", strlen(name) + 9); 418 | sprintf(cmdObj->bytes, "win32api.%s", name); 419 | Jim_CreateCommand(interp, cmdObj->bytes, Win32_ApiHandler, declPtr, Win32_ApiCleanup); 420 | Jim_SetResult(interp, cmdObj); 421 | return JIM_OK; 422 | } 423 | 424 | /* ---------------------------------------------------------------------- */ 425 | 426 | int 427 | Jim_OnLoad(Jim_Interp *interp) 428 | { 429 | Jim_HashTable *hashPtr; 430 | Jim_InitExtension(interp); 431 | if (Jim_PackageProvide(interp, "win32api", "1.0", JIM_ERRMSG) != JIM_OK) 432 | return JIM_ERR; 433 | 434 | hashPtr = (Jim_HashTable *)Jim_Alloc(sizeof(Jim_HashTable)); 435 | Jim_InitHashTable(hashPtr, &Win32ApiTypeHashTableType, NULL); 436 | Jim_SetAssocData(interp, win32api_type_hash, Win32_PackageDeleteProc, hashPtr); 437 | 438 | Jim_CreateCommand(interp, "win32.declare", Win32_Declare, hashPtr, NULL); 439 | Jim_CreateCommand(interp, "win32.typedef", Win32_Typedef, hashPtr, NULL); 440 | 441 | return JIM_OK; 442 | } 443 | 444 | /* ---------------------------------------------------------------------- 445 | * Local variables: 446 | * indent-tabs-mode: nil 447 | * End: 448 | */ 449 | -------------------------------------------------------------------------------- /jimsh.c: -------------------------------------------------------------------------------- 1 | /* Jimsh - An interactive shell for Jim 2 | * Copyright 2005 Salvatore Sanfilippo 3 | * Copyright 2009 Steve Bennett 4 | * 5 | * Licensed under the Apache License, Version 2.0 (the "License"); 6 | * you may not use this file except in compliance with the License. 7 | * You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * A copy of the license is also included in the source distribution 12 | * of Jim, as a TXT file name called LICENSE. 13 | * 14 | * Unless required by applicable law or agreed to in writing, software 15 | * distributed under the License is distributed on an "AS IS" BASIS, 16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | */ 20 | 21 | #ifdef WIN32 22 | #define STRICT 23 | #define WIN32_LEAN_AND_MEAN 24 | #include 25 | #endif /* WIN32 */ 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #define JIM_EMBEDDED 32 | #include "jim.h" 33 | 34 | 35 | /* JimGetExePath try to get the absolute path of the directory 36 | * of the jim binary, in order to add this path to the library path. 37 | * Likely shipped libraries are in the same path too. */ 38 | 39 | /* That's simple on windows: */ 40 | #ifdef WIN32 41 | static Jim_Obj *JimGetExePath(Jim_Interp *interp, const char *argv0) 42 | { 43 | char path[MAX_PATH+1], *p; 44 | JIM_NOTUSED(argv0); 45 | 46 | GetModuleFileNameA(NULL, path, MAX_PATH); 47 | if ((p = strrchr(path, '\\')) != NULL) 48 | *p = 0; 49 | return Jim_NewStringObj(interp, path, -1); 50 | } 51 | #else /* WIN32 */ 52 | #ifndef JIM_ANSIC 53 | /* A bit complex on POSIX */ 54 | #include 55 | static Jim_Obj *JimGetExePath(Jim_Interp *interp, const char *argv0) 56 | { 57 | char path[JIM_PATH_LEN+1]; 58 | 59 | /* Check if the executable was called with an absolute pathname */ 60 | if (argv0[0] == '/') { 61 | char *p; 62 | 63 | strncpy(path, argv0, JIM_PATH_LEN); 64 | p = strrchr(path, '/'); 65 | *(p+1) = '\0'; 66 | return Jim_NewStringObj(interp, path, -1); 67 | } else { 68 | char cwd[JIM_PATH_LEN+1]; 69 | char base[JIM_PATH_LEN+1], *p; 70 | int l; 71 | 72 | strncpy(base, argv0, JIM_PATH_LEN); 73 | if (getcwd(cwd, JIM_PATH_LEN) == NULL) { 74 | return Jim_NewStringObj(interp, "/usr/local/lib/jim/", -1); 75 | } 76 | l = strlen(cwd); 77 | if (l > 0 && cwd[l-1] == '/') 78 | cwd[l-1] = '\0'; 79 | p = strrchr(base, '/'); 80 | if (p == NULL) 81 | base[0] = '\0'; 82 | else if (p != base) 83 | *p = '\0'; 84 | sprintf(path, "%s/%s", cwd, base); 85 | l = strlen(path); 86 | if (l > 2 && path[l-2] == '/' && path[l-1] == '.') 87 | path[l-1] = '\0'; 88 | return Jim_NewStringObj(interp, path, -1); 89 | } 90 | } 91 | #else /* JIM_ANSIC */ 92 | /* ... and impossible with just ANSI C */ 93 | static Jim_Obj *JimGetExePath(Jim_Interp *interp, const char *argv0) 94 | { 95 | JIM_NOTUSED(argv0); 96 | return Jim_NewStringObj(interp, "/usr/local/lib/jim/", -1); 97 | } 98 | #endif /* JIM_ANSIC */ 99 | #endif /* WIN32 */ 100 | 101 | static void JimLoadJimRc(Jim_Interp *interp) 102 | { 103 | const char *home; 104 | char buf [JIM_PATH_LEN+1]; 105 | const char *names[] = {".jimrc", "jimrc.tcl", NULL}; 106 | int i; 107 | FILE *fp; 108 | 109 | if ((home = getenv("HOME")) == NULL) return; 110 | for (i = 0; names[i] != NULL; i++) { 111 | if (strlen(home)+strlen(names[i])+1 > JIM_PATH_LEN) continue; 112 | sprintf(buf, "%s/%s", home, names[i]); 113 | if ((fp = fopen(buf, "r")) != NULL) { 114 | fclose(fp); 115 | if (Jim_EvalFile(interp, buf) != JIM_OK) { 116 | Jim_PrintErrorMessage(interp); 117 | } 118 | return; 119 | } 120 | } 121 | } 122 | 123 | int main(int argc, char *const argv[]) 124 | { 125 | int retcode, n; 126 | Jim_Interp *interp; 127 | Jim_Obj *listObj; 128 | 129 | Jim_InitEmbedded(); /* This is the first function embedders should call. */ 130 | 131 | /* Create and initialize the interpreter */ 132 | interp = Jim_CreateInterp(); 133 | Jim_RegisterCoreCommands(interp); 134 | 135 | /* Append the path where the executed Jim binary is contained 136 | * in the jim_libpath list. */ 137 | listObj = Jim_GetVariableStr(interp, "jim_libpath", JIM_NONE); 138 | if (Jim_IsShared(listObj)) 139 | listObj = Jim_DuplicateObj(interp, listObj); 140 | Jim_ListAppendElement(interp, listObj, JimGetExePath(interp, argv[0])); 141 | Jim_SetVariableStr(interp, "jim_libpath", listObj); 142 | 143 | /* Populate argv and argv0 global vars */ 144 | listObj = Jim_NewListObj(interp, NULL, 0); 145 | for (n = 2; n < argc; n++) { 146 | Jim_Obj *obj = Jim_NewStringObj(interp, argv[n], -1); 147 | Jim_ListAppendElement(interp, listObj, obj); 148 | } 149 | 150 | Jim_SetVariableStr(interp, "argv", listObj); 151 | 152 | if (argc == 1) { 153 | Jim_SetVariableStrWithStr(interp, "jim_interactive", "1"); 154 | JimLoadJimRc(interp); 155 | retcode = Jim_InteractivePrompt(interp); 156 | } else { 157 | Jim_SetVariableStr(interp, "argv0", Jim_NewStringObj(interp, argv[1], -1)); 158 | Jim_SetVariableStrWithStr(interp, "jim_interactive", "0"); 159 | if ((retcode = Jim_EvalFile(interp, argv[1])) == JIM_ERR) { 160 | Jim_PrintErrorMessage(interp); 161 | } 162 | } 163 | if (retcode == JIM_OK) { 164 | retcode = 0; 165 | } 166 | else if (retcode == JIM_EXIT) { 167 | retcode = interp->exitCode; 168 | } 169 | else { 170 | retcode = 1; 171 | } 172 | Jim_FreeInterp(interp); 173 | return retcode; 174 | } 175 | -------------------------------------------------------------------------------- /regtest.tcl: -------------------------------------------------------------------------------- 1 | # REGTEST 1 2 | # 27Jan2005 - SIGSEGV for bug on Jim_DuplicateObj(). 3 | 4 | for {set i 0} {$i < 100} {incr i} { 5 | set a "x" 6 | lappend a n 7 | } 8 | puts "TEST 1 PASSED" 9 | 10 | # REGTEST 2 11 | # 29Jan2005 - SEGFAULT parsing script composed of just one comment. 12 | eval {#foobar} 13 | puts "TEST 2 PASSED" 14 | 15 | # REGTEST 3 16 | # 29Jan2005 - "Error in Expression" with correct expression 17 | set x 5 18 | expr {$x-5} 19 | puts "TEST 3 PASSED" 20 | 21 | # REGTEST 4 22 | # 29Jan2005 - SIGSEGV when run this code, due to expr's bug. 23 | proc fibonacci {x} { 24 | if {$x <= 1} { 25 | expr 1 26 | } else { 27 | expr {[fibonacci [expr {$x-1}]] + [fibonacci [expr {$x-2}]]} 28 | } 29 | } 30 | fibonacci 6 31 | puts "TEST 4 PASSED" 32 | 33 | # REGTEST 5 34 | # 06Mar2005 - This looped forever... 35 | for {set i 0} {$i < 10} {incr i} {continue} 36 | puts "TEST 5 PASSED" 37 | 38 | # REGTEST 6 39 | # 07Mar2005 - Unset create variable + dict is using dict syntax sugar at 40 | # currently non-existing variable 41 | catch {unset thisvardoesnotexists(thiskeytoo)} 42 | if {[catch {set thisvardoesnotexists}] == 0} { 43 | puts "TEST 6 FAILED - unset created dict for non-existing variable" 44 | break 45 | } 46 | puts "TEST 6 PASSED" 47 | 48 | # REGTEST 7 49 | # 04Nov2008 - variable parsing does not eat last brace 50 | set a 1 51 | list ${a} 52 | puts "TEST 7 PASSED" 53 | 54 | # REGTEST 8 55 | # 04Nov2008 - string toupper/tolower do not convert to string rep 56 | string tolower [list a] 57 | string toupper [list a] 58 | puts "TEST 8 PASSED" 59 | 60 | # REGTEST 9 61 | # 04Nov2008 - crash on exit when replacing Tcl proc with C command. Requires the aio extension 62 | proc aio.open {args} {} 63 | catch {package require aio} 64 | # Note, crash on exit, so don't say we passed! 65 | 66 | # REGTEST 10 67 | # 05Nov2008 - incorrect lazy expression evaluation with unary not 68 | expr {1 || !0} 69 | puts "TEST 10 PASSED" 70 | 71 | # TAKE THE FOLLOWING puts AS LAST LINE 72 | 73 | puts "--- ALL TESTS PASSED ---" 74 | -------------------------------------------------------------------------------- /tools/benchtable.tcl: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env tclsh 2 | # 3 | # Tabulate the output of Jim's bench.tcl -batch 4 | # 5 | # Copyright (C) 2005 Pat Thoyts 6 | # 7 | 8 | proc main {filename} { 9 | set versions {} 10 | array set bench {} 11 | set f [open $filename r] 12 | while {![eof $f]} { 13 | gets $f data 14 | lappend versions [lindex $data 0] 15 | set results [lindex $data 1] 16 | foreach {title time} $results { 17 | lappend bench($title) $time 18 | } 19 | } 20 | close $f 21 | 22 | puts "Jim benchmarks - time in milliseconds" 23 | puts -nonewline [string repeat " " 21] 24 | foreach v $versions { 25 | puts -nonewline [format "% 6s " $v] 26 | } 27 | puts "" 28 | 29 | foreach test [array names bench] { 30 | puts -nonewline "[format {% 20s} $test] " 31 | foreach v $bench($test) { 32 | if {$v eq "F"} { 33 | puts -nonewline " F " 34 | } else { 35 | puts -nonewline [format "% 6d " [expr {$v / 1000}]] 36 | } 37 | } 38 | puts "" 39 | } 40 | } 41 | 42 | if {!$tcl_interactive} { 43 | set r [catch {eval [linsert $argv 0 main]} res] 44 | puts $res 45 | exit $r 46 | } 47 | --------------------------------------------------------------------------------