Changes On Branch better-parse-args

Changes In Branch better-parse-args Excluding Merge-Ins

This is equivalent to a diff from 215571a61c to ee8987ea9d

2017-10-17
03:07
When compiling with stubs enabled, also define Tcl_InitStubs() check-in: 765a81ec0f user: rkeene tags: trunk
03:06
Added start of better "parse_command_line" implementation Leaf check-in: ee8987ea9d user: rkeene tags: better-parse-args
2017-10-13
20:37
tcc4tcl 0.30 check-in: 215571a61c user: rkeene tags: trunk, 0.30
20:36
Disabled a test which now does not work check-in: 30810bb6d9 user: rkeene tags: trunk

Modified tcc4tcl.c from [2f5bd45b79] to [def1825a4b].

65
66
67
68
69
70
71

72
73
74
75
76
77

78
79
80


81
82
83
84
85
86
87
	struct TclTCCState *ts;
	TCCState *s;
	Tcl_Obj *sym_addr;
	static CONST char *options[] = {
		"add_include_path", "add_file",  "add_library", 
		"add_library_path", "add_symbol", "command", "compile",
		"define", "get_symbol", "output_file", "undefine",

		(char *) NULL
	};
	enum options {
		TCC4TCL_ADD_INCLUDE, TCC4TCL_ADD_FILE, TCC4TCL_ADD_LIBRARY, 
		TCC4TCL_ADD_LIBRARY_PATH, TCC4TCL_ADD_SYMBOL, TCC4TCL_COMMAND, TCC4TCL_COMPILE,
		TCC4TCL_DEFINE, TCC4TCL_GET_SYMBOL, TCC4TCL_OUTPUT_FILE, TCC4TCL_UNDEFINE

	};
	char *str;
	int rv;



	ts = (struct TclTCCState *) cdata;
	s = ts->s;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "subcommand arg ?arg ...?");
        return TCL_ERROR;







>





|
>



>
>







65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
	struct TclTCCState *ts;
	TCCState *s;
	Tcl_Obj *sym_addr;
	static CONST char *options[] = {
		"add_include_path", "add_file",  "add_library", 
		"add_library_path", "add_symbol", "command", "compile",
		"define", "get_symbol", "output_file", "undefine",
		"parse_args",
		(char *) NULL
	};
	enum options {
		TCC4TCL_ADD_INCLUDE, TCC4TCL_ADD_FILE, TCC4TCL_ADD_LIBRARY, 
		TCC4TCL_ADD_LIBRARY_PATH, TCC4TCL_ADD_SYMBOL, TCC4TCL_COMMAND, TCC4TCL_COMPILE,
		TCC4TCL_DEFINE, TCC4TCL_GET_SYMBOL, TCC4TCL_OUTPUT_FILE, TCC4TCL_UNDEFINE,
		TCC4TCL_PARSE_ARGS
	};
	char *str;
	int rv;
	int tcc_argc;
	char **tcc_argv;

	ts = (struct TclTCCState *) cdata;
	s = ts->s;

    if (objc < 2) {
        Tcl_WrongNumArgs(interp, 1, objv, "subcommand arg ?arg ...?");
        return TCL_ERROR;
251
252
253
254
255
256
257
















258
259
260
261
262
263
264
        case TCC4TCL_UNDEFINE:
            if (objc != 3) {
                Tcl_WrongNumArgs(interp, 2, objv, "symbol");
                return TCL_ERROR;
            }
            tcc_undefine_symbol(s,Tcl_GetString(objv[2]));
            return TCL_OK;
















        default:
            Tcl_Panic("internal error during option lookup");
    }
    return TCL_OK;
} 

static int Tcc4tclCreateCmd( ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]){







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







255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
        case TCC4TCL_UNDEFINE:
            if (objc != 3) {
                Tcl_WrongNumArgs(interp, 2, objv, "symbol");
                return TCL_ERROR;
            }
            tcc_undefine_symbol(s,Tcl_GetString(objv[2]));
            return TCL_OK;
	case TCC4TCL_PARSE_ARGS:
		if (objc < 3) {
                	Tcl_WrongNumArgs(interp, 2, objv, "args...");
	                return TCL_ERROR;
		}

		tcc_argc = objc - 2;
		tcc_argv = (char **) ckalloc(sizeof(*tcc_argv) * (tcc_argc + 1));
		for (index = 0; index < tcc_argc; index++) {
			tcc_argv[index] = Tcl_GetString(objv[index + 2]);
		}
		tcc_argv[tcc_argc] = NULL;

		tcc_parse_args(s, tcc_argc, tcc_argv);

		return(TCL_OK);
        default:
            Tcl_Panic("internal error during option lookup");
    }
    return TCL_OK;
} 

static int Tcc4tclCreateCmd( ClientData cdata, Tcl_Interp *interp, int objc, Tcl_Obj * CONST objv[]){

Modified tcc4tcl.tcl from [895fa80a76] to [68fdbd726e].

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
			if {$pkgName == ""} {
				set type "exe"
			} else {
				set type "package"
			}
		}

		array set $handle [list code "" type $type filename $output package $pkgName add_inc_path "" add_lib_path "" add_lib "" add_macros ""]

		proc $handle {cmd args} [string map [list @@HANDLE@@ $handle] {
			set handle {@@HANDLE@@}

			if {$cmd == "go"} {
				set args [list 0 {*}$args]
			}







|







42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
			if {$pkgName == ""} {
				set type "exe"
			} else {
				set type "package"
			}
		}

		array set $handle [list code "" type $type filename $output package $pkgName add_inc_path "" add_lib_path "" add_lib "" add_cmdline ""]

		proc $handle {cmd args} [string map [list @@HANDLE@@ $handle] {
			set handle {@@HANDLE@@}

			if {$cmd == "go"} {
				set args [list 0 {*}$args]
			}
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205

	proc _tk {handle} {
		upvar #0 $handle state

		set state(tk) 1
	}

	proc _process_command_line {handle cmdStr} {
		# XXX:TODO: This needs to handle shell-quoted arguments
		upvar #0 $handle state
		set cmdStr [regsub -all {   *} $cmdStr { }]
		set work [split $cmdStr " "]

		foreach cmd $work {
			switch -glob -- $cmd {
				"-I*" {
					set dir [string range $cmd 2 end]
					_add_include_path $handle $dir
				}
				"-D*" {
					set symbolval [string range $cmd 2 end]
					set symbolval [split $symbolval =]
					set symbol [lindex $symbolval 0]
					set val    [join [lrange $symbolval 1 end] =]

					dict set state(add_macros) $symbol $val
				}
				"-U*" {
					set symbol [string range $cmd 2 end]
					dict unset state(add_macros) $symbol $val
				}
				"-l*" {
					set library [string range $cmd 2 end]
					_add_library $handle $library
				}
				"-L*" {
					set libraryDir [string range $cmd 2 end]
					_add_library_path $handle $libraryDir
				}
				"-g" {
					# Ignored
				}
			}
		}
	}

	proc _delete {handle} {
		rename $handle ""
		unset $handle
	}








|
<

<
<

<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







155
156
157
158
159
160
161
162

163


164











165



















166
167
168
169
170
171
172

	proc _tk {handle} {
		upvar #0 $handle state

		set state(tk) 1
	}

	proc _process_command_line {handle args} {

		upvar #0 $handle state














		lappend state(add_cmdline) {*}$args



















	}

	proc _delete {handle} {
		rename $handle ""
		unset $handle
	}

460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
	proc _go {handle {outputOnly 0}} {
		variable dir

		upvar #0 $handle state

		set code ""

		foreach {macroName macroVal} $state(add_macros) {
			append code "#define [string trim "$macroName $macroVal"]\n"
		}

		append code $state(code) "\n"

		if {$state(type) == "exe" || $state(type) == "dll"} {
			if {[info exists state(procs)] && [llength $state(procs)] > 0} {
				set code "int _initProcs(Tcl_Interp *interp);\n\n$code"
			}
		}







<
<
<
<







427
428
429
430
431
432
433




434
435
436
437
438
439
440
	proc _go {handle {outputOnly 0}} {
		variable dir

		upvar #0 $handle state

		set code ""





		append code $state(code) "\n"

		if {$state(type) == "exe" || $state(type) == "dll"} {
			if {[info exists state(procs)] && [llength $state(procs)] > 0} {
				set code "int _initProcs(Tcl_Interp *interp);\n\n$code"
			}
		}
565
566
567
568
569
570
571




572
573
574
575
576
577
578
		}

		if {[info command ::tcc4tcl] == ""} {
			return -code error "Unable to load tcc4tcl library"
		}

		::tcc4tcl $dir $tcc_type tcc





		foreach path $state(add_inc_path) {
			tcc add_include_path $path
		}

		foreach path $state(add_lib_path) {
			tcc add_library_path $path







>
>
>
>







528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
		}

		if {[info command ::tcc4tcl] == ""} {
			return -code error "Unable to load tcc4tcl library"
		}

		::tcc4tcl $dir $tcc_type tcc

		if {$state(add_cmdline) ne ""} {
			tcc parse_args {*}$state(add_cmdline)
		}

		foreach path $state(add_inc_path) {
			tcc add_include_path $path
		}

		foreach path $state(add_lib_path) {
			tcc add_library_path $path

Modified test.tcl from [27bd9c9018] to [0ace8ff7f3].

1
2
3
4
5
6
7
8
9
10
11
#! /usr/bin/env tclsh

lappend auto_path [lindex $argv 0]
package require tcc4tcl

tcc4tcl::cproc test {int i} int { return(i+42); }
tcc4tcl::cproc test1 {int i} int { return(i+42); }
tcc4tcl::cproc ::bob::test1 {int i} int { return(i+42); }

# This will fail
catch {



|







1
2
3
4
5
6
7
8
9
10
11
#! /usr/bin/env tclsh

lappend auto_path [lindex $argv 0]
package require -exact tcc4tcl 0.0

tcc4tcl::cproc test {int i} int { return(i+42); }
tcc4tcl::cproc test1 {int i} int { return(i+42); }
tcc4tcl::cproc ::bob::test1 {int i} int { return(i+42); }

# This will fail
catch {
233
234
235
236
237
238
239
240























241
#define test 1234
}

critcl::cproc test14 {int x} int {
	return(x + test);
}
puts "Test14: [test14 3]"
























exit 0








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

233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
#define test 1234
}

critcl::cproc test14 {int x} int {
	return(x + test);
}
puts "Test14: [test14 3]"

# Executable
close [file tempfile exe]
file delete -force -- $exe
set handle [tcc4tcl::new $exe]
$handle ccode {
	#include <stdio.h>
	int main(int argc, char **argv) {
		printf("hi\n");
		return(0);
	}
}
$handle process_command_line -r
$handle go
set execCode [catch {
	puts [exec ls -l $exe]
	exec ld -o $exe.e $exe
	puts [exec $exe.e]
} err]
file delete $exe
if {$execCode} {
	error $err
}

exit 0