summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--compat/zlib/contrib/dotzlib/DotZLib.chmbin72726 -> 73157 bytes
-rw-r--r--doc/L/little.doc3441
-rwxr-xr-xdoc/L/pod2html.l253
-rwxr-xr-xdoc/L/pod2man513
-rw-r--r--doc/l-paper/NOTES165
-rw-r--r--doc/l-paper/btree.l43
-rw-r--r--doc/l-paper/cat.l16
-rw-r--r--doc/l-paper/echo.l8
-rw-r--r--doc/l-paper/grep.l35
-rw-r--r--doc/l-paper/interop.l36
-rw-r--r--doc/l-paper/julia.l103
-rw-r--r--doc/l-paper/l-language.me113
-rw-r--r--doc/l-paper/little.ms1505
-rw-r--r--doc/l-paper/little.ol129
-rw-r--r--doc/l-paper/printenv.l9
-rw-r--r--doc/l-paper/references56
-rw-r--r--generic/Last.c386
-rw-r--r--generic/Last.h490
-rw-r--r--generic/Lcompile.c8167
-rw-r--r--generic/Lcompile.h606
-rw-r--r--generic/Lgetopt.c238
-rw-r--r--generic/Lgrammar-pregen.c6447
-rw-r--r--generic/Lgrammar.h233
-rw-r--r--generic/Lgrammar.y1750
-rw-r--r--generic/Lscanner-pregen.c4739
-rw-r--r--generic/Lscanner.l1334
-rw-r--r--generic/Ltypecheck.c498
-rw-r--r--generic/blowfish.c446
-rw-r--r--generic/blowfish.h12
-rw-r--r--generic/keydecode.c29
-rw-r--r--generic/tcl.h20
-rw-r--r--generic/tclBasic.c44
-rw-r--r--generic/tclCmdIL.c1
-rw-r--r--generic/tclCmdMZ.c374
-rw-r--r--generic/tclCompCmds.c1
-rw-r--r--generic/tclCompile.c100
-rw-r--r--generic/tclCompile.h20
-rw-r--r--generic/tclDisassemble.c39
-rw-r--r--generic/tclExecute.c1409
-rw-r--r--generic/tclIO.c78
-rw-r--r--generic/tclIO.h2
-rw-r--r--generic/tclIOCmd.c6
-rw-r--r--generic/tclIOSock.c29
-rw-r--r--generic/tclIOUtil.c57
-rw-r--r--generic/tclInt.h74
-rw-r--r--generic/tclInterp.c42
-rw-r--r--generic/tclListObj.c46
-rw-r--r--generic/tclMain.c89
-rw-r--r--generic/tclNamesp.c12
-rw-r--r--generic/tclObj.c6
-rw-r--r--generic/tclParse.c125
-rw-r--r--generic/tclPipe.c1
-rw-r--r--generic/tclRegexp.c757
-rw-r--r--generic/tclRegexp.h8
-rw-r--r--library/Lver.tcl1
-rw-r--r--library/http/http.tcl3
-rw-r--r--library/init.tcl3
-rw-r--r--library/libl.tcl1926
-rw-r--r--library/tcltest/tcltest.tcl17
-rw-r--r--library/tm.tcl2
-rw-r--r--license.terms4
-rw-r--r--tests/all.tcl6
-rw-r--r--tests/interp.test33
-rw-r--r--tests/l-core.test22690
-rw-r--r--tests/l-leak.test686
-rw-r--r--tests/l-libl.test3922
-rw-r--r--tests/l-regression.test381
-rw-r--r--tests/langbench/BEFORE-PERF26
-rw-r--r--tests/langbench/BEFORE.pcre8
-rw-r--r--tests/langbench/ChangeLog10
-rw-r--r--tests/langbench/PERF_LOG20
-rw-r--r--tests/langbench/README56
-rw-r--r--tests/langbench/RUN58
-rw-r--r--tests/langbench/WEIRD9
-rw-r--r--tests/langbench/cat.l18
-rw-r--r--tests/langbench/cat.pl10
-rw-r--r--tests/langbench/cat.py16
-rw-r--r--tests/langbench/cat.rb3
-rw-r--r--tests/langbench/cat.tcl9
-rw-r--r--tests/langbench/fib.l20
-rw-r--r--tests/langbench/fib.pl11
-rw-r--r--tests/langbench/fib.py8
-rw-r--r--tests/langbench/fib.rb11
-rw-r--r--tests/langbench/fib.tcl11
-rwxr-xr-xtests/langbench/findtcl26
-rwxr-xr-xtests/langbench/findtclsh35
-rw-r--r--tests/langbench/grep.l15
-rw-r--r--tests/langbench/grep.pl3
-rw-r--r--tests/langbench/grep.py12
-rw-r--r--tests/langbench/grep.rb4
-rw-r--r--tests/langbench/grep.tcl12
-rw-r--r--tests/langbench/hash.l17
-rw-r--r--tests/langbench/hash.pl5
-rw-r--r--tests/langbench/hash.py16
-rw-r--r--tests/langbench/hash.rb10
-rw-r--r--tests/langbench/hash.tcl17
-rw-r--r--tests/langbench/loop.l11
-rw-r--r--tests/langbench/loop.pl2
-rw-r--r--tests/langbench/loop.py3
-rw-r--r--tests/langbench/loop.rb4
-rw-r--r--tests/langbench/loop.tcl4
-rw-r--r--tests/langbench/proc.l20
-rw-r--r--tests/langbench/proc.pl13
-rw-r--r--tests/langbench/proc.py28
-rw-r--r--tests/langbench/proc.rb36
-rw-r--r--tests/langbench/proc.tcl16
-rw-r--r--tests/langbench/sort.l19
-rw-r--r--tests/langbench/sort.pl7
-rw-r--r--tests/langbench/sort.py13
-rw-r--r--tests/langbench/sort.rb8
-rw-r--r--tests/langbench/sort.tcl20
-rw-r--r--tests/langbench/wc.l52
-rw-r--r--tests/langbench/wc.pl23
-rw-r--r--tests/langbench/wc.py30
-rw-r--r--tests/langbench/wc.rb25
-rw-r--r--tests/langbench/wc.tcl36
-rw-r--r--tests/reg.test3
-rw-r--r--tests/regexp.test20
-rw-r--r--tests/regexpComp.test22
-rw-r--r--tools/installData.tcl3
-rw-r--r--unix/Makefile.in68
-rwxr-xr-xunix/configure19059
-rw-r--r--unix/configure.in31
-rw-r--r--unix/tcl.m4151
-rw-r--r--unix/tclUnixPort.h9
-rw-r--r--win/Makefile.in58
-rwxr-xr-xwin/configure207
-rw-r--r--win/configure.in7
-rw-r--r--win/tcl.m4138
-rw-r--r--win/tclWinPort.h5
-rw-r--r--win/tclWinSock.c6
131 files changed, 71383 insertions, 14064 deletions
diff --git a/compat/zlib/contrib/dotzlib/DotZLib.chm b/compat/zlib/contrib/dotzlib/DotZLib.chm
index f214a44..e41b1cf 100644
--- a/compat/zlib/contrib/dotzlib/DotZLib.chm
+++ b/compat/zlib/contrib/dotzlib/DotZLib.chm
Binary files differ
diff --git a/doc/L/little.doc b/doc/L/little.doc
new file mode 100644
index 0000000..8235e3c
--- /dev/null
+++ b/doc/L/little.doc
@@ -0,0 +1,3441 @@
+=head1 NAME
+
+L
+
+=head1 SYNOPSIS
+
+L [options] script.l [args]
+
+=head1 DESCRIPTION
+
+L is a little interpreted language that draws heavily from C and Perl.
+From C, L gets C syntax, simple types (int, float, string), and
+complex types (arrays, structs).
+From Perl, L gets associative arrays and regular expressions (PCRE).
+And from neither, L gets its own simplistic form of classes.
+
+L stands for "little" as in little language. The idea was to distill
+the useful parts of other languages and combine them into a scripting
+language, with type checking, classes (not full-blown OO but useful none
+the less), and direct access to a cross-platform graphical toolkit.
+
+L provides a set of built-in functions, drawn from Perl and the
+standard C library.
+
+L is built on top of the Tcl/TK system. The L compiler generates Tcl
+byte codes and uses the Tcl calling convention. This means that L and
+Tcl code may be intermixed. More importantly, it means that
+L may use all of the TK widgets. The net result is a type-checked
+scripting language which may be used for cross-platform GUIs.
+
+L is open source under the same license as Tcl/TK (BSD like).
+
+=head1 RUNNING L PROGRAMS
+
+You can run an L program from the command line.
+
+ L [options] progname.l [args]
+
+Alternatively, put this as the first line of your script, but make
+sure your script is executable (C<chmod 755 script.l> under Unix).
+
+ #!/path/to/L [options]
+
+Options:
+
+=over 4
+
+=item B<--fnhook=myhook>
+
+When function tracing is enabled, use C<myhook> as the trace hook.
+
+=item B<--fntrace=on | entry | exit | off>
+
+Enable function tracing on both function entry and exit, entry only,
+exit only, or disable tracing altogether.
+
+=item B<--norun>
+
+Compile only (do not run). This is useful to check for compilation
+errors.
+
+=item B<--nowarn>
+
+Disable compiler warnings. This is useful when you know you have
+unused variables or other warnings that you don't want to be
+bothered with.
+
+=item B<--poly>
+
+Treat all types as C<poly>. This effectively disables type checking.
+
+=item B<--trace-depth=n>
+
+When function tracing is enabled, trace only to a maximum call depth of n.
+
+=item B<--trace-file=colon-separated list of glob | /regexpr/>
+
+Enable tracing of all functions in the given files, specified either
+as globs or regular expressions. A leading + before a glob or regexp
+means to add to what is otherwise being traced and a leading - means
+to remove.
+No leading + or - means to trace exactly what is specified.
+
+=item B<--trace-funcs=colon-separated list of glob | /regexpr/>
+
+Like --trace-file but specifies functions.
+
+=item B<--trace-out=filename | host:port>
+
+Send default trace output to a file or a TCP socket.
+
+=item B<--warn-undefined-fns>
+
+Just before main() is called, warn if any functions referenced by
+L code are undefined.
+You can combine this with --norun to do this check even when no
+code is run.
+
+=item B<--version>
+
+Print the L build version and immediately exit.
+
+=back
+
+Any of the command-line options also can be specified in a #pragma
+inside the program.
+
+The optional [args] is a white-space separated list of arguments that
+are passed to the script's main() function as an argument count (argc)
+and an array of strings (argv).
+
+=head1 SYNTAX
+
+An L script or program consists of one or more statements. These may
+be executable statements, variable or type declarations, or function
+or class declarations. Statements outside of functions are said
+to be at the C<top level> and are executed in the order they appear,
+although you can use a C<return> statement to bail out.
+There is no need to have a C<main()> function, but if one is
+present, it is executed after all of the top-level statements
+(even if you did a C<return> from the top level).
+
+ puts("This is printed first.");
+ void main()
+ {
+ puts("This is printed last.");
+ }
+ puts("This is printed second.");
+
+L statements end in a semi-colon.
+
+ printf("Hello, world\n");
+
+Both C style and hash style comments are allowed, but the hash-style
+comments are only for the first line and must start on column 1.
+
+ # This is a comment
+ // So is this
+ /* And this too */
+ # But this is an error (does not start on column 1)
+
+Whitespace usually is irrelevant.
+
+ printf(
+ "Hello, world\n")
+ ;
+
+... except inside quoted strings:
+
+ # this would print with a linebreak in the middle
+ print "Hello\
+ world";
+
+and around the string-concatenation operator " . " so it can
+be distinguished from the struct-member selection operator ".".
+
+Double quotes or single quotes may be used around literal strings:
+
+ puts("Hello, world");
+ puts('Hello, world');
+
+However, only double quotes "interpolate" variables and handle
+character escapes such as for newlines (C<\n>):
+
+ printf("Hello, ${name}\n"); // works fine
+ printf('Hello, ${name}\n'); // prints ${name}\n literally
+
+Inside single quotes, you can still escape a line break, the
+single quote character (C<\'>), and the escape character (C<\\>).
+
+If you put a line break in the middle of a string but forget to escape
+it, L will complain.
+
+Adjacent string constants are automatically concatenated, like in C.
+
+ printf("This " "prints "
+ "the concatenation "
+ "of ""all"" strings\n");
+
+prints "This prints the concatenation of all strings".
+
+L requires that they be the same "type", all interpolated ("") or
+all not interpolated ('') but the dot operator comes the rescue
+in this contrived example:
+
+ 'Hi there. ${USER} is ' . "${USER} today";
+
+=head1 HTML WITH EMBEDDED L
+
+For building web-based applications, L has a mode where the input
+can be HTML with embedded L code (which we call C<Lhtml>).
+This works in a way similar to PHP.
+To invoke this mode, the input file must end in .lhtml:
+
+ L [options] home.lhtml
+
+All text in home.lhtml is passed through to stdout except
+that anything between <? and ?> is taken to be one or more
+L statements that are replaced by whatever that L code outputs,
+and anything between <?= and ?> is taken to be a single L
+expression that is replaced by its value.
+All L code is compiled at the global scope, so you can include L
+variable declarations early in the Lhtml document and reference them
+later.
+
+Here's an example that iterates over an array of key/value pairs
+and formats them into a rudimentary table:
+
+ <? key_value_pair row, rows[]; ?>
+ <html>
+ <body>
+ <p>This is a table of data</p>
+
+ <table>
+ <? rows = get_data();
+ foreach (row in rows) { ?>
+ <tr>
+ <td><?= row.key ?></td>
+ <td><?= row.value ?></td>
+ </tr>
+ <? } ?>
+ </table>
+
+ </body>
+ </html>
+
+=head1 NAME SCOPING
+
+Variables must be declared before use, or a compile-time error
+will result. However, functions need not be declared before use
+although it is good practice to do so.
+
+Declarations at the top-level code exist at the C<global> scope and
+are visible across all scripts executed by a single run of L. You can
+qualify a global declaration with C<private> to restrict it to the
+current file only; this is similar to a C<static> in C, except that
+private globals are not allowed to shadow public globals. Names
+declared in a function, or in a block within a function, are C<local>
+and are scoped to the block in which they are declared.
+
+Functions and global variables share the same namespace, so a
+variable and function cannot have identical names. Struct tags
+have their own namespace, and type names have theirs.
+
+Inside a function, two locals cannot share the same name, even if they
+are in parallel scopes. This is different than C where this is
+allowed. But a local can share the same name as a global, in which
+case the local is said to C<shadow> the global.
+
+Names declared inside of a class can be either local or global
+depending on how they are qualified. Classes are discussed later.
+
+=head1 VARIABLES AND TYPES
+
+L is a strongly typed language with both scalar and complex types.
+All variables are typed and must be declared before use.
+
+The scalar types are int, float, and string. The complex types are
+array, hash, struct, and list. L also supports function pointers,
+classes, and a special type called C<poly> which matches any type and
+normally is used to disable type checking. Finally, L has the concept
+of an C<undefined> value which a variable of any type can possess.
+These all are discussed next.
+
+Strong typing means that you can assign something of one type only to
+something else of a compatible type. Normally, to be compatible the
+types must be structurally the same, but there are exceptions such as
+an int being compatible with float and a list sometimes being
+compatible with an array or struct. These special cases are discussed
+further below.
+
+An L variable is written as an identifier without any special prefix
+characters like in Perl. Variables begin with a letter and can
+contains letters, numerals, and underscores, but they B<cannot> begin
+with an underscore (_). This is because the L compiler reserves names
+starting with _ for internal use.
+
+A variable declaration includes the
+type, the variable name, and optionally an initial value which can
+be any L expression:
+
+ int i = 3*2;
+
+ printf("i = %d\n", i); // prints i = 6
+
+If an initial value is omitted, the variable starts out with the
+undefined value C<undef>, discussed more below.
+
+=over 4
+
+=item Scalars
+
+A scalar represents a single value that is a string, integer, or
+floating-point number.
+Strings are wide char (unicode),
+integers are arbitrarily large,
+and floats are like C's double.
+
+Examples:
+
+ string animal = "camel";
+ int answer = 42;
+ float pi = 3.14159;
+
+When one of these types is expected, supplying another one usually is
+an error, except that an int always can be used as a float. You can
+override this behavior with a type cast, discussed below.
+
+Hex and octal integer constants are specified like this:
+
+ int space = 0x20;
+ int escape = 0o33;
+
+Integer constants can be arbitrarily large; they are not limited
+by the machine's word size.
+
+Strings have a special feature where they can be indexed like arrays,
+to get a character or range of characters, or to change a character
+(but you cannot change a range of characters):
+
+ string s1, s2;
+
+ s1 = "hello";
+ s2 = s1[1]; // s2 gets "e"
+ s2 = s1[1..3]; // s2 gets "ell"
+ s1[1] = "x"; // changes s1 to "hxllo"
+ s1[END+1] = "there"; // changes s1 to "hxllothere"
+
+The pre-defined identifier C<END> is the index of the last character,
+or is -1 if the string is empty. You always can write to one past the end
+of a string to append to it, but writing beyond END+1 is an error.
+
+You delete a character within a string by indexing the string and
+setting it to "" (the empty string), or by using the C<undef()> built-in:
+
+ s[3] = ""; // deletes fourth character of s
+ undef(s[3]); // also deletes fourth character
+
+=item Undef
+
+Sometimes you want to signify that a variable has no legal value, such
+as when returning an error from a function. L has a read-only pre-defined
+constant called C<undef> which you can assign to anything.
+
+ int_var = undef;
+ array_var = undef;
+
+This is different than the C<undef()> built-in I<function> which
+deletes array, hash, or string elements and which is described
+later.
+
+When used in comparisons, a variable that is undefined is never seen
+as true, or as equal to anything defined, so you can easily check for
+error conditions:
+
+ unless (f = fopen("file", "r")) {
+ die("fopen");
+ }
+ while (s = <f>) {
+ printf("%s\n", s);
+ }
+
+And for the cases where it matters, you can test whether something is
+undefined with the built-in function C<defined()>:
+
+ ret = myfunc();
+ unless (defined(ret)) die("error");
+ if (ret != 0) {
+ printf("myfunc returned %d\n", ret);
+ } else {
+ printf("no data from myfunc\n");
+ }
+
+L itself sometimes uses undef to tell you that no value is available.
+One case is when you assign to an array element that is more than one
+past the end of an array. L auto-extends the array and sets the
+unassigned elements to undef.
+
+Undefinedness is an attribute of a
+variable; undefined does not have a value. It may be anything since
+the underlying Tcl system "shimmers" variables. If a variable can be
+undefined, don't rely on its value until you've checked it first with
+C<defined(var)>.
+
+=item Arrays
+
+An array holds a list of values, all of the same type:
+
+ string animals[] = { "camel", "llama", "owl" };
+ int numbers[] = { 23, 42, 69 };
+
+You do not specify a size when declaring an array, because
+arrays grow dynamically.
+
+Arrays are zero-indexed. Here's how you get at elements in an array:
+
+ puts(animals[0]); // prints "camel"
+ puts(animals[1]); // prints "llama"
+
+The pre-defined identifier C<END> is the index of the last element
+of an array, or is -1 if the array is empty.
+
+ puts(animals[END]); // last element, prints "owl"
+
+END is valid only inside of an array subscript.
+
+If you need the length of an array, use a built-in function:
+
+ num_elems = length(animals); // will get 3
+
+If the array is empty, length() returns 0.
+
+To get multiple values from an array, you use what's called an array
+C<slice> which is a sub-array of the array being sliced.
+Slices are for reading values only, you cannot write to a slice.
+
+ animals[0..1]; // gives { "camel", "llama" }
+ animals[1..END]; // gives all except the first element
+
+In this last example where END is used, you must be careful, because if
+the array is empty, END will be -1, and an array slice where the
+second index is less than the first causes a run-time error.
+
+You can add and remove from an array with C<push> and C<pop>,
+C<unshift> and C<shift>, and C<insert>.
+The C<push> and C<pop> functions add and remove from the end:
+
+ string birds[], next;
+
+ push(&birds, "robin");
+ push(&birds, "dove", "cardinal", "bluejay");
+ next = pop(&birds); // next gets "bluejay"
+ // birds is now { "robin", "dove", "cardinal" }
+
+The & means that birds is passed by reference, because it will
+be changed. This is discussed more later.
+
+Another way to append:
+
+ birds[END+1] = "towhee";
+
+The C<unshift> and C<shift> functions are similar but they add
+and remove from the beginning of the array.
+
+You can insert anywhere in an array with C<insert>:
+
+ insert(&birds, 2, "crow"); // insert crow before birds[2]
+ insert(&birds, 3, "hawk", "eagle");
+
+In these examples we inserted one or more single elements but
+whereever you can put an element you also can splice in a list:
+
+ string new_birds[] = { "chickadee", "turkey" };
+ push(&birds, new_birds); // appends chickadee and turkey
+
+The variable is not required; the constant could have been passed instead.
+There is an ambiguity, resolved by the type of the first argument, as to
+whether it is two strings being pushed as two new entries in the array, or if
+it is a single item being pushed. You have to know the type of the
+first argument to know which is which.
+
+You can remove from anywhere in an array with C<undef>:
+
+ string dev_team[] = { "larry", "curly", "mo" };
+ undef(dev_team[0]); // delete "larry" from dev_team
+
+When you delete an element, all subsequent elements slide down
+by one index. Note that undef() works only on a variable; it
+cannot remove an element from a function return value, for example.
+
+You also can directly assign to any array index even if the array
+hasn't yet grown up to that index. If you assign more than one past
+the current end, the unassigned elements are assigned undef:
+
+ string colors[] = { "blue, "red" };
+ colors[3] = "green"; // colors[2] gets undef and colors[3] gets "green"
+
+You can read from any non-negative array index as well. You will simply
+get undef if the element doesn't exist. Reading from a negative index
+causes a run-time error.
+
+An array can hold elements of any type, including other arrays.
+Although L does not have true multi-dimensional arrays, arrays of
+arrays give you basically the same thing:
+
+ int matrix[][] = {
+ { 1, 2, 3 },
+ { 4, 5, 6 },
+ { 7, 8, 9 }
+ };
+
+When declaring an array, it is legal to put the brackets after the
+type instead of the name. This is useful in function prototypes that
+omit the parameter name, and is required if a function returns an
+array. This example illustrates both cases:
+
+ int[] mysort(int[]);
+
+=item Hashes
+
+A hash holds a set of key/value pairs:
+
+ int grades{string} = { "Tom"=>85, "Rose"=>90 };
+
+When you declare a hash, you specify both the key type (within the {})
+and the value type. The keys must be of scalar type but the values can
+be of any type, allowing you to create hashes of arrays or other hashes.
+
+To get at a hash element, you index the hash with the key:
+
+ grades{"Rose"}; // gives 90
+
+If the given key does not exist in the hash, you get back undef.
+Using undef as a key causes a run-time error.
+
+You get a list of all the keys in a hash with the C<keys()> built-in,
+which returns an array:
+
+ string students[] = keys(grades);
+
+Because hashes have no particular internal order, the order in which
+the keys ("Tom" and "Rose") appear is undefined. However, you can
+obtain a sorted array of keys like this:
+
+ string students[] = sort(keys(grades));
+
+The C<length> built-in works on hashes too and returns the number of
+key/value pairs.
+
+You remove an element from a hash with C<undef>:
+
+ undef(grades{"Tom"}); // removes "Tom" from the hash
+
+It is not an error to remove something that's not in the hash. Note
+that undef() works only on a variable; it cannot remove an element
+from a function return value, for example.
+
+When declaring a hash, it is legal to put the braces after the base
+type instead of the name. This is useful in function prototypes that
+omit the parameter name, and is required is a function returns a
+hash. This example illustrates both cases:
+
+ int{string} adjust_grades(int{string});
+
+=item Structs
+
+L structs are much like structs in C. They contain a fixed number
+of named things of various types:
+
+ struct my_struct {
+ int i;
+ int j;
+ string s;
+ };
+ struct my_struct st = { 1, 2, "hello" };
+
+You index a struct with the "." operator except when it is a
+call-by-reference parameter and then you use "->":
+
+ void foo(struct my_struct &byref) {
+ puts(byref->s); // prints hello
+ }
+ puts(st.i); // prints 1
+ puts(st.j); // prints 2
+ puts(st.s); // prints hello
+ foo(&st); // pass st by reference
+
+It is an error to use "." when "->" is required and vice-versa. Be
+careful to not put any whitespace around the "." or else you will get
+the string concatenation operator and not struct-member selection.
+
+Structs can be named like C<my_struct> above or they can be anonymous:
+
+ struct {
+ int i;
+ int j;
+ } var1;
+
+Struct names have their own namespace, so they will never clash with
+function, variable, or type names.
+
+=item Lists
+
+In the examples above, we have been initializing arrays, hashes, and
+structs by putting values inside of {}:
+
+ string nums[] = { "one", "two", "three" };
+
+In L, the C<{}> is an operator that creates a C<list> and can be used
+anywhere an expression is valid. The array could instead be
+initialized like this:
+
+ string nums[];
+ nums = { "one", "two", "three" };
+
+We said before that you can assign a value to something only if it has
+a compatible type. Lists are special in that they can be compatible
+with arrays, hashes, and structs. A list where all the elements are
+of the same type, say T, is compatible with an array of things of
+type T. The example above illustrates this.
+
+A list also is compatible with a struct if the list elements agree
+in type and number with the struct. The assignment of the variable
+C<st> above illustrates this.
+
+A list is compatible with a hash if it has a sequence of key/value
+pairs and they are all compatible with the key/value types of
+the hash:
+
+ int myhash{string} = { "one"=>1, "two"=>2, "three"=>3 };
+
+Lists are very useful at times because you can use them to build up
+larger complex structures. To concatenate two arrays, you could do
+this:
+
+ { (expand)array1, (expand)array2 };
+
+The (expand) operator takes an array (or struct or list) and moves its
+elements out a level as if they were between the { and } separated by
+commas. This is discussed more later.
+
+=item Poly
+
+Sometimes you don't want L to do type checking.
+In this case, you use the C<poly> type, which is compatible with
+any type. Poly effectively disables type checking, allowing you
+to use or assign values without regard to their types. Obviously,
+care must be taken when using poly.
+
+The B<-poly> option to L causes all variables to be treated as if they
+were of type poly, regardless of how they are declared.
+
+=item Type Casts
+
+Something of one type can be converted into something of another
+type with a type cast like in C:
+
+ string_var = (string)13;
+
+If the thing being cast cannot be converted to the requested type, the
+result of the cast is C<undef>.
+
+=item Typedefs
+
+You can declare a type name to be a short hand for another type, as
+you would in C:
+
+ typedef int index_t;
+ typedef string table_t{index_t};
+
+And then use the short-hand as you would any other type name:
+
+ table_t my_table;
+ my_table{3} = "value";
+
+You can typedef a function pointer too. This declares compar_t
+as type function that takes two ints and returns an int:
+
+ typedef int compar_t(int a, int b);
+
+Type names belong to their own namespace, so you can define a typedef
+with the same name as a variable, function, or struct name without
+ambiguity.
+
+=back
+
+=head1 INTERPOLATION
+
+Expressions can be interpolated into double-quoted strings, which
+means that within a string you can write an expression and at run-time
+its value will be inserted. For example, this interpolates two
+variables:
+
+ int a = 12;
+ string b = "hello";
+
+ /* This will print "A is 12 and b is hello". */
+
+ printf("A is ${a} and b is ${b}\n");
+
+Everything inside the ${} is evaluated like any other L expression, so
+it is not limited to just variables:
+
+ printf("The time is ${`date`}\n");
+
+=head1 FUNCTIONS
+
+L's functions are much like functions in C. Like variable names,
+function names B<cannot> begin with an underscore (_).
+
+Each function must be declared with a return type and a
+formal-parameter list:
+
+ int sum(int a, int b)
+ {
+ return (a + b);
+ }
+
+C<void> is a legal return type for a function that returns no value.
+Functions cannot be nested.
+
+Function prototypes are allowed, where all but the function body is
+declared. In a prototype, you can omit any parameter names or use
+C<void> for an empty parameter list:
+
+ void no_op1(void);
+ void no_op2();
+ int sum(int, int);
+
+Unlike Perl, when calling a function you must use parentheses around
+the arguments:
+
+ sum(a, b);
+
+L does a special kind of call called a C<pattern function> call
+when the function name is capitalized and contains an underscore;
+these are useful for calling Tcl commands and are described later.
+Normal function names should avoid being both capitalized and
+with an underscore.
+
+Parameters are passed by value by default. To pass by reference,
+you use a C<&> in the declaration and in the function call:
+
+ void inc(int &arg)
+ {
+ ++arg;
+ }
+
+ inc(&x); // inc() can change x
+
+The C<&> only tells L to pass by reference. It is not a pointer.
+You use a reference to give the called function the ability to change
+the caller's variable.
+
+Only variables can be passed by reference, not elements of arrays,
+hashes, or structs. This is one significant difference from C.
+Passing an array, hash, or struct element with C<&> uses C<copy in/out>,
+not a true reference. The element value is copied
+into a temp variable and the temp is passed by reference. Then when
+the function returns, any changes to the temp are copied back into the
+array, hash, or struct element. In most cases this behaves like
+call-by-reference and you don't need to worry about it.
+But if you access the passed element during the function call,
+by referencing it directly instead of through the formal parameter,
+then you must be careful:
+
+ string array[] = { "one", "two" };
+ void fn(string &var, string val)
+ {
+ var = val;
+ array[0] = "this gets overwritten by the copy-out";
+ }
+ void main()
+ {
+ fn(&array[0], "new");
+ puts(array[0]); // will print "new"
+ }
+
+Instead of passing a reference, you can pass C<undef> like you would a
+NULL pointer in C.
+You test for this with the C<defined()> operator:
+
+ void inc(int &arg)
+ {
+ if (defined(&arg)) ++arg;
+ }
+
+ inc(undef); // does nothing
+ inc(&x); // increments x
+
+If you pass C<undef> as a reference and then attempt to access
+the parameter, a run-time error results similar to derefencing
+a NULL pointer in C.
+
+When accessing a struct argument inside a function, if the struct was
+passed by reference, the "->" operator must be used instead of ".".
+This makes it clear to the reader that the struct variable is passed
+by reference; it is intended to allude to a C pointer even though L
+does not have pointers.
+
+Functions can take a variable number of arguments, like printf does.
+In the function declaration, you use the qualifier "..." in front
+of the last formal parameter name and omit its type:
+
+ void dump(...args)
+ {
+ string s;
+ foreach(s in args) puts(s);
+ }
+ dump("just one");
+ dump("but two", "or three", "or more is OK");
+
+Inside the function, C<args> has type array of poly, allowing any
+number of parameters of any type to be passed.
+
+=head2 The main() Function
+
+If main() is present, it is called after all of the top-level statements
+have executed. The main() function may defined in any of the following
+ways:
+
+ void|int main() {}
+ void|int main(string argv[]) {}
+ void|int main(int argc, string argv[]) {}
+ void|int main(int argc, string argv[], string env{string}) {}
+
+The C<argv> array is populated from the script name and any arguments
+that appear after the name on the L command line.
+In this example, argc is 4 and argv[] contains "script.l", "arg1",
+"arg2", and "arg3":
+
+ L script.l arg1 arg2 arg3
+
+The C<env> hash is populated with the environment variables present
+when L is invoked. Although you can change this hash, writes to it
+are not reflected back into the environment. To do that use the
+C<putenv> library function.
+
+Only a C<main> written in L is automatically called.
+You can write a C<main> in Tcl but L will not call it automatically.
+
+If C<main> is declared to have return type C<int> and it returns
+a non-zero value, L will exit with an exit status equal to
+the return value.
+
+=head2 Function Pointers
+
+Function pointers are supported, but only as arguments -- you cannot
+otherwise assign a function pointer to a variable. It is common to
+first typedef the function-pointer type; here is one for a function
+that compares two strings:
+
+ typedef int str_compar_t(string a, string b);
+
+You can then pass such a compare function as follows:
+
+ string a[];
+
+ bubble_sort(a, &unary_compar);
+
+Where the sort function looks like this:
+
+ string[] bubble_sort(string a[], str_compar_t &compar)
+ {
+ do {
+ ...
+ if (compar(a[i], a[i+1] > 0) { ... }
+ ...
+ } ...
+ }
+
+And the compare function looks like this:
+
+ int unary_compar(string a, string b)
+ {
+ int al = length(a);
+ int bl = length(b);
+
+ if (al < bl) {
+ return -1;
+ } else if (al > bl) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+
+=head1 CONTROL TRANSFER STATEMENTS
+
+L has most of the usual conditional and looping constructs.
+
+A variable of any type will evaluate to false if it is undefined.
+An int or a float with a value of 0 is also false.
+All other values are true.
+
+ int undefined = undef;
+ int zero = 0;
+ int one = 1;
+
+ if (undefined) // false
+ if (zero) // false
+ if (one) // true
+ if (defined(zero)) // true
+
+See the list of operators in the next section for information on
+comparison and logic operators, which are commonly used in conditional
+statements.
+
+=over 2
+
+=item if
+
+The C<if> statement comes in the traditional form:
+
+ if ( condition ) {
+ ...
+ } else if ( other condition ) {
+ ...
+ } else {
+ ...
+ }
+
+And there's a negated version of it provided as a more readable
+version of C<if (!I<condition>)>.
+
+ unless ( condition ) {
+ ...
+ }
+
+=item while
+
+ while ( condition ) {
+ ...
+ }
+
+ do {
+ ...
+ } while ( condition )
+
+=item for
+
+ for (i = 0; i < max; ++i) {
+ ...
+ }
+
+=item foreach
+
+The C<foreach> statement lets you iterate through the elements of an
+array:
+
+ string element;
+ string myarray[];
+
+ foreach (element in myarray) {
+ printf("This element is %s\n", element);
+ }
+
+... of a hash:
+
+ string key;
+ int value;
+ int myhash{string};
+
+ foreach (key=>value in myhash) {
+ printf("Key %s has value %d\n", key, value);
+ }
+
+... or of a string:
+
+ string char;
+
+ foreach (char in mystring) {
+ printf("This char is %s\n", char);
+ }
+
+... or through the lines in a string:
+
+ int i = 0;
+ string s, lines;
+
+ foreach (s in <lines>) {
+ puts("line #${++i}: ${s}");
+ }
+
+Inside the loop, the index variable(s) (C<element>, C<key>, C<val>, and
+C<char> above) get I<copies> of the iterated elements, so
+if you assign to them, the thing you're iterating over does not change.
+
+If you want to stride through more than one array element, character,
+or line in each iteration, just use a list of value variables instead of one:
+
+ foreach (e1,e2,e3 in myarray) {
+ printf("Next three are %s:%s:%s\n", e1, e2, e3);
+ }
+
+If there isn't a multiple of three things to iterate through, the
+stragglers get undef on the last iteration. Strides
+work only for arrays and strings, not hashes.
+
+After completing the loop and falling through, all loop counters
+become undefined (they get the C<undef> value). If the loop
+is prematurely ended with a C<break> or by jumping out of the
+loop with a C<goto>, the loop counters keep their values.
+
+=item switch
+
+The C<switch> statement is like C's except that regular expressions
+can be used as case expressions:
+
+ switch (string_var) {
+ case /[0-9]+/:
+ puts("numeric");
+ break;
+ case /[a-zA-Z][0-9a-zA-Z]*/:
+ puts("alphanumeric");
+ break;
+ default:
+ puts("neither");
+ break;
+ }
+
+The default case is optional. The expression being switched on
+must be of type integer, string or poly.
+
+In addition to checking the value of the switch expression,
+you can test whether it is undefined.
+This is useful when switching on a function return value
+which could be C<undef> to signal an error condition.
+
+ switch (myfunc(arg)) {
+ case /OK/:
+ puts("all is A-OK");
+ break;
+ case undef:
+ puts("error");
+ break;
+ default:
+ puts("unknown return value");
+ break;
+ }
+
+To avoid confusion, the alternate regular-expression-delimiter syntax
+is restricted:
+
+ switch (str) {
+ case m|x*y|: // "|" and most other punctuation as the delim -- ok
+ // except ( and : -- error
+ // and any alphabetic character -- error
+ break;
+ case m: // is the variable m (not a regexp) -- ok
+ break;
+ case mvar: // and variables starting with "m" -- ok
+ break;
+ }
+
+=item break and continue
+
+L has C<break> and C<continue> statements that behave like C's.
+They work in all L loops including C<foreach> loops, and C<break> works
+in C<switch> case bodies.
+
+=item goto
+
+The C<goto> statement unconditionally transfers control to a label in
+the same function, or to a label at the global scope if the goto is at
+the global scope. You cannot use a goto to transfer in to or out of
+a function. Labels have their own namespace so they will not clash
+with variable, function, or type names.
+
+ /* A goto at the global scope. */
+ goto L1;
+ puts("this is not executed");
+L1: puts("but this is");
+
+ void foo()
+ {
+ goto L2;
+ puts("this is not executed");
+L2: puts("but this is");
+ }
+
+Some caveats: do not jump into a foreach loop or a run-time error may
+result due to bypassing the loop set-up. Do not bypass a variable
+declaration or else the variable will be inaccessible.
+
+=back
+
+=head1 INCLUDES
+
+L has an C<#include> statement like the one in the C pre-processor.
+A #include can appear anywhere a statement can appear as long as it begins
+in the first column and is contained entirely on one line:
+
+ #include <types.l>
+ #include "myglobals.l"
+ void main()
+ {
+ ...
+ }
+
+Unless given an absolute path, when the file name is in angle brackets
+(like <types.l>), L searches these paths, where BIN is where the
+running tclsh exists:
+
+ $BIN/include
+ /usr/local/include/L
+ /usr/include/L
+
+When the file name is in quotes (like "myglobals.l"), L searches only
+the directory containing the script that did the #include.
+
+L also remembers which files have been included and will not include a file
+more than once, allowing you to have #include files that include each
+other.
+
+=head1 HERE DOCUMENTS
+
+Sometimes you need to assign a multi-line string to a variable.
+C<Here documents> help with that:
+
+ string s = <<END
+ This is the first line in s.
+ This is the second.
+ And the last.
+ END;
+
+Everything in the line starting after the initial <<END delimiter and
+before the final END delimiter gets put into the variable C<s>. You
+can use any identifier you want as the delimiter, it doesn't have
+to be END.
+A semicolon after the END is optional.
+
+The text inside the here document undergoes interpolation and escape
+processing.
+If you don't want that, put the initial delimiter inside of single
+quotes:
+
+ string s = <<'END'
+ None of this text is interpolated.
+ So this ${xyz} appears literally as '${xyz}'.
+ And so does \ and ' and " and anything else.
+ END;
+
+To help readability, you can indent your here document but have
+the indenting white space ignored.
+Put the initial delimiter on the next line and then
+whatever whitespace you put before it gets ignored:
+
+ string s =
+ <<END
+ This is the first line in s and gets no leading white space.
+ This line ends up with a single leading space.
+ And this ends up with two.
+ END;
+
+Exceptions to the indentation rule:
+a blank line is processed as if it is indented,
+and the end delimiter can have any amount of leading white space
+so that you can indent it differently.
+
+=head1 WORKING WITH TCL/TK
+
+L is built on top of Tcl: L functions are compiled down to Tcl procs,
+L local variables are just Tcl variables local to the proc, and L global
+variables are Tcl globals.
+Although L is designed to hide its Tcl underpinnings, sometimes it is
+useful for L and Tcl to cooperate.
+
+=head2 Mixing L and Tcl Code
+
+When you invoke L with a script whose name ends in C<.l>, the script
+must contain only L code.
+If you run a C<.tcl> script, you can mix L and Tcl:
+
+ puts "This is Tcl code"
+ #lang L
+ printf("This is L code\n");
+ #lang tcl
+ puts "Back to Tcl code"
+
+You also can run L code from within Tcl by passing the L code to the
+Tcl command named C<L>:
+
+ puts "Tcl code again"
+ L { printf("Called from the L Tcl command.\n"); }
+
+=head2 Calling Tcl from L
+
+You call a Tcl proc from L like you would an L function:
+
+ string s = "hello world";
+ puts(s);
+
+In this example, C<puts> is the Tcl command that outputs its argument
+to the C<stdout> channel.
+
+If you want argument type checking, you can provide a prototype for the Tcl
+functions you call. Otherwise, no type checking is performed.
+
+In Tcl, options usually are passed as strings like "-option1" or "-option2".
+L has a feature to pass these options more pleasantly:
+
+ func(option1:); // passes "-option1"
+ func(option2: value, arg); // passes "-option2", value, arg
+
+Without this, you would have to say:
+
+ func("-option1");
+ func("-option2", value, arg);
+
+A similar feature is for passing sub-commands to Tcl commands:
+
+ String_length("xyzzy"); // like Tcl's [string length xyzzy]
+ String_isSpace(s); // like Tcl's [string is space $s]
+
+Whenever the function name is capitalized and contains an underscore,
+the sequence of capitalized names after the underscore are converted
+to (lower case) arguments (although capitalizing the
+first name after the underscore is optional).
+This is called a C<pattern function> call.
+
+A pattern-function call often is used to call a Tcl proc, but you
+can call an L function just as easily, and L has a special case
+when the function is named like C<Myfunc_*>:
+
+ void Myfunc_*(...args)
+ {
+ poly p;
+
+ printf("Myfunc_%s called with:\n", $1);
+ foreach (p in args) printf("%s\n", p);
+ }
+ void main()
+ {
+ Myfunc_cmd1(1);
+ Myfunc_cmd2(3,4,5);
+ }
+
+If C<Myfunc_*> is declared, then any call like C<Myfunc_x> becomes a
+call to C<Myfunc_*> where the string C<x> is put into the local
+variable C<$1> inside C<Myfunc_*>. The remaining parameters are
+handled normally.
+This gives you a way to handle a collection of sub-commands without
+having to declare each as a separate L function.
+Note that this use of C<$1> clashes with regular expression captures
+(described later), so if you use both, you should save off C<$1>
+before using any such regular expressions.
+
+If you need to execute arbitrary Tcl code rather than just call a proc,
+you pass it to Tcl's C<eval> command:
+
+ eval("puts {you guessed it, Tcl code again}");
+
+=head2 Calling L from Tcl
+
+L functions are easily called from Tcl, because an L function
+C<foo> compiles down to a Tcl proc named C<foo> in the global
+namespace.
+Let's say this is run from a script named C<script.tcl>:
+
+ #lang L
+ int avg(...args)
+ {
+ int i, sum=0;
+ unless (length(args)) return (0);
+ foreach (i in args) sum += i;
+ return (sum/length(args));
+ }
+ #lang tcl
+ set x [avg 4 5 6]
+ puts "The average is $x"
+
+The L code defines a proc named C<avg> which the Tcl code then calls.
+
+An exception is that C<private> L functions are not callable from Tcl.
+
+=head2 Variables
+
+Because L variables are just Tcl variables, you can access L variables
+from Tcl code. Here is an example from the L library:
+
+ int size(string path)
+ {
+ int sz;
+
+ if (catch("set sz [file size $path]")) {
+ return (-1);
+ } else {
+ return (sz);
+ }
+ }
+
+In this Tcl code, C<$path> refers to the L formal parameter C<path>,
+and the L local C<sz> is set to the file size. This example also
+illustrates how you can use Tcl's exception-handling facility
+to catch an exception raised within some Tcl code.
+
+An exception is that private L global names are mangled (to
+make them unique per-file).
+You can pass the mangled name to Tcl code with the C<&> operator.
+Here we are passing the name of the private function C<mycallback> to
+register a Tcl fileevent "readable" handler:
+
+ private void mycallback(FILE f) { ... }
+
+ fileevent(f, "readable", {&mycallback, f});
+
+=head2 Complex variables
+
+Passing scalar variables works because they have the same representation
+in L and in Tcl.
+
+Passing complex variables is trickier and is not supported, but if you
+want to try here is what you need to know. This is subject to change.
+An L array is a Tcl list.
+An L struct is a Tcl list with the first struct member as the first
+list element and so on.
+An L hash table is a Tcl dict.
+If an L variable is deeply nested, so is the Tcl variable.
+
+So long as you understand that and do the appropriate thing in both
+languages, passing complex variables usually is possible.
+
+=head2 Namespaces
+
+You can access Tcl procs and variables in namespaces other than
+the global namespace by qualifying the name:
+
+ extern string ::mynamespace::myvar;
+
+ /* Print a bytecode disassembly of the proc "foo". */
+ puts(::tcl::unsupported::disassemble("proc", "foo"));
+
+ /* Print a variable in another namespace. */
+ puts(::mynamespace::myvar);
+
+=head2 Calling Tk
+
+To help call Tk widgets, L has a C<widget> type that is used with the
+pattern function calls described above. A widget value behaves like
+a string except in a pattern function call where it is the name
+of the widget to call:
+
+ widget w = Text_new();
+ Text_insert(w, "end", "hi!"); // like Tcl's $w insert end hi!
+
+Another feature is useful for calling Tk widgets that take the I<name>
+of a variable whose value is updated when the user changes a widget
+field. You can use an L variable like this:
+
+ string msg;
+ ttk::label(".foo", textvariable: &msg);
+
+The ampersand (&) in front of C<msg> alludes to a C pointer but it
+really passes just the name of the variable. L does this when the
+option name ends in "variable", as "textvariable" does in the example
+above (yes, this is a hack).
+
+You can do this with globals, class variables, or class instance
+variables, and only with a variable and not an array, structure, or
+hash element.
+
+=head1 OPERATORS
+
+=over 4
+
+=item Arithmetic
+
+ + addition
+ - subtraction
+ * multiplication
+ / division
+ % remainder
+
+=item Numeric and String comparison
+
+ == equality
+ != inequality
+ < less than
+ > greater than
+ <= less than or equal
+ >= greater than or equal
+
+=item String comparison
+
+ =~ regexp match or substitute
+ !~ negated regexp match
+
+=item Comparison of composite types (array, hash, struct)
+
+ eq(a,b)
+
+=item Bit operations
+
+ & bit and
+ | bit or
+ ^ bit exclusive or
+ ~ bit complement
+ << left shift
+ >> right shift
+
+=item Boolean logic
+
+ && and
+ || or
+ ! not
+
+=item Conditional
+
+ ?: ternary conditional (as in C)
+
+=item Indexing
+
+ [] array index
+ {} hash index
+ . struct index (no whitespace around the dot)
+ -> struct index (call-by-reference parameters dereference)
+ -> class and instance variable access (object dereference)
+
+=item Miscellaneous
+
+ = assignment
+ , statement sequence
+ . string concatenation (must have whitespace around the dot)
+ `` command expansion
+
+=item Assignment
+
+ +=, -=, *=, /=, %=, &=, |=, ^=, <<=, >>=, .=
+
+=item Operator precedence (highest to lowest) and associativity
+
+ `` (non assoc)
+ [] {} . (struct index) -> ++ -- (left)
+ unary + unary - ! ~ & (right)
+ * / % (left)
+ + - . (string concatenation) (left)
+ << >> (left)
+ < <= > >= (left)
+ == != =~ !~ (left)
+ & (left)
+ ^ (left)
+ | (left)
+ && (left)
+ || (left)
+ ?: (right)
+ = += -= *= /= %= &= |= ^= <<= >>= .= (right)
+ , (left)
+
+=back
+
+=head1 PRE-DEFINED IDENTIFIERS
+
+=over 4
+
+=item __FILE__
+
+A string containing the name of the current source file, or "<stdin>"
+if the script is read from stdin instead of from a file.
+Read only.
+
+=item __LINE__
+
+An int containing the current line number within the script.
+Read only.
+
+=item __FUNC__
+
+A string containing the name of the enclosing function.
+At the top level, this will contain a unique name created internally
+by the compiler to uniquely identify the current file's top-level
+code.
+Read only.
+
+=item END
+
+An int containing the index of the last character of a non-empty
+string or the last element of a non-empty array. If the array or
+string is empty, END is -1. Valid only inside of a string or array
+subscript. Read only.
+
+=item stdio_status
+
+A struct of type STATUS (see system()) containing status of the
+last system(), `command`, successful waitpid(), or failed spawn().
+
+=item undef
+
+A poly containing the undef value, where defined(undef) is false.
+Assigning this to something makes it undefined.
+However, undef is not guaranteed to have any particular value, so applications
+should not rely on the value. Read only.
+
+=back
+
+=head1 RESERVED WORDS
+
+The following identifiers are reserved. They cannot be used for
+variable, function, or type names:
+
+ break
+ case
+ class
+ constructor
+ continue
+ default
+ defined
+ destructor
+ do
+ else
+ expand
+ extern
+ float
+ for
+ foreach
+ goto
+ if
+ instance
+ int
+ poly
+ private
+ public
+ return
+ string
+ struct
+ switch
+ typedef
+ undef
+ unless
+ void
+ while
+ widget
+
+=head1 BUILT-IN AND LIBRARY FUNCTIONS
+
+L has several built-in functions and a set of library functions
+modeled after the standard C library and Perl.
+
+=over 4
+
+=proto string <>
+
+=proto string <FILE f>
+
+Get the next line from a FILE handle and return it, or return undef
+for EOF or errors. Trailing newlines are removed. If a file handle
+is specified, it is not closed by this function.
+
+The form without a file handle
+
+ while (buf = <>) {
+ ...
+ }
+
+means
+
+ unless (argv[1]) {
+ while (buf = <stdin>) {
+ ...
+ }
+ } else for (i = 1; argv[i]; i++) {
+ unless (f = open(argv[i], "r")) {
+ perror(argv[i]);
+ continue;
+ }
+ while (buf = <f>) {
+ ...
+ }
+ }
+
+A trivial cat implementation:
+
+ void
+ main(int ac, string argv[])
+ {
+ string buf;
+
+ while (buf = <>) print(buf);
+ }
+
+=item `command`
+
+Execute the command (the string enclosed within back-ticks) and
+substitute its stdout as the value of the expression.
+Any output to stderr is passed through to the calling application's
+stderr and is not considered an error.
+The command is executed using the Tcl C<exec> command which
+understands I/O re-direction and pipes, except that the command undergoes
+bash-style quoting instead of Tcl quoting.
+The command string is interpolated.
+Backslash escapes $, `, and \, \<newline> is ignored, but otherwise
+backslash is literally interpreted.
+An embedded newline is an error.
+If the command cannot be run, undef is returned.
+The global variable C<stdio_status> (see system()) contains the
+command's exit status.
+
+=proto int abs(int val)
+
+=proto float abs(float val)
+
+Return the absolute value of the argument.
+
+=proto void assert(int condition)
+
+Print an error and exit with status 1 if C<condition> is false.
+The filename, line number, and text of the condition are printed.
+
+=proto string basename(string path)
+
+Return the file portion of a path name.
+
+=proto string caller(int frame)
+
+Return the name of a calling function, or the caller's caller, etc.
+To get the caller, use a frame of 0, to get the caller's caller, use
+1, etc.
+
+=proto int chdir(string dir)
+
+Change directory to dir.
+Return 0 on success, -1 on error.
+
+=proto int chmod(string path, string permissions)
+
+Not available on Windows.
+Change the mode of the file or directory named by path. Permissions
+can be the octal code that chmod(1) uses, or symbolic attributes that
+chmod(1) uses of the form [ugo]?[[+-=][rwxst],[...]], where multiple
+symbolic attributes can be separated by commas (example: u+s,go-rw add
+sticky bit for user, remove read and write permissions for group and
+other). A simplified ls-style string, of the form rwxrwxrwx (must be 9
+characters), is also supported (example: rwxr-xr-t is equivalent to
+01755).
+Return 0 on success, -1 on error.
+
+=proto int chown(string owner, string group, string path)
+
+Not available on Windows.
+Change the file ownership of the file or directory names by path. If
+either owner or group is an empty string, the attribute will not be
+modified.
+Return 0 on success, -1 on error.
+
+=proto int cpus()
+
+Return the number of processors (if known). Defaults to 1.
+
+=proto void die(string fmt, ...args)
+
+Output a printf-like message to stderr and exit 1.
+If fmt does not end with a newline, append
+" in <filename> at line <linenum>.\n"
+
+=proto string dirname(string path)
+
+Return the directory portion of a pathname.
+
+=proto int eq(compositeType a, compositeType b)
+
+Compare two arrays, hashes, structs, or lists for equality.
+The two arguments are compared recursively element by element.
+
+=proto int exists(string path)
+
+Return 1 if the given path exists or 0 if it does not exist.
+
+=proto int fclose(FILE f)
+
+Close an open FILE handle.
+Return 0 on success, -1 on error.
+
+=proto FILE fopen(string path, string mode)
+
+Open a file. The C<mode> string indicates how the file will be accessed.
+
+=over 4
+
+=item "r"
+
+Open the file for reading only; the file must already exist. This is
+the default value if access is not specified.
+
+=item "r+"
+
+Open the file for both reading and writing; the file must already exist.
+
+=item "w"
+
+Open the file for writing only. Truncate it if it exists. If it
+doesn't exist, create a new file.
+
+=item "w+"
+
+Open the file for reading and writing. Truncate it if it exists. If it
+doesn't exist, create a new file.
+
+=item "a"
+
+Open the file for writing only. The file must already exist, and the
+file is positioned so that new data is appended to the file.
+
+=item "a+"
+
+Open the file for reading and writing. If the file doesn't exist,
+create a new empty file. Set the initial access position to the end of
+the file.
+
+=item "v"
+
+This mode can be added to any of the above and causes open errors to
+be written to stderr.
+
+=back
+
+Return a FILE handle on success and undef on error.
+
+=proto int fprintf(FILE f, string fmt, ...args)
+
+Format and print a string to the given FILE handle. The FILE handles
+C<stdin>, C<stdout>, and C<stderr> are pre-defined.
+
+Return 0 on success, -1 on error.
+
+=proto int Fprintf(string filename, string fmt, ...args)
+
+Like fprintf but write to the given file name. The file is
+overwritten if it already exists. Return 0 on success, -1 on error.
+
+=proto string ftype(string path)
+
+Return the type of file at the given path. Type can be C<directory>, C<file>,
+C<character>, C<block>, C<fifo>, C<symlink> or C<socket>.
+Return undef on error.
+
+=proto string[] getdir(string dir)
+
+=proto string[] getdir(string dir, string pattern)
+
+Return the files in the given directory, as a sorted string array.
+Optionally filter the list by C<pattern> which is a glob and may
+contain the following special characters:
+
+=proto dirent[] getdirx(string dir)
+
+Return the files in the given directory as an array of structs, with
+the directories sort and coming first in the array followed by
+the sorted file names.
+Return undef on error.
+The C<dirent> struct is defined as follows:
+
+=over 4
+
+ typedef struct dirent {
+ string name;
+ string type; // "file", "directory", "other"
+ int hidden;
+ } dirent;
+
+=back
+
+=over 4
+
+=item ?
+
+Matches any single character.
+
+=item *
+
+Matches any sequence of zero or more characters.
+
+=item [chars]
+
+Matches any single character in chars. If chars contains a sequence of
+the form a-b then any character between a and b (inclusive) will
+match.
+
+=item \x
+
+Matches the character x.
+=item {a,b,...}
+
+Matches any of the strings a, b, etc.
+
+=back
+
+If the first character in a pattern is ``~'' then it refers to the
+home directory for the user whose name follows the ``~''. If the ``~''
+is followed immediately by ``/'' then the value of the HOME
+environment variable is used.
+
+=proto string getenv(string varname)
+
+Return the value of an environment variable if it exists and is of
+non-zero length, or return undef if it has zero length or does not
+exist.
+This allows you to say putenv("VAR=") and have getenv("VAR") return
+undef.
+
+=proto string getopt(string av[], string opts, string longopts[])
+
+Parse command-line arguments.
+This version recognizes the following types of short and long options
+in the av array:
+
+ - (leaves it and returns)
+ -- end of options
+ -a
+ -abcd
+ -r <arg>
+ -r<arg>
+ -abcr <arg>
+ -abcr<arg>
+ -r<arg> -R<arg>, etc.
+ --long
+ --long:<arg>
+ --long=<arg>
+ --long <arg>
+
+Short options are all specified in a single C<opts> string as follows:
+
+ d boolean option -d
+ d: required arg -dARG or -d ARG
+ d; required arg no space -dARG
+ d| optional arg no space -dARG or -d
+
+Long options are specified in the C<longopts> array (one option
+per element) as follows:
+
+ long boolean option --long
+ long: required arg --long=ARG or --long ARG
+ long; required arg no space --long=ARG
+ long| optional arg no space --long=ARG or --long
+
+The function returns the name of the next recognized option or
+undef if no more options exist.
+The global variable C<optind> is set to the next av[] index to
+process.
+If the option has no arg, C<optarg> is set to C<undef>.
+
+If an unrecognized option is seen, the empty string ("") is returned
+and the global variable C<optopt> is set to the name of the
+offending option (unless the option is a long option).
+
+This example shows a typical usage of both short and long options.
+
+ int debug_level, verbose;
+ string c, lopts[] = { "verbose" };
+
+ while (c = getopt(av, "d|v", lopts)) {
+ switch (c) {
+ case "d":
+ if (optarg) debug_level = (int)optarg;
+ break;
+ case "v":
+ case "verbose":
+ verbose = 1;
+ break;
+ default:
+ die("unrecognized option ${optopt}");
+ }
+ }
+
+=proto int getpid()
+
+Return the caller's process id.
+
+=proto void here()
+
+Output a message like "myfunc() in script.l:86" to stderr which
+contains the file name, line number, and currently executing function
+name.
+Typically used for debugging.
+
+=proto void insert(type &array[], int index, type element1 | type elements1[], ...)
+
+Insert one or more elements into C<array> before the element specified
+by C<index>.
+If C<index> is 0, the elements are inserted at the beginning of the
+array; this is what C<unshift()> does.
+If C<index> is -1 or larger than or equal to the number of elements in
+the array, the elements are inserted at the end; this is what C<push> does.
+You can insert single elements or arrays of elements.
+
+=proto int isalpha(string s)
+
+Return 1 if the given string contains only alphabetic characters, else
+return 0.
+An empty string also returns 0.
+
+=proto int isalnum(string s)
+
+Return 1 if the given string contains only alphabetic or digit characters, else
+return 0.
+An empty string also returns 0.
+
+=proto int isdigit(string s)
+
+Return 1 if the given string contains only digit characters, else
+return 0.
+An empty string also returns 0.
+
+=proto int isdir(string path)
+
+Return 1 if the given path exists and is a directory, else return 0.
+
+=proto int islink(string path)
+
+Return 1 if the given path exists and is a link, else return 0.
+
+=proto int islower(string s)
+
+Return 1 if the given string contains only lower-case alphabetic characters, else
+return 0.
+An empty string also returns 0.
+
+=proto int isreg(string path)
+
+Return 1 if the given path exists and is a regular file, else return 0.
+
+=proto int isspace(string buf)
+
+Return 1 if all characters in the argument are space characters, else
+return 0.
+An empty string also returns 0.
+
+=proto int isupper(string s)
+
+Return 1 if the given string contains only upper-case alphabetic characters, else
+return 0.
+An empty string also returns 0.
+
+=proto int iswordchar(string s)
+
+Return 1 if the given string contains only alphanumeric or connector
+punctuation characters (such as underscore), else return 0.
+An empty string also returns 0.
+
+=proto string join(string sep, type array[])
+
+Convert an array into a string by joining all of its elements by
+inserting sep between each pair.
+
+=proto keyType[] keys(valType hash{keyType})
+
+Return an array containing the keys of a given hash. Note that the
+return type depends on the argument type.
+
+=proto string lc(string s)
+
+Return a copy of the string that is in all lower case.
+
+=proto int length(string s)
+
+Return the number of characters in the given string.
+Returns 0 if the argument is C<undef>.
+
+=proto int length(type array[])
+
+Return the number of elements in the given array.
+Returns 0 if the argument is C<undef>.
+
+ for (i = 0; i < length(array); i++)
+
+=proto int length(valType hash{keyType})
+
+Return the number of key/value pairs in the given hash.
+Returns 0 if the argument is C<undef>.
+
+=proto int link(string sourcePath, string targetPath)
+
+Create a hard link from sourcePath to targetPath.
+Return 0 on success, -1 on error.
+
+=proto int lstat(string path, struct stat &buf)
+
+Call lstat(2) on C<path> and place the information in C<buf>.
+Return 0 on success, -1 on error.
+The C<struct stat> type is defined as follows:
+
+=over 4
+
+ struct stat {
+ int st_dev;
+ int st_ino;
+ int st_mode;
+ int st_nlink;
+ int st_uid;
+ int st_gid;
+ int st_size;
+ int st_atime;
+ int st_mtime;
+ int st_ctime;
+ string st_type;
+ };
+
+=back
+
+where C<st_type> is a string giving the type of file name, which will
+be one of file, directory, characterSpecial, blockSpecial, fifo, link,
+or socket.
+
+=proto int|float max(int|float, int|float)
+
+=proto int|float min(int|float, int|float)
+
+Return the maximum or minimum of two numbers. The return type is
+float if either of the arguments is a float, otherwise the return type
+is int.
+
+=proto int milli()
+
+Return the number of milliseconds since the currently executing
+script started.
+
+=proto void milli_reset()
+
+Reset the internal state for milli() to begin counting from 0 again.
+
+=proto int mkdir(string path)
+
+Create a directory at the given path. This creates all non-existing
+parent directories. The directories are created with mode 0775
+(rwxrwxr-x).
+Return 0 on success, -1 on error.
+
+=proto int mtime(string path)
+
+Return the modified time of path, or 0 to indicate error.
+
+=proto string normalize(string path)
+
+Return a normalized version of path. The pathname will be an absolute
+path with all "../" and "./" removed.
+
+=proto int ord(string c)
+
+Return the numeric value of the encoding (ASCII, Unicode) of the first character
+of C<c>, or -1 on error or if C<c> is the empty string.
+
+=proto int pclose(FILE f)
+
+=proto int pclose(FILE f, STATUS &s)
+
+Close an open pipe created by popen().
+Return 0 on success, -1 on error.
+See system() for details of the STATUS struct.
+
+=proto void perror()
+
+=proto void perror(string message)
+
+Print the error message corresponding to the last error from
+various L library calls.
+If C<message> is not undef, it is prepended to the error string
+with a ": ".
+
+=proto type pop(type &array[])
+
+Remove an element from the end of C<array>.
+Return undef if the array is already empty.
+
+=proto FILE popen(string cmd | argv[], string mode)
+
+=proto FILE popen(string cmd | argv[], string mode, void &stderr_callback(string cmd, FILE f))
+
+Open a file handle to a process running the command specified in
+C<argv[]> or C<cmd>. In the C<cmd> case, the command is split into
+arguments respecting Bourne shell style quoting.
+The returned FILE handle may be
+used to write to the command's input pipe or read from its output
+pipe, depending on the value of C<mode>. If write-only access is used
+("w"), then standard output for the pipeline is directed to the
+current standard output unless overridden by the command. If
+read-only access is used ("r"), standard input for the pipeline is
+taken from the current standard input unless overridden by the
+command.
+
+The optional third argument is a callback function that is
+invoked by Tcl's event loop when the command's stderr pipe has data
+available to be read.
+The second argument of the callback is a non-blocking FILE for the
+read end of this pipe.
+Care must be taken to ensure that the event loop is run often enough
+for the callback to reap data from the pipe often enough to avoid deadlock.
+In console apps, this may mean calling Tcl's C<update()> function.
+The pclose() function also invokes the callback, so it is guaranteed to
+be called at least once.
+
+If the third argument to C<popen> is C<undef>, the command's stderr
+output is ignored. Otherwise, unless re-directed by the command, any
+stderr output is passed through to the calling script's stderr and is
+not considered an error.
+
+If Tk is being used, there is a default callback that pops up a window
+with any output the command writes to stderr.
+
+Return the FILE handle on success, or undef on error.
+
+=proto int printf(string fmt, ...args)
+
+Format arguments and print to stdout, as in printf(3).
+Return 0 on success, -1 on error.
+
+=proto void push(type &array[], type element1 | type elements1[], ...)
+
+Push one or more elements onto the end of C<array>.
+You can insert single elements or arrays of elements.
+
+=proto string putenv(string var_fmt, ...args)
+
+Set an environment variable, overwriting any pre-existing value,
+using printf-like arguments:
+
+ putenv("VAR=val");
+ putenv("MYPID=%d", getpid());
+
+Return the new value or undef if var_fmt contains no "=".
+
+=proto int read(FILE f, string &buffer)
+
+=proto int read(FILE f, string &buffer, int numBytes)
+
+Read at most numBytes from the given FILE handle into the buffer, or
+read the entire file if numBytes == -1 or is omitted. Return the number of
+bytes read, -1 on error or EOF.
+
+=proto int rename(string oldpath, string newpath)
+
+Rename a file.
+Return 0 on success, -1 on error.
+
+=proto string require(string packageName)
+=proto string require(string packageName, string version)
+
+Find and load the given Tcl package packageName. Return the version
+string of the package loaded on success, and undef on error.
+The second form is used when only when the given version is acceptable.
+
+=proto int rmdir(string dir)
+
+Delete the given directory.
+Return 0 on success, -1 on error.
+
+=proto type shift(type &array[])
+
+Remove and return the element at the beginning of C<array>.
+Return undef if the array is already empty.
+
+=proto int size(string path)
+
+Return the size, in bytes, of the named file path, or -1 on error.
+
+=proto void sleep(float seconds)
+
+Sleep for C<seconds> seconds. Note that C<seconds> can be fractional to
+get sub-second sleeps.
+
+=proto type[] sort(type[] array)
+
+=proto type[] sort([decreasing: | increasing:], type[] array)
+
+=proto type[] sort([integer: | real: | ascii:], type[] array)
+
+=proto type[] sort(command: &compar, type[] array)
+
+Sort the array C<array> and return a new array of sorted elements.
+The first variation sorts the elements into ascending order, and does
+an integer, real, or ascii sort based on the type of C<array>. The
+second two variations show optional arguments that can be passed to
+change this behavior. The last variation shows how a custom compare
+function can be specified. The function must take two array elements
+of type T as arguments and return -1 if the first comes before the
+second in the sort order, +1 if the first comes after the second, and
+0 if the two are equal.
+
+=proto int spawn(string cmd)
+
+=proto int spawn(string cmd, STATUS &s)
+
+=proto int spawn(string argv[])
+
+=proto int spawn(string argv[], STATUS &s)
+
+=proto int spawn(cmd | argv[], FILE in, FILE out, FILE err)
+
+=proto int spawn(cmd | argv[], FILE in, FILE out, FILE err, STATUS &s)
+
+=proto int spawn(cmd | argv[], string in, FILE out, FILE err)
+
+=proto int spawn(cmd | argv[], string in, FILE out, FILE err, STATUS &s)
+
+=proto int spawn(cmd | argv[], string[] in, FILE out, FILE err)
+
+=proto int spawn(cmd | argv[], string[] in, FILE out, FILE err, STATUS &s)
+
+=proto int spawn(cmd | argv[], "input", "${outf}", "errors")
+
+=proto int spawn(cmd | argv[], "input", "${outf}", "errors", STATUS &s)
+
+Execute a command in background. All forms return either a process id or
+undef to indicate an error.
+In the error case the STATUS argument is set, otherwise it remains untouched
+and the status can be reaped by waitpid().
+
+See the system() function for information about the arguments.
+
+See the waitpid() function for information about waiting on the child.
+
+=proto string[] split(string s)
+
+=proto string[] split(/regexp/, string s)
+
+=proto string[] split(/regexp/, string s, int limit)
+
+Split a string into substrings.
+In the first variation, the string is split on whitespace, and any
+leading or trailing white space does not produce a null field in the result.
+This is useful when you just want to get at the things delimited
+by the white space:
+
+ split("a b c"); // returns {"a", "b", "c"}
+ split(" x y z "); // returns {"x", "y", "z"}
+
+In the second variation, the string is split using a regular expression
+as the delimiter:
+
+ split(/,/, "we,are,commas"); // returns {"we", "are", "commas"}
+ split(/xxx/, "AxxxBxxxC"); // returns {"A", "B", "C"}
+ split(/[;,]/, "1;10,20"); // returns {"1", "10", "20"}
+
+When a delimiter is used, split returns a null first field if the
+string begins with the delimiter, but if the string ends with the
+delimiter no trailing null field is returned. This provides
+compatibility with Perl's split:
+
+ split(/xx/, "xxAxxBxxCxx"); // returns {"", "A", "B", "C"}
+
+You can avoid the leading null fields in the result if you put a
+C<t> after the regular expression (to tell it to "trim" the result):
+
+ split(/xx/t, "xxAxxBxxCxx"); // returns {"A", "B", "C"}
+
+If a C<limit> argument is given, at most C<limit> substrings are returned
+(limit <= 0 means no limit):
+
+ split(/ /, "a b c d e f", 3); // returns {"a", "b", "c d e f"}
+
+To allow splitting on variables or function calls that start with
+C<m>, the alternate regular-expression-delimiter syntax
+is restricted:
+
+ split(m|/|, pathname); // "|" and most other punctuation -- ok
+ // but ( and ) as delimiters -- error
+ split(m); // splits the variable "m" -- ok
+ split(m(arg)); // splits the result of m(arg) -- ok
+
+Regular expressions, and the strings to split,
+both can contain unicode characters or binary data as well as ASCII:
+
+ split(/\0/, string_with_nulls); // split on null
+ split(/ש/, "זו השפה שלנו"); // unicode regexp and string
+
+=proto string sprintf(string fmt, ...args)
+
+Format arguments and return a formatted string like sprintf(3).
+Return undef on error.
+
+=proto int stat(string path, struct stat &buf)
+
+Call stat(2) on C<path> and place the information in C<buf>.
+Return 0 on success, -1 on error.
+See the lstat() command for the definition of C<struct stat>.
+
+=proto int strchr(string s, string c)
+
+Return the first index of c into s, or -1 if c is not found.
+
+=proto int strlen(string s)
+
+Return the string length.
+
+=proto int strrchr(string s, string c)
+
+Return the last index of c into s, or -1 if c is not found.
+
+=proto int symlink(string sourcePath, string targetPath)
+
+Create a symbolic link from sourcePath to targetPath.
+Return 0 on success, -1 on failure.
+
+=proto int system(string cmd)
+
+=proto int system(string cmd, STATUS &s)
+
+=proto int system(string argv[])
+
+=proto int system(string argv[], STATUS &s)
+
+=proto int system(cmd | argv[], string in, string &out, string &err)
+
+=proto int system(cmd | argv[], string in, string &out, string &err, STATUS &s)
+
+=proto int system(cmd | argv[], string[] in, string[] &out, string[] &err)
+
+=proto int system(cmd | argv[], string[] in, string[] &out, string[] &err, STATUS &s)
+
+=proto int system(cmd | argv[], FILE in, FILE out, FILE err);
+
+=proto int system(cmd | argv[], FILE in, FILE out, FILE err, STATUS &s);
+
+=proto int system(cmd | argv[], "input", "${outf}", "errors")
+
+=proto int system(cmd | argv[], "input", "${outf}", "errors", STATUS &s)
+
+Execute a command and wait for it to finish (see C<spawn()> for the
+async version).
+The command is executed using Tcl's C<exec> command, except that
+the single-command-string form requires bash-style quoting, not Tcl quoting,
+and the argv[] form must not be quoted at all.
+
+If the number of arguments is one or two, then the existing stdin,
+stdout, stderr channels are used.
+
+If the number of arguments is four or five, then the second, third,
+and fourth arguments specify stdin, stdout, stderr, respectively.
+Each can be a string variable or string array
+(a reference is required for stdout and stderr),
+a FILE variable which must be an open file handle, or
+a string literal which is interpreted as a file path name.
+If you want to specify a file name from a variable, use the string
+literal "${filename}".
+It is an error to both re-direct input/output in the command string
+and to specify the corresponding input/output argument; in such a
+case, the command is not run and C<undef> is returned.
+
+If stdout or stderr are sent to strings or string arrays and no output
+is produced, then C<out> or C<err> are C<undef> upon return.
+
+The optional last argument is a reference to the following structure:
+
+ typedef struct {
+ string argv[]; // args passed in
+ string path; // if defined, this is the path to the exe
+ // if undef, the executable was not found
+ int exit; // if defined, the process exited with this value
+ int signal; // if defined, the signal that killed the process
+ } STATUS;
+
+The global variable C<stdio_status> is also set.
+If the the command is a pipeline and a process in that pipeline fails,
+the returned status is for the first process that failed.
+
+If there is an error executing the command, or if the process
+is killed by a signal, undef is returned;
+otherwise, the return value is the
+process exit status (for a pipeline, the status of the first process
+that exited with error).
+
+Examples:
+
+ // No futzing with input/output, uses stdin/out/err.
+ ret = system(cmd);
+
+ // Same thing but no quoting issues, like execve(2).
+ ret = system(argv);
+
+ // Get detailed status.
+ unless (defined(ret = system(cmd, &status))) {
+ unless (defined(status.path)) {
+ warn("%s not found or bad perm\n", status.path);
+ }
+ if (defined(status.signal)) {
+ warn("%s killed with %d\n", status.argv[0], status.signal);
+ }
+ }
+
+ // Taking input and sending output to string arrays.
+ // The in_vec elements should not contain newlines and
+ // the out/err_vec elements will not contain newlines.
+ string in_vec[], out_vec[], err_vec[];
+ ret = system(cmd, in_vec, &out_vec, &err_vec);
+
+ // Taking input and sending output to files.
+ string outf = sprintf("/tmp/out%d", getpid());
+ ret = system(cmd, "/etc/passwd", "${outf}", "/tmp/errors");
+
+ // Using open file handles.
+ FILE in = popen("/some/producer/process", "r");
+ FILE out = popen("/some/consumer/process", "w");
+ FILE err = popen("cat > /dev/tty", "w");
+ ret = system(argv, buf, in, out, err, &status);
+ // error handling here
+ pclose(in, &status);
+ // error handling here
+ ...
+
+ // Mixing and matching.
+ ret = system(argv, buf, &out, "/tmp/errors", &status);
+
+=proto string trim(string s)
+
+Return a copy of the string that has been trimmed of any leading and
+trailing whitespace (spaces, tabs, newlines, and carriage returns).
+
+=proto string typeof(<variable>)
+
+Return the simple type name of the given variable.
+This is one of "int", "string", "poly", "widget", "array",
+"hash", or "struct";
+or if the variable's type is a typedef, the typedef name;
+or if the variable has a class type, the class name;
+of if the variable is really a function name, "function".
+
+=proto string uc(string s)
+
+Return a copy of the string that is in all upper case.
+
+=proto void undef(<array>[index])
+
+=proto void undef(<string>[index])
+
+=proto void undef(<hash>{index})
+
+=proto void undef(<variable>)
+
+In the first three forms, remove an array, string, or hash element
+from the specified variable.
+In the last form, sets the variable to undef.
+When setting a hash or array to undef, all of its old elements are
+freed (unless they were shared with some other variable).
+
+=proto int unlink(string path)
+
+Delete the named file.
+Return 0 on success, -1 on failure.
+
+=proto void unshift(type &array[], type element1 | type elements1[], ...)
+
+Add one or more elements onto the beginning of C<array>.
+You can insert single elements or arrays of elements.
+
+=proto int waitpid(int pid, STATUS &status, int nohang)
+
+Given a pid returned by spawn(), wait for it, and place the exit information
+in the (optional) STATUS struct.
+If C<pid> is -1, return any process that has exited or return -1 if
+no more child processes exist;
+otherwise return C<pid> or -1 on error.
+If C<nohang> is non-zero, returns -1 if the process does not exist or other
+error, returns 0 if the process exists and has not exited, and
+returns C<pid> and updates C<status> if the process has exited.
+
+=proto int wait(STATUS &status)
+
+Same as C<waitpid(-1, &status, 0)>.
+
+=proto void warn(string fmt, ...args)
+
+Output a printf-like message to stderr.
+If fmt does not end with a newline, append
+" in <filename> at line <linenum>.\n"
+
+=proto int write(FILE f, string buffer, int numBytes)
+
+Write at most numBytes to the given FILE handle from the buffer.
+Return the number of bytes written, or -1 on error.
+
+=back
+
+=head1 MANIPULATING COMPLEX STRUCTURES
+
+L has built-in operators for turning complex data structures into
+something else: (expand), and (tcl).
+
+(expand) takes an array of things and pushes them all onto the
+run-time stack to call a function that expects such a list.
+It is identical to Tcl's {*}:
+
+ void foo(string a, string b, string c);
+
+ string v[] = { "one", "two", "three" };
+
+ foo((expand)v); // passes three string arguments to foo
+
+It expands only one level, so if the array contains three hashes
+instead of three strings, (expand)v passes three hashes to foo.
+(expand) works with structs too.
+
+If you have this structure:
+
+ struct {
+ int i[];
+ int h{string};
+ } foo = {
+ { 0, 1, 2, 3, },
+ { "big" => 100, "medium" => 50, "small" => 10 }
+ };
+
+And you use (expand) when passing these as arguments:
+
+ func((expand)foo);
+
+you need a function definition like this:
+
+ void func(int nums[], int sizes{string})
+ {
+ }
+
+There is no way to recursively expand at this time.
+
+(tcl) is used to pass a single string to a Tcl proc for processing.
+It puts in the Tcl quotes. So
+
+ (tcl)foo
+
+is
+
+ 0 1 2 3 { big 100 medium 50 small 10 }
+
+Another example:
+
+ string v[] = { "a b c", "d", "e" };
+ string arg = (tcl)v; // arg is "{a b c} d e"
+
+Sometimes you need to assign a group of variables all at once.
+You can do this by assigning a list of values to a list of variables:
+
+ {a, b, c} = {1, 2, 3};
+
+This is more than a short-cut for the three individual assignments.
+The entire right-hand side gets evaluated first, then the assignment
+occurs, so you can use this to swap the value of two variables:
+
+ {a, b} = {b, a};
+
+If you want to ignore one of the elements in the right-hand list, you
+can put C<undef> in the corresponding element of left-hand list
+instead of having to use a dummy variable:
+
+ {a, undef, b} = {1, 2, 3}; // a gets 1, b gets 3
+
+If the right-hand side list isn't as long as the left-hand list,
+the stragglers get C<undef>:
+
+ {a, b, c} = {1, 2}; // a gets 1, b gets 2, c gets undef
+
+These composite assignments also work with arrays or structs
+on the right-hand side:
+
+ int dev, inode;
+ struct stat st;
+
+ lstat(file, &st);
+ {dev, inode} = st; // pull out first two fields of the stat struct
+
+ {first, second} = split(line); // get first two words in line
+
+=head1 REGULAR EXPRESSIONS
+
+L's regular expression support is based on the PCRE (Perl Compatible
+Regular Expressions) library L<http://www.pcre.org>. The basics are
+documented here but for more extensive documentation please see
+L<http://www.pcre.org/pcre.txt>.
+
+=over 4
+
+=item Simple matching
+
+ if (s =~ /foo/) { ... } // true if s contains "foo"
+ if (s !~ /foo/) { ... } // false if s contains "foo"
+
+The C<//> matching operator must be used in conjunction with C<=~> and
+C<!~> to tell L what variable to look at.
+
+If your regular expression contains forward slashes, you must
+escape them with a backslash, or you can use an alternate
+syntax where almost any punctuation becomes the delimiter:
+
+ if (s =~ m|/path/to/foo|) { ... }
+ if (s =~ m#/path/to/foo#) { ... }
+ if (s =~ m{/path/to/foo}) { ... }
+
+In the last case, note that the end delimiter } is different
+than the start delimiter { and you must escape all
+uses of either delimiter inside the regular expression.
+
+=item Simple substitution
+
+ x =~ s/foo/bar/; // replaces foo with bar in x
+ x =~ s/foo/bar/g; // replaces ALL INSTANCES of foo with bar in x
+ x =~ s/foo/bar/i; // does a case-insensitive search
+
+This form also has an alternate syntax:
+
+ x =~ s{foo}{bar};
+ x =~ s{foo}/bar/;
+
+=item More complex regular expressions
+
+ . a single character
+ \s a whitespace character (space, tab, newline, ...)
+ \S non-whitespace character
+ \d a digit (0-9)
+ \D a non-digit
+ \w a word character (a-z, A-Z, 0-9, _)
+ \W a non-word character
+ [aeiou] matches a single character in the given set
+ [^aeiou] matches a single character outside the given set
+ (foo|bar|baz) matches any of the alternatives specified
+
+ ^ start of string
+ $ end of string
+
+Quantifiers can be used to specify how many of the previous thing you
+want to match on, where "thing" means either a literal character, one
+of the meta characters listed above, or a group of characters or
+meta characters in parentheses.
+
+ * zero or more of the previous thing
+ + one or more of the previous thing
+ ? zero or one of the previous thing
+ {3} matches exactly 3 of the previous thing
+ {3,6} matches between 3 and 6 of the previous thing
+ {3,} matches 3 or more of the previous thing
+
+Some brief examples:
+
+ /^\d+/ string starts with one or more digits
+ /^$/ nothing in the string (start and end are adjacent)
+ /(\d\s){3}/ a three digits, each followed by a whitespace
+ character (eg "3 4 5 ")
+ /(a.)+/ matches a string in which every odd-numbered letter
+ is a (eg "abacadaf")
+
+ // This loop reads from stdin, and prints non-blank lines.
+ string buf;
+ while (buf = <stdin>) {
+ unless (buf =~ /^$/) puts(buf);
+ }
+
+=item Unicode
+
+Both regular expressions and the strings they are matched against
+can contain unicode characters or binary data.
+This example looks for a null byte in a string:
+
+ if (s =~ /\0/) puts("has a null");
+
+=item Parentheses for capturing
+
+As well as grouping, parentheses serve a second purpose. They can be
+used to capture the results of parts of the regexp match for later use.
+The results end up in C<$1>, C<$2> and so on, and these capture
+variables are available in the substitution part of the operator
+as well as afterward.
+You can use up to nine captures ($1 - $9).
+
+ // Break an e-mail address into parts.
+ if (email =~ /([^@]+)@(.+)/) {
+ printf("Username is %s\n", $1);
+ printf("Hostname is %s\n", $2);
+ }
+
+ // Use $1,$2 in the substitution to swap two words.
+ str =~ s/(\w+) (\w+)/$2 $1/;
+
+Capturing has a limitation. If you have more than one regexp with
+captures in an expression, the last one evaluated sets C<$1>, C<$2>,
+etc.
+
+ // This loses email1's captures.
+ if ((email1 =~ /([^@]+)@(.+)/) && (email2 =~ /([^@]+)@(.+)/)) {
+ printf("Username is %s\n", $1);
+ printf("Hostname is %s\n", $2);
+ }
+
+In situations like this, care must be taken because the evaluation
+order of sub-expressions generally is undefined. But this example is
+an exception because the && operator always evaluates its operands in
+order.
+
+=back
+
+=head1 CLASSES
+
+L has a C<class> abstraction for encapsulating data and
+functions that operate on that data. L classes are simpler than
+full-blown object-oriented programming (there is no inheritance), but
+they get you most of the way there.
+
+You declare a class like this:
+
+ class myclass
+ {
+ ....
+ }
+
+The name C<myclass> becomes a global type name, allowing you to
+declare an C<object> of C<myclass>:
+
+ myclass obj;
+
+You can declare both variables and functions inside the class. These
+all must be declared inside one class declaration at the global scope.
+You cannot have one class declaration that has some of the
+declarations and another with the rest, and you cannot nest classes
+inside of functions or other classes.
+
+Inside the class, you can have C<class variables> and
+C<instance variables>. Class variables are associated with the class
+and not the individual objects that you allocate, so there is only one
+copy of each. Instance variables get attached to each object.
+
+ class myclass
+ {
+ /* Class variables. */
+ public string pub_var;
+ private int num = 0;
+
+ /* Instance variables. */
+ instance {
+ public string inst_var;
+ private int n;
+ }
+ ...
+ }
+
+All declarations (except the constructors and destructors) must be
+qualified with either C<public> or C<private> to say whether the name
+is visible at the global scope or only inside the class.
+
+A class can have one or more constructors and destructors but they are optional.
+Inside a constructor, the variable C<self> is automatically declared
+as the object being constructed. A constructor should return
+C<self>, although it also could return C<undef> to signal an error.
+A destructor must be declared with C<self> as the first parameter.
+
+ constructor myclass_new()
+ {
+ n = num++;
+ return (self);
+ }
+ destructor myclass_delete(myclass self) {}
+
+If omitted, L creates a default constructor or destructor named
+C<classname_new> and C<classname_delete>. Although not shown in this
+example, you can declare them with any number of parameters, just like
+regular functions.
+
+A C<public> class member function is visible at the global scope, so
+its name must not clash with any other global function or variable. A
+private member function is local to the class.
+
+The first parameter to each public function must be C<self>, the
+object being operated on. Private functions do not explicitly include
+C<self> in the parameter list because it is implicitly passed by the
+compiler.
+
+ private void bump_num()
+ {
+ ++n;
+ }
+ public int myclass_getnum(myclass self)
+ {
+ bump_num();
+ return (n);
+ }
+
+To create an object, you must call a constructor, because just
+declaring the variable does not allocate anything:
+
+ myclass obj;
+
+ obj = myclass_new();
+
+To operate on an object, you call one of its public member functions,
+passing the object as the first argument:
+
+ int n = myclass_getnum(obj);
+
+L allows you to directly access public class and instance variables
+from outside the class. To get a class variable, you dereference the
+class name (you must use ->):
+
+ string s = myclass->pub_var;
+
+To get a public instance variable, you dereference the object whose
+data you want to access:
+
+ string s = obj->inst_var;
+
+Once you free an object
+
+ myclass_delete(obj);
+
+you must be careful to not use C<obj> again unless you assign a
+new object to it, or else a run-time error will result.
+
+=head1 DEBUGGING
+
+=head2 Function Tracing
+
+L function tracing is controlled with #pragma statements, _attribute
+clauses in function declarations, command-line options,
+environment variables, and a run-time API.
+When a function is marked for tracing,
+by default its entry and exit are traced to stderr,
+but you can use your own custom hooks
+to do anything you want.
+
+A #pragma takes a comma-separated list of attribute assignments:
+
+ #pragma fntrace=on
+ string myfunc(int arg)
+ {
+ return("return value");
+ }
+ void main()
+ {
+ myfunc(123);
+ }
+
+When this program runs, traces go to stderr with a millisecond
+timestamp, the function name, parameter values, and return value:
+
+ 1: enter main
+ 1: enter myfunc: '123'
+ 2: exit myfunc: '123' ret 'return value'
+ 3: exit main
+
+The allowable tracing attributes are as follows.
+
+=over 4
+
+=item B<fntrace=on | entry | exit | off>
+
+Enable tracing on both function entry and exit, entry only, exit only,
+or disable tracing altogether.
+
+=item B<trace_depth=n>
+
+Trace only to a maximum call depth of n.
+
+=item B<fnhook=myhook>
+
+Use myhook as the trace hook (see below).
+
+=back
+
+A #pragma stays in effect until overridden by another #pragma or by
+an _attribute clause in a function declaration which provides
+per-function tracing control:
+
+ void myfunc2(int arg) _attribute (fntrace=off) // don't trace this one
+ {
+ }
+
+Tracing also can be controlled with command-line options:
+
+=over 4
+
+=item B<--fntrace = <on | entry | exit | off>>
+
+Enable tracing of all functions on both function entry and exit, entry
+only, exit only, or disable all tracing.
+This overrides any #pragma or _attribute clauses in the program.
+
+=item B<--trace-out=stdin | stderr | filename | host:port>
+
+Send default trace output to stdin, stderr, a file, or a TCP socket.
+
+=item B<--trace-files=colon-separated list of glob | /regexp/>
+
+Enable tracing of all functions in the given files, specified
+either as globs or regular expressions.
+A + before a glob or regexp enables tracing, a - disables, and no
++ or - is like having a +, except that
+the leading one is special: if omitted,
+it means trace exactly what is specified,
+overriding any #pragmas or _attribute clauses in the code,
+by first removing all traces and then processing the file list.
+
+=item B<--trace-funcs=colon-separated list of glob | /regexp/>
+
+Like trace-files but specifies functions.
+
+=item B<--fnhook=myhook>
+
+Use C<myhook> as the trace hook, overriding any #pragmas in the program.
+
+=item B<--trace-script=script.l | <L code>>
+
+Get the trace hook from a file, or use the given L code (see below).
+
+=back
+
+Some examples:
+
+ # Trace all functions
+ $ L --fntrace=on myscript.l
+
+ # Trace only foo
+ $ L --trace-funcs=foo myscript.l
+
+ # Trace foo in addition to what the source marks for tracing
+ $ L --trace-funcs=+foo myscript.l
+
+ # Trace all functions except foo
+ $ L --trace-funcs=*:-foo myscript.l
+ # This does it too
+ $ L --fntrace=on --trace-funcs=-foo myscript.l
+
+Environment variables also can control tracing and take precedence
+over the other ways above:
+
+ L_TRACE_ALL=on | entry | exit | off
+ L_TRACE_OUT=stdin | stderr | filename | host:port
+ L_TRACE_FILES=colon-separated list of glob | /regexp/
+ L_TRACE_FUNCS=colon-separated list of glob | /regexp/
+ L_TRACE_DEPTH=n
+ L_TRACE_HOOK=myhook
+ L_TRACE_SCRIPT=script.l | <L code>
+
+Things in L_TRACE_FUNCS are applied after things in L_TRACE_FILES.
+As with the command-line options, they also can begin with + or - to
+add or subtract from what is specified elsewhere.
+
+As a short-cut,
+
+ L_TRACE=stdin | stderr | filename | host:port
+
+traces all functions and sets the trace output location.
+
+More examples:
+
+ # Trace all files except foo.l
+ L_TRACE_FILE=*:-foo.l L myscript.l
+
+ # Trace main() and buggy() in addition to whatever is marked
+ # for tracing with #pragmas or _attribute clauses in the code.
+ L_TRACE_FUNCS=+main:buggy L myscript.l
+
+ # Trace *only* main() and buggy().
+ L_TRACE_FUNCS=main:buggy L myscript.l
+
+There also is a run-time API that takes a hash of named arguments
+analogous to those above:
+
+ Ltrace({ "fntrace" => "on",
+ "fnhook_out" => "myhook",
+ "trace_depth" => 3,
+ "trace_out" => "tracing.out",
+ "trace_files" => "foo.l",
+ "trace_funcs" => "+main:buggy" });
+
+To use your own tracing function, specify C<fnhook> in any of the
+above ways.
+Your hook is called on function entry and exit instead of
+the default hook.
+Its prototype must look like this:
+
+ void myhook(int pre, poly argv[], poly ret);
+
+where pre is 1 when your hook is called upon function entry and 0 when
+called upon exit, argv contains the function's arguments
+(argv[0] is the function name; argv[1] is the first
+parameter), and ret is the return value (exit hook only; it is undef
+for entry).
+
+If you use your own hook and then want to go back to the default,
+set C<fnhook=def>.
+
+To avoid infinite recursion, during the call of a hook, further calls
+into the hook are disabled. Also, functions defined as hooks, and the
+L library functions, are not traced.
+
+The trace-script attribute is a useful way to provide your own hook:
+
+ L_TRACE_SCRIPT=my-trace-hook.l // filename must end in .l
+ L_TRACE_SCRIPT=<L code>
+
+In the latter case, the L code gets wrapped in a function like this:
+
+ void L_fn_hook(int pre, poly av[], poly ret)
+ {
+ ...code from L_TRACE_SCRIPT...
+ }
+
+and C<L_fn_hook> is used as the default trace hook.
+
+As one example of where this is useful: say you are trying to find
+whether the function C<foo> is ever called with the first argument of 123,
+and if so, to print all the arguments:
+
+ L_TRACE_FUNCS=foo L_TRACE_SCRIPT='if (av[0]==123) puts(av)' L myscript.l
+
+=head1 EXAMPLE CODE
+
+=head2 shapes.l
+
+This is something we hand to our customers to see what "shape"
+their source trees have.
+
+ #!/usr/bin/bk tclsh
+ /*
+ * Determine the files/size of each directory under a bk repository.
+ * Optionally transform the directory names to obscure their structure.
+ *
+ * The idea is that you can run this script like this:
+ *
+ * bk tclsh shapes.l <path_to_root_of_repo>
+ *
+ * and get a list of directories with their sizes and number of files in
+ * each of them. Save the output, then run it again with -o:
+ *
+ * bk tclsh shapes.l -o <path_to_root_of_repo>
+ *
+ * and send the output to BitMover.
+ *
+ * The names of all the directories will be rot13'd and sorted (since
+ * sort is a destructive transform, it makes it harder to reverse the
+ * rot13). This is a weak form of obfuscation, but it lets BitMover
+ * work with the directory structure without inadvertedly learning
+ * about the client's projects.
+ *
+ * The line numbers at the beginning is so that we can talk about a certain
+ * directory by number without BitMover knowing the name of the directory.
+ *
+ * ob@dirac.bitmover.com|src/contrib/shapes.l|20100723224240|23777
+ *
+ */
+
+ string obscure(string s); // pathname to no-IP-leak pathname
+ string pp(float n); // pretty print a number, like df -h
+ string rot13(string str); // if you don't know, you don't know
+
+ int
+ main(int ac, string[] av)
+ {
+ int size, files, maxlen, n;
+ int do_obscure = 0;
+ string fn, root, dir, d, ob;
+ FILE f;
+ struct stat sb;
+ struct dirstats {
+ int files;
+ int size;
+ int total_files;
+ int total_size;
+ } dirs{string};
+
+ dir = ".";
+ if (ac == 3) {
+ if (av[1] == "-o") {
+ do_obscure = 1;
+ } else {
+ fprintf(stderr, "usage: %s [-o] [<dir>]\n", av[0]);
+ exit(1);
+ }
+ dir = av[2];
+ } else if (ac == 2) {
+ if (av[1] == "-o") {
+ do_obscure = 1;
+ dir = ".";
+ } else {
+ dir = av[1];
+ }
+ } else if (ac > 3) {
+ fprintf(stderr, "usage: %s [-o] [<dir>]\n", av[0]);
+ exit(1);
+ }
+ if (chdir(dir)) {
+ fprintf(stderr, "Could not chdir to %s\n", dir);
+ exit(1);
+ }
+ root = `bk root`;
+ if (root == "") {
+ fprintf(stderr, "Must be run in a BitKeeper repository\n");
+ exit(1);
+ }
+ if (chdir(root)) {
+ fprintf(stderr, "Could not chdir to %s\n", root);
+ exit(1);
+ }
+
+ size = 0;
+ files = 0;
+ f = popen("bk sfiles", "r");
+ while (defined(fn = <f>)) {
+ dir = dirname(fn);
+ if (dir == "SCCS") {
+ dir = ".";
+ } else {
+ // remove SCCS and obscure
+ dir = dirname(dir);
+ }
+ unless (defined(dirs{dir})) dirs{dir} = {0, 0, 0, 0};
+ if (maxlen < length(dir)) maxlen = length(dir);
+ dirs{dir}.files++;
+ files++;
+ if (lstat(fn, &sb)) {
+ fprintf(stderr, "Could not stat %s\n", fn);
+ continue;
+ }
+ dirs{dir}.size += sb.st_size;
+ size += sb.st_size;
+ // add our size/file count to each parent dir
+ for (d = dirname(dir); d != "."; d = dirname(d)) {
+ unless (defined(dirs{d})) dirs{d} = {0,0,0,0};
+ dirs{d}.total_size += sb.st_size;
+ dirs{d}.total_files++;
+ }
+ dirs{"."}.total_size += sb.st_size;
+ dirs{"."}.total_files++;
+ }
+ close(f);
+ // now print it
+ printf(" N | %-*s | FILES | SIZE | T_FILES | T_SIZE \n",
+ maxlen, "DIRS");
+ n = 1;
+ foreach (dir in sort(keys(dirs))) {
+ ob = dir;
+ if (do_obscure) {
+ ob = obscure(dir);
+ }
+ if (dirs{dir}.total_files > 0) {
+ printf("%5d | %-*s | %5d | %7s | %7s | %7s\n",
+ n, maxlen,
+ ob, dirs{dir}.files, pp(dirs{dir}.size),
+ dirs{dir}.total_files, pp(dirs{dir}.total_size));
+ } else {
+ printf("%5d | %-*s | %5d | %7s | %7s | %7s\n",
+ n, maxlen,
+ ob, dirs{dir}.files, pp(dirs{dir}.size),
+ "","");
+ }
+ n++;
+ }
+ printf("TOTAL: %u files, %s\n",
+ dirs{"."}.total_files, pp(dirs{"."}.total_size));
+ return (0);
+ }
+
+ /* Pretty print a number */
+ string
+ pp(float n)
+ {
+ int i;
+ float num = (float)n;
+ string sizes[] = {"b", "K", "M", "G", "T"};
+
+ for (i = 0; i < 5; i++) {
+ if (num < 1024.0) return (sprintf("%3.2f%s", num, sizes[i]));
+ num /= 1024.0;
+ }
+ }
+
+ /* Table for rot13 function below */
+ string rot13_table{string} = {
+ "A" => "N", "B" => "O", "C" => "P", "D" => "Q", "E" => "R", "F" => "S",
+ "G" => "T", "H" => "U", "I" => "V", "J" => "W", "K" => "X", "L" => "Y",
+ "M" => "Z", "N" => "A", "O" => "B", "P" => "C", "Q" => "D", "R" => "E",
+ "S" => "F", "T" => "G", "U" => "H", "V" => "I", "W" => "J", "X" => "K",
+ "Y" => "L", "Z" => "M", "a" => "n", "b" => "o", "c" => "p", "d" => "q",
+ "e" => "r", "f" => "s", "g" => "t", "h" => "u", "i" => "v", "j" => "w",
+ "k" => "x", "l" => "y", "m" => "z", "n" => "a", "o" => "b", "p" => "c",
+ "q" => "d", "r" => "e", "s" => "f", "t" => "g", "u" => "h", "v" => "i",
+ "w" => "j", "x" => "k", "y" => "l", "z" => "m",
+ };
+
+ /* rot13 a string */
+ string
+ rot13(string str)
+ {
+ int i;
+ string ret = "";
+
+ for (i = 0; i < length(str); i++) {
+ ret .= rot13_table{str[i]};
+ }
+ return (ret);
+ }
+
+ /*
+ * Print an obscured version of the string
+ * rot13 + sort
+ */
+ string
+ obscure(string s)
+ {
+ string p;
+ string[] ret;
+ string[] sp = split(s, "/");
+
+ foreach (p in sp) {
+ push(&ret, rot13(join("", lsort(split(p, "")))));
+ }
+ return (join("/", ret));
+ }
+
+=head2 pod2html.l
+
+This is an L implementation of pod2html. Pretty stripped down but slightly
+prettier than the Perl pod2html.
+
+ int
+ main(int ac, string av[])
+ {
+ FILE f;
+ int i, ul;
+ int space = 0, dd = 0, p = 0, pre = 0, table = 0;
+ string head, buf, tmp, title, trim, all[];
+
+ // lint
+ if (0) ac++;
+
+ /*
+ * -t<title> or --title=<title>
+ */
+ for (i = 1; defined(av[i]) && (av[i] =~ /^-/); i++) {
+ if (av[i] == "--") {
+ i++;
+ break;
+ }
+ if ((av[i] =~ /--title=(.*)/) || (av[i] =~ /-t(.*)/)) {
+ title = $1;
+ } else {
+ die("usage: ${av[0]} [--title=whatever]");
+ }
+ }
+ if (!defined(av[i]) ||
+ defined(av[i+1]) || !defined(f = fopen(av[i], "r"))) {
+ die("usage: ${av[0]} filename");
+ }
+ unless (defined(title)) title = av[i];
+
+ header(title);
+
+ /*
+ * Load up the whole file in all[] and spit out the index.
+ */
+ puts("<ul>");
+ ul = 1;
+ while (defined(buf = <f>)) {
+ push(&all, buf);
+ if (buf =~ /^=head(\d+)\s+(.*)/) {
+ i = (int)$1;
+ while (ul > i) {
+ puts("</ul>");
+ ul--;
+ }
+ while (i > ul) {
+ puts("<ul>");
+ ul++;
+ }
+ tmp = $2;
+ tmp =~ s/\s+/_/g;
+ buf =~ s/^=head(\d+)\s+//;
+ puts("<li><a href=\"#${tmp}\">${buf}</a></li>");
+ }
+ }
+ while (ul--) puts("</ul>");
+ fclose(f);
+
+ /*
+ * Now walk all[] and process the markup. We currently handle:
+ * =head%d title
+ * =over
+ * =item name
+ * =proto return_type func(args)
+ * =back
+ * <blank line>
+ * B<bold this>
+ * C<some code>
+ * I<italics>
+ */
+ for (i = 0; i <= length(all); i++) {
+ buf = inline(all[i]);
+ if (buf =~ /^=head(\d+)\s+(.*)/) {
+ if ((int)$1 == 1) puts("<HR>");
+ tmp = $2;
+ tmp =~ s/\s+/_/g;
+ printf("<H%d><a name=\"%s\">%s</a></H%d>\n",
+ $1, tmp, $2, $1);
+ } else if (buf =~ /^=over/) {
+ puts("<dl>");
+ } else if (buf =~ /^=item\s+(.*)/) {
+ if (dd) {
+ puts("</dd>");
+ dd--;
+ }
+ puts("<dt><strong>${$1}</strong></dt><dd>");
+ dd++;
+ } else if (buf =~ /^=proto\s+([^ \t]+)\s+(.*)/) {
+ if (dd) {
+ puts("</dd>");
+ dd--;
+ }
+ puts("<dt><b>${$1} ${$2}</b></dt><dd>");
+ dd++;
+ } else if (buf =~ /=table/) {
+ } else if (buf =~ /^=back/) {
+ if (dd) {
+ puts("</dd>");
+ dd--;
+ }
+ puts("</dl>");
+ } else if (buf =~ /^\s*$/) {
+ if (p) {
+ puts("</p>");
+ p = 0;
+ }
+ if (pre) {
+ /*
+ * If we see a blank line in a preformatted
+ * block, we don't want to stop the pre
+ * unless the next line is not indented.
+ * So peek ahead.
+ */
+ if (defined(buf = all[i+1]) && (buf =~ /^\s/)) {
+ puts("");
+ continue;
+ }
+ puts("</pre>");
+ pre = 0;
+ trim = undef;
+ }
+ space = 1;
+ } else {
+ if (space) {
+ if (buf =~ /^(\s+)[^ \t]+/) {
+ trim = $1;
+ puts("<pre>");
+ pre = 1;
+ } else {
+ puts("<p>");
+ p = 1;
+ }
+ space = 0;
+ }
+ if (defined(trim)) buf =~ s/^${trim}//;
+ puts(buf);
+ }
+ }
+ puts("</body></html>");
+ return (0);
+ }
+
+ /*
+ * header and style sheet
+ */
+ void
+ header(string title)
+ {
+ string head = <<EOF
+ <html>
+ <head>
+ <title>${title}</title>
+ <style>
+ pre {
+ background: #eeeedd;
+ border-width: 1px;
+ border-style: solid solid solid solid;
+ border-color: #ccc;
+ padding: 5px 5px 5px 5px;
+ font-family: monospace;
+ font-weight: bolder;
+ }
+ body {
+ padding-left: 10px;
+ }
+ dt {
+ font-size: large;
+ }
+ </style>
+ </head>
+ <body>
+ EOF
+ puts(head);
+ puts("<h1>${title}</h1>");
+ }
+
+ /*
+ * Process B<bold>, C<code>, I<italic>, F<italic>, L<link>, S<non-breaking>.
+ * This will handle nested stuff like C<if (!I<condition>)>
+ * but dies if there are nested ones of the same type.
+ */
+ string
+ inline(string buf)
+ {
+ string c, prev, result, link, stack[];
+ int B = 0, C = 0, I = 0, L = 0, S = 0;
+
+ foreach (c in buf) {
+ if ((c == "<") && defined(prev)) {
+ if (prev == "B") {
+ if (B++) die("Nested B<> unsupported: ${buf}");
+ result[END] = "";
+ result .= "<B>";
+ push(&stack, "B");
+ } else if (prev == "C") {
+ if (C++) die("Nested C<> unsupported: ${buf}");
+ result[END] = "";
+ result .= "<CODE>";
+ push(&stack, "CODE");
+ } else if (prev == "I" || prev == "F") {
+ if (I++) die("Nested I<> unsupported: ${buf}");
+ result[END] = "";
+ result .= "<I>";
+ push(&stack, "I");
+ } else if (prev == "L") {
+ if (L++) die("Nested L<> unsupported: ${buf}");
+ result[END] = "";
+ result .= "<a href=\"";
+ link = "";
+ push(&stack, "L");
+ } else if (prev == "S") {
+ if (S++) die("Nested S<> unsupported: ${buf}");
+ result[END] = "";
+ push(&stack, "S");
+ } else {
+ result .= "&lt;";
+ prev = c;
+ }
+ } else if ((c == ">") && length(stack)) {
+ c = pop(&stack);
+ if (c == "B") {
+ B--;
+ } else if (c == "CODE") {
+ C--;
+ } else if (c == "I") {
+ I--;
+ } else if (c == "L") {
+ L--;
+ result .= "\">${link}</a>";
+ c = undef;
+ } else {
+ S--;
+ c = undef;
+ }
+ if (defined(c)) {
+ result .= "</" . c . ">";
+ }
+ prev = undef;
+ } else {
+ if (S && isspace(c)) {
+ result .= "&nbsp;";
+ } else if (c == "<") {
+ result .= "&lt;";
+ } else if (c == ">") {
+ result .= "&gt;";
+ } else {
+ result .= c;
+ }
+ if (L) link .= c;
+ prev = c;
+ }
+ }
+ return (result);
+ }
diff --git a/doc/L/pod2html.l b/doc/L/pod2html.l
new file mode 100755
index 0000000..38ab3a4
--- /dev/null
+++ b/doc/L/pod2html.l
@@ -0,0 +1,253 @@
+#!../../unix/tclsh
+
+int
+main(string av[])
+{
+ FILE f;
+ int i, ul;
+ int space = 0, dd = 0, p = 0, pre = 0;
+ string buf, c, tmp, title, trim, all[];
+
+ /*
+ * -t<title> or --title=<title>
+ */
+ while (c = getopt(av, "t:", {"title:"})) {
+ switch (c) {
+ case "t":
+ case "title":
+ title = optarg;
+ break;
+ }
+ }
+ unless (av[optind] && (f = fopen(av[optind], "r"))) {
+ die("usage: ${av[0]} filename");
+ }
+ unless (title) title = av[optind];
+
+ header(title);
+
+ /*
+ * Load up the whole file in all[] and spit out the index.
+ */
+ puts("<ul>");
+ ul = 1;
+ while (buf = <f>) {
+ push(&all, buf);
+ if (buf =~ /^=head(\d+)\s+(.*)/) {
+ i = (int)$1;
+ while (ul > i) {
+ puts("</ul>");
+ ul--;
+ }
+ while (i > ul) {
+ puts("<ul>");
+ ul++;
+ }
+ tmp = $2;
+ tmp =~ s/\s+/_/g;
+ buf =~ s/^=head(\d+)\s+//;
+ puts("<li><a href=\"#${tmp}\">${buf}</a></li>");
+ }
+ }
+ while (ul--) puts("</ul>");
+ fclose(f);
+
+ /*
+ * Now walk all[] and process the markup. We currently handle:
+ * =head%d title
+ * =over
+ * =item name
+ * =proto return_type func(args)
+ * =back
+ * <blank line>
+ * B<bold this>
+ * C<some code>
+ * I<italics>
+ */
+ // The <= is intentional to run an empty string through at the end
+ // to kick out any final </pre> etc.
+ for (i = 0; i <= length(all); i++) {
+ buf = inline(all[i]);
+ if (buf =~ /^=head(\d+)\s+(.*)/) {
+ if ((int)$1 == 1) puts("<HR>");
+ tmp = $2;
+ tmp =~ s/\s+/_/g;
+ printf("<H%d><a name=\"%s\">%s</a></H%d>\n",
+ $1, tmp, $2, $1);
+ } else if (buf =~ /^=over/) {
+ puts("<dl>");
+ } else if (buf =~ /^=item\s+(.*)/) {
+ if (dd) {
+ puts("</dd>");
+ dd--;
+ }
+ puts("<dt><strong>${$1}</strong></dt><dd>");
+ dd++;
+ } else if (buf =~ /^=proto\s+([^ \t]+)\s+(.*)/) {
+ if (dd) {
+ puts("</dd>");
+ dd--;
+ }
+ puts("<dt><b>${$1} ${$2}</b></dt><dd>");
+ dd++;
+ } else if (buf =~ /^=back/) {
+ if (dd) {
+ puts("</dd>");
+ dd--;
+ }
+ puts("</dl>");
+ } else if (buf =~ /^\s*$/) {
+ if (p) {
+ puts("</p>");
+ p = 0;
+ }
+ if (pre) {
+ /*
+ * If we see a blank line in a preformatted
+ * block, we don't want to stop the pre
+ * unless the next line is not indented.
+ * So peek ahead.
+ */
+ if (defined(buf = all[i+1]) && (buf =~ /^\s/)) {
+ puts("");
+ continue;
+ }
+ puts("</pre>");
+ pre = 0;
+ trim = undef;
+ }
+ space = 1;
+ } else {
+ if (space) {
+ if (buf =~ /^(\s+)[^ \t]+/) {
+ trim = $1;
+ puts("<pre>");
+ pre = 1;
+ } else {
+ puts("<p>");
+ p = 1;
+ }
+ space = 0;
+ }
+ if (defined(trim)) buf =~ s/^${trim}//;
+ puts(buf);
+ }
+ }
+ puts("</body></html>");
+ return (0);
+}
+
+/*
+ * header and style sheet
+ */
+void
+header(string title)
+{
+ string head = <<EOF
+<html>
+<head>
+<title>${title}</title>
+<style>
+pre {
+ background: #eeeedd;
+ border-width: 1px;
+ border-style: solid solid solid solid;
+ border-color: #ccc;
+ padding: 5px 5px 5px 5px;
+ font-family: monospace;
+ font-weight: bolder;
+}
+body {
+ padding-left: 10px;
+}
+dt {
+ font-size: large;
+}
+</style>
+</head>
+<body>
+EOF
+ puts(head);
+ puts("<h1>${title}</h1>");
+}
+
+/*
+ * Process B<bold>, C<code>, I<italic>, F<italic>, L<link>, S<non-breaking>.
+ * This will handle nested stuff like C<if (!I<condition>)>
+ * but dies if there are nested ones of the same type, i.e.,
+ * C<whatever C<some more>>
+ */
+string
+inline(string buf)
+{
+ string c, prev, result = "", link, stack[];
+ int B = 0, C = 0, I = 0, L = 0, S = 0;
+
+ unless (buf) buf = "";
+ foreach (c in buf) {
+ if ((c == "<") && prev) {
+ if (prev == "B") {
+ if (B++) die("Nested B<> unsupported: ${buf}");
+ result[END] = "";
+ result .= "<B>";
+ push(&stack, "B");
+ } else if (prev == "C") {
+ if (C++) die("Nested C<> unsupported: ${buf}");
+ result[END] = "";
+ result .= "<CODE>";
+ push(&stack, "CODE");
+ } else if (prev == "I" || prev == "F") {
+ if (I++) die("Nested I<> unsupported: ${buf}");
+ result[END] = "";
+ result .= "<I>";
+ push(&stack, "I");
+ } else if (prev == "L") {
+ if (L++) die("Nested L<> unsupported: ${buf}");
+ result[END] = "";
+ result .= "<a href=\"";
+ link = "";
+ push(&stack, "L");
+ } else if (prev == "S") {
+ if (S++) die("Nested S<> unsupported: ${buf}");
+ result[END] = "";
+ push(&stack, "S");
+ } else {
+ result .= "&lt;";
+ prev = c;
+ }
+ } else if ((c == ">") && length(stack)) {
+ c = pop(&stack);
+ if (c == "B") {
+ B--;
+ } else if (c == "CODE") {
+ C--;
+ } else if (c == "I") {
+ I--;
+ } else if (c == "L") {
+ L--;
+ result .= "\">${link}</a>";
+ c = undef;
+ } else {
+ S--;
+ c = undef;
+ }
+ if (c) {
+ result .= "</" . c . ">";
+ }
+ prev = undef;
+ } else {
+ if (S && isspace(c)) {
+ result .= "&nbsp;";
+ } else if (c == "<") {
+ result .= "&lt;";
+ } else if (c == ">") {
+ result .= "&gt;";
+ } else {
+ result .= c;
+ }
+ if (L) link .= c;
+ prev = c;
+ }
+ }
+ return (result);
+}
diff --git a/doc/L/pod2man b/doc/L/pod2man
new file mode 100755
index 0000000..854aa23
--- /dev/null
+++ b/doc/L/pod2man
@@ -0,0 +1,513 @@
+#!/usr/bin/perl
+ eval 'exec /usr/bin/perl -S $0 ${1+"$@"}'
+ if $running_under_some_shell;
+
+# pod2man -- Convert POD data to formatted *roff input.
+# $Id: pod2man.PL,v 1.10 2002/07/15 05:45:56 eagle Exp $
+#
+# Copyright 1999, 2000, 2001 by Russ Allbery <rra@stanford.edu>
+#
+# This program is free software; you may redistribute it and/or modify it
+# under the same terms as Perl itself.
+
+require 5.004;
+
+use Getopt::Long qw(GetOptions);
+use Pod::Man ();
+use Pod::Usage qw(pod2usage);
+
+use strict;
+
+# Silence -w warnings.
+use vars qw($running_under_some_shell);
+
+# Insert -- into @ARGV before any single dash argument to hide it from
+# Getopt::Long; we want to interpret it as meaning stdin (which Pod::Parser
+# does correctly).
+my $stdin;
+@ARGV = map { $_ eq '-' && !$stdin++ ? ('--', $_) : $_ } @ARGV;
+
+# Parse our options, trying to retain backwards compatibility with pod2man but
+# allowing short forms as well. --lax is currently ignored.
+my %options;
+Getopt::Long::config ('bundling_override');
+GetOptions (\%options, 'section|s=s', 'release|r:s', 'center|c=s',
+ 'date|d=s', 'fixed=s', 'fixedbold=s', 'fixeditalic=s',
+ 'fixedbolditalic=s', 'name|n=s', 'official|o', 'quotes|q=s',
+ 'lax|l', 'help|h', 'verbose|v') or exit 1;
+pod2usage (0) if $options{help};
+
+# Official sets --center, but don't override things explicitly set.
+if ($options{official} && !defined $options{center}) {
+ $options{center} = 'Perl Programmers Reference Guide';
+}
+
+# Verbose is only our flag, not a Pod::Man flag.
+my $verbose = $options{verbose};
+delete $options{verbose};
+
+# This isn't a valid Pod::Man option and is only accepted for backwards
+# compatibility.
+delete $options{lax};
+
+# Initialize and run the formatter, pulling a pair of input and output off at
+# a time.
+my $parser = Pod::Man->new (%options);
+my @files;
+do {
+ @files = splice (@ARGV, 0, 2);
+ print " $files[1]\n" if $verbose;
+ $parser->parse_from_file (@files);
+} while (@ARGV);
+
+__END__
+
+=head1 NAME
+
+pod2man - Convert POD data to formatted *roff input
+
+=head1 SYNOPSIS
+
+pod2man [B<--section>=I<manext>] [B<--release>=I<version>]
+[B<--center>=I<string>] [B<--date>=I<string>] [B<--fixed>=I<font>]
+[B<--fixedbold>=I<font>] [B<--fixeditalic>=I<font>]
+[B<--fixedbolditalic>=I<font>] [B<--name>=I<name>] [B<--official>]
+[B<--lax>] [B<--quotes>=I<quotes>] [B<--verbose>]
+[I<input> [I<output>] ...]
+
+pod2man B<--help>
+
+=head1 DESCRIPTION
+
+B<pod2man> is a front-end for Pod::Man, using it to generate *roff input
+from POD source. The resulting *roff code is suitable for display on a
+terminal using nroff(1), normally via man(1), or printing using troff(1).
+
+I<input> is the file to read for POD source (the POD can be embedded in
+code). If I<input> isn't given, it defaults to STDIN. I<output>, if given,
+is the file to which to write the formatted output. If I<output> isn't
+given, the formatted output is written to STDOUT. Several POD files can be
+processed in the same B<pod2man> invocation (saving module load and compile
+times) by providing multiple pairs of I<input> and I<output> files on the
+command line.
+
+B<--section>, B<--release>, B<--center>, B<--date>, and B<--official> can be
+used to set the headers and footers to use; if not given, Pod::Man will
+assume various defaults. See below or L<Pod::Man> for details.
+
+B<pod2man> assumes that your *roff formatters have a fixed-width font named
+CW. If yours is called something else (like CR), use B<--fixed> to specify
+it. This generally only matters for troff output for printing. Similarly,
+you can set the fonts used for bold, italic, and bold italic fixed-width
+output.
+
+Besides the obvious pod conversions, Pod::Man, and therefore pod2man also
+takes care of formatting func(), func(n), and simple variable references
+like $foo or @bar so you don't have to use code escapes for them; complex
+expressions like C<$fred{'stuff'}> will still need to be escaped, though.
+It also translates dashes that aren't used as hyphens into en dashes, makes
+long dashes--like this--into proper em dashes, fixes "paired quotes," and
+takes care of several other troff-specific tweaks. See L<Pod::Man> for
+complete information.
+
+=head1 OPTIONS
+
+=over 4
+
+=item B<-c> I<string>, B<--center>=I<string>
+
+Sets the centered page header to I<string>. The default is "User
+Contributed Perl Documentation", but also see B<--official> below.
+
+=item B<-d> I<string>, B<--date>=I<string>
+
+Set the left-hand footer string to this value. By default, the modification
+date of the input file will be used, or the current date if input comes from
+STDIN.
+
+=item B<--fixed>=I<font>
+
+The fixed-width font to use for vertabim text and code. Defaults to CW.
+Some systems may want CR instead. Only matters for troff(1) output.
+
+=item B<--fixedbold>=I<font>
+
+Bold version of the fixed-width font. Defaults to CB. Only matters for
+troff(1) output.
+
+=item B<--fixeditalic>=I<font>
+
+Italic version of the fixed-width font (actually, something of a misnomer,
+since most fixed-width fonts only have an oblique version, not an italic
+version). Defaults to CI. Only matters for troff(1) output.
+
+=item B<--fixedbolditalic>=I<font>
+
+Bold italic (probably actually oblique) version of the fixed-width font.
+Pod::Man doesn't assume you have this, and defaults to CB. Some systems
+(such as Solaris) have this font available as CX. Only matters for troff(1)
+output.
+
+=item B<-h>, B<--help>
+
+Print out usage information.
+
+=item B<-l>, B<--lax>
+
+No longer used. B<pod2man> used to check its input for validity as a manual
+page, but this should now be done by L<podchecker(1)> instead. Accepted for
+backwards compatibility; this option no longer does anything.
+
+=item B<-n> I<name>, B<--name>=I<name>
+
+Set the name of the manual page to I<name>. Without this option, the manual
+name is set to the uppercased base name of the file being converted unless
+the manual section is 3, in which case the path is parsed to see if it is a
+Perl module path. If it is, a path like C<.../lib/Pod/Man.pm> is converted
+into a name like C<Pod::Man>. This option, if given, overrides any
+automatic determination of the name.
+
+Note that this option is probably not useful when converting multiple POD
+files at once. The convention for Unix man pages for commands is for the
+man page title to be in all-uppercase even if the command isn't.
+
+=item B<-o>, B<--official>
+
+Set the default header to indicate that this page is part of the standard
+Perl release, if B<--center> is not also given.
+
+=item B<-q> I<quotes>, B<--quotes>=I<quotes>
+
+Sets the quote marks used to surround CE<lt>> text to I<quotes>. If
+I<quotes> is a single character, it is used as both the left and right
+quote; if I<quotes> is two characters, the first character is used as the
+left quote and the second as the right quoted; and if I<quotes> is four
+characters, the first two are used as the left quote and the second two as
+the right quote.
+
+I<quotes> may also be set to the special value C<none>, in which case no
+quote marks are added around CE<lt>> text (but the font is still changed for
+troff output).
+
+=item B<-r>, B<--release>
+
+Set the centered footer. By default, this is the version of Perl you run
+B<pod2man> under. Note that some system an macro sets assume that the
+centered footer will be a modification date and will prepend something like
+"Last modified: "; if this is the case, you may want to set B<--release> to
+the last modified date and B<--date> to the version number.
+
+=item B<-s>, B<--section>
+
+Set the section for the C<.TH> macro. The standard section numbering
+convention is to use 1 for user commands, 2 for system calls, 3 for
+functions, 4 for devices, 5 for file formats, 6 for games, 7 for
+miscellaneous information, and 8 for administrator commands. There is a lot
+of variation here, however; some systems (like Solaris) use 4 for file
+formats, 5 for miscellaneous information, and 7 for devices. Still others
+use 1m instead of 8, or some mix of both. About the only section numbers
+that are reliably consistent are 1, 2, and 3.
+
+By default, section 1 will be used unless the file ends in .pm in which case
+section 3 will be selected.
+
+=item B<-v>, B<--verbose>
+
+Print out the name of each output file as it is being generated.
+
+=back
+
+=head1 DIAGNOSTICS
+
+If B<pod2man> fails with errors, see L<Pod::Man> and L<Pod::Parser> for
+information about what those errors might mean.
+
+=head1 EXAMPLES
+
+ pod2man program > program.1
+ pod2man SomeModule.pm /usr/perl/man/man3/SomeModule.3
+ pod2man --section=7 note.pod > note.7
+
+If you would like to print out a lot of man page continuously, you probably
+want to set the C and D registers to set contiguous page numbering and
+even/odd paging, at least on some versions of man(7).
+
+ troff -man -rC1 -rD1 perl.1 perldata.1 perlsyn.1 ...
+
+To get index entries on stderr, turn on the F register, as in:
+
+ troff -man -rF1 perl.1
+
+The indexing merely outputs messages via C<.tm> for each major page,
+section, subsection, item, and any C<XE<lt>E<gt>> directives. See
+L<Pod::Man> for more details.
+
+=head1 BUGS
+
+Lots of this documentation is duplicated from L<Pod::Man>.
+
+=head1 NOTES
+
+For those not sure of the proper layout of a man page, here are some notes
+on writing a proper man page.
+
+The name of the program being documented is conventionally written in bold
+(using BE<lt>E<gt>) wherever it occurs, as are all program options.
+Arguments should be written in italics (IE<lt>E<gt>). Functions are
+traditionally written in italics; if you write a function as function(),
+Pod::Man will take care of this for you. Literal code or commands should
+be in CE<lt>E<gt>. References to other man pages should be in the form
+C<manpage(section)>, and Pod::Man will automatically format those
+appropriately. As an exception, it's traditional not to use this form when
+referring to module documentation; use C<LE<lt>Module::NameE<gt>> instead.
+
+References to other programs or functions are normally in the form of man
+page references so that cross-referencing tools can provide the user with
+links and the like. It's possible to overdo this, though, so be careful not
+to clutter your documentation with too much markup.
+
+The major headers should be set out using a C<=head1> directive, and are
+historically written in the rather startling ALL UPPER CASE format, although
+this is not mandatory. Minor headers may be included using C<=head2>, and
+are typically in mixed case.
+
+The standard sections of a manual page are:
+
+=over 4
+
+=item NAME
+
+Mandatory section; should be a comma-separated list of programs or functions
+documented by this podpage, such as:
+
+ foo, bar - programs to do something
+
+Manual page indexers are often extremely picky about the format of this
+section, so don't put anything in it except this line. A single dash, and
+only a single dash, should separate the list of programs or functions from
+the description. Functions should not be qualified with C<()> or the like.
+The description should ideally fit on a single line, even if a man program
+replaces the dash with a few tabs.
+
+=item SYNOPSIS
+
+A short usage summary for programs and functions. This section is mandatory
+for section 3 pages.
+
+=item DESCRIPTION
+
+Extended description and discussion of the program or functions, or the body
+of the documentation for man pages that document something else. If
+particularly long, it's a good idea to break this up into subsections
+C<=head2> directives like:
+
+ =head2 Normal Usage
+
+ =head2 Advanced Features
+
+ =head2 Writing Configuration Files
+
+or whatever is appropriate for your documentation.
+
+=item OPTIONS
+
+Detailed description of each of the command-line options taken by the
+program. This should be separate from the description for the use of things
+like L<Pod::Usage|Pod::Usage>. This is normally presented as a list, with
+each option as a separate C<=item>. The specific option string should be
+enclosed in BE<lt>E<gt>. Any values that the option takes should be
+enclosed in IE<lt>E<gt>. For example, the section for the option
+B<--section>=I<manext> would be introduced with:
+
+ =item B<--section>=I<manext>
+
+Synonymous options (like both the short and long forms) are separated by a
+comma and a space on the same C<=item> line, or optionally listed as their
+own item with a reference to the canonical name. For example, since
+B<--section> can also be written as B<-s>, the above would be:
+
+ =item B<-s> I<manext>, B<--section>=I<manext>
+
+(Writing the short option first is arguably easier to read, since the long
+option is long enough to draw the eye to it anyway and the short option can
+otherwise get lost in visual noise.)
+
+=item RETURN VALUE
+
+What the program or function returns, if successful. This section can be
+omitted for programs whose precise exit codes aren't important, provided
+they return 0 on success as is standard. It should always be present for
+functions.
+
+=item ERRORS
+
+Exceptions, error return codes, exit statuses, and errno settings.
+Typically used for function documentation; program documentation uses
+DIAGNOSTICS instead. The general rule of thumb is that errors printed to
+STDOUT or STDERR and intended for the end user are documented in DIAGNOSTICS
+while errors passed internal to the calling program and intended for other
+programmers are documented in ERRORS. When documenting a function that sets
+errno, a full list of the possible errno values should be given here.
+
+=item DIAGNOSTICS
+
+All possible messages the program can print out--and what they mean. You
+may wish to follow the same documentation style as the Perl documentation;
+see perldiag(1) for more details (and look at the POD source as well).
+
+If applicable, please include details on what the user should do to correct
+the error; documenting an error as indicating "the input buffer is too
+small" without telling the user how to increase the size of the input buffer
+(or at least telling them that it isn't possible) aren't very useful.
+
+=item EXAMPLES
+
+Give some example uses of the program or function. Don't skimp; users often
+find this the most useful part of the documentation. The examples are
+generally given as verbatim paragraphs.
+
+Don't just present an example without explaining what it does. Adding a
+short paragraph saying what the example will do can increase the value of
+the example immensely.
+
+=item ENVIRONMENT
+
+Environment variables that the program cares about, normally presented as a
+list using C<=over>, C<=item>, and C<=back>. For example:
+
+ =over 6
+
+ =item HOME
+
+ Used to determine the user's home directory. F<.foorc> in this
+ directory is read for configuration details, if it exists.
+
+ =back
+
+Since environment variables are normally in all uppercase, no additional
+special formatting is generally needed; they're glaring enough as it is.
+
+=item FILES
+
+All files used by the program or function, normally presented as a list, and
+what it uses them for. File names should be enclosed in FE<lt>E<gt>. It's
+particularly important to document files that will be potentially modified.
+
+=item CAVEATS
+
+Things to take special care with, sometimes called WARNINGS.
+
+=item BUGS
+
+Things that are broken or just don't work quite right.
+
+=item RESTRICTIONS
+
+Bugs you don't plan to fix. :-)
+
+=item NOTES
+
+Miscellaneous commentary.
+
+=item SEE ALSO
+
+Other man pages to check out, like man(1), man(7), makewhatis(8), or
+catman(8). Normally a simple list of man pages separated by commas, or a
+paragraph giving the name of a reference work. Man page references, if they
+use the standard C<name(section)> form, don't have to be enclosed in
+LE<lt>E<gt> (although it's recommended), but other things in this section
+probably should be when appropriate.
+
+If the package has a mailing list, include a URL or subscription
+instructions here.
+
+If the package has a web site, include a URL here.
+
+=item AUTHOR
+
+Who wrote it (use AUTHORS for multiple people). Including your current
+e-mail address (or some e-mail address to which bug reports should be sent)
+so that users have a way of contacting you is a good idea. Remember that
+program documentation tends to roam the wild for far longer than you expect
+and pick an e-mail address that's likely to last if possible.
+
+=item COPYRIGHT AND LICENSE
+
+For copyright
+
+ Copyright YEAR(s) by YOUR NAME(s)
+
+(No, (C) is not needed. No, "all rights reserved" is not needed.)
+
+For licensing the easiest way is to use the same licensing as Perl itself:
+
+ This library is free software; you may redistribute it and/or modify
+ it under the same terms as Perl itself.
+
+This makes it easy for people to use your module with Perl. Note that
+this licensing is neither an endorsement or a requirement, you are of
+course free to choose any licensing.
+
+=item HISTORY
+
+Programs derived from other sources sometimes have this, or you might keep
+a modification log here. If the log gets overly long or detailed,
+consider maintaining it in a separate file, though.
+
+=back
+
+In addition, some systems use CONFORMING TO to note conformance to relevant
+standards and MT-LEVEL to note safeness for use in threaded programs or
+signal handlers. These headings are primarily useful when documenting parts
+of a C library. Documentation of object-oriented libraries or modules may
+use CONSTRUCTORS and METHODS sections for detailed documentation of the
+parts of the library and save the DESCRIPTION section for an overview; other
+large modules may use FUNCTIONS for similar reasons. Some people use
+OVERVIEW to summarize the description if it's quite long.
+
+Section ordering varies, although NAME should I<always> be the first section
+(you'll break some man page systems otherwise), and NAME, SYNOPSIS,
+DESCRIPTION, and OPTIONS generally always occur first and in that order if
+present. In general, SEE ALSO, AUTHOR, and similar material should be left
+for last. Some systems also move WARNINGS and NOTES to last. The order
+given above should be reasonable for most purposes.
+
+Finally, as a general note, try not to use an excessive amount of markup.
+As documented here and in L<Pod::Man>, you can safely leave Perl variables,
+function names, man page references, and the like unadorned by markup and
+the POD translators will figure it out for you. This makes it much easier
+to later edit the documentation. Note that many existing translators
+(including this one currently) will do the wrong thing with e-mail addresses
+or URLs when wrapped in LE<lt>E<gt>, so don't do that.
+
+For additional information that may be more accurate for your specific
+system, see either L<man(5)> or L<man(7)> depending on your system manual
+section numbering conventions.
+
+=head1 SEE ALSO
+
+L<Pod::Man>, L<Pod::Parser>, L<man(1)>, L<nroff(1)>, L<podchecker(1)>,
+L<troff(1)>, L<man(7)>
+
+The man page documenting the an macro set may be L<man(5)> instead of
+L<man(7)> on your system.
+
+The current version of this script is always available from its web site at
+L<http://www.eyrie.org/~eagle/software/podlators/>. It is also part of the
+Perl core distribution as of 5.6.0.
+
+=head1 AUTHOR
+
+Russ Allbery <rra@stanford.edu>, based I<very> heavily on the original
+B<pod2man> by Larry Wall and Tom Christiansen. Large portions of this
+documentation, particularly the sections on the anatomy of a proper man
+page, are taken from the B<pod2man> documentation by Tom.
+
+=head1 COPYRIGHT AND LICENSE
+
+Copyright 1999, 2000, 2001 by Russ Allbery <rra@stanford.edu>.
+
+This program is free software; you may redistribute it and/or modify it
+under the same terms as Perl itself.
+
+=cut
diff --git a/doc/l-paper/NOTES b/doc/l-paper/NOTES
new file mode 100644
index 0000000..72aac51
--- /dev/null
+++ b/doc/l-paper/NOTES
@@ -0,0 +1,165 @@
+[Fri Sep 22 16:07:30 PDT 2006]
+
+The problem is pass by reference vs value. There isn't a nice way to do it
+like C so we're inventing a different way, trying to keep it readable.
+
+proc tcl_ref {setme} {
+ upvar $setme ptr
+ set ptr "some string"
+}
+
+/*
+ * how this works is that the compiler sees the &setme and generates code like:
+ * upvar ${&setme} setme
+ */
+void
+L_ref(string &setme)
+{
+ setme = "some string";
+}
+
+It does mean that if I want to call gets() from L I need to do
+
+ while (gets(fd, &buf) > 0) {
+ ...
+ }
+
+which isn't very C like. That's OK, L isn't C because strings are first
+class in L and they aren't in C. Oscar wacked that into my head. Slowly.
+
+The next issue is compound types like arrays / hashes. I want those to be
+implicit references, like C. So no &my_array in args, it's just my_array.
+
+/*
+ * as above, the compiler sees foo[] and subs in &foo as the parameter
+ * and does the upvar ${&foo} foo
+ */
+void
+L_array_ref(int foo[])
+{
+ foo[3] = 3;
+}
+
+/*
+ * as above, the compiler sees foo{} and does the code like
+ * upvar $foo 0foo
+ *
+ * Note also the new full specified syntax for a hash declaration.
+ * The following are the same thing and for 1.0 we implement the
+ * first one only. But the second form allows us to have var/poly/int
+ * etc. as keys or indices. The syntax is "value" varname{"key"} where
+ * value is the type of the value and key is the type of the key. Nifty.
+ * hash foo{};
+ * string foo{string};
+ *
+ * For 1.0 this is just
+ * L_hash_ref(hash foo)
+ * and I do want to insist on the {} in declarations (args and formal) because
+ * it gets people used to the foo{"string"} syntax.
+ */
+void
+L_hash_ref(string foo{string})
+{
+ int mine{};
+
+ foo{"some key"} = "some value";
+}
+
+A calling wrinkle.
+
+When calling an L function/tcl proc which expects a reference, i.e.,
+func(string &buf) or proc foo {bufname} { upvar $bufname buf ... },
+from an L context, there is a question as to whether or not the
+L variable needs a leading &. And the answer is: depends on what you
+want. All the leading ampersand does is to push the name of the
+variable on the stack instead of the value of the variable (w/ all
+the COW semantics). So consider this
+
+void
+stomp(string &buf)
+{
+ buf = "stomped";
+}
+
+void
+L_caller()
+{
+ string foo = "bar";
+ string fooname = "foo";
+
+ if (what_I_would_expect) {
+ stomp(&foo); // foo will get "stomped"
+ } else {
+ stomp(fooname); // foo will get "stomped" this way too
+ }
+}
+
+The stomp(fooname) could work but we should disallow it in L 1.0 - we
+can allow it in the future. Tim points out that we can throw a syntax
+error for L calling L and the type mismatch but not for L calling tcl,
+i.e., calling gets, unless we have some sort of extern int gets(FILE fd,
+string &buf) that we use to load the function signature table (what is
+that called?)
+
+Tcl calling L
+
+Suppose we had an L procedure that implemented puts, maybe it's written
+in C, but it would be declared like
+
+void
+L_puts(string stuff_to_print[])
+{
+ print it
+}
+
+If we are in tcl and we do
+
+ set stuff [list a b c]
+
+and we want to print it it would look like
+
+ puts $stuff
+
+but if we're calling L that won't work, it should be an arg miss match because
+
+ L_puts $stuff
+
+is like calling
+
+ L_puts("a", "b", "c")
+
+and L_puts wants a single arg.
+
+We get around this by noting that L implements pass by reference by passing
+by name and doing an upvar so the calling syntax is:
+
+ L_puts stuff
+
+Kind of annoying but that's a ramification of the impedance mismatch between
+L and tcl. If you want to make breakfast you have to break some eggs.
+
+============================================================================
+
+Structs
+
+ struct foo {
+ int a; /* I am A */
+ string b; /* oh, love those strings */
+ }
+
+results in the creation of a list in ::L like
+
+ # Note the offset into the list is the index into the struct "list"
+ set ::L::{struct foo} [list \
+ [list int a {I am A}] \
+ [list string b {oh, love those strings}] \
+ ]
+
+and now I can pass a struct to tcl just like an other COW thingy and I
+can make a little struct command that gets me fields, sets them, does
+introspection, etc.
+
+And the cool thing is L can do the introspection which means I can write
+my little preferences struct and call some wacky code that takes the
+struct and con's up the code to make a preference dialogue.
+
diff --git a/doc/l-paper/btree.l b/doc/l-paper/btree.l
new file mode 100644
index 0000000..3e1ad72
--- /dev/null
+++ b/doc/l-paper/btree.l
@@ -0,0 +1,43 @@
+struct node {
+ double i;
+};
+
+struct node tree[100000];
+
+int
+insert(int node, struct node element)
+{
+ /* using Tcl's {} as NULL */
+ if (tree[node] == "{}") {
+ tree[node] = element;
+ } else if (tree[node].i > element.i) {
+ insert(2*node+1, element);
+ } else {
+ insert(2*node+2, element);
+ }
+}
+
+int
+print(int node)
+{
+ if (tree[node] == "{}") {
+ return;
+ }
+ print(2*node+1);
+ puts(tree[node].i);
+ print(2*node+2);
+}
+
+int
+main()
+{
+ struct node tmp;
+ int i;
+
+ namespace("import", "::tcl::mathfunc::*");
+ for (i = 0; i < 100; i++) {
+ tmp.i = floor(rand()*100);
+ insert(0, tmp);
+ }
+ print(0);
+}
diff --git a/doc/l-paper/cat.l b/doc/l-paper/cat.l
new file mode 100644
index 0000000..4fcaf88
--- /dev/null
+++ b/doc/l-paper/cat.l
@@ -0,0 +1,16 @@
+typedef string FILE;
+
+main(int ac, string av[])
+{
+ int i;
+ FILE fd;
+
+ if (ac == 1) {
+ puts("-nonewline", read("stdin"));
+ } else {
+ for (i = 1; defined(av[i]); i++) {
+ fd = open(av[i], "r");
+ puts("-nonewline", read(fd));
+ }
+ }
+}
diff --git a/doc/l-paper/echo.l b/doc/l-paper/echo.l
new file mode 100644
index 0000000..6919828
--- /dev/null
+++ b/doc/l-paper/echo.l
@@ -0,0 +1,8 @@
+main(int argc, string argv[])
+{
+ int i;
+
+ for (i = 0; defined(argv[i]); i++) {
+ printf("[%d] = %s\n", i, argv[i]);
+ }
+}
diff --git a/doc/l-paper/grep.l b/doc/l-paper/grep.l
new file mode 100644
index 0000000..08b7185
--- /dev/null
+++ b/doc/l-paper/grep.l
@@ -0,0 +1,35 @@
+typedef string FILE;
+
+main(int ac, string av[], hash env)
+{
+ int i;
+ string regex;
+ FILE fd;
+
+ if (ac < 2) {
+ error("Not enough arguments.");
+ }
+ regex = av[1];
+ ac--;
+ if (ac == 1) {
+ grep(regex, "stdin");
+ } else {
+ for (i = 2; defined(av[i]); i++) {
+ fd = open(av[i], "r");
+ grep(regex, fd);
+ close(fd);
+ }
+ }
+}
+
+void
+grep(string regex, FILE in)
+{
+ string buf;
+
+ while (gets(in, &buf) >= 0) {
+ if (buf =~ /${regex}/) {
+ printf("%s\n", buf);
+ }
+ }
+}
diff --git a/doc/l-paper/interop.l b/doc/l-paper/interop.l
new file mode 100644
index 0000000..4c7b03c
--- /dev/null
+++ b/doc/l-paper/interop.l
@@ -0,0 +1,36 @@
+#lang(L)
+
+/*
+ * Demonstrate interop between L and tcl.
+ * We want to show that you can pass any data structure between L and tcl.
+ *
+ * Base types, pass them, modify them.
+ * Structures, pass them, iterate over the fields.
+ * Arrays & hashes.
+ * Pointers to base types.
+ */
+main(int ac, string av[])
+{
+
+}
+
+/*
+ * L calling tcl functions
+ */
+L_to_tcl()
+{
+ string s = "Hi there mom";
+ int a = 1234;
+
+ puts(a); // prints 1234\n
+ puts(s); // prints Hi there mom\n
+ set(&s, "Hi yourself");
+ puts(s); // prints Hi yourself\n
+ puts(:nonewline, "Hi "); // prints Hi
+ puts("there"); // prints there\n
+}
+
+set(string &out, string value)
+{
+ out = value;
+}
diff --git a/doc/l-paper/julia.l b/doc/l-paper/julia.l
new file mode 100644
index 0000000..6394e92
--- /dev/null
+++ b/doc/l-paper/julia.l
@@ -0,0 +1,103 @@
+#pragma language L
+
+julia(int size, int depth, double zreal, double zimag)
+{
+ double z[2];
+ double real_min = -1.2, real_max = 1.2, imag_min = -1.2;
+ double xreal, ximag;
+ double delta = (real_max - real_min) / size;
+ int i = 0, j = 0;
+
+ wm("title", ".", "Pretty Julia");
+ wm("geometry", ".", "+1+1");
+ canvas(".c1", "-width", size, "-height", size);
+ pack(".c1");
+ update();
+ z[0] = zreal;
+ z[1] = zimag;
+ xreal = real_min;
+ while (i < size) {
+ j = 0;
+ ximag = imag_min;
+ while (j < size) {
+ double count = 0.0;
+ double x[2];
+
+ x[0] = xreal;
+ x[1] = ximag;
+ while ((count < depth) && (complex_abs(x) < 2.0)) {
+ count = count + 1;
+ x = complex_add(complex_multiply(x, x), z);
+ }
+ if (complex_abs(x) <= 2.0) {
+ .c1("create", "rectangle", i, j, i, j,
+ "-outline", make_color(0, 0, 0));
+ } else {
+ double intensity = count / depth;
+
+ if (intensity > 0.001) {
+ .c1("create", "rectangle", i, j, i, j,
+ "-outline",
+ make_color(round(255.0 / depth *
+ (depth -
+ depth * intensity)),
+ round(255.0 / depth * (depth -
+ depth * intensity)),
+ round(255.0 / depth * depth)));
+ }
+ }
+ j++;
+ ximag = ximag + delta;
+ } i++;
+ puts("-nonewline", format("%d .. ", i));
+ flush("stdout");
+ update();
+ xreal = xreal + delta;
+ } z[0] = zreal;
+ z[1] = zimag;
+ puts("\nDONE");
+}
+
+string
+make_color(int r, int g, int b)
+{
+ return format("#%02X%02X%02X", r, g, b);
+}
+
+double
+complex_multiply(double c1[2], double c2[2])
+{
+ double c3[2];
+
+ c3[0] = c1[0] * c2[0] - c1[1] * c2[1];
+ c3[1] = c1[0] * c2[1] + c1[1] * c2[0];
+ return c3;
+}
+
+double
+complex_add(double c1[2], double c2[2])
+{
+ double c3[2];
+
+ c3[0] = c1[0] + c2[0];
+ c3[1] = c1[1] + c2[1];
+ return c3;
+}
+
+#pragma end
+
+interp alias {} sqrt {} tcl::mathfunc::sqrt
+interp alias {} round {} tcl::mathfunc::round
+proc complex_abs {x} {
+ puts "complex_abs $x"
+ set a [lindex $x 0]
+ set b [lindex $x 1]
+ expr {sqrt(($a * $a)+($b * $b))}
+}
+#puts [time {julia 100 25 -0.74543 0.11302}]
+puts [time {julia 300 25 -0.84543 0.21302}]
+# bigger, different coords:
+#julia 256 25 -0.84543 0.21302
+# if you raise the depth, the islands get smaller:
+#julia 256 50 -0.84543 0.21302
+
diff --git a/doc/l-paper/l-language.me b/doc/l-paper/l-language.me
new file mode 100644
index 0000000..0864bf2
--- /dev/null
+++ b/doc/l-paper/l-language.me
@@ -0,0 +1,113 @@
+.\" The L Programming Language
+.\" Copyright (c) 2006 BitMover, Inc.
+.\"
+.\" process with
+.\" groff -R -me l-language.me > l-language.ps
+.\"
+.\" Commands for refer
+.R1
+database references
+accumulate
+.R2
+.\" Title, authors, etc.
+.+c
+.(l C
+.sz 16
+.b "The L Programming Language"
+.sz
+or
+.sz 12
+Tcl for C Programmers
+.sz
+.sp 3
+.i "Oscar Bonilla, Tim Daly, Jr., Jeff Hobbs, Larry McVoy"
+.sp
+BitMover, Inc.
+300 Orchard City Drive, Suite 132
+Campbell, CA 95008
+\f(CR
+l@bitmover.com
+\fP
+.)l
+.sp 3
+.\" Abstract
+.(l F
+.b Abstract.
+This paper describes a new programming language called L. The goal of
+L is to make it easy for C programmers to take full advantage of
+Tcl/Tk without requiring them to be proficient in Tcl. L is a new
+programming language that shares most of its syntax and semantics with
+C, including pointers and a weak static type system. We have modified
+the Tcl parser to add a special command which can be used to switch
+between L and Tcl syntax. Source code written in L syntax is passed to
+a simple compiler which emits Tcl bytecode. So L source code can be
+mixed freely with Tcl source code, and Tcl and L can share data and
+functions transparently. L is free and open source, and the authors
+hope it will bring many new people to the Tcl community.
+.)l
+.\" Main text
+.sh 1 "Introduction"
+.lp
+At BitMover, we are great fans of code reading. We spend much more
+time reading our source code than writing it. Most of our source base
+is written in C, but our GUI is written in Tcl. It would greatly
+simplify things for us if everything was in a common language.
+However, using Tk from C would be difficult and error-prone.
+.pp
+For that reason, we've decided to implement a new language that shares
+the Tcl runtime. By keeping the language similar to C we can use the
+same idioms as we would in C, avoiding confusion. To make access to Tk
+and other Tcl libraries seamless, the language runs right in the Tcl
+runtime. Its functions are Tcl functions, and its types are Tcl types.
+.pp
+In keeping with the grand tradition of one letter language names, this
+new language is called L. In the next section, we will go into more
+detail about some interesting aspects of the language. After that we
+discuss its implementation as a front-end for Tcl. Finally we touch
+on our plans for the future of L, and tell you where you can get a
+copy.
+.sh 1 "The L Language"
+.lp
+Say that we're mostly like C and then go on to describe where we're
+different. Explain how L types correspond to Tcl types, and give an
+example of the interaction between the two languages.
+.\" This is an example reference so that I don't forget how to make one
+.[
+kernighan cherry eqn
+.]
+.sh 1 "The Implementation"
+.lp
+The first step in processing an L program is to read in the source
+code. L source code can be in its own file, or it can be in a mixed
+file together with Tcl source code.
+.sh 2 "Parsing Mixed Languages"
+.lp
+The most obvious approach to embedding L code within a Tcl program
+would be to pass the L code as an argument to a new Tcl command which
+implements L. However, the Tcl syntax rule that "braces nest within a
+word" [cite endekalogue/tcl book?] means that we would still be
+required to match (or escape) braces within the L code. This would be
+an unpleasant wrinkle for the L programmer to deal with.
+.pp
+In order to free the brace characters from the reign of Tcl, it was
+necessary to modify the Tcl parser. We added support for special
+comments that start with the word "pragma". The parser consumes the
+input from an opening pragma to a closing pragma, and packages it as a
+pair of Tcl words -- the name of the command that implements L,
+followed by the source code between the pragmas. In this way, the
+result of parsing embedded L code is the same as if the L code had
+been properly escaped.
+.sh 1 "..."
+.lp
+Mention using Tcl to generate C code, and explain how L pointers work.
+Take opportunity to release bile about Tcl being a bizarre backend for
+a C compiler.
+.sh 1 "Current Status, Availability"
+.lp
+L is completely finished and golden, and has a magic shield of +2
+anti-bitrot. You can get it from sunsite, tsx-11, or wuarchive.
+Build instructions are for sissies.
+.\" All done, print the references
+.[
+$LIST$
+.]
diff --git a/doc/l-paper/little.ms b/doc/l-paper/little.ms
new file mode 100644
index 0000000..83a452c
--- /dev/null
+++ b/doc/l-paper/little.ms
@@ -0,0 +1,1505 @@
+.\" The L Programming Language
+.\" Copyright (c) 2006 BitMover, Inc.
+.\"
+.\" process with
+.\" groff -R -ms l.ms > l.ps
+.\"
+.\" Mail to tcl2006@tcl.tk when done.
+.\"
+.\" Commands for refer
+.R1
+database references
+accumulate
+label-in-text
+label A.nD.y%a
+.R2
+.de CS
+.sp .25
+.KS
+.in +.5
+.ta .55i 1i
+.ft CW
+.nf
+..
+.de CE
+.sp .25
+.in
+.ft
+.fi
+.KE
+..
+.de BR
+\fB\\$1\fR\\$2
+..
+.de LI
+.br
+.ne 4
+.LP
+.B "\\$*"
+'br
+..
+.de BU
+.IP \(bu 2
+..
+.\" Title, authors, etc.
+.nr PO 1i
+.nr LL 6.5i
+.po \n[PO]u
+.ll \n[LL]u
+.HM .75i
+.FM .75i
+.TL
+The L Programming Language
+.br
+or
+.br
+Tcl for C Programmers
+.AU
+Oscar Bonilla, Tim Daly, Jr., Larry McVoy
+.AI
+BitMover, Inc.
+300 Orchard City Drive, Suite 132
+Campbell, CA 95008
+.AU
+Jeffrey Hobbs
+.AI
+ActiveState Software Inc.
+1700-409 Granville Street
+Vancouver, BC, Canada
+V6C 1T2
+.sp
+\f(CRl@bitmover.com\fP
+.\" Abstract
+.AB
+This paper describes a new programming language called L.
+L is a compiled-to-byte-code language with the unusual twist that it
+compiles to Tcl byte codes and by doing so leverages the entire Tcl
+runtime.
+L is designed to peacefully coexist with Tcl rather than replace Tcl.
+L functions may call Tcl procs and vice versa.
+They may also coexist in the same source file.
+L is a static weakly typed language with int, float, string, struct,
+array, and hash as first-class objects.
+The L syntax is reminiscent of C with a tiny bit of C++ thrown in.
+.PP
+The implementation consists primarily of a simple compiler that Tcl
+invokes whenever L source code is encountered.
+The L code is parsed by a Bison-generated parser into an abstract syntax
+tree (AST), which is
+type-checked and then translated into Tcl byte code.
+Upon its execution, L code is indistinguishable from Tcl code, which
+makes for easy interoperability.
+.ig
+.PP
+L has been discussed slightly on the #tcl IRC channel and the best quote
+to date is from Donal K Fellows who said:
+.I "\(lqIt's like perl without the nastiest bits.\(rq"
+..
+.PP
+L is open source software, and it is made available under the same
+license as Tcl/Tk with the hope that people will find it useful and it
+may encourage more people to join the Tcl/Tk community.
+.AE
+.bp
+.EQ
+delim @@
+.EN
+.ce 1
+.I "\(lqIt's like perl without the nastiest bits.\(rq"
+.sp .5
+.ce 1
+-- Donal K. Fellows \s7(on the #tcl IRC channel)\s0
+.ig
+.sp .5
+.ce 1
+.I "\(lqHe shouldn't have said if he didn't mean it.\(rq"
+.sp .5
+.ce 1
+-- Oscar Bonilla
+..
+.sp
+.2C
+.NH 1
+Introduction
+.LP
+BitMover software is produced using a conservative development methodology.
+All development goes through a stringent process that relies heavily on
+peer review and extensive regression tests to ensure quality products.
+.LP
+Because of the stability requirements of our market,
+we read code much more than we write it.
+Spot checks indicate that we spend at least 10 times as much
+time reading and reviewing as we do writing.
+Naturally, we tend to optimize heavily for the read path rather than the
+write path.
+.\" Much like a file system. H'm. Work that into the talk?
+.LP
+For years we have used the Tcl/Tk system for our graphical user interfaces.
+We periodically consider the alternatives and have consistently found that
+short of doing native implementations, the
+Tcl/Tk system is still the best choice from a development cost point of
+view.
+Our estimate is that it would cost roughly six times as much to develop
+and maintain native GUIs instead of using a single Tcl source base for all
+platforms.
+However, the maintenance of our Tcl source base has recently become
+problematic because two things happened:
+.BU
+Our Tcl source base grew past a manageable size (for us).
+.BU
+Our peer review system could not handle Tcl code.
+.LP
+We have about 25,000 lines lines of Tcl, implementing about a dozen
+graphical interfaces for browsing code, checking in code, viewing changes,
+etc.\**
+.FS
+This number is artificially low because we have been holding off on a number
+of GUIs until we had a better answer. Had we not been holding back, 100,000
+lines is more likely where we would be.
+.FE
+Maintaining and extending the Tcl source base has become unmanageable, and
+when the review process was added to the mix, the costs became
+too high.
+.LP
+This has been a problem for us for years and we were forced to come up with
+a better answer.
+We investigated the alternatives but in the end the Tcl runtime
+and the Tk widgets were too compelling.
+We solved our problems by marrying a language syntax we felt
+was well suited for fast reviewing and understanding with what
+we feel is the best GUI toolkit and runtime available today.
+.LP
+The rest of the paper is divided into sections that discuss the following
+topics:
+an overview of L,
+why the L approach is interesting,
+why other runtimes were not chosen,
+why not pure Tcl,
+why not native GUIs,
+L language details such as types, calling/return conventions,
+current status,
+features we have not yet done but want to do,
+licensing and availability,
+and a summary.
+There is an appendix with some small working program examples.
+.NH 1
+L overview
+.LP
+L is actually a very small addition to the Tcl system.
+If we divide the Tcl system into logical parts this becomes obvious:
+.TS
+expand box;
+l l
+l c.
+Subsection Percentage of Tcl/Tk 8.5
+=
+Tcl parser/compiler <= 1%
+L parser/compiler <= 1%
+Tcl runtime 48%
+Tk 51%
+.TE
+.LP
+The parser and compiler are quite small when compared to the
+code that implements the runtime and the libraries (in both Tcl and L it
+is less than 10K lines of code).
+Because the parser/compiler is such a small part of the system, it is
+reasonable to add an alternative parser/compiler to the
+system and let them both run side by side.
+That is L in a nutshell.
+It is the small amount of effort required to leverage a large amount of
+value embodied in the runtime and libraries.
+.LP
+The L compiler creates an abstract syntax tree from L
+source and compiles that to byte codes.
+The byte codes generated are standard Tcl byte codes, following Tcl
+call/return conventions and using Tcl variables.
+Because we are careful not to break any Tcl rules,
+L functions may call Tcl procs and vice versa.
+This allows L to use the extensive, mature Tcl/Tk runtime
+and libraries unmodified.
+.NH 1
+Unique design
+.LP
+As we dive deeper into the L syntax and semantics it would be
+easy to be drawn into a discussion of why L is better or why Tcl
+is better.
+To do so would be to miss an important point.
+Regardless of the merits of each language, the value of L
+is that it demonstrates a new way to leverage and reuse existing code.
+With a relatively small amount of effort, we have leveraged over
+1.4 million lines of source making up the Tcl/Tk system plus some
+extensions.
+.LP
+The existence of L opens the door to any number of domain-specific
+languages being added to the Tcl runtime system.
+.ig
+If some group prefers Python syntax we see no reason they could
+not take the L scanner and parser, change the syntax to Python,
+and add another syntax to Tcl.
+A reasonable question is \(lqwhy bother?\(rq because Python has a
+runtime.
+The answer isn't Python, it is domain specific languages.
+Any effort that needs a specific syntax to be interpreted could
+take our approach and get the job done for far less effort than
+starting from scratch.
+..
+.LP
+For example, consider the GDB debugger.
+GDB lets users type C, C++, etc., at it and run the code.
+Doing so means GDB has to provide an interpreter and a runtime.
+Rather than building one, GDB could reuse the ideas and code
+pioneered by the L effort.
+Having a well maintained runtime with the option of creating an
+arbitrary syntax to use that runtime is useful for any sort of
+debugger or runtime inspector.
+L is just one example of a different syntax leveraging the Tcl/Tk system;
+we are confident there will be others.
+.NH 1
+Alternative runtimes
+.LP
+Once the idea of adding a different parser/compiler to a scripting
+language is understood, the question becomes: why Tcl rather than some
+other runtime such as Perl, Python, Ruby, Java, or others?
+We looked briefly at that question.
+Our need was for a well supported, mature runtime that supported
+scripting GUI interfaces and was extensible from C.
+.LP
+We dismissed Java because the runtime is too large and the GUI toolkits
+are weak, both in features and in performance.
+The other runtimes addressed the GUI issues mostly by providing Tk
+bindings (and in some cases Qt or Gtk bindings).
+Any system that is using Tk bindings is already dragging along a Tcl
+interpreter to run the Tk code.
+It seemed like a waste to have a different interpreter just for the GUIs.
+It has also been our experience that the only way to build robust
+software systems is to have the minimum number of ``moving parts.''
+Having two interpreters is an unnecessary complication.
+.LP
+But even if there were a good runtime with a good GUI interface, there was
+another requirement we felt was only well addressed by Tcl.
+Tcl has been designed from the onset to be an extendable language.
+The original vision was that Tcl was glue and all the heavy lifting would
+be done by C extensions to the language.
+The internal Tcl code is fairly small and quite pleasant to use; adding
+extensions is straightforward and natural.
+We needed to take advantage of this feature of the Tcl system and other
+runtimes made this difficult.
+.NH 1
+L vs pure Tcl
+.\" Brian went on and on about syntax / lint checker.
+.\" Coverity example.
+.LP
+Many in the Tcl community may question whether there is any value in an
+alternate syntax for the Tcl runtime.
+After all, Tcl is a powerful, dynamic language and many significant
+applications are based on Tcl.
+.LP
+We agree that Tcl is powerful, but that power comes at a cost.
+Tcl's dynamic nature makes it impossible to detect even simple parse
+errors, such as typos, without running the program.
+.LP
+Although there are advantages to the dynamic approach in language
+design, there are also drawbacks:
+.LI Data structures.
+Probably the single largest problem we found with Tcl was the lack of a
+C-style struct, i.e., a centralized collection of variables with
+annotations indicating why they are there.
+These are commonly emulated in Tcl with associative arrays.
+That isn't good enough because the ``struct fields'' are
+scattered all over the source base rather than being in one place,
+laid out with types and comments.
+To paraphrase Fred Brooks:
+.ft I
+\(lqShow me your code and conceal your data structures, and I shall
+continue to be mystified. Show me your data structures, and I won't
+usually need your code; it'll be obvious.\(rq
+.[
+mythical man month
+.]
+.LI Lint.
+It is impossible to write a syntax checker or a lint-like tool for Tcl that
+works 100% of the time unless that tool is actually running the program it
+is checking.
+Even an interpreter-based tool would have the problem that it is not
+practical to force the application through all possible code paths.
+It is worth noting that this problem is present in all dynamic languages
+and object-oriented languages have the same problem; you can't
+just look at the code and know what it is doing.
+.LI Reviewing.
+As mentioned previously, at BitMover we do a lot of peer review as well as
+other forms of code reading.
+For the same reasons that it is difficult to write a lint-like tool
+for Tcl, it is difficult for a human to look at Tcl and understand what
+it is doing.
+The verbose style of basic operations in Tcl, e.g.,
+.CS
+lset fib $i \\
+ [expr \\
+ {[lindex $fib [expr {$i-1}]] +
+ [lindex $fib [expr {$i-2}]]}]
+.CE
+vs
+.CS
+fib[i] = fib[i-1] + fib[i-2];
+.CE
+tend to obscure what is actually being said in the code.
+.LI Optimization.
+Optimizing Tcl is more challenging than optimizing a ``weaker'' language
+such as L.
+Many well understood optimization techniques could be applied to the
+compilation of L, resulting in a significant performance increase for
+some programs.
+As an example, due to the static type system of L, we believe it's
+possible to make L immune to ``shimmering.''
+.[
+shimmering
+.]
+.LP
+We tend to view Tcl more like assembly language on steroids.
+It is a powerful tool and when that power is needed it is
+appreciated.
+But most of the time we are doing fairly simplistic programming
+deliberately so it is easy to read, and we find that a static language
+with a static type system is much easier for us to read and easier
+for a compiler to optimize and check.
+.NH 1
+L vs native GUIs
+.LP
+This question gets raised at least once a year here: why not do native
+GUIs?
+It is certainly possible to do so.
+We have done implementations of several of our GUIs in other
+toolkits.
+The arguments for doing so are compelling: better look and feel, native
+behavior, etc.
+.LP
+The reasons for staying with Tcl/Tk are simple:
+.LI Cost.
+The cost of creating 2-4 different implementations of each GUI interface is
+probably 3 times what it took us to get where we are today.
+But the cost does not end there.
+The cost extends to testing the GUIs on each platform as well as putting
+processes in place to make sure that the GUIs march forward in sync,
+i.e., if the Java revtool gets a new feature, that same feature needs to
+be added to the Linux, Windows, and Aqua GUIs.
+When we add up all the costs, it looks more like 6 times the effort.
+.LI Functionality.
+Every time we go look at the other toolkits we find that they are not as
+powerful as the Tk toolkit.
+In particular, the canvas and text widgets are more useful than any others
+we have found.
+.sp .5
+That said, a large drawback of the Tk approach is the lack of a complete
+widget set in the core.
+In order to get the functionality needed, a ragtag group of extensions,
+with partially overlapping features, need to be combined into a Tcl/Tk
+``distribution.''
+We look forward to the day that this issue is resolved.
+.NH 1
+L language details
+.LP
+In this section we cover some of the differences from C, differences
+from Tcl, types, call/return conventions, expressions, and control flow.
+.NH 2
+Extensions to C
+.LI Regex.
+L uses Perl's syntax for regular expressions in statements, but it uses
+Tcl's regular expression engine.
+So you may say:
+.CS
+if (a =~ /${r}/) {...
+.CE
+to get the same results as Tcl's
+.CS
+if {[regexp $r $a]} {...
+.CE
+.LI Associative arrays.
+We call these hashes in L to distinguish them from traditional C-style arrays.
+The keys and values are strings.
+.LI Arrays grow.
+If you assign into an array past the last element the array grows as needed.
+Many constructs that would normally use C pointers, such as linked lists
+or trees, can be constructed with an array of structures linked via indices
+rather than pointers.
+.LI defined().
+A built-in that indicates if the variable passed is defined.
+The following tests for the existence of the
+field in the hash, and the existence of the array element, respectively.
+.CS
+defined(foo{"bar"})
+defined(stuff[3])
+.CE
+.LI Strings.
+Strings are first-class objects like any other base type.
+One implication of this is that unlike C strings, which are pointers,
+if you want to pass a reference to the string you must do so
+explicitly.
+.NH 2
+Unimplemented C features
+.LP
+L does not have bit fields, enums, unions, or C-style pointers.
+L currently does not have a C-like preprocessor, though one is planned.
+.NH 2
+Extensions to Tcl
+.LI Type checking.
+L has a weak static type system, which makes it possible to do type
+checking at compile time.
+Note that L's type system is independent of Tcl's runtime type system,
+although the two can interoperate.
+Variables in L may not change types, unlike Tcl variables, which are
+strings except when they're not (as with floats, ints, lists, etc.)
+.LI Structs.
+C-style structs are part of L.
+A Tcl API is provided that supports getting and setting fields as well as
+introspection.
+.LI References.
+Pass by reference in Tcl is possible but awkward.
+Attempts have been made to improve it in Tcl
+.[
+pass by reference
+.]
+but they are unsatisfying.
+We think our syntax is cleaner and easier to read.
+.LI Function prototypes.
+Currently these are used to get type checking when calling Tcl built-ins.
+For example, we can prototype gets() as
+.CS
+extern int gets(FILE, string &);
+.CE
+to always require gets to be called with two arguments.
+We could also prototype gets() as
+.CS
+extern string gets(FILE);
+.CE
+to make it return a string.
+If prototypes are missing, L treats undefined functions as external Tcl
+functions that return poly and take a variable number of arguments of
+type poly.
+.br
+.ne 20
+.NH 2
+Types
+.NH 3
+Simple types
+.LI int.
+Integer types in L are like C integers: they are sized to the
+machine's word size (at least 32 bits and possibly 64).
+Integers in L are initialized to 0, even for local variables.
+.CS
+int a = 5;
+int b; // defaults to 0
+.CE
+.LP
+Any constant that looks like an int is typed as an int.
+.LI float.
+Floating-point numbers in L are at least double-precision IEEE 754.
+Floats are initialized to 0.0, even for local variables.
+.LP
+Any constant that looks like a float is typed as a float.
+Note that this means that assigning an integer to a float is only
+legal because of automatic type conversion.
+.CS
+float f = 1; // converts to 1.0
+float g; // defaults to 0.0
+float pi = 3.14159265;
+.CE
+.LI string.
+The string type is the same as a Tcl string but different from a C string.
+Strings are not null-terminated as they are in C, nor are they arrays
+of bytes.
+L strings are Tcl strings, which are UTF-8 encoded and have a known
+length.
+L strings are initialized to the empty string.
+.LP
+To iterate over each character in a string, use the defined() operator:
+.CS
+int i;
+string s = "a string";
+.sp .5
+for (i = 0; defined(s[i]); i++) {
+ printf("s[%d]=%s\\n", i, s[i]);
+}
+.CE
+Note that there is no separate character type in L.
+When indexing into a string, each character is merely a string of length 1.
+This also means that there is no need to use special single-quoted
+syntax for character literals:
+.CS
+str[i] = "c";
+.CE
+L provides a special escape sequence, ${, which allows embedding code in
+strings.
+All the text from ${ to the matching } is collected and evaluated.
+Its value is then substituted into the string:
+.CS
+int i = 41;
+.sp .5
+printf("41 + 1 is ${i + 1}\\n");
+.CE
+prints:
+.CS
+41 + 1 is 42
+.CE
+.NH 3
+Tclish types
+.LI poly.
+This is a generic type that is like a Tcl variable on which no type checking
+is done.
+Normal variables cause compile-time errors if they attempt to
+change types; a poly variable suppresses the static type checking so
+that a variable can switch from one type to another, e.g. float to
+array or to int, etc.
+The following is legal code:
+.CS
+poly unchecked;
+string s;
+.sp .5
+unchecked = 1;
+unchecked = "Hey there";
+unchecked = 3.14;
+// cast is required
+s = (string)unchecked;
+.CE
+.LI var.
+This is a compromise variable type.
+It is type-checked but the type is not
+set until the first assignment.
+The type is determined from the assignment and may not change.
+The following throws an error:
+.CS
+var late_binding;
+.sp .5
+late_binding = 1;
+late_binding = "Hey there";
+.CE
+As we noted above, constant types are intuited.
+This might cause problems with @var@ variables.
+For example, this throws an error:
+.CS
+var f = 1; // f is now an int
+.sp .5
+f = "pi"; // int/string error
+.CE
+but this works fine:
+.CS
+var f = 1.0;
+.sp .5
+f += 3.14;
+.CE
+.NH 3
+Magic
+.LI :constant.
+Many Tcl/Tk interfaces take key/value pairs that look like
+.CS
+text .t -bg white -fg black
+.CE
+which in L might look like
+.CS
+text(".t",
+ "-bg", "white", "-fg", "black");
+.CE
+We wanted a way to make the @-whatever@ stand out from the values being passed
+as an argument to @-whatever@.
+We decide to do that like this:
+.CS
+text(".t",
+ :bg, "white", :fg, "black");
+.CE
+When the parser sees an identifier in a function call that has a leading
+colon, L treats it as if it were a quoted string with the colon replaced
+by a dash.
+.NH 3
+Compound types
+.LI array.
+Arrays are like C arrays in syntax but are implemented as Tcl lists under
+the covers.
+Array elements are homogeneous; all elements must share the same type.
+Array assignments in declarations are supported for globals and locals:
+.CS
+string foo[] = { "Hi", "there" };
+int bar[] = { 1, 2, 3, 4 };
+int i;
+int total = 0;
+.sp .5
+for (i = 0; defined(bar[i]); i++) {
+ total += bar[i];
+}
+.CE
+Arrays are dynamically grown and cannot be sparse.
+.CS
+int a[2];
+.sp .5
+a[0] = 10;
+a[100] = 20; // allowed
+.CE
+After the previous code has been executed, @a@ has 101 elements.
+@a[1]@ to @a[99]@ have the value 0, which is the default initial
+value for integers.
+.LP
+The defined operator is an easy way to check if an index is outside
+the array bounds:
+.CS
+// prints 'no'
+if (defined(a[101])) {
+ printf("yes\\n");
+} else {
+ printf("no\\n");
+}
+.CE
+.LI hash.
+Hashes are associative arrays, indexed by strings and returning string
+values.
+They are implemented by Tcl dictionaries under the covers.
+Hash assignments in declarations are supported for globals and locals
+and follow the Perl syntax:
+.CS
+hash h = { "key" => "val",
+ "key2" => "val2" };
+.sp .5
+h{"foo"} = "bar";
+if (defined(h{"blech"})) {
+ printf("blech is not a key!\\n");
+}
+.CE
+.LP
+The defined operator can also be used to check if a key is present in a
+hash:
+.CS
+// prints no
+if (defined(foo{"k"})) {
+ printf("yes\\n");
+} else {
+ printf("no\\n");
+}
+.CE
+.br
+.ne 10
+.LP
+It is possible to iterate over each value in a hash using a foreach
+loop:
+.CS
+foreach (h as k => v) {
+ printf("%s => %s\\n", k, v);
+}
+.CE
+.LI struct.
+Structs are collections of typed variables, as in C.
+Declarations are the same as C declarations.
+Struct assignments in declarations are supported for globals and locals:
+.CS
+typedef struct {
+ int a;
+ float b;
+ string c;
+} eg;
+.sp .5
+eg s = { 1, 3.14, "hi there" };
+.CE
+.LP
+Structures are implemented as Tcl lists just like L arrays.
+The names are translated into integer indices by the L compiler.
+Since it is just a Tcl list, an L structure can be passed to any Tcl proc
+that expects a list.
+.LP
+It is likely that we will extend the struct construct to have initializers,
+e.g.,
+.CS
+typedef struct {
+ int a = 1;
+ float b = 3.14;
+ string c = "hi there";
+} eg;
+.sp .5
+eg foo;
+puts(foo.a); // prints 1
+.CE
+.NH 2
+Passing semantics
+.LP
+A C programmer, looking at Tcl, would think that the Tcl model is pass by
+value.
+While Tcl has no way to pass a C-style pointer to an object, it does have
+a way to fake it with something called @upvar@.
+L wants pass by value but it also wants to provide pass by reference.
+This section describes how we used the Tcl system to provide the L passing
+semantics.
+It amounts to a little syntactic sugar on top of @upvar@.
+.NH 3
+By value
+.LP
+L obeys Tcl's semantics for pass by value.
+Parameter passing looks like it does in C:
+.CS
+int i = 1234;
+.sp .5
+foo(i, 0xdeadbeef, "string");
+.CE
+L programs typically do not pass compound types by value to other
+L functions (but see the @(tcl)@ cast below for how to pass them to
+Tcl procs).
+.br
+.ne 8
+.NH 3
+By reference
+.LP
+The Tcl system has a way of passing by reference that might appear strange
+to C programmers.
+.CS
+proc foo {ref} {
+ upvar $ref pointer
+
+ set pointer 1
+}
+.CE
+The @upvar@ command creates a reference to the variable in the caller's
+context and places it in @pointer@.
+Assignments to @pointer@ are the same as if the assignment were done in
+the caller's context (after evaluating the right-hand side).
+.LP
+We used this mechanism to emulate pass by reference in L.
+We call it ``pass by name'' because the caller is putting the name
+of the variable on the stack and the callee is doing an automatic
+@upvar@ to create the reference.
+The syntax looks like:
+.CS
+void foo(int &ref)
+{
+ ref = 1234;
+}
+
+int a = 19;
+.sp .5
+foo(&a);
+puts(a);
+.CE
+and that prints
+.CS
+1234
+.CE
+Arrays and hashes do not take the ampersand because they are trying to
+behave like C arrays, i.e., they are already references.
+.CS
+void clear(int v[])
+{
+ int i;
+.sp .5
+ for (i = 0; defined(v[i]); i++) {
+ v[i] = 0;
+ }
+}
+.sp .5
+int junk[] = { 1, 2, 3 };
+.sp .5
+clear(junk); // junk = { 0, 0, 0 }
+.CE
+Note that strings, unlike in C, are first-class objects and are
+.B not
+references.
+If you want to modify a string, you must pass it by reference.
+For example, to use the Tcl built-in for reading a line of input
+you have to do this:
+.CS
+string buf;
+.sp .5
+// buf is an out parameter
+gets(stdin, &buf);
+.CE
+.NH 3
+L pointers
+.LP
+While the @upvar@ trick works nicely for many cases, there is still a need
+for real pointers.
+When creating a widget, such as an entry box, it would be natural to
+have a struct that contained all the things related to that widget
+such as its path, the variable that the entry box sets, etc., like so:
+.CS
+widgets(entry &e)
+{
+ e.frame = frame(".f");
+ e.entry = entry("${top}.entry");
+ e.entry("configure",
+ :textvariable, &e.textvar);
+}
+.CE
+Our trick of making an ampersand mean ``push the variable name on the
+stack'' does not work here for multiple reasons.
+First, the variable in this case is a structure field, which is an element
+of a Tcl list.
+There is currently no way to pass a list element as a @-variable@ argument;
+Tcl does not support that.
+Second, @-variable@ arguments must be accessible at the global scope.
+There is no guarantee that the name passed in makes sense at the global scope.
+.LP
+What is needed is a way to take an L variable and turn it into something
+that Tcl can find out of the event loop.
+The natural answer is some kind of pointer.
+.LP
+We created a new Tcl object type to hold all the information related to a
+pointer.
+The information looks like:
+.CS
+struct pointer {
+ int depth; // upvar #depth
+ string name; // var pointed to
+ string index; // optional index
+};
+.CE
+The depth field is used to get to the call frame where the variable being
+pointed at was declared.
+For GUI code like the example above, the depth is almost always 0,
+indicating a global.
+The string is the name of the variable to which the pointer refers.
+If the underlying type of the variable is a list (remember that structs
+are implemented as lists) then the index is the index into that list.
+The index is a string because in the future we intend to make pointers
+into hashes work.
+.br
+.ne 20
+.LP
+There is a new Tcl command, @pointer@, which may be used to manipulate
+pointers from Tcl directly.
+The following code creates a pointer,
+points it at the last element of the list @l@,
+uses the pointer to get the value of the variable pointed at,
+and uses the pointer to set the value of the variable pointed at to @foo@.
+When we are done, @$l@ contains \fIa\ b\ foo\fP.
+.CS
+set l [list a b c]
+set p [pointer create l]
+pointer index $p 2
+pointer get $p # prints c
+pointer set $p foo
+.CE
+Let's now consider the widget example above, remembering that it had a
+variable reference @&e.textvar@.
+The compiler provides some magic to treat that construct as
+an L pointer.
+When the compiler sees a string constant of the form @-.*variable@\** and
+the next token is an L variable with a leading ampersand,
+the compiler automatically wraps the variable in an L pointer.
+.FS
+Remember that @:foo@ token is just syntactic sugar for ``@-foo@.''
+.FE
+.NH 3
+Return values
+.LP
+Because returns are by value in L, and Tcl also returns by value,
+no changes were required to make returns work in L.
+.LP
+It is worth noting, especially for C programmers, that there is a sneaky
+way to do an allocation.
+When a local variable is returned, the return bumps the reference count.
+Without that bump, the local variable in question would have been freed
+along with any other locals that were on the callee's stack.
+Tcl objects are reference counted so the variable will get freed when
+the caller is finished with it.
+.CS
+string[]
+vector(int n)
+{
+ string v[];
+.sp .5
+ // Allocate 0..n-1
+ v[n - 1] = "";
+ return (v);
+}
+
+string foo[] = v(100);
+.CE
+.NH 2
+Casts
+.LI (tcl).
+There are times when we need to pass a compound object (array,
+hash) as a string.
+Any Tcl proc that expects to see a string on the stack will want this.
+The @(tcl)@ cast is used to do this.
+.CS
+string v[] = { "hi", "good day" };
+.sp .5
+puts((tcl)v);
+.CE
+prints
+.CS
+hi {good day}
+.CE
+.LI (L).
+There may be times when a Tcl proc is returning a complex structure to us
+and we want to cast it from the Tcl list to our structure:
+.CS
+#lang(tcl)
+proc demo {} {
+ return [list {good day} sir]
+}
+.sp .5
+#lang(L)
+v = (L)demo();
+printf("%s %s\\n", v[0], v[1]);
+.CE
+prints
+.CS
+good day sir
+.CE
+Note: doing this sort of thing puts you at the mercy of the Tcl code
+which knows nothing about the L type system.
+.NH 2
+Operators
+.LP
+L supports most of the operators in the C programming language, as well
+as several of the most useful operators from Perl.
+In this section we do a quick run through all of the operators in L
+and discuss some of their more subtle aspects in depth.
+.LP
+Much of this section is cribbed from the C reference manual.
+.[
+C
+.]
+.NH 3
+Arithmetic operators
+.LP
+The binary arithmetic operators in L are +, -, *, /, and % (modulus).
+They work as in C with the C precedence rules.
+.NH 3
+True vs. false
+.LP
+All of the relational and logical operators are part of an expression and
+that expression evaluates to either true or false.
+.LP
+In L, there is only one false value.
+This is different from Tcl, which allows many false values, such as the
+strings ``false'' and ``off.''
+The false value in L is 0, or, equivalently, ``0''.
+Any value other than 0 is considered true.
+.CS
+if (0) {
+ printf("consequent\\n");
+} else {
+ printf("alternative\\n");
+}
+.CE
+prints: \f(CWalternative\fP
+.br
+.ne 20
+.NH 3
+Numeric Comparison
+.LP
+These all work as in C with the C precedence rules.
+.sp .25
+.B "Relational operators"
+.CS
+@expr@ > @expr@
+@expr@ >= @expr@
+@expr@ < @expr@
+@expr@ <= @expr@
+.CE
+.B "Equality operators"
+.CS
+@expr@ == @expr@
+@expr@ != @expr@
+.CE
+.LI "Logical Operators"
+.sp .25
+The && and || operators short-circuit as in C.
+.CS
+@expr@ && @expr@
+@expr@ || @expr@
+!@expr@
+.CE
+.NH 3
+Regular expression operators
+.LP
+Stolen from Perl, the first form is true if @regex@ is a regular expression
+that matches @string@.
+The second form is true if @regex@ is a regular expression
+that does not match @string@.
+The @//@ construct is an alias for a double quoted string,
+which means that all or part
+of the string may be an interpolated variable (or expression).
+The @m||@ construct is also from perl; it means use the vertical bars instead
+of slashes (frequently useful when dealing with path names).
+.CS
+@string@ =~ /@regex@/
+@string@ !~ /@regex@/
+@string@ =~ m|\fI${expr}\fP|
+.CE
+.ig
+.NH 3
+String Comparison
+.LP
+To use a numeric operator on a string is a type error in L.
+Instead of extending the numeric operators to work on strings, L provides
+a separate set of string operators.
+.LP
+**** relational operators
+
+ gt Greater Than
+ ge Greater Than or Equal
+ lt Less Than
+ le Less Than or Equal
+
+**** equality operators
+
+ eq Equal
+ ne Not equal
+..
+.NH 3
+Increment and Decrement Operators
+.LP
+As in C, with the value returned either before or after the
+increment or decrement.
+.CS
+@lvalue@++
+++@lvalue@
+@lvalue@--
+--@lvalue@
+.CE
+.NH 3
+Bitwise Operators
+.CS
+@expr@ & @expr@
+@expr@ | @expr@
+@expr@ ^ @expr@
+@expr@ << @expr@
+@expr@ >> @expr@
+~@expr@
+.CE
+.ne 10
+.NH 3
+Assignment Operators
+.CS
+@lvalue@ = @expr@
+@lvalue@ += @expr@
+@lvalue@ -= @expr@
+@lvalue@ *= @expr@
+@lvalue@ /= @expr@
+@lvalue@ %= @expr@
+@lvalue@ <<= @expr@
+@lvalue@ >>= @expr@
+@lvalue@ &= @expr@
+@lvalue@ |= @expr@
+@lvalue@ ^= @expr@
+.CE
+.NH 3
+Ternary Operator
+.CS
+@expr@ ? @expr@ : @expr@
+.CE
+.NH 2
+Reserved Words
+.LP
+These are L's reserved words:
+.CS
+break case continue defined do
+else float for foreach if int L
+poly return string struct switch
+tcl typedef unless until var void
+while
+.CE
+.NH 2
+Control flow
+.LI Conditional statements
+.CS
+if ( @expr@ ) @statement@
+if ( @expr@ ) @statement@ else @statement@
+unless ( @expr@ ) @statement@
+.CE
+In all cases @expr@ is evaluated and if it returns anything other than
+zero, then the first
+.B if
+statement is executed.
+If it returns zero, then the
+.B else
+statement or the
+.B unless
+statement is executed.
+.LI While/until statements
+.CS
+while ( @expr@ ) @statement@
+until ( @expr@ ) @statement@
+.CE
+The @expr@ is evaluated and @statement@ is executed repeatedly while
+@expr@ is non-zero in the
+.B while
+case, or zero in the
+.B until
+case.
+.LI do statements
+.CS
+do @statement@ while ( @expr@ )
+do @statement@ until ( @expr@ )
+.CE
+@statement@ is executed repeatedly while @expr@ is non-zero in the
+.B while
+case, or until non-zero in the
+.B until
+case.
+.br
+.ne 10
+.LI for statement
+.CS
+for ( @exp1 sub opt@; @exp2 sub opt@; @exp3 sub opt@ ) @statement@
+.CE
+All expressions are optional.
+Other than the continue statement, which in this case executes
+@exp3@, this is the same as
+.CS
+@exp1@;
+while ( @exp2@ ) {
+ @statement@
+ @exp3@;
+}
+.CE
+.LI foreach statement
+.CS
+foreach (@h@ as @key@ => @val@) @statement@
+foreach (@p@ in @v@) @statement@
+.CE
+The first statement iterates over each key/value pair in the hash @h@.
+The key/value pair is placed in @key@ and @val@
+and then @statement@ is executed.
+Behavior is undefined if keys are inserted or deleted in @h@ in @statement@.
+The second statement sets @p@ to each element of @v@, calling @statement@
+once per element.
+.LI switch statement
+.CS
+switch ( @expr@ ) @statement@
+.CE
+@expr@ must evaluate to an
+.B int
+or a
+.BR string .
+Any statement within @statement@ may contain one or more labeled statements
+of the form
+.CS
+case @constant-expr@: @statement@
+case /@constant-expr@/: @statement@
+case <@constant-expr@>: @statement@
+.CE
+There may be at most one statement of the form:
+.CS
+default: @statement@
+.CE
+When the
+.B switch
+statement is run, @expr@ is evaluated and jumps to the
+.B case
+label that matches.
+Case labels may be double-quoted string constants,
+integer constants (not floats),
+constant regular expressions (@/.*.[ch]/@),
+or constant globs (@<*.[ch]>@).
+If no label matches, then if the
+.B default
+label exists, a jump to the
+.B default
+label occurs.
+As in C, control continues to flow past labels; see
+the \(lqbreak statement\(rq for exiting from a
+.BR switch .
+.LI break
+.CS
+break ;
+.CE
+causes termination of the smallest enclosing
+.BR while ,
+.BR until ,
+.BR do ,
+.BR for ,
+or
+.B switch
+statement.
+.LI continue
+.CS
+continue ;
+.CE
+causes control to pass to the loop-continuation portion of the smallest
+enclosing
+.BR while ,
+.BR until ,
+.BR do ,
+or
+.B for
+loop.
+.LI return
+.CS
+return;
+return ( @expr@ );
+.CE
+In the first case the return value is undefined.
+In the second, the return value is @expr@.
+.NH 2
+Changes to Tcl
+.LP
+In the course of implementing L, two small but important changes were
+made to Tcl that could affect all Tcl programs, although we don't
+expect the effects to be visible.
+.NH 3
+Top-level Compilation
+.LP
+Top-level code in Tcl, i.e., code that isn't contained in a proc body,
+is now passed to the byte-code compiler.
+We require this so that the L compiler can emit byte code for top-level L
+code.
+It could be useful in the future for saving Tcl byte code between
+invocations, similar to the TclPro compiler.
+.NH 3
+Changes to the Tcl Parser
+.LP
+The @#lang(tcl)@ string forces the language to be Tcl, the
+@#lang(L)@ forces the language to be L.
+It is allowed to have snippets of both L and Tcl in the same source file.
+.LP
+When Tcl starts up with a file argument, if the file ends in @.l@ then
+@#lang(L)@ is implicit.
+The default is to start up in Tcl mode.
+.LP
+Tcl's @Tcl_ParseCommand@ has been modified to recognize a
+comment with a special form. Whenever the parser sees @#lang(L)@ it
+stops normal parsing and inserts two tokens into the token stream. The
+first token is a call to the @LCompileCommand@ function and the second
+is the text after the @#lang(L)@ comment up to the next @#lang(tcl)@
+comment or end-of-file.
+.EQ
+delim ||
+.EN
+.NH 1
+Status
+.LP
+The L language is under active development and the speed of development
+is increasing.
+Our expectation is that we will have a usable system in 1-2 months.
+Our goal is to be rewriting our GUI tools in L early in 2007.
+There is a mailing list, \f(CWl@bitmover.com\fP, and an IRC channel,
+\f(CW##l\fP on \f(CWFreenode\fP.
+People are welcome to join either.
+.NH 1
+Future work
+.NH 2
+Scoping
+.LP
+Like a C source file, a scope provides a container for private and/or
+public variables and/or functions.
+This could be used to provide a self-contained ``class.''
+.NH 2
+Pre-compiled modules
+.LP
+Imagine that each scope is a module and each module can be pre-compiled.
+The on-disk format is in sections: there is a byte-code section and a
+sort of table of contents which can be thought of as a header file containing
+function prototypes.
+.NH 2
+Optimizations
+.LP
+The dynamic nature of Tcl means that many traditional compiler optimization
+techniques cannot be used.
+L compiles the source to an abstract syntax tree and could take advantage
+of a number of well known optimizations.
+These include: constant subexpression elimination,
+dead code removal, strength reduction, loop invariant code
+motion, tail-call optimization, code hoisting, and others.
+.[
+optimization
+.]
+.LP
+The lack of general C-like pointers in L greatly simplifies alias analysis
+and makes it possible to be more aggressive when applying optimizations.
+.[
+aliasing1
+.]
+.[
+aliasing2
+.]
+.NH 2
+Debugging
+.LP
+The static nature of L code would make it possible to create a
+mapping between L source code and Tcl byte codes such that traditional
+debugging techniques could be used. One possible approach would be to
+instrument the generated byte code to invoke a debugger every time an L
+statement completes.
+.NH 1
+Licensing and availability
+.LP
+The license is the Tcl license; L is part of Tcl as far as we are
+concerned.
+.LP
+The source is maintained in a BitKeeper repository which is an import of
+the CVS Tcl repository.
+For the 3 people in the world who won't use BK, we will do nightly tarballs
+and make them available on our FTP server.
+.NH 1
+Conclusion
+.LP
+This paper has described the L programming language.
+The L language is unique in that it is an alternate syntax which peacefully
+coexists with the Tcl/Tk system and leverages all of that system.
+.LP
+Over the course of the next year we expect to use L to rewrite our GUI systems.
+Given that L is a young language, we expect that it will continue to evolve
+as we use it.
+It is likely that we will publish
+an updated version of this paper after the language stabilizes.
+.NH 1
+Acknowledgements
+.LP
+The L language draws heavily from the C language. It's hard to imagine
+that Brian, Dennis and Ken want any more pats on the back, but here is one
+more. We are definitely C fans.
+.LP
+Rob Netzer, Brian Griffin, and Mark Roseman were helpful in
+talking over various language problems and ideas.
+.LP
+John Ousterhout for Tcl/Tk, introduced in 1988 and still going strong.
+.LP
+Kennan Rossi for being there as always with editorial help.
+.LP
+This paper was typeset using groff and as always we thank Joe Ossana for
+troff and James Clark for groff.
+.[
+$LIST$
+.]
+.bp
+.de CS
+.sp .25
+.KS
+.in +.5
+.ft CW
+.nf
+.ps 9
+.vs 10
+..
+.de CE
+.sp .25
+.in
+.ft
+.ps
+.vs
+.fi
+.KE
+..
+.SH
+Appendix - code samples
+.SH
+A simple cat
+.CS
+int
+main(int ac, string av[])
+{
+ int i;
+ FILE fd;
+
+ if (ac == 1) {
+ puts(:nonewline, read(stdin));
+ return (0);
+ }
+ for (i = 1; defined(av[i]); i++) {
+ fd = open(av[i], "r");
+ puts(:nonewline, read(fd));
+ }
+}
+.CE
+.SH
+A simple grep
+.CS
+int
+main(int ac, string av[])
+{
+ int i, rc;
+ string regex;
+ FILE fd;
+.sp .5
+ if (ac < 2) {
+ // Tcl's [error]
+ error("Not enough arguments.");
+ }
+ regex = av[1];
+ ac--;
+ if (ac == 1) {
+ rc = grep(regex, stdin) ? 0 : 1;
+ return (rc);
+ } else {
+ rc = 1;
+ for (i = 2; i < ac; i++) {
+ fd = open(av[i], "r");
+ if (grep(regex, fd))) rc = 0;
+ close(fd);
+ }
+ return (rc);
+ }
+
+}
+
+int
+grep(string regex, FILE in)
+{
+ string buf;
+ int matches = 0;
+.sp .5
+ while (gets(in, &buf) >= 0) {
+ if (buf =~ /${regex}/) {
+ printf("%s\\n", buf);
+ matches++;
+ }
+ }
+ return (matches);
+}
+.CE
+.ne 20
+.SH
+Fibonacci
+.CS
+main()
+{
+ int fib[] = fib(100);
+.sp .5
+ for (i=0; defined(fib[i]); i++) {
+ printf("%d\\t%d\\n", i, fib[i]);
+ }
+}
+
+int[]
+fib(int n)
+{
+ int fib[] = { 0, 1 };
+ int i;
+.sp .5
+ for (i=2; i<n; i++) {
+ fib[i] = fib[i-1] + fib[i-2];
+ }
+ return (fib);
+}
+.CE
+.SH
+Quicksort
+.CS
+/*
+ * qsort:
+ * sort v[left]...v[right]
+ * into increasing order.
+ * From K&R C, verbatim.
+ */
+void qsort(int v[], int left, int right)
+{
+ int i, last;
+.sp .5
+ if (left >= right)
+ return;
+ swap(v, left, (left + right)/2);
+ last = left;
+ for (i = left+1; i<= right; i++)
+ if (v[i] < v[left])
+ swap(v, ++last, i);
+ swap(v, left, last);
+ qsort(v, left, last-1);
+ qsort(v, last+1, right);
+}
+
+/* swap: interchange v[i] and v[j] */
+void swap(int v[], int i, int j)
+{
+ int temp;
+.sp .5
+ temp = v[i];
+ v[i] = v[j];
+ v[j] = temp;
+}
+.CE
diff --git a/doc/l-paper/little.ol b/doc/l-paper/little.ol
new file mode 100644
index 0000000..71c812e
--- /dev/null
+++ b/doc/l-paper/little.ol
@@ -0,0 +1,129 @@
+Outline
+ What is it?
+ Why is that interesting?
+ Why not some other runtime?
+ Why not just tcl?
+ Language details
+ Code examples
+ Status or what doesn't work yet
+ Future directions
+ License and Availability
+ What people are saying
+What is it?
+ C-like syntax on top of the Tcl runtime
+ Alternate compiler that generates tcl byte codes
+ Does not change tcl system
+ Interoperates with the tcl system
+ Leverages the tcl runtime
+ An example of a multi-syntax system (can have tcl & L in same file)
+Why not some other runtime?
+ Lotso good stuff about the tcl runtime
+Why not pure tcl?
+ Tcl cons from below
+Why did we do it?
+ Already comitted to tcl/tk
+ Tcl pros
+ Stable runtime
+ Easy to extend in C
+ Powerful, dynamic language
+ Tcl cons
+ Hard to read (for us)
+ No structs - probably the single biggest reason
+ Lots of missing syntactic sugar
+ foo[3] or [lindex foo 3]
+ if (buf =~ /blah.*blech/)
+ or
+ if {[regexp blah.*blah buf]}
+ etc.
+ Pass by reference with upvar is annoying
+ We're a conservative development organization. We sell
+ to enterprise customers and we support releases going back
+ indefinitely in some cases. All code goes through peer review and
+ is optimized for ease of reading more than for ease of writing.
+ We found tcl to be suboptimal in this environment, particularly
+ because of the lack of structs but also because of the lack of
+ syntactic sugar - calling procs to do array indexing is way over
+ our threshold of pain for readability.
+Language details
+ C-like syntax compiled to tcl byte code
+ L can call tcl, tcl can call L
+ Additions over C
+ perl like regex in statements
+ associative arrays
+ defined() for variables, hashes, arrays
+ defined(foo) [info exists] or winfo ???
+ defined(foo{"bar"})
+ defined(blech[2])
+ strings are a basic type like int/float
+ Additions over tcl
+ structs
+ type checking
+ pass by reference improvements
+ function fingerprints
+ Types
+ string (same as tcl string)
+ int, float (type checked)
+ var (unknown type, strongly typed on first assignment)
+ poly (like tcl variable, no type checking)
+ hash (associative array, currently string types for key/val)
+ Implemented as dicts
+ string types as key/values
+ We could allow
+ hash poly foo{poly}
+ if we ever want that fucked up syntax.
+ structs
+ like C structs
+ implemented as lists
+ fields are in ::L::{struct name} as a list of lists,
+ each list is {type name comments}
+ struct struct {
+ string type;
+ string name;
+ string comments;
+ }
+ Pass by reference or value?
+ base types are all by value, COW, like tcl
+ arrays and hashes are implicit references
+ pass an array to a proc, modify array[3], caller sees
+ base types and structures may be passed by reference
+ pass by reference is done with &variable in the
+ caller which is an alias for "variable", i.e.,
+ we pass by name.
+ In the callee the argument also wants a & and it means
+ do an automagic upvar to get the real variable
+ Returns
+ All returns are by value
+ all types just work as expected
+ push the object onto the stack
+ the other end gets the object into it's
+ variable name.
+Code examples
+ printenv.l
+Status or what doesn't work yet
+ Well there are issues
+Future directions
+ Scoping so you can do modules
+ Precompiled modules (and byte code loader)
+ Optimizations
+ Debugging support
+ Having an L contest for the best ($10K seem right?)
+License and Availability
+ Same license as Tcl
+ Exported as tarballs nightly
+What people are saying
+ "It'll make your jaw drop"
+ -- Steve Jobs
+ "It's an amazing, amazing innovation."
+ -- Steve Ballmer
+ "I want to thank Larry McVoy"
+ -- Richard Stallman
+ "L == Tcl 9.0"
+ -- Jeff Hobbs
+ "L? Of course I like it. It's named for me. Right?"
+ -- Linus Torvalds
+ "It's like perl without the nastiest bits"
+ -- Donal K Fellows
+ "I think that's easier to read."
+ -- Larry Wall
+ "L is the coolest thing I've ever seen"
+ -- Vadim Gelfer
diff --git a/doc/l-paper/printenv.l b/doc/l-paper/printenv.l
new file mode 100644
index 0000000..4de5dc7
--- /dev/null
+++ b/doc/l-paper/printenv.l
@@ -0,0 +1,9 @@
+main(int argc, string argv[], hash env)
+{
+ string key, val;
+
+ foreach (env as key => val) {
+ printf("env{%s} = %s\n", key, val);
+ }
+
+}
diff --git a/doc/l-paper/references b/doc/l-paper/references
new file mode 100644
index 0000000..9fe0f9c
--- /dev/null
+++ b/doc/l-paper/references
@@ -0,0 +1,56 @@
+%A Brian W. Kernighan
+%A Lorinda L. Cherry
+%T A System for Typesetting Mathematics
+%J J. Comm. ACM
+%V 18
+%N 3
+%D March 1978
+%P 151-157
+%K eqn
+
+%A Fred Brooks
+%T The Mythical Man Month
+%D 1975
+%K mythical man month
+
+%A The Tcler's Wiki
+%T shimmering
+%J http://wiki.tcl.tk/3033
+%D Dec 2005
+%K shimmering
+
+%A The Tcler's Wiki
+%T use_ref
+%J http://wiki.tcl.tk/15120
+%D Dec 2005
+%K pass by reference
+
+%A Michael Hind
+%T Pointer Analysis: Haven't We Solved This Problem Yet?"
+%D 2001
+%K aliasing1
+
+%A Steven S. Muchnick
+%T Advanced Compiler Design and Implementation
+%D 1997
+%I Morgan Kaufmann
+%K optimization
+
+%A Brian W. Kernighan
+%A Dennis M. Ritchie
+%I Prentice-Hall, Inc.
+%T The C Programming Language
+%D 1978
+%K C
+
+%T Pointer-Induced Aliasing: A Clarification
+%A Thomas J. Marlowe
+%A Jong-Deok Choi
+%A William G. Landi
+%A Michael G. Burke
+%A Barbara G. Ryder
+%A Paul Carini
+%J ACM SIGPLAN Notices
+%D September 1993
+%N Volume 28, No. 9
+%K aliasing2
diff --git a/generic/Last.c b/generic/Last.c
new file mode 100644
index 0000000..0ce480a
--- /dev/null
+++ b/generic/Last.c
@@ -0,0 +1,386 @@
+/*
+ * used to be: tclsh gen-l-ast2.tcl to regenerate
+ * As of Feb 2008 it is maintained by hand.
+ */
+#include "tclInt.h"
+#include "Lcompile.h"
+
+private void
+ast_init(void *node, Node_k type, YYLTYPE beg, YYLTYPE end)
+{
+ Ast *ast = (Ast *)node;
+
+ ast->type = type;
+ ast->loc.beg = beg.beg;
+ ast->loc.end = end.end;
+ ast->loc.line = beg.line;
+ ast->loc.file = beg.file;
+ ast->next = L->ast_list;
+ L->ast_list = (void *)ast;
+}
+
+Block *
+ast_mkBlock(VarDecl *decls, Stmt *body, YYLTYPE beg, YYLTYPE end)
+{
+ Block *block = (Block *)ckalloc(sizeof(Block));
+ memset(block, 0, sizeof(Block));
+ block->body = body;
+ block->decls = decls;
+ ast_init(block, L_NODE_BLOCK, beg, end);
+ return (block);
+}
+
+Expr *
+ast_mkExpr(Expr_k kind, Op_k op, Expr *a, Expr *b, Expr *c, YYLTYPE beg,
+ YYLTYPE end)
+{
+ Expr *expr = (Expr *)ckalloc(sizeof(Expr));
+ memset(expr, 0, sizeof(Expr));
+ expr->a = a;
+ expr->b = b;
+ expr->c = c;
+ expr->kind = kind;
+ expr->op = op;
+ ast_init(expr, L_NODE_EXPR, beg, end);
+ return (expr);
+}
+
+ForEach *
+ast_mkForeach(Expr *expr, Expr *key, Expr *value, Stmt *body,
+ YYLTYPE beg, YYLTYPE end)
+{
+ ForEach *foreach = (ForEach *)ckalloc(sizeof(ForEach));
+ memset(foreach, 0, sizeof(ForEach));
+ foreach->expr = expr;
+ foreach->key = key;
+ foreach->value = value;
+ foreach->body = body;
+ ast_init(foreach, L_NODE_FOREACH_LOOP, beg, end);
+ return (foreach);
+}
+
+FnDecl *
+ast_mkFnDecl(VarDecl *decl, Block *body, YYLTYPE beg, YYLTYPE end)
+{
+ FnDecl *fndecl = (FnDecl *)ckalloc(sizeof(FnDecl));
+ memset(fndecl, 0, sizeof(FnDecl));
+ fndecl->body = body;
+ fndecl->decl = decl;
+ /*
+ * Propagate tracing attributes from L->options, which come
+ * from cmd-line options or #pragmas. Any attributes
+ * specified in the function declaration end up overwriting
+ * these.
+ */
+ fndecl->attrs = Tcl_NewDictObj();
+ hash_put(fndecl->attrs, "fntrace", hash_get(L->options, "fntrace"));
+ hash_put(fndecl->attrs, "fnhook", hash_get(L->options, "fnhook"));
+ hash_put(fndecl->attrs, "trace_depth",
+ hash_get(L->options, "trace_depth"));
+ ast_init(fndecl, L_NODE_FUNCTION_DECL, beg, end);
+ return (fndecl);
+}
+
+Cond *
+ast_mkIfUnless(Expr *expr, Stmt *if_body, Stmt *else_body, YYLTYPE beg,
+ YYLTYPE end)
+{
+ Cond *cond = (Cond *)ckalloc(sizeof(Cond));
+ memset(cond, 0, sizeof(Cond));
+ cond->cond = expr;
+ cond->else_body = else_body;
+ cond->if_body = if_body;
+ ast_init(cond, L_NODE_IF_UNLESS, beg, end);
+ return (cond);
+}
+
+Loop *
+ast_mkLoop(Loop_k kind, Expr *pre, Expr *cond, Expr *post, Stmt *body,
+ YYLTYPE beg, YYLTYPE end)
+{
+ Loop *loop = (Loop *)ckalloc(sizeof(Loop));
+ memset(loop, 0, sizeof(Loop));
+ loop->cond = cond;
+ loop->post = post;
+ loop->pre = pre;
+ loop->kind = kind;
+ loop->body = body;
+ ast_init(loop, L_NODE_LOOP, beg, end);
+ return (loop);
+}
+
+Switch *
+ast_mkSwitch(Expr *expr, Case *cases, YYLTYPE beg, YYLTYPE end)
+{
+ Switch *sw = (Switch *)ckalloc(sizeof(Switch));
+ memset(sw, 0, sizeof(Switch));
+ sw->expr = expr;
+ sw->cases = cases;
+ ast_init(sw, L_NODE_SWITCH, beg, end);
+ return (sw);
+}
+
+Case *
+ast_mkCase(Expr *expr, Stmt *body, YYLTYPE beg, YYLTYPE end)
+{
+ Case *c = (Case *)ckalloc(sizeof(Case));
+ memset(c, 0, sizeof(Case));
+ c->expr = expr;
+ c->body = body;
+ ast_init(c, L_NODE_CASE, beg, end);
+ return (c);
+}
+
+Try *
+ast_mkTry(Stmt *try, Expr *msg, Stmt *catch)
+{
+ Try *t = (Try *)ckalloc(sizeof(Try));
+ memset(t, 0, sizeof(Try));
+ t->try = try;
+ t->msg = msg;
+ t->catch = catch;
+ return (t);
+}
+
+Stmt *
+ast_mkStmt(Stmt_k kind, Stmt *next, YYLTYPE beg, YYLTYPE end)
+{
+ Stmt *stmt = (Stmt *)ckalloc(sizeof(Stmt));
+ memset(stmt, 0, sizeof(Stmt));
+ stmt->next = next;
+ stmt->kind = kind;
+ ast_init(stmt, L_NODE_STMT, beg, end);
+ return (stmt);
+}
+
+TopLev *
+ast_mkTopLevel(Toplv_k kind, TopLev *next, YYLTYPE beg, YYLTYPE end)
+{
+ TopLev *toplev = (TopLev *)ckalloc(sizeof(TopLev));
+ memset(toplev, 0, sizeof(TopLev));
+ toplev->next = next;
+ toplev->kind = kind;
+ ast_init(toplev, L_NODE_TOPLEVEL, beg, end);
+ return (toplev);
+}
+
+VarDecl *
+ast_mkVarDecl(Type *type, Expr *id, YYLTYPE beg, YYLTYPE end)
+{
+ VarDecl *vardecl = (VarDecl *)ckalloc(sizeof(VarDecl));
+ memset(vardecl, 0, sizeof(VarDecl));
+ vardecl->id = id;
+ vardecl->type = type;
+ ast_init(vardecl, L_NODE_VAR_DECL, beg, end);
+ return (vardecl);
+}
+
+ClsDecl *
+ast_mkClsDecl(VarDecl *decl, YYLTYPE beg, YYLTYPE end)
+{
+ ClsDecl *clsdecl = (ClsDecl *)ckalloc(sizeof(ClsDecl));
+ memset(clsdecl, 0, sizeof(ClsDecl));
+ clsdecl->decl = decl;
+ ast_init(clsdecl, L_NODE_CLASS_DECL, beg, end);
+ return (clsdecl);
+}
+
+/* Build a default constructor if the user didn't provide one. */
+FnDecl *
+ast_mkConstructor(ClsDecl *class)
+{
+ char *name;
+ Type *type;
+ Expr *id;
+ VarDecl *decl;
+ Block *block;
+ FnDecl *fn;
+ YYLTYPE loc = class->node.loc;
+
+ type = type_mkFunc(class->decl->type, NULL);
+ name = cksprintf("%s_new", class->decl->id->str);
+ id = ast_mkId(name, loc, loc);
+ decl = ast_mkVarDecl(type, id, loc, loc);
+ decl->flags |= SCOPE_GLOBAL | DECL_CLASS_FN | DECL_PUBLIC |
+ DECL_CLASS_CONST;
+ decl->clsdecl = class;
+ block = ast_mkBlock(NULL, NULL, loc, loc);
+ fn = ast_mkFnDecl(decl, block, loc, loc);
+
+ return (fn);
+}
+
+/* Build a default destructor if the user didn't provide one. */
+FnDecl *
+ast_mkDestructor(ClsDecl *class)
+{
+ char *name;
+ Type *type;
+ Expr *id, *self;
+ VarDecl *decl, *parm;
+ Block *block;
+ FnDecl *fn;
+ YYLTYPE loc = class->node.loc;
+
+ self = ast_mkId("self", loc, loc);
+ parm = ast_mkVarDecl(class->decl->type, self, loc, loc);
+ parm->flags = SCOPE_LOCAL | DECL_LOCAL_VAR;
+ type = type_mkFunc(L_void, parm);
+ name = cksprintf("%s_delete", class->decl->id->str);
+ id = ast_mkId(name, loc, loc);
+ decl = ast_mkVarDecl(type, id, loc, loc);
+ decl->flags |= SCOPE_GLOBAL | DECL_CLASS_FN | DECL_PUBLIC |
+ DECL_CLASS_DESTR;
+ decl->clsdecl = class;
+ block = ast_mkBlock(NULL, NULL, loc, loc);
+ fn = ast_mkFnDecl(decl, block, loc, loc);
+
+ return (fn);
+}
+
+Expr *
+ast_mkUnOp(Op_k op, Expr *e1, YYLTYPE beg, YYLTYPE end)
+{
+ return (ast_mkExpr(L_EXPR_UNOP, op, e1, NULL, NULL, beg, end));
+}
+
+Expr *
+ast_mkBinOp(Op_k op, Expr *e1, Expr *e2, YYLTYPE beg, YYLTYPE end)
+{
+ return (ast_mkExpr(L_EXPR_BINOP, op, e1, e2, NULL, beg, end));
+}
+
+Expr *
+ast_mkTrinOp(Op_k op, Expr *e1, Expr *e2, Expr *e3, YYLTYPE beg,
+ YYLTYPE end)
+{
+ return (ast_mkExpr(L_EXPR_TRINOP, op, e1, e2, e3, beg, end));
+}
+
+Expr *
+ast_mkConst(Type *type, char *str, YYLTYPE beg, YYLTYPE end)
+{
+ Expr *e = ast_mkExpr(L_EXPR_CONST, L_OP_NONE, NULL, NULL, NULL,
+ beg, end);
+ e->type = type;
+ e->str = str;
+ return (e);
+}
+
+Expr *
+ast_mkRegexp(char *re, YYLTYPE beg, YYLTYPE end)
+{
+ Expr *e = ast_mkExpr(L_EXPR_RE, L_OP_NONE, NULL, NULL, NULL, beg, end);
+ e->str = re;
+ e->type = L_string;
+ return (e);
+}
+
+Expr *
+ast_mkFnCall(Expr *id, Expr *arg_list, YYLTYPE beg, YYLTYPE end)
+{
+ Expr *e = ast_mkExpr(L_EXPR_FUNCALL, L_OP_NONE, id, arg_list, NULL,
+ beg, end);
+ return (e);
+}
+
+Expr *
+ast_mkId(char *name, YYLTYPE beg, YYLTYPE end)
+{
+ Expr *e = ast_mkExpr(L_EXPR_ID, L_OP_NONE, NULL, NULL, NULL, beg, end);
+ e->str = ckstrdup(name);
+ return (e);
+}
+
+private Type *
+type_alloc(Type_k kind)
+{
+ Type *type = (Type *)ckalloc(sizeof(Type));
+ memset(type, 0, sizeof(Type));
+ type->kind = kind;
+ type->list = L->type_list;
+ L->type_list = type;
+ return (type);
+}
+
+Type *
+type_dup(Type *type)
+{
+ Type *dup = (Type *)ckalloc(sizeof(Type));
+ *dup = *type;
+ if (type->name) {
+ dup->name = ckstrdup(type->name);
+ }
+ if ((type->kind == L_STRUCT) && type->u.struc.tag) {
+ dup->u.struc.tag = ckstrdup(type->u.struc.tag);
+ }
+ dup->list = L->type_list;
+ L->type_list = dup;
+ return (dup);
+}
+
+Type *
+type_mkScalar(Type_k kind)
+{
+ Type *type = type_alloc(kind);
+ return (type);
+}
+
+Type *
+type_mkArray(Expr *size, Type *base_type)
+{
+ Type *type = type_alloc(L_ARRAY);
+ type->u.array.size = size;
+ type->base_type = base_type;
+ return (type);
+}
+
+Type *
+type_mkHash(Type *index_type, Type *base_type)
+{
+ Type *type = type_alloc(L_HASH);
+ type->u.hash.idx_type = index_type;
+ type->base_type = base_type;
+ return (type);
+}
+
+Type *
+type_mkStruct(char *tag, VarDecl *members)
+{
+ Type *type = type_alloc(L_STRUCT);
+ type->u.struc.tag = ckstrdup(tag);
+ type->u.struc.members = members;
+ return (type);
+}
+
+Type *
+type_mkNameOf(Type *base_type)
+{
+ Type *type = type_alloc(L_NAMEOF);
+ type->base_type = base_type;
+ return (type);
+}
+
+Type *
+type_mkFunc(Type *ret_type, VarDecl *formals)
+{
+ Type *type = type_alloc(L_FUNCTION);
+ type->base_type = ret_type;
+ type->u.func.formals = formals;
+ return (type);
+}
+
+Type *
+type_mkList(Type *a)
+{
+ Type *type = type_alloc(L_LIST);
+ type->base_type = a;
+ return (type);
+}
+
+Type *
+type_mkClass(void)
+{
+ Type *type = type_alloc(L_CLASS);
+ return (type);
+}
diff --git a/generic/Last.h b/generic/Last.h
new file mode 100644
index 0000000..74246f5
--- /dev/null
+++ b/generic/Last.h
@@ -0,0 +1,490 @@
+/*
+ * used to be: tclsh gen-l-ast2.tcl to regenerate
+ * As of Feb 2008 it is maintained by hand.
+ */
+#ifndef L_AST_H
+#define L_AST_H
+
+#define unless(p) if (!(p))
+#define private static
+
+typedef struct Ast Ast;
+typedef struct Block Block;
+typedef struct VarDecl VarDecl;
+typedef struct FnDecl FnDecl;
+typedef struct ClsDecl ClsDecl;
+typedef struct Stmt Stmt;
+typedef struct TopLev TopLev;
+typedef struct ClsLev ClsLev;
+typedef struct Cond Cond;
+typedef struct Loop Loop;
+typedef struct ForEach ForEach;
+typedef struct Switch Switch;
+typedef struct Case Case;
+typedef struct Expr Expr;
+typedef struct Type Type;
+typedef struct Try Try;
+typedef struct Sym Sym;
+
+/*
+ * Source-file offset and line # of an AST node, token, or
+ * nonterminal. Set by the scanner and parser.
+ */
+typedef struct {
+ int beg; // source offset of first char
+ int end; // source offset of last char + 1
+ int line; // line # of first char adjusted for any #include's
+ char *file; // file name
+} YYLTYPE;
+#define YYLTYPE YYLTYPE
+
+typedef enum {
+ L_LOOP_DO,
+ L_LOOP_FOR,
+ L_LOOP_WHILE,
+} Loop_k;
+
+typedef enum {
+ L_STMT_BLOCK,
+ L_STMT_BREAK,
+ L_STMT_COND,
+ L_STMT_CONTINUE,
+ L_STMT_DECL,
+ L_STMT_EXPR,
+ L_STMT_FOREACH,
+ L_STMT_SWITCH,
+ L_STMT_LOOP,
+ L_STMT_RETURN,
+ L_STMT_GOTO,
+ L_STMT_LABEL,
+ L_STMT_PRAGMA,
+ L_STMT_TRY,
+} Stmt_k;
+
+typedef enum {
+ L_TOPLEVEL_CLASS,
+ L_TOPLEVEL_FUN,
+ L_TOPLEVEL_GLOBAL,
+ L_TOPLEVEL_STMT,
+} Toplv_k;
+
+typedef enum {
+ L_NODE_BLOCK,
+ L_NODE_EXPR,
+ L_NODE_FOREACH_LOOP,
+ L_NODE_FUNCTION_DECL,
+ L_NODE_IF_UNLESS,
+ L_NODE_SWITCH,
+ L_NODE_CASE,
+ L_NODE_LOOP,
+ L_NODE_STMT,
+ L_NODE_TOPLEVEL,
+ L_NODE_CLSLEVEL,
+ L_NODE_VAR_DECL,
+ L_NODE_CLASS_DECL,
+} Node_k;
+
+/*
+ * A compiler temp.
+ */
+typedef struct Tmp Tmp;
+struct Tmp {
+ int free;
+ int idx; // local variable slot #
+ char *name;
+ Tmp *next;
+};
+
+/*
+ * An L type name is represented with exactly one instance of a
+ * Type structure. All references to the type name point to that
+ * structure, so pointer comparison can be used to check for name
+ * equivalence of types.
+ *
+ * L_int, L_float, etc are the global Type pointers for the
+ * pre-defined types. L_INT, L_FLOAT, etc are the type kinds
+ * (enum) used in the type structure.
+ *
+ * L_NAMEOF is like an address in other languages. An expression
+ * of this type holds the name of an lvalue (e.g., &p has the value
+ * "p"). The base_type is the type of the name.
+ */
+
+typedef enum {
+ L_INT = 0x0001,
+ L_FLOAT = 0x0002,
+ L_STRING = 0x0004,
+ L_ARRAY = 0x0008,
+ L_HASH = 0x0010,
+ L_STRUCT = 0x0020,
+ L_LIST = 0x0040,
+ L_VOID = 0x0080,
+ L_POLY = 0x0100,
+ L_NAMEOF = 0x0200,
+ L_FUNCTION = 0x0400,
+ L_CLASS = 0x0800,
+ L_WIDGET = 0x1000,
+} Type_k;
+
+struct Type {
+ Type_k kind;
+ Type *base_type; // for array, hash, list, nameof, etc
+ Type *next; // for linking list types
+ char *name; // if a typedef, the type name being declared
+ union {
+ struct {
+ Expr *size;
+ } array;
+ struct {
+ Type *idx_type;
+ } hash;
+ struct {
+ char *tag;
+ VarDecl *members;
+ } struc;
+ struct {
+ VarDecl *formals;
+ } func;
+ struct {
+ ClsDecl *clsdecl;
+ } class;
+ } u;
+ Type *list; // links all type structures ever allocated
+};
+
+struct Ast {
+ Node_k type;
+ Ast *next; // links all nodes in an AST
+ YYLTYPE loc;
+};
+
+struct Block {
+ Ast node;
+ Stmt *body;
+ VarDecl *decls;
+};
+
+typedef enum {
+ L_EXPR_ID,
+ L_EXPR_CONST,
+ L_EXPR_FUNCALL,
+ L_EXPR_UNOP,
+ L_EXPR_BINOP,
+ L_EXPR_TRINOP,
+ L_EXPR_RE,
+} Expr_k;
+
+typedef enum {
+ L_OP_NONE,
+ L_OP_CAST,
+ L_OP_BANG,
+ L_OP_ADDROF,
+ L_OP_MINUS,
+ L_OP_UMINUS,
+ L_OP_PLUS,
+ L_OP_UPLUS,
+ L_OP_PLUSPLUS_PRE,
+ L_OP_PLUSPLUS_POST,
+ L_OP_MINUSMINUS_PRE,
+ L_OP_MINUSMINUS_POST,
+ L_OP_EQUALS,
+ L_OP_EQPLUS,
+ L_OP_EQMINUS,
+ L_OP_EQSTAR,
+ L_OP_EQSLASH,
+ L_OP_EQPERC,
+ L_OP_EQBITAND,
+ L_OP_EQBITOR,
+ L_OP_EQBITXOR,
+ L_OP_EQLSHIFT,
+ L_OP_EQRSHIFT,
+ L_OP_EQTWID,
+ L_OP_BANGTWID,
+ L_OP_EQDOT,
+ L_OP_STAR,
+ L_OP_SLASH,
+ L_OP_PERC,
+ L_OP_STR_EQ,
+ L_OP_STR_NE,
+ L_OP_STR_GT,
+ L_OP_STR_LT,
+ L_OP_STR_GE,
+ L_OP_STR_LE,
+ L_OP_EQUALEQUAL,
+ L_OP_NOTEQUAL,
+ L_OP_GREATER,
+ L_OP_LESSTHAN,
+ L_OP_GREATEREQ,
+ L_OP_LESSTHANEQ,
+ L_OP_ANDAND,
+ L_OP_OROR,
+ L_OP_LSHIFT,
+ L_OP_RSHIFT,
+ L_OP_BITOR,
+ L_OP_BITAND,
+ L_OP_BITXOR,
+ L_OP_BITNOT,
+ L_OP_DEFINED,
+ L_OP_ARRAY_INDEX,
+ L_OP_HASH_INDEX,
+ L_OP_DOT,
+ L_OP_POINTS,
+ L_OP_CLASS_INDEX,
+ L_OP_INTERP_STRING,
+ L_OP_INTERP_RE,
+ L_OP_LIST,
+ L_OP_KV,
+ L_OP_COMMA,
+ L_OP_ARRAY_SLICE,
+ L_OP_EXPAND,
+ L_OP_CONCAT,
+ L_OP_CMDSUBST,
+ L_OP_TERNARY_COND,
+ L_OP_FILE,
+} Op_k;
+
+/*
+ * Flags for L expression compilation. Bits are used for simplicity
+ * even though some of these are mutually exclusive. These are used
+ * in various places such as calls to compile_expr() and in the AST.
+ */
+typedef enum {
+ L_EXPR_RE_I = 0x00000001, // expr is an re with "i" qualifier
+ L_EXPR_RE_G = 0x00000002, // expr is an re with "g" qualifier
+ L_EXPR_RE_T = 0x00000004, // expr is an re with "t" qualifier
+ L_EXPR_DEEP = 0x00000008, // expr is the result of a deep dive
+ L_IDX_ARRAY = 0x00000010, // what kind of thing we're indexing
+ L_IDX_HASH = 0x00000020,
+ L_IDX_STRING = 0x00000040,
+ L_LVALUE = 0x00000080, // if we will be writing the obj
+ L_DELETE = 0x00000100, // delete from parent hash/array/string
+ L_PUSH_VAL = 0x00000200, // what we want INST_L_INDEX to leave on
+ L_PUSH_PTR = 0x00000400, // the stack
+ L_PUSH_VALPTR = 0x00000800,
+ L_PUSH_PTRVAL = 0x00001000,
+ L_DISCARD = 0x00002000, // have compile_expr push nothing
+ L_PUSH_NAME = 0x00004000, // have compile_expr push name not val
+ L_PUSH_NEW = 0x00008000, // whether INST_L_DEEP_WRITE should push
+ L_PUSH_OLD = 0x00010000, // the new or old value
+ L_SAVE_IDX = 0x00020000, // save idx to a tmp var (for copy in/out)
+ L_REUSE_IDX = 0x00040000, // get idx from tmp var instead of expr
+ L_NOTUSED = 0x00080000, // do not update used_p in symtab entry
+ L_NOWARN = 0x00100000, // issue no err if symbol undefined
+ L_SPLIT_RE = 0x00200000, // split on a regexp
+ L_SPLIT_STR = 0x00400000, // split on a string
+ L_SPLIT_LIM = 0x00800000, // enforce split limit
+ L_INSERT_ELT = 0x01000000, // insert a single elt into a list
+ L_INSERT_LIST = 0x02000000, // insert a list into a list
+ L_NEG_OK = 0x04000000, // indexing element -1 is OK
+ L_EXPR_RE_L = 0x08000000, // expr is an re with "l" qualifier
+} Expr_f;
+
+struct Expr {
+ Ast node;
+ Expr_k kind;
+ Op_k op;
+ Type *type;
+ Expr *a;
+ Expr *b;
+ Expr *c;
+ Expr_f flags;
+ Sym *sym; // for id, ptr to symbol table entry
+ char *str; // for constants/id/re/struct-index
+ union {
+ struct {
+ Tmp *idx;
+ Tmp *val;
+ } deepdive;
+ } u;
+ Expr *next;
+};
+
+struct ForEach {
+ Ast node;
+ Expr *expr;
+ Expr *key;
+ Expr *value;
+ Stmt *body;
+};
+
+struct FnDecl {
+ Ast node;
+ Block *body;
+ VarDecl *decl;
+ FnDecl *next;
+ Tcl_Obj *attrs; // hash of function attributes, if any
+};
+
+struct ClsDecl {
+ Ast node;
+ VarDecl *decl;
+ VarDecl *clsvars;
+ VarDecl *instvars;
+ FnDecl *fns;
+ FnDecl *constructors;
+ FnDecl *destructors;
+ Tcl_HashTable *symtab;
+};
+
+struct Cond {
+ Ast node;
+ Expr *cond;
+ Stmt *else_body;
+ Stmt *if_body;
+};
+
+struct Loop {
+ Ast node;
+ Expr *cond;
+ Expr *post;
+ Expr *pre;
+ Loop_k kind;
+ Stmt *body;
+};
+
+struct Switch {
+ Ast node;
+ Expr *expr;
+ Case *cases;
+};
+
+struct Case {
+ Ast node;
+ Expr *expr;
+ Stmt *body;
+ Case *next;
+};
+
+struct Try {
+ Ast node;
+ Stmt *try;
+ Stmt *catch;
+ Expr *msg;
+};
+
+struct Stmt {
+ Ast node;
+ Stmt *next;
+ Stmt_k kind;
+ union {
+ Block *block;
+ Expr *expr;
+ ForEach *foreach;
+ Cond *cond;
+ Loop *loop;
+ Switch *swich; // not a typo -- illegal to call it "switch"
+ VarDecl *decl;
+ char *label;
+ Try *try;
+ } u;
+};
+
+struct TopLev {
+ Ast node;
+ TopLev *next;
+ Toplv_k kind;
+ union {
+ ClsDecl *class;
+ FnDecl *fun;
+ Stmt *stmt;
+ VarDecl *global;
+ } u;
+};
+
+/*
+ * These encode both scope information and the kind of declaration.
+ * Some flags are redundant but were chosen for clarity.
+ */
+typedef enum {
+ SCOPE_LOCAL = 0x00000001, // scope the symbol should go in
+ SCOPE_SCRIPT = 0x00000002, // visible in current script
+ SCOPE_GLOBAL = 0x00000004, // visible across scripts
+ SCOPE_CLASS = 0x00000008, // visible in a class
+ DECL_GLOBAL_VAR = 0x00000010, // the kind of declaration
+ DECL_LOCAL_VAR = 0x00000020,
+ DECL_ERR = 0x00000040, // added on undeclared var
+ DECL_FN = 0x00000080, // regular function
+ DECL_CLASS_VAR = 0x00000100, // class variable
+ DECL_CLASS_INST_VAR = 0x00000200, // class instance variable
+ DECL_CLASS_FN = 0x00000400, // class member fn
+ DECL_CLASS_CONST = 0x00000800, // class constructor
+ DECL_CLASS_DESTR = 0x00001000, // class destructor
+ DECL_REST_ARG = 0x00002000, // ...arg formal parameter
+ DECL_EXTERN = 0x00004000, // decl has extern qualifier
+ DECL_PRIVATE = 0x00008000, // decl has private qualifier
+ DECL_PUBLIC = 0x00010000, // decl has public qualifier
+ DECL_REF = 0x00020000, // decl has & qualifier
+ DECL_ARGUSED = 0x00040000, // decl has _argused qualifier
+ DECL_OPTIONAL = 0x00080000, // decl has _optional qualifier
+ DECL_NAME_EQUIV = 0x00100000, // decl has _mustbetype qualifier
+ DECL_FORWARD = 0x00200000, // a forward decl
+ DECL_DONE = 0x00400000, // decl already processed
+ FN_PROTO_ONLY = 0x00800000, // compile fn proto only
+ FN_PROTO_AND_BODY = 0x01000000, // compile entire fn decl
+} Decl_f;
+
+struct VarDecl {
+ Ast node;
+ Expr *id;
+ char *tclprefix; // prepend to L var name to create Tcl var name
+ Expr *initializer;
+ Expr *attrs; // optional _attributes(...)
+ Type *type;
+ ClsDecl *clsdecl; // for class member fns, class & instance vars
+ Sym *refsym; // for a call-by-ref parm x, ptr to &x sym
+ VarDecl *next;
+ Decl_f flags;
+};
+
+extern Expr *ast_mkBinOp(Op_k op, Expr *e1, Expr *e2, YYLTYPE beg,
+ YYLTYPE end);
+extern Block *ast_mkBlock(VarDecl *decls,Stmt *body, YYLTYPE beg,
+ YYLTYPE end);
+extern Case *ast_mkCase(Expr *expr, Stmt *body, YYLTYPE beg,
+ YYLTYPE end);
+extern ClsDecl *ast_mkClsDecl(VarDecl *decl, YYLTYPE beg, YYLTYPE end);
+extern Expr *ast_mkConst(Type *type, char *str, YYLTYPE beg,
+ YYLTYPE end);
+extern FnDecl *ast_mkConstructor(ClsDecl *class);
+extern FnDecl *ast_mkDestructor(ClsDecl *class);
+extern Expr *ast_mkExpr(Expr_k kind, Op_k op, Expr *a, Expr *b, Expr *c,
+ YYLTYPE beg, YYLTYPE end);
+extern Expr *ast_mkFnCall(Expr *id, Expr *arg_list, YYLTYPE beg,
+ YYLTYPE end);
+extern FnDecl *ast_mkFnDecl(VarDecl *decl, Block *body, YYLTYPE beg,
+ YYLTYPE end);
+extern ForEach *ast_mkForeach(Expr *hash, Expr *key, Expr *value,
+ Stmt *body, YYLTYPE beg, YYLTYPE end);
+extern Expr *ast_mkId(char *name, YYLTYPE beg, YYLTYPE end);
+extern Cond *ast_mkIfUnless(Expr *expr, Stmt *if_body, Stmt *else_body,
+ YYLTYPE beg, YYLTYPE end);
+extern Loop *ast_mkLoop(Loop_k kind, Expr *pre, Expr *cond, Expr *post,
+ Stmt *body, YYLTYPE beg, YYLTYPE end);
+extern Expr *ast_mkRegexp(char *re, YYLTYPE beg, YYLTYPE end);
+extern Stmt *ast_mkStmt(Stmt_k kind, Stmt *next, YYLTYPE beg,
+ YYLTYPE end);
+extern Switch *ast_mkSwitch(Expr *expr, Case *cases, YYLTYPE beg,
+ YYLTYPE end);
+extern TopLev *ast_mkTopLevel(Toplv_k kind, TopLev *next, YYLTYPE beg,
+ YYLTYPE end);
+extern Expr *ast_mkTrinOp(Op_k op, Expr *e1, Expr *e2, Expr *e3,
+ YYLTYPE beg, YYLTYPE end);
+extern Try *ast_mkTry(Stmt *try, Expr *msg, Stmt *catch);
+extern Expr *ast_mkUnOp(Op_k op, Expr *e1, YYLTYPE beg, YYLTYPE end);
+extern VarDecl *ast_mkVarDecl(Type *type, Expr *name, YYLTYPE beg,
+ YYLTYPE end);
+extern void hash_dump(Tcl_Obj *hash);
+extern char *hash_get(Tcl_Obj *hash, char *key);
+extern void hash_put(Tcl_Obj *hash, char *key, char *val);
+extern void hash_rm(Tcl_Obj *hash, char *key);
+extern Type *type_dup(Type *type);
+extern Type *type_mkArray(Expr *size, Type *base_type);
+extern Type *type_mkClass(void);
+extern Type *type_mkFunc(Type *base_type, VarDecl *formals);
+extern Type *type_mkHash(Type *index_type, Type *base_type);
+extern Type *type_mkList(Type *a);
+extern Type *type_mkNameOf(Type *base_type);
+extern Type *type_mkScalar(Type_k kind);
+extern Type *type_mkStruct(char *tag, VarDecl *members);
+
+#endif /* L_AST_H */
diff --git a/generic/Lcompile.c b/generic/Lcompile.c
new file mode 100644
index 0000000..38fb447
--- /dev/null
+++ b/generic/Lcompile.c
@@ -0,0 +1,8167 @@
+/*
+ * Copyright (c) 2006-2009 BitMover, Inc.
+ */
+#include <stdio.h>
+#include <stdarg.h>
+#include <setjmp.h>
+#include "tclInt.h"
+#include "tclIO.h"
+#include "tclCompile.h"
+#include "tclRegexp.h"
+#include "Lcompile.h"
+#include "Lgrammar.h"
+
+/* Used by compile_spawn_system(). */
+enum {
+ SYSTEM_ARGV = 0x00000001,
+ SYSTEM_IN_STRING = 0x00000002,
+ SYSTEM_IN_ARRAY = 0x00000004,
+ SYSTEM_IN_FILENAME = 0x00000008,
+ SYSTEM_IN_HANDLE = 0x00000010,
+ SYSTEM_OUT_STRING = 0x00000020,
+ SYSTEM_OUT_ARRAY = 0x00000040,
+ SYSTEM_OUT_FILENAME = 0x00000080,
+ SYSTEM_OUT_HANDLE = 0x00000100,
+ SYSTEM_ERR_STRING = 0x00000200,
+ SYSTEM_ERR_ARRAY = 0x00000400,
+ SYSTEM_ERR_FILENAME = 0x00000800,
+ SYSTEM_ERR_HANDLE = 0x00001000,
+ SYSTEM_BACKGROUND = 0x00002000,
+};
+
+/*
+ * As of March 2009, we use a bit in the Tcl_Obj structure to
+ * represent when an object has the L undefined value. This avoids
+ * the problems we had when Tcl would shimmer undef away into another
+ * type, making it look defined. But we also need an undef object, as
+ * the value of array, hash, and struct members when they dynamically
+ * are brought into life. This is also the value of the "undef"
+ * pre-defined constant. We create one object of this type and dup it
+ * whenever undef is requested.
+ */
+
+private void
+undef_freeInternalRep(Tcl_Obj *o)
+{
+}
+
+/*
+ * Return an error if someone tries to convert something to undef
+ * type.
+ */
+private int
+undef_setFromAny(Tcl_Interp *interp, Tcl_Obj *o)
+{
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("cannot convert to undefined value",
+ -1));
+ return (TCL_ERROR);
+}
+
+/*
+ * Get a pointer to the "undefined" object pointer, allocating it the
+ * first time it is needed. Keep the refCount high because we want
+ * the one-and-only undef object to never be freed.
+ */
+Tcl_Obj **
+L_undefObjPtrPtr()
+{
+ static Tcl_Obj *undef_obj = NULL;
+
+ unless (undef_obj) {
+ undef_obj = Tcl_NewObj();
+ undef_obj->bytes = tclEmptyStringRep;
+ undef_obj->typePtr = &L_undefType;
+ undef_obj->undef = 1;
+ undef_obj->refCount = 1234; // arbitrary; to be recognizable
+ }
+ ASSERT(undef_obj->undef);
+ return (&undef_obj);
+}
+
+int
+L_isUndef(Tcl_Obj *o)
+{
+ return (o->undef);
+}
+
+Tcl_ObjType L_undefType = {
+ "undef",
+ undef_freeInternalRep,
+ NULL,
+ NULL,
+ undef_setFromAny
+};
+
+/* Returned by re_kind. */
+typedef enum {
+ RE_NOT_AN_RE = 0x0001,
+ RE_CONST = 0x0002,
+ RE_GLOB = 0x0004,
+ RE_SIMPLE = 0x0008,
+ RE_COMPLEX = 0x0010,
+ RE_NEEDS_EVAL = 0x0020,
+} ReKind;
+
+/* Used by tmp_* API. */
+typedef enum {
+ TMP_REUSE,
+ TMP_UNSET,
+} TmpKind;
+
+/*
+ * Lists of allowable attributes in #pragma, _attribute, and cmd-line
+ * options. Each array must end with a NULL.
+ */
+char *L_attrs_attribute[] = {
+ "dis",
+ "fnhook",
+ "fntrace",
+ "trace_depth",
+ NULL
+};
+char *L_attrs_cmdLine[] = {
+ "L",
+ "dis",
+ "fnhook",
+ "fntrace",
+ "line",
+ "lineadj",
+ "norun",
+ "nowarn",
+ "poly",
+ "trace_depth",
+ "trace_files",
+ "trace_funcs",
+ "trace_out",
+ "trace_script",
+ "warn_undefined_fns",
+ "version",
+ NULL
+};
+char *L_attrs_pragma[] = {
+ "dis",
+ "fnhook",
+ "fntrace",
+ "line",
+ "lineadj",
+ "norun",
+ "nowarn",
+ "poly",
+ "trace_depth",
+ "warn_undefined_fns",
+ NULL
+};
+char *L_attrs_Lhtml[] = {
+ "line",
+ "lineadj",
+};
+
+/* The next two functions are generated by flex. */
+extern void *L__scan_bytes (const char *bytes, int len);
+extern void L__delete_buffer(void *buf);
+
+private int ast_compile(void *ast);
+private void ast_free(Ast *ast_list);
+private char *basenm(char *s);
+private int compile_abs(Expr *expr);
+private int compile_assert(Expr *expr);
+private void compile_assign(Expr *expr);
+private void compile_assignComposite(Expr *expr);
+private void compile_assignFromStack(Expr *lhs, Type *rhs_type, Expr *expr,
+ int flags);
+private int compile_binOp(Expr *expr, Expr_f flags);
+private void compile_block(Block *block);
+private void compile_break(Stmt *stmt);
+private int compile_cast(Expr *expr, Expr_f flags);
+private int compile_catch(Expr *expr);
+private void compile_clsDecl(ClsDecl *class);
+private int compile_clsDeref(Expr *expr, Expr_f flags);
+private int compile_clsInstDeref(Expr *expr, Expr_f flags);
+private void compile_condition(Expr *cond);
+private void compile_continue(Stmt *stmt);
+private void compile_defined(Expr *expr);
+private int compile_die(Expr *expr);
+private void compile_do(Loop *loop);
+private void compile_eq_stack(Expr *expr, Type *type);
+private void compile_for_while(Loop *loop);
+private int compile_idxOp(Expr *expr, Expr_f flags);
+private int compile_idxOp2(Expr *expr, Expr_f flags);
+private int compile_expr(Expr *expr, Expr_f flags);
+private int compile_exprs(Expr *expr, Expr_f flags);
+private int compile_fnCall(Expr *expr);
+private void compile_fnDecl(FnDecl *fun, Decl_f flags);
+private void compile_fnDecls(FnDecl *fun, Decl_f flags);
+private void compile_foreach(ForEach *loop);
+private void compile_foreachAngle(ForEach *loop);
+private void compile_foreachArray(ForEach *loop);
+private void compile_foreachHash(ForEach *loop);
+private void compile_foreachString(ForEach *loop);
+private void compile_goto(Stmt *stmt);
+private int compile_here(Expr *expr);
+private void compile_ifUnless(Cond *cond);
+private void compile_incdec(Expr *expr);
+private int compile_insert_unshift(Expr *expr);
+private int compile_join(Expr *expr);
+private int compile_keys(Expr *expr);
+private void compile_label(Stmt *stmt);
+private int compile_length(Expr *expr);
+private void compile_loop(Loop *loop);
+private int compile_min_max(Expr *expr);
+private int compile_fnParms(VarDecl *decl);
+private int compile_popen(Expr *expr);
+private int compile_pop_shift(Expr *expr);
+private int compile_push(Expr *expr);
+private void compile_reMatch(Expr *re);
+private int compile_read(Expr *expr);
+private int compile_rename(Expr *expr);
+private void compile_return(Stmt *stmt);
+private int compile_script(Tcl_Obj *scriptObj, Tcl_Obj *nameObj);
+private void compile_shortCircuit(Expr *expr);
+private int compile_sort(Expr *expr);
+private int compile_spawn_system(Expr *expr);
+private int compile_split(Expr *expr);
+private void compile_stmt(Stmt *stmt);
+private void compile_stmts(Stmt *stmt);
+private void compile_switch(Switch *sw);
+private void compile_switch_fast(Switch *sw);
+private void compile_switch_slow(Switch *sw);
+private int compile_trinOp(Expr *expr);
+private int compile_trace_script(char *script);
+private void compile_trycatch(Stmt *stmt);
+private void compile_twiddle(Expr *expr);
+private void compile_twiddleSubst(Expr *expr);
+private int compile_typeof(Expr *expr);
+private int compile_undef(Expr *expr);
+private int compile_unOp(Expr *expr);
+private int compile_var(Expr *expr, Expr_f flags);
+private void compile_varDecl(VarDecl *decl);
+private void compile_varDecls(VarDecl *decls);
+private int compile_warn(Expr *expr);
+private int compile_write(Expr *expr);
+private void copyout_parms(Expr *actuals);
+private Tcl_Obj *do_getline(Tcl_Interp *interp, Tcl_Channel chan);
+private void emit_globalUpvar(Sym *sym);
+private void emit_instrForLOp(Expr *expr, Type *type);
+private void emit_jmp_back(TclJumpType jmp_type, int offset);
+private Jmp *emit_jmp_fwd(int op, Jmp *next);
+private void fixup_jmps(Jmp **jumps);
+private int fnCallBegin();
+private void fnCallEnd(int lev);
+private int fnInArgList();
+private Frame *frame_find(Frame_f flags);
+private char *frame_name(void);
+private void frame_pop(void);
+private void frame_push(void *node, char *name, Frame_f flags);
+private void frame_resumeBody();
+private void frame_resumePrologue();
+private char *get_text(Expr *expr);
+private int has_END(Expr *expr);
+private void init_predefined();
+private Type *iscallbyname(VarDecl *formal);
+private int ispatternfn(char *name, Expr **foo, Expr **Foo_star,
+ Expr **opts, int *nopts);
+private Label *label_lookup(Stmt *stmt, Label_f flags);
+private Expr *mkId(char *name);
+private int parse_options(int objc, Tcl_Obj **objv, char *allowed[]);
+private int parse_script(char *str, Ast **L_ast, Tcl_Obj *nameObj);
+private void proc_mkArg(Proc *proc, VarDecl *decl);
+private int push_index(Expr *expr, int flags);
+private int push_parms(Expr *actuals, VarDecl *formals);
+private int push_regexpModifiers(Expr *regexp);
+private ReKind re_kind(Expr *re, Tcl_DString *ds);
+private int re_submatchCnt(Expr *re);
+private VarDecl *struct_lookupMember(Type *t, Expr *idx, int *offset);
+private Sym *sym_mk(char *name, Type *t, Decl_f flags);
+private Sym *sym_lookup(Expr *id, Expr_f flags);
+private Sym *sym_store(VarDecl *decl);
+private Tmp *tmp_get(TmpKind kind);
+private void tmp_free(Tmp *tmp);
+private void tmp_freeAll(Tmp *tmp);
+private void track_cmd(int codeOffset, void *node);
+private void type_free(Type *type_list);
+private int typeck_spawn(Expr *in, Expr *out, Expr *err);
+private int typeck_system(Expr *in, Expr *out, Expr *err);
+
+Linterp *L; // per-interp L state
+Type *L_int; // pre-defined types
+Type *L_float;
+Type *L_string;
+Type *L_void;
+Type *L_var;
+Type *L_poly;
+Type *L_widget;
+
+/*
+ * L built-in functions.
+ */
+static struct {
+ char *name;
+ int (*fn)(Expr *);
+} builtins[] = {
+ { "abs", compile_abs },
+ { "assert", compile_assert },
+ { "catch", compile_catch },
+ { "die", compile_die },
+ { "here", compile_here },
+ { "insert", compile_insert_unshift },
+ { "join", compile_join },
+ { "keys", compile_keys },
+ { "length", compile_length },
+ { "max", compile_min_max },
+ { "min", compile_min_max },
+ { "popen", compile_popen },
+ { "pop", compile_pop_shift },
+ { "push", compile_push },
+ { "read", compile_read },
+ { "rename", compile_rename },
+ { "shift", compile_pop_shift },
+ { "sort", compile_sort },
+ { "split", compile_split },
+ { "spawn", compile_spawn_system },
+ { "system", compile_spawn_system },
+ { "typeof", compile_typeof },
+ { "undef", compile_undef },
+ { "unshift", compile_insert_unshift },
+ { "warn", compile_warn },
+ { "write", compile_write },
+};
+
+/*
+ * L compiler entry point.
+ */
+int
+Tcl_LObjCmd(ClientData clientData, Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[])
+{
+ char *s;
+ int argc, ret;
+ Tcl_Obj **argvList;
+
+ /* Extract the L state from the interp. */
+ L = Tcl_GetAssocData(interp, "L", NULL);
+
+ /*
+ * Verify that lib L was loaded. L fails badly if lib L isn't
+ * there, and this catches cases where the user overrides the
+ * Tcl library path.
+ */
+ unless (Tcl_GetVar(L->interp, "::L_libl_initted", 0)) {
+ Tcl_SetResult(L->interp, "fatal -- libl.tcl not found", 0);
+ return (TCL_ERROR);
+ }
+
+ if (objc < 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "?options? l-program");
+ return (TCL_ERROR);
+ }
+
+ /* Parse options from both the Tcl L command and the tclsh cmd line. */
+ L->errs = NULL;
+ L->options = Tcl_NewDictObj();
+ ret = parse_options(objc-1, (Tcl_Obj **)(objv+1), L_attrs_cmdLine);
+ unless (ret == TCL_OK) {
+ Tcl_SetObjResult(interp, L->errs);
+ return (ret);
+ }
+ if (L->global->tclsh_argv &&
+ Tcl_ListObjGetElements(L->interp, L->global->tclsh_argv, &argc,
+ &argvList) == TCL_OK) {
+ ret = parse_options(argc-1, argvList+1, L_attrs_cmdLine);
+ unless (ret == TCL_OK) {
+ Tcl_SetObjResult(interp, L->errs);
+ return (ret);
+ }
+ }
+
+ /* L_synerr() longjmps back here on a parser syntax error. */
+ if (setjmp(L->jmp)) {
+ Tcl_SetObjResult(interp, L->errs);
+ return (TCL_ERROR);
+ }
+
+ /*
+ * If a function-tracing script was specified in
+ * --trace_script or L_TRACE_SCRIPT (takes precedence),
+ * compile that (once) but only after libL has been compiled.
+ */
+ unless (hash_get(L->options, "trace_script_compiled")) {
+ if ((s = getenv("L_TRACE_SCRIPT"))) {
+ hash_put(L->options, "trace_script", s);
+ }
+ if ((s = hash_get(L->options, "trace_script")) &&
+ Tcl_GetVar(L->interp, "::L_libl_done", 0)) {
+ hash_put(L->options, "trace_script_compiled", "yes");
+ s = ckstrdup(s);
+ ret = compile_trace_script(s);
+ if (ret != TCL_OK) return (ret);
+ }
+ }
+
+ /*
+ * Propagate some cmd-line options to env variables for lib L.
+ * Pre-existing env variables take precedence.
+ */
+ if ((s = hash_get(L->options, "trace_funcs"))) {
+ unless (getenv("L_TRACE_FUNCS")) {
+ s = cksprintf("L_TRACE_FUNCS=%s", s);
+ putenv(s);
+ }
+ }
+ if ((s = hash_get(L->options, "trace_files"))) {
+ unless (getenv("L_TRACE_FILES")) {
+ s = cksprintf("L_TRACE_FILES=%s", s);
+ putenv(s);
+ }
+ }
+ if ((s = hash_get(L->options, "trace_out"))) {
+ unless (getenv("L_TRACE_OUT")) {
+ s = cksprintf("L_TRACE_OUT=%s", s);
+ putenv(s);
+ }
+ }
+ if ((s = hash_get(L->options, "fnhook"))) {
+ unless (getenv("L_TRACE_HOOK")) {
+ s = cksprintf("L_TRACE_HOOK=%s", s);
+ putenv(s);
+ }
+ }
+ if ((s = hash_get(L->options, "fntrace"))) {
+ unless (getenv("L_TRACE_ALL")) {
+ s = cksprintf("L_TRACE_ALL=%s", s);
+ putenv(s);
+ }
+ }
+ if ((s = hash_get(L->options, "dis"))) {
+ unless (getenv("L_DISASSEMBLE")) {
+ s = cksprintf("L_DISASSEMBLE=%s", s);
+ putenv(s);
+ }
+ }
+
+ /* This allows the old comparison-op syntax (eq ne lt le gt ge). */
+ if (getenv("_L_ALLOW_EQ_OPS")) {
+ hash_put(L->options, "allow_eq_ops", "yes");
+ }
+
+ return (compile_script(objv[objc-1], ((Interp *)L->interp)->scriptFile));
+}
+
+private int
+compile_trace_script(char *script)
+{
+ int len, ret;
+ Tcl_Channel chan;
+ Tcl_Obj *nameObj, *scriptObj;
+
+ len = strlen(script);
+ if ((len > 3) && (script[len-2] == '.') && (script[len-1] == 'l')) {
+ nameObj = Tcl_NewStringObj(script, -1);
+ Tcl_IncrRefCount(nameObj);
+ chan = Tcl_FSOpenFileChannel(L->interp, nameObj, "r", 0644);
+ unless (chan) return (TCL_ERROR);
+ scriptObj = Tcl_NewObj();
+ Tcl_IncrRefCount(scriptObj);
+ ret = Tcl_ReadChars(chan, scriptObj, -1, 0);
+ Tcl_Close(L->interp, chan);
+ if (ret < 0) {
+ Tcl_DecrRefCount(scriptObj);
+ return (TCL_ERROR);
+ }
+ } else {
+ nameObj = Tcl_NewStringObj("L_TRACE_SCRIPT", -1);
+ scriptObj = Tcl_ObjPrintf(
+ "void L_fn_hook(_argused int pre, _argused poly av[], "
+ "_argused poly ret) { %s ;}",
+ script);
+ hash_put(L->options, "fnhook", "L_fn_hook");
+ Tcl_IncrRefCount(nameObj);
+ }
+ ret = compile_script(scriptObj, nameObj);
+ Tcl_DecrRefCount(nameObj);
+ return (ret);
+}
+
+private int
+compile_script(Tcl_Obj *scriptObj, Tcl_Obj *nameObj)
+{
+ int ret;
+ Ast *ast;
+#ifdef TCL_COMPILE_DEBUG
+ char *s;
+#endif
+
+ L->script = Tcl_NewObj();
+ Tcl_IncrRefCount(L->script);
+ L->script_len = 0;
+
+ ret = parse_script(TclGetString(scriptObj), &ast, nameObj);
+
+ if ((ret == TCL_OK) && ast) {
+ ret = ast_compile(ast);
+ }
+
+#ifdef TCL_COMPILE_DEBUG
+ if ((s = getenv("L_TRACE_BYTECODES"))) {
+ extern int tclTraceExec;
+ tclTraceExec = atoi(s);
+ }
+#endif
+ return (ret);
+}
+
+/*
+ * Parse key=val (where =val is optional and is replaced by "yes" if
+ * omitted) and add to the L->options hash. Strip any leading -'s from
+ * key so that -key and --key both work. Replace all other -'s with _'s
+ * so that --trace-files becomes trace_files.
+ */
+private int
+parse_options(int objc, Tcl_Obj **objv, char *allowed[])
+{
+ int i, ret = TCL_OK;
+ char *key, *newkey, *p, *val;
+ char **q;
+
+ for (i = 0; i < objc; ++i) {
+ key = Tcl_GetString(objv[i]);
+ unless (key[0] == '-') break;
+ /* Look for key=val */
+ val = strchr(key, '=');
+ if (val) {
+ *val = 0;
+ }
+ newkey = ckalloc(strlen(key)+1);
+ /* Skip past all leading -'s in the key */
+ while (*key == '-') ++key;
+ /* Now copy except replace all other -'s with _ */
+ for (p = newkey; *key; ++key, ++p) {
+ *p = *key;
+ if (*p == '-') *p = '_';
+ }
+ *p = 0;
+ key = newkey;
+ for (q = allowed; *q; ++q) {
+ if (!strcmp(key, *q)) break;
+ }
+ unless (*q) {
+ L_errf(NULL, "illegal option '%s'",
+ Tcl_GetString(objv[i]));
+ ret = TCL_ERROR;
+ }
+ if (val) {
+ hash_put(L->options, key, val+1);
+ *val = '=';
+ } else {
+ hash_put(L->options, key, "yes");
+ }
+ }
+ return (ret);
+}
+
+/*
+ * Parse an L script into an AST. Parsing and compiling are broken into two
+ * stages in order to support an interactive mode that parses many times
+ * before finally compiling.
+ */
+private int
+parse_script(char *str, Ast **ast_p, Tcl_Obj *nameObj)
+{
+ char *prepend, *s;
+ void *lex_buffer;
+
+ L_typeck_init();
+
+ if (nameObj) {
+ L->file = ckstrdup(Tcl_GetString(nameObj));
+ L->dir = L_dirname(L->file);
+ } else {
+ char *cwd = getcwd(NULL, 0);
+ L->file = ckstrdup("<stdin>");
+ L->dir = ckstrdup(cwd);
+ free(cwd);
+ }
+
+ /*
+ * Calculate the starting line # from the --line and --lineadj
+ * cmd-line options and inject a #line directive at the start
+ * of the source code. This communicates the file-relative
+ * line # to code elsewhere that prints run-time error
+ * messages.
+ */
+ if ((s = getenv("_L_LINE"))) {
+ L->line = strtoul(s, NULL, 10);
+ } else {
+ if ((s = hash_get(L->options, "line"))) {
+ L->line = atoi(s);
+ } else {
+ L->line = 1;
+ }
+ if ((s = hash_get(L->options, "lineadj"))) {
+ L->line += atoi(s);
+ }
+ }
+ prepend = cksprintf("#line %d\n", L->line);
+ str = cksprintf("%s%s", prepend, str);
+
+ L->token_off = 0;
+ L->prev_token_off = 0;
+ L->prev_token_len = 0;
+ L->errs = NULL;
+ L_lex_start();
+ lex_buffer = (void *)L__scan_bytes(str, strlen(str));
+
+ L_parse();
+ ASSERT(ast_p);
+ *ast_p = L->ast;
+
+ L__delete_buffer(lex_buffer);
+ ckfree(str);
+ ckfree(prepend);
+
+ if (L->errs) {
+ Tcl_SetObjResult(L->interp, L->errs);
+ return (TCL_ERROR);
+ }
+ return (TCL_OK);
+}
+
+/* Compile an L AST into Tcl ByteCodes. The envPtr may be NULL. */
+private int
+ast_compile(void *ast)
+{
+ int ret = TCL_OK;
+ TopLev *toplev;
+ static int ctr = 0;
+
+ ASSERT(((Ast *)ast)->type == L_NODE_TOPLEVEL);
+
+ L->toplev = cksprintf("%d%%l_toplevel", ctr++);
+
+ init_predefined(); // set the L pre-defined identifiers
+
+ /*
+ * Two frames get pushed, one for private globals that exist
+ * at file scope, and one for the top-level code. See the
+ * comment in sym_store().
+ */
+ frame_push(NULL, NULL, SCRIPT|SEARCH);
+ frame_push(NULL, L->toplev, FUNC|TOPLEV|SKIP);
+
+ /*
+ * Before compiling, enter prototypes for all functions into
+ * the global symbol table.
+ */
+ for (toplev = (TopLev *)ast; toplev; toplev = toplev->next) {
+ switch (toplev->kind) {
+ case L_TOPLEVEL_FUN:
+ compile_fnDecl(toplev->u.fun, FN_PROTO_ONLY);
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (toplev = (TopLev *)ast; toplev; toplev = toplev->next) {
+ switch (toplev->kind) {
+ case L_TOPLEVEL_CLASS:
+ compile_clsDecl(toplev->u.class);
+ break;
+ case L_TOPLEVEL_FUN:
+ compile_fnDecl(toplev->u.fun, FN_PROTO_AND_BODY);
+ break;
+ case L_TOPLEVEL_GLOBAL:
+ compile_varDecls(toplev->u.global);
+ break;
+ case L_TOPLEVEL_STMT:
+ compile_stmts(toplev->u.stmt);
+ break;
+ default:
+ L_bomb("Unexpected toplevel stmt type %d", toplev->kind);
+ }
+ }
+
+ /* If main() was defined, emit a %%call_main_if_defined call. */
+ if (sym_lookup(mkId("main"), L_NOWARN)) {
+ if (hash_get(L->options, "warn_undefined_fns")) {
+ push_lit("%%check_L_fns");
+ emit_invoke(1);
+ }
+ push_lit("%%call_main_if_defined");
+ emit_invoke(1);
+ }
+
+ push_lit("");
+ TclEmitOpcode(INST_DONE, L->frame->envPtr);
+ frame_pop();
+ frame_pop();
+
+ if (L->errs) {
+ Tcl_SetObjResult(L->interp, L->errs);
+ return (TCL_ERROR);
+ }
+
+ if (hash_get(L->options, "norun") || (L->err && !getenv("_L_TEST"))) {
+ /* Still check for undefined functions if requested. */
+ if (hash_get(L->options, "warn_undefined_fns") &&
+ sym_lookup(mkId("main"), L_NOWARN)) {
+ if (L->frame->envPtr) {
+ push_lit("%%check_L_fns");
+ emit_invoke(1);
+ } else {
+ Tcl_Eval(L->interp, "%%check_L_fns");
+ }
+ }
+ return (TCL_OK);
+ }
+
+ /* Invoke the top-level code that was just compiled. */
+ if (L->frame->envPtr) {
+ push_lit("LtraceInit");
+ emit_invoke(1);
+ push_lit(L->toplev);
+ emit_invoke(1);
+ } else {
+ if (Tcl_GetVar(L->interp, "::L_libl_done", 0)) {
+ ret = Tcl_Eval(L->interp, "LtraceInit");
+ }
+ if (ret == TCL_OK) ret = Tcl_Eval(L->interp, L->toplev);
+ }
+ return (ret);
+}
+
+private void
+init_predefined()
+{
+#define SET_INT(name, val) \
+ Tcl_SetVar2Ex(L->interp, (name), NULL, Tcl_NewIntObj(val), \
+ TCL_GLOBAL_ONLY)
+
+ /*
+ * These are flags used by compile_spawn_system() when
+ * compiling calls to libl.tcl's system_(). Pre-define them as L
+ * variables so that system_() in lib L can see their values.
+ */
+ SET_INT("SYSTEM_ARGV__", SYSTEM_ARGV);
+ SET_INT("SYSTEM_IN_STRING__", SYSTEM_IN_STRING);
+ SET_INT("SYSTEM_IN_ARRAY__", SYSTEM_IN_ARRAY);
+ SET_INT("SYSTEM_IN_FILENAME__", SYSTEM_IN_FILENAME);
+ SET_INT("SYSTEM_IN_HANDLE__", SYSTEM_IN_HANDLE);
+ SET_INT("SYSTEM_OUT_STRING__", SYSTEM_OUT_STRING);
+ SET_INT("SYSTEM_OUT_ARRAY__", SYSTEM_OUT_ARRAY);
+ SET_INT("SYSTEM_OUT_FILENAME__", SYSTEM_OUT_FILENAME);
+ SET_INT("SYSTEM_OUT_HANDLE__", SYSTEM_OUT_HANDLE);
+ SET_INT("SYSTEM_ERR_STRING__", SYSTEM_ERR_STRING);
+ SET_INT("SYSTEM_ERR_ARRAY__", SYSTEM_ERR_ARRAY);
+ SET_INT("SYSTEM_ERR_FILENAME__", SYSTEM_ERR_FILENAME);
+ SET_INT("SYSTEM_ERR_HANDLE__", SYSTEM_ERR_HANDLE);
+ SET_INT("SYSTEM_BACKGROUND__", SYSTEM_BACKGROUND);
+
+#undef SET_INT
+}
+
+private void
+compile_clsDecl(ClsDecl *clsdecl)
+{
+ ASSERT(clsdecl->constructors);
+ ASSERT(clsdecl->destructors);
+
+ /*
+ * A class creates two scopes, one for the class symbols and
+ * the other for its top-level code (class variable
+ * initializers). See the comments in sym_store(). The class
+ * symtab is persisted so it can be later retrieved from the
+ * class type to support obj->var or classname->var lookups.
+ */
+ frame_push(NULL, NULL, CLS_OUTER|SEARCH|KEEPSYMS);
+ clsdecl->symtab = L->frame->symtab;
+ frame_push(NULL, NULL, CLS_TOPLEV|SKIP);
+ L->frame->clsdecl = clsdecl;
+
+ frame_resumePrologue();
+ push_lit("::namespace");
+ push_lit("eval");
+ push_litf("::L::_class_%s", clsdecl->decl->id->str);
+ push_lit("variable __num 0");
+ emit_invoke(4);
+ emit_pop();
+ frame_resumeBody();
+
+ compile_varDecls(clsdecl->clsvars);
+ /* Process function decls first, then compile the bodies. */
+ compile_fnDecls(clsdecl->fns, FN_PROTO_ONLY);
+ compile_fnDecls(clsdecl->constructors, FN_PROTO_ONLY);
+ compile_fnDecls(clsdecl->destructors, FN_PROTO_ONLY);
+ compile_fnDecls(clsdecl->constructors, FN_PROTO_AND_BODY);
+ compile_fnDecls(clsdecl->destructors, FN_PROTO_AND_BODY);
+ compile_fnDecls(clsdecl->fns, FN_PROTO_AND_BODY);
+
+ frame_pop();
+ frame_pop();
+}
+
+/*
+ * Take an expr list consisting of
+ *
+ * id like the arg to "#pragma fntrace"
+ * id=constant like the arg to "#pragma fnhook=myhook"
+ *
+ * and add hash entries to the given hash. The id's here aren't taken
+ * as variables, but the name of the id itself is used, to avoid
+ * making the programmer put everything inside quotes. This is used
+ * for #pragmas and function attributes.
+ */
+void
+L_compile_attributes(Tcl_Obj *hash, Expr *expr, char *allowed[])
+{
+ Expr *arg;
+ char *key, *val;
+ char **p;
+
+ ASSERT(hash);
+ for (arg = expr; arg; arg = arg->next) {
+ if (arg->kind == L_EXPR_ID) {
+ key = arg->str;
+ val = "yes";
+ } else if ((arg->kind == L_EXPR_BINOP) &&
+ (arg->op == L_OP_EQUALS)) {
+ key = arg->a->str;
+ val = arg->b->str;
+ unless (isconst(arg->b) || (arg->b->kind == L_EXPR_ID)) {
+ L_errf(arg,
+ "non-constant value for attribute %s",
+ key);
+ }
+ } else {
+ L_errf(arg, "illegal attribute; not id or id=constant");
+ continue;
+ }
+ for (p = allowed; *p; ++p) {
+ if (!strcmp(key, *p)) break;
+ }
+ unless (*p) {
+ L_errf(expr, "illegal attribute '%s'", key);
+ } else {
+ hash_put(hash, key, val);
+ }
+ }
+}
+
+private void
+compile_fnDecls(FnDecl *fun, Decl_f flags)
+{
+ for (; fun; fun = fun->next) {
+ compile_fnDecl(fun, flags);
+ }
+}
+
+private void
+compile_fnDecl(FnDecl *fun, Decl_f flags)
+{
+ int i;
+ VarDecl *decl = fun->decl;
+ char *name = decl->id->str;
+ char *clsname = NULL;
+ ClsDecl *clsdecl = NULL;
+ Sym *self_sym = NULL;
+ Sym *sym;
+
+ flags |= decl->flags;
+
+ ASSERT(fun && decl);
+ ASSERT(!(flags & SCOPE_LOCAL));
+ ASSERT(flags & (SCOPE_CLASS | SCOPE_GLOBAL | SCOPE_SCRIPT));
+ ASSERT(flags & (DECL_FN | DECL_CLASS_FN));
+ // DECL_CLASS_FN ==> DECL_PUBLIC | DECL_PRIVATE
+ ASSERT(!(flags & DECL_CLASS_FN) ||
+ (flags & (DECL_PUBLIC | DECL_PRIVATE)));
+ ASSERT(flags & (FN_PROTO_ONLY | FN_PROTO_AND_BODY));
+
+ /*
+ * Sort out the possible error cases:
+ *
+ * - main() declared with wrong types for formals
+ * - name illegal
+ * - name already declared as a variable
+ * - proto already declared and doesn't match this decl
+ * - this decl declares function body but body already declared
+ */
+ if (!strcmp(name, "main")) L_typeck_main(decl);
+ if (name[0] == '_') {
+ L_errf(decl->id, "function names cannot begin with _");
+ }
+ if (!strcmp(name, "END")) {
+ L_errf(decl->id, "cannot use END for function name");
+ } else if (!strcmp(name, "undef")) {
+ L_errf(decl->id, "cannot use undef for function name");
+ }
+ for (i = 0; i < sizeof(builtins)/sizeof(builtins[0]); ++i) {
+ if (!strcmp(builtins[i].name, name)) {
+ L_errf(decl->id,
+ "function '%s' conflicts with built-in",
+ name);
+ return;
+ }
+ }
+ sym = sym_lookup(decl->id, L_NOWARN|L_NOTUSED);
+ if (sym) {
+ unless (sym->kind & L_SYM_FN) {
+ L_errf(fun, "%s already declared as a variable",name);
+ return;
+ } else if ((sym->kind & L_SYM_FNBODY) && fun->body) {
+ L_errf(fun, "function %s already declared", name);
+ return;
+ } else unless (L_typeck_same(decl->type, sym->type)) {
+ L_errf(fun, "does not match other declaration of %s",
+ name);
+ return;
+ }
+ } else {
+ sym = sym_store(decl);
+ unless (sym) return;
+ }
+
+ /* Check arg and return types for legality. */
+ L_typeck_declType(decl);
+
+ if (!fun->body || (flags & FN_PROTO_ONLY)) return;
+
+ /*
+ * Add this function's attributes to the hash of all declared
+ * functions in L->fn_decls which is put into the Tcl global
+ * variable L_fnsDeclared, for use by the function-tracing
+ * subsystem code in libl.tcl when tracing is enabled.
+ */
+ L_compile_attributes(fun->attrs, decl->attrs, L_attrs_attribute);
+ if (flags & FN_PROTO_AND_BODY) {
+ Tcl_Obj *key;
+ Var *arrayPtr, *varPtr;
+
+ /*
+ * L->fn_decls can get out of date when the L code in
+ * lib L writes to L_fnsDeclared, so grab the latest.
+ */
+ varPtr = TclLookupVar(L->interp,
+ "L_fnsDeclared",
+ NULL,
+ TCL_GLOBAL_ONLY,
+ NULL,
+ 0,
+ 0,
+ &arrayPtr);
+ if (L->fn_decls != varPtr->value.objPtr) {
+ L->fn_decls = varPtr->value.objPtr;
+ }
+
+ hash_put(fun->attrs, "name", name);
+ hash_put(fun->attrs, "file", basenm(fun->node.loc.file));
+ if (Tcl_IsShared(L->fn_decls)) {
+ L->fn_decls = Tcl_DuplicateObj(L->fn_decls);
+ Tcl_SetVar2Ex(L->interp, "L_fnsDeclared", NULL,
+ L->fn_decls, TCL_GLOBAL_ONLY);
+ }
+ key = Tcl_NewStringObj(sym->tclname, -1);
+ Tcl_IncrRefCount(key);
+ Tcl_DictObjPut(L->interp, L->fn_decls, key, fun->attrs);
+ Tcl_DecrRefCount(key);
+ }
+
+ frame_push(fun, sym->tclname, FUNC|SEARCH);
+ sym->kind |= L_SYM_FNBODY;
+ L->frame->block = (Ast *)fun;
+
+ compile_fnParms(decl);
+
+ /* Gather class decl and name, for class member functions. */
+ clsdecl = fun->decl->clsdecl;
+ if (clsdecl) clsname = clsdecl->decl->id->str;
+
+ /*
+ * For private class member fns and the constructor, declare
+ * the local variable "self". For public member fns, lookup
+ * "self" which is required to be the first parameter (and is
+ * added by compile_fnParms if not present).
+ */
+ if (isClsConstructor(decl) || isClsFnPrivate(decl)) {
+ self_sym = sym_mk("self",
+ clsdecl->decl->type,
+ SCOPE_LOCAL | DECL_LOCAL_VAR);
+ ASSERT(self_sym && self_sym->idx >= 0);
+ self_sym->used_p = TRUE;
+ } else if (isClsFnPublic(decl)) {
+ self_sym = sym_lookup(mkId("self"), L_NOWARN);
+ ASSERT(self_sym && self_sym->idx >= 0);
+ }
+
+ /*
+ * For a constructor, before compiling the user's
+ * constructor body, emit code to increment the class instance
+ * #, set "self" to the namespace name of the class instance,
+ * create the namespace, then compile the instance-variable
+ * initializers. Basically this:
+ *
+ * incrStkImm ::L::_class_<cls_name>::__num
+ * set self ::L::_instance_<cls_name>${__num}
+ * namespace eval $self {}
+ * ...instance variable initializers...
+ * ...user's constructor body...
+ */
+ if (isClsConstructor(decl)) {
+ frame_resumePrologue();
+ ASSERT(clsdecl && clsname && self_sym);
+ push_litf("::L::_class_%s::__num", clsname);
+ TclEmitInstInt1(INST_INCR_STK_IMM, 1, L->frame->envPtr);
+ emit_pop();
+ push_lit("::namespace");
+ push_lit("eval");
+ push_litf("::L::_instance_%s", clsname);
+ push_litf("::L::_class_%s::__num", clsname);
+ TclEmitOpcode(INST_LOAD_STK, L->frame->envPtr);
+ TclEmitInstInt1(INST_STR_CONCAT1, 2, L->frame->envPtr);
+ emit_store_scalar(self_sym->idx);
+ push_lit("");
+ emit_invoke(4);
+ emit_pop();
+ frame_resumeBody();
+ compile_varDecls(clsdecl->instvars);
+ }
+
+ /*
+ * For private member functions, upvar "self" to the "self" in
+ * the calling frame. This works because only other class member
+ * functions can call private member functions, and they have "self".
+ */
+ if (isClsFnPrivate(decl)) {
+ frame_resumePrologue();
+ push_lit("1");
+ push_lit("self");
+ TclEmitInstInt4(INST_UPVAR, self_sym->idx, L->frame->envPtr);
+ emit_pop();
+ frame_resumeBody();
+ }
+
+ L->enclosing_func = fun;
+ L->enclosing_func_frame = L->frame;
+ compile_block(fun->body);
+ L->enclosing_func = NULL;
+ L->enclosing_func_frame = NULL;
+
+ /*
+ * Emit a "fall off the end" implicit return for void
+ * functions. Class constructors return the value of "self".
+ * Non-void functions throw an exception if you fall
+ * off the end.
+ */
+ if (isClsConstructor(decl)) {
+ emit_load_scalar(self_sym->idx);
+ } else if (isvoidtype(decl->type->base_type)) {
+ push_lit("");
+ } else {
+ push_lit("::throw");
+ push_lit("{FUNCTION NO-RETURN-VALUE "
+ "{no value returned from function}}");
+ push_lit("no value returned from function");
+ emit_invoke(3);
+ }
+
+ /*
+ * Fix-up the return jmps so that all return stmts jump to here.
+ * The return value will already be on the run-time stack.
+ */
+ fixup_jmps(&L->frame->ret_jmps);
+
+ /*
+ * For class destructor, delete the instance namespace.
+ */
+ if (isClsDestructor(decl)) {
+ ASSERT(self_sym);
+ push_lit("::namespace");
+ push_lit("delete");
+ emit_load_scalar(self_sym->idx);
+ emit_invoke(3);
+ emit_pop();
+ }
+
+ TclEmitOpcode(INST_DONE, L->frame->envPtr);
+
+ frame_pop();
+}
+
+/*
+ * Push a semantic-stack frame. If flags & FUNC, start a new proc
+ * too. To support the delayed generation of proc prologue code, we
+ * allocate two CompileEnv's, one for the proc body and one for its
+ * prologue. You switch between the two with frame_resumePrologue()
+ * and frame_resumeBody(). A jump is emitted at the head of the proc
+ * that jumps to the end, and when the proc is done being compiled,
+ * the prologue code is emitted at the end along with a jump back.
+ * This provides a way to lazily output proc initialization code, such
+ * as the upvars for accessing globals and class variables.
+ */
+private void
+frame_push(void *node, char *name, Frame_f flags)
+{
+ Frame *frame;
+ Proc *proc;
+ CompileEnv *bodyEnvPtr, *prologueEnvPtr;
+
+ frame = (Frame *)ckalloc(sizeof(Frame));
+ memset(frame, 0, sizeof(*frame));
+ frame->flags = flags;
+ frame->symtab = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
+ Tcl_InitHashTable(frame->symtab, TCL_STRING_KEYS);
+ frame->labeltab = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
+ Tcl_InitHashTable(frame->labeltab, TCL_STRING_KEYS);
+ frame->prevFrame = L->frame;
+ L->frame = frame;
+
+ unless (frame->flags & FUNC) {
+ frame->block = node;
+ if (frame->prevFrame) {
+ frame->envPtr = frame->prevFrame->envPtr;
+ frame->bodyEnvPtr = frame->prevFrame->bodyEnvPtr;
+ frame->prologueEnvPtr = frame->prevFrame->prologueEnvPtr;
+ }
+ return;
+ }
+
+ bodyEnvPtr = (CompileEnv *)ckalloc(sizeof(CompileEnv));
+ prologueEnvPtr = (CompileEnv *)ckalloc(sizeof(CompileEnv));
+ frame->bodyEnvPtr = bodyEnvPtr;
+ frame->prologueEnvPtr = prologueEnvPtr;
+ frame->envPtr = bodyEnvPtr;
+
+ proc = (Proc *)ckalloc(sizeof(Proc));
+ proc->iPtr = (struct Interp *)L->interp;
+ proc->refCount = 1;
+ proc->numArgs = 0;
+ proc->numCompiledLocals = 0;
+ proc->firstLocalPtr = NULL;
+ proc->lastLocalPtr = NULL;
+ proc->bodyPtr = Tcl_NewObj();
+ Tcl_IncrRefCount(proc->bodyPtr);
+ TclInitCompileEnv(L->interp, bodyEnvPtr, TclGetString(L->script),
+ L->script_len, NULL, 0);
+ bodyEnvPtr->procPtr = proc;
+
+ TclInitCompileEnv(L->interp, prologueEnvPtr, NULL, 0, NULL, 0);
+
+ frame->proc = proc;
+ frame->name = name;
+
+ /*
+ * Emit a jump to what will eventually be the prologue code
+ * (output by frame_pop()).
+ */
+ frame->end_jmp = emit_jmp_fwd(INST_JUMP4, NULL);
+ frame->proc_top = currOffset(frame->envPtr);
+}
+
+private void
+frame_resumePrologue()
+{
+ L->frame->envPtr = L->frame->prologueEnvPtr;
+}
+
+private void
+frame_resumeBody()
+{
+ L->frame->envPtr = L->frame->bodyEnvPtr;
+}
+
+private void
+frame_pop()
+{
+ int off;
+ Frame *frame = L->frame;
+ Proc *proc = frame->proc;
+ Sym *sym;
+ Label *label;
+ ByteCode *codePtr;
+ Tcl_HashEntry *hPtr;
+ Tcl_HashSearch hSearch;
+
+ /*
+ * Emit proc prologue code and the jump back to the head of
+ * the proc. Splice in any code in the frame->prologueEnvPtr
+ * CompileEnv. This is dependent on CompileEnv details.
+ */
+ if (frame->flags & FUNC) {
+ CompileEnv *body = frame->bodyEnvPtr;
+ CompileEnv *prologue = frame->prologueEnvPtr;
+ int len = prologue->codeNext - prologue->codeStart;
+
+ ASSERT(frame->envPtr == frame->bodyEnvPtr);
+
+ fixup_jmps(&frame->end_jmp);
+ while ((body->codeNext + len) >= body->codeEnd) {
+ TclExpandCodeArray(body);
+ }
+ memcpy(body->codeNext, prologue->codeStart, len);
+ body->codeNext += len;
+ if (prologue->maxStackDepth > body->maxStackDepth) {
+ body->maxStackDepth = prologue->maxStackDepth;
+ }
+ off = currOffset(frame->envPtr);
+ TclEmitInstInt4(INST_JUMP4, frame->proc_top-off, frame->envPtr);
+ }
+
+ /*
+ * Check for unused local symbols, and free the frame's symbol table.
+ */
+ for (hPtr = Tcl_FirstHashEntry(frame->symtab, &hSearch);
+ hPtr != NULL;
+ hPtr = Tcl_NextHashEntry(&hSearch)) {
+ sym = (Sym *)Tcl_GetHashValue(hPtr);
+ unless (sym->used_p || !(sym->kind & L_SYM_LVAR) ||
+ (sym->decl->flags & DECL_ARGUSED)) {
+ L_warnf(sym->decl, "%s unused", sym->name);
+ }
+ unless (frame->flags & KEEPSYMS) {
+ ckfree(sym->name);
+ ckfree(sym->tclname);
+ ckfree((char *)sym);
+ }
+ }
+ unless (frame->flags & KEEPSYMS) {
+ Tcl_DeleteHashTable(frame->symtab);
+ ckfree((char *)frame->symtab);
+ }
+
+ /*
+ * Check for unresolved labels, and free the frame's label table.
+ */
+ for (hPtr = Tcl_FirstHashEntry(frame->labeltab, &hSearch);
+ hPtr != NULL;
+ hPtr = Tcl_NextHashEntry(&hSearch)) {
+ label = (Label *)Tcl_GetHashValue(hPtr);
+ unless (label->offset >= 0) {
+ L_err("label %s referenced but not defined",
+ label->name);
+ }
+ ckfree((char *)label);
+ }
+ Tcl_DeleteHashTable(frame->labeltab);
+ ckfree((char *)frame->labeltab);
+
+ /*
+ * Create the Tcl command and free the old frame.
+ */
+ if (frame->flags & FUNC) {
+ TclInitByteCodeObj(proc->bodyPtr, frame->envPtr);
+ proc->cmdPtr = (Command *)Tcl_CreateObjCommand(L->interp,
+ frame->name,
+ TclObjInterpProc,
+ (ClientData)proc,
+ TclProcDeleteProc);
+ // Don't recompile on compileEpoch changes.
+ codePtr = (ByteCode *)proc->bodyPtr->internalRep.twoPtrValue.ptr1;
+ codePtr->flags |= TCL_BYTECODE_PRECOMPILED;
+ TclFreeCompileEnv(frame->bodyEnvPtr);
+ TclFreeCompileEnv(frame->prologueEnvPtr);
+ ckfree((char *)frame->bodyEnvPtr);
+ ckfree((char *)frame->prologueEnvPtr);
+ }
+
+ L->frame = frame->prevFrame;
+ tmp_freeAll(frame->tmps);
+ ckfree((char *)frame);
+}
+
+private Frame *
+frame_find(Frame_f flags)
+{
+ Frame *f = L->frame;
+
+ ASSERT(f);
+ while (f && !(f->flags & flags)) f = f->prevFrame;
+ return (f);
+}
+
+private char *
+frame_name()
+{
+ if (L->enclosing_func) {
+ return(L->enclosing_func->decl->id->str);
+ } else {
+ return(L->toplev);
+ }
+}
+
+private void
+compile_varInitializer(VarDecl *decl)
+{
+ int start_off = currOffset(L->frame->envPtr);
+
+ unless (decl->initializer) {
+ decl->initializer = ast_mkBinOp(L_OP_EQUALS,
+ decl->id,
+ mkId("undef"),
+ decl->node.loc,
+ decl->node.loc);
+ }
+ compile_expr(decl->initializer, L_DISCARD);
+ track_cmd(start_off, decl);
+}
+
+private void
+compile_varDecl(VarDecl *decl)
+{
+ char *name;
+ Sym *sym;
+
+ /*
+ * Process any declaration only once, but generate code for
+ * its initializers each time through here. This is for class
+ * constructors where the class instance variables get
+ * compiled once for each constructor.
+ */
+ if (decl->flags & DECL_DONE) {
+ compile_varInitializer(decl);
+ return;
+ }
+ decl->flags |= DECL_DONE;
+
+ ASSERT(decl->id && decl->type);
+
+ name = decl->id->str;
+
+ unless (L_typeck_declType(decl)) return;
+
+ if (decl->flags & DECL_LOCAL_VAR) {
+ if (name[0] == '_') {
+ L_errf(decl,
+ "local variable names cannot begin with _");
+ }
+ if (decl->flags & (DECL_PRIVATE | DECL_PUBLIC)) {
+ L_errf(decl,
+ "public/private qualifiers illegal for locals");
+ decl->flags &= ~(DECL_PRIVATE | DECL_PUBLIC);
+ }
+ }
+ if (!strcmp(name, "END")) {
+ L_errf(decl, "cannot use END for variable name");
+ return;
+ } else if (!strcmp(name, "undef")) {
+ L_errf(decl, "cannot use undef for variable name");
+ return;
+ }
+ if ((decl->type->kind == L_CLASS) &&
+ !strcmp(name, decl->type->u.class.clsdecl->decl->id->str)) {
+ L_errf(decl, "cannot declare object with same name as class");
+ }
+
+ sym = sym_store(decl);
+ unless (sym) return; // bail if multiply declared
+
+ if (decl->flags & DECL_EXTERN) {
+ if (decl->initializer) {
+ L_errf(decl, "extern initializers illegal");
+ }
+ unless (L->frame->flags & TOPLEV) {
+ L_errf(decl, "externs legal only at global scope");
+ }
+ sym->used_p = TRUE; // to suppress extraneous warning
+ return;
+ }
+
+ compile_varInitializer(decl);
+
+ /* Mark var as unused even though it was just initialized. */
+ sym->used_p = FALSE;
+}
+
+private void
+compile_varDecls(VarDecl *decls)
+{
+ for (; decls; decls = decls->next) {
+ compile_varDecl(decls);
+ }
+}
+
+private void
+compile_stmt(Stmt *stmt)
+{
+ int start_off = currOffset(L->frame->envPtr);
+
+ unless (stmt) return;
+ switch (stmt->kind) {
+ case L_STMT_BLOCK:
+ frame_push(stmt, NULL, SEARCH);
+ compile_block(stmt->u.block);
+ frame_pop();
+ break;
+ case L_STMT_EXPR:
+ compile_exprs(stmt->u.expr, L_DISCARD);
+ break;
+ case L_STMT_COND:
+ compile_ifUnless(stmt->u.cond);
+ break;
+ case L_STMT_LOOP:
+ compile_loop(stmt->u.loop);
+ break;
+ case L_STMT_SWITCH:
+ compile_switch(stmt->u.swich);
+ break;
+ case L_STMT_FOREACH:
+ compile_foreach(stmt->u.foreach);
+ break;
+ case L_STMT_RETURN:
+ compile_return(stmt);
+ break;
+ case L_STMT_BREAK:
+ compile_break(stmt);
+ break;
+ case L_STMT_CONTINUE:
+ compile_continue(stmt);
+ break;
+ case L_STMT_LABEL:
+ compile_label(stmt);
+ break;
+ case L_STMT_GOTO:
+ compile_goto(stmt);
+ break;
+ case L_STMT_TRY:
+ compile_trycatch(stmt);
+ break;
+ default:
+ L_bomb("Malformed AST in compile_stmt");
+ }
+ switch (stmt->kind) {
+ case L_STMT_BLOCK:
+ case L_STMT_COND:
+ case L_STMT_EXPR:
+ case L_STMT_TRY:
+ break;
+ default:
+ track_cmd(start_off, stmt);
+ break;
+ }
+}
+
+private void
+compile_stmts(Stmt *stmts)
+{
+ for (; stmts; stmts = stmts->next) {
+ compile_stmt(stmts);
+ }
+}
+
+private void
+compile_trycatch(Stmt *stmt)
+{
+ int range;
+ int msg_idx = -1;
+ Jmp *jmp;
+ Try *try = stmt->u.try;
+ Expr *msg = try->msg;
+
+ if (msg) {
+ unless (msg->op == L_OP_ADDROF) {
+ L_errf(msg, "expected catch(&variable)");
+ return;
+ }
+ compile_expr(msg, L_DISCARD);
+ if (msg->a->sym) {
+ msg_idx = msg->a->sym->idx;
+ } else {
+ L_errf(msg->a, "illegal operand to &");
+ }
+ }
+
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE, L->frame->envPtr);
+ TclEmitInstInt4(INST_BEGIN_CATCH4, range, L->frame->envPtr);
+
+ /*
+ * Emit separate INST_END_CATCH's for the non-error and error
+ * paths so that a return can be done inside of a catch()
+ * clause -- the "try" is done when the body finishes without
+ * error or by the time the catch() is entered.
+ */
+
+ /* body */
+ ExceptionRangeStarts(L->frame->envPtr, range);
+ compile_stmts(try->try);
+ ExceptionRangeEnds(L->frame->envPtr, range);
+ TclEmitOpcode(INST_END_CATCH, L->frame->envPtr);
+ jmp = emit_jmp_fwd(INST_JUMP4, 0);
+
+ /* error case */
+ ExceptionRangeTarget(L->frame->envPtr, range, catchOffset);
+ if (msg_idx != -1) {
+ TclEmitOpcode(INST_PUSH_RESULT, L->frame->envPtr);
+ TclEmitInstInt4(INST_STORE_SCALAR4, msg_idx, L->frame->envPtr);
+ TclEmitOpcode(INST_POP, L->frame->envPtr);
+ }
+ TclEmitOpcode(INST_END_CATCH, L->frame->envPtr);
+ compile_stmts(try->catch);
+
+ /* out */
+ fixup_jmps(&jmp);
+}
+
+private void
+compile_block(Block *block)
+{
+ compile_varDecls(block->decls);
+ compile_stmts(block->body);
+}
+
+private void
+compile_return(Stmt *stmt)
+{
+ VarDecl *decl;
+ Type *ret_type;
+
+ /* Handle return from the top level. */
+ unless (L->enclosing_func) {
+ if (stmt->u.expr) {
+ compile_expr(stmt->u.expr, L_PUSH_VAL);
+ } else {
+ push_lit("");
+ }
+ TclEmitOpcode(INST_DONE, L->frame->envPtr);
+ return;
+ }
+
+ decl = L->enclosing_func->decl;
+ ret_type = decl->type->base_type;
+
+ if (isvoidtype(ret_type) && (stmt->u.expr)) {
+ L_errf(stmt, "void function cannot return value");
+ compile_expr(stmt->u.expr, L_DISCARD);
+ } else if (stmt->u.expr) {
+ compile_expr(stmt->u.expr, L_PUSH_VAL); // return value
+ unless (L_typeck_compat(ret_type, stmt->u.expr->type)) {
+ L_errf(stmt, "incompatible return type");
+ }
+ } else unless (isvoidtype(ret_type)) {
+ L_errf(stmt, "must specify return value");
+ } else {
+ push_lit(""); // no return value -- push a ""
+ }
+
+ /* Jmp to the function end where any necessary clean-up code is. */
+ ASSERT(L->enclosing_func_frame);
+ L->enclosing_func_frame->ret_jmps =
+ emit_jmp_fwd(INST_JUMP4, L->enclosing_func_frame->ret_jmps);
+}
+
+private void
+proc_mkArg(Proc *proc, VarDecl *decl)
+{
+ int argnum;
+ char *name = decl->id->str;
+ CompiledLocal *local;
+
+ argnum = proc->numArgs++;
+ ++proc->numCompiledLocals;
+ local = (CompiledLocal *)ckalloc(sizeof(CompiledLocal) -
+ sizeof(local->name) +
+ strlen(name) + 1);
+ if (proc->firstLocalPtr == NULL) {
+ proc->firstLocalPtr = local;
+ proc->lastLocalPtr = local;
+ } else {
+ proc->lastLocalPtr->nextPtr = local;
+ proc->lastLocalPtr = local;
+ }
+ local->nextPtr = NULL;
+ local->resolveInfo = NULL;
+ local->defValuePtr = NULL;
+ local->frameIndex = argnum;
+ local->nameLength = strlen(name);
+ strcpy(local->name, name);
+
+ local->flags = VAR_ARGUMENT;
+ if (decl->flags & DECL_REST_ARG) local->flags |= VAR_IS_ARGS;
+ if (decl->flags & DECL_OPTIONAL) {
+ if (isnameoftype(decl->type)) {
+ local->defValuePtr =
+ Tcl_NewStringObj("::L_undef_ref_parm_", -1);
+ local->defValuePtr->undef = 1;
+ } else {
+ local->defValuePtr = *L_undefObjPtrPtr();
+ }
+ Tcl_IncrRefCount(local->defValuePtr);
+ }
+}
+
+/*
+ * Determine whether the parameter-passing mode for a formal parameter
+ * declaration is call-by-reference. Return NULL or the base type of
+ * the parameter (without the name-of). You get call-by-reference if
+ * the parameter was declared with & and is not a function pointer.
+ */
+private Type *
+iscallbyname(VarDecl *formal)
+{
+ unless (formal) return (NULL);
+ if (formal->flags & DECL_REF) {
+ if (isfntype(formal->type->base_type)) {
+ return (NULL);
+ } else {
+ return (formal->type->base_type);
+ }
+ }
+ return (NULL);
+}
+
+private int
+compile_fnParms(VarDecl *decl)
+{
+ int n;
+ int name_parms = 0;
+ char *name;
+ Proc *proc = L->frame->envPtr->procPtr;
+ Expr *varId;
+ VarDecl *p, *varDecl;
+ Sym *parmSym, *varSym;
+ Type *type;
+ VarDecl *param = decl->type->u.func.formals;
+
+ proc->numArgs = 0;
+ proc->numCompiledLocals = 0;
+
+ /*
+ * Public class member fns (except constructor) must have "self"
+ * as the first arg and it must be of the class type.
+ */
+ if (isClsFnPublic(decl) && !isClsConstructor(decl)) {
+ Type *clstype = decl->clsdecl->decl->type;
+ Expr *self_id;
+ VarDecl *self_decl;
+ unless (param && param->id && isid(param->id, "self")) {
+ L_errf(decl->id, "class public member function lacks "
+ "'self' as first arg");
+ /* Add it so we can keep compiling. */
+ self_id = mkId("self");
+ self_decl = ast_mkVarDecl(clstype, self_id,
+ decl->node.loc,
+ decl->node.loc);
+ self_decl->flags = SCOPE_LOCAL | DECL_LOCAL_VAR;
+ self_decl->next = param;
+ param = self_decl;
+ } else unless (L_typeck_same(param->type, clstype)) {
+ L_errf(param, "'self' parameter must be of class type");
+ }
+ }
+
+ /*
+ * To handle call-by-name formals, make two passes through the
+ * formals list. In the first pass, mangle any formal name to
+ * "&name". In the second pass, for formals only, create a
+ * local "name" as an upvar to the variable one frame up whose
+ * name is passed in the arg. Note that the formal will have
+ * type "name-of <t>" and the local gets type <t>. This is
+ * needed since Tcl requires the locals to follow the args.
+ */
+ for (p = param, n = 0; p; p = p->next, n++) {
+ unless (p->id) {
+ L_errf(p, "formal parameter #%d lacks a name", n+1);
+ name = cksprintf("unnamed-arg-%d", n+1);
+ p->id = mkId(name);
+ ckfree(name);
+ }
+ if (isClsConstructor(decl) && isid(p->id, "self")) {
+ L_errf(p,
+ "'self' parameter illegal in class constructor");
+ continue;
+ }
+ if (isClsFnPrivate(decl) && isid(p->id, "self")) {
+ L_errf(p,
+ "'self' parameter illegal in private function");
+ continue;
+ }
+ if ((p->flags & DECL_REST_ARG) && (p->next)) {
+ L_errf(p, "Rest parameter must be last");
+ }
+ if ((p->flags & DECL_OPTIONAL) && (p->next)) {
+ L_errf(p, "_optional parameter must be last");
+ }
+ if (typeis(p->type, "FMT") &&
+ (!p->next || !(p->next->flags & DECL_REST_ARG))) {
+ L_errf(p, "rest argument must follow FMT");
+ }
+ if (iscallbyname(p)) {
+ name = cksprintf("&%s", p->id->str);
+ ckfree(p->id->str);
+ p->id->str = name;
+ ++name_parms;
+ }
+ proc_mkArg(proc, p);
+ parmSym = sym_store(p);
+ unless (parmSym) continue; // multiple declaration
+ parmSym->idx = n;
+ /* Suppress unused warning for obj arg to class member fns. */
+ if ((p == param) &&
+ isClsFnPublic(decl) && !isClsConstructor(decl)) {
+ parmSym->used_p = TRUE;
+ }
+ }
+ /* For call by name, push a 1 the first time (arg to INST_UPVAR). */
+ if (name_parms) push_lit("1");
+ /*
+ * For each call-by-reference formal, we have
+ * "&var" - a fn parm that gets the name of the caller's actual parm
+ * "var" - a local upvar'd to this name, becomes alias for the actual
+ * The first was created above. Create the second one now.
+ */
+ for (p = param; p; p = p->next) {
+ unless (type = iscallbyname(p)) continue;
+
+ /* Lookup "&var". */
+ parmSym = sym_lookup(p->id, L_NOWARN);
+ ASSERT(parmSym && (p->id->str[0] == '&'));
+
+ /* Create "var". */
+ varId = ast_mkId(p->id->str + 1, // point past the &
+ p->id->node.loc,
+ p->id->node.loc);
+ varDecl = ast_mkVarDecl(type, varId, p->node.loc, p->node.loc);
+ varDecl->flags = SCOPE_LOCAL | DECL_LOCAL_VAR | p->flags;
+ varDecl->node.loc.line = p->node.loc.line;
+ unless (varSym = sym_store(varDecl)) continue; // multiple decl
+ varSym->decl->refsym = parmSym;
+ emit_load_scalar(parmSym->idx);
+ TclEmitInstInt4(INST_UPVAR, varSym->idx, L->frame->envPtr);
+ }
+ /* Pop the 1 pushed for INST_UPVAR. */
+ if (name_parms) emit_pop();
+ return (n);
+}
+
+private int
+compile_rename(Expr *expr)
+{
+ int n;
+
+ push_lit("frename_");
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+ unless (n == 2) {
+ L_errf(expr, "incorrect # args for rename");
+ }
+ emit_invoke(3);
+ expr->type = L_int;
+ return (1); // stack effect
+}
+
+private int
+compile_split(Expr *expr)
+{
+ int n;
+ Expr *str = NULL, *lim = NULL, *sep = NULL;
+ Expr_f flags = 0;
+
+ expr->type = L_poly; // for err return path
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+ ASSERT(n > 0); // grammar ensures this
+ if (n > 3) {
+ L_errf(expr, "too many args to split");
+ return (0);
+ }
+ switch (n) {
+ case 1: // split(<str>)
+ str = expr->b;
+ break;
+ case 2: // split(/re/, <str>)
+ sep = expr->b;
+ str = sep->next;
+ break;
+ case 3: // split(/re/, <str>, <lim>)
+ sep = expr->b;
+ str = sep->next;
+ lim = str->next;
+ break;
+ }
+ unless (istype(str, L_STRING|L_WIDGET|L_POLY)) {
+ L_errf(str, "expression to split must be string");
+ }
+ if (sep) {
+ unless (isregexp(sep)) {
+ L_errf(sep, "split delimiter must be a "
+ "regular expression");
+ }
+ if (sep->flags & ~(L_EXPR_RE_T | L_EXPR_RE_I)) {
+ L_errf(sep, "illegal regular expression modifier");
+ }
+ flags |= L_SPLIT_RE | sep->flags;
+ }
+ if (lim) {
+ flags |= L_SPLIT_LIM;
+ unless (isint(lim)) {
+ L_errf(expr, "third arg to split must be integer");
+ return (0);
+ }
+ }
+ TclEmitInstInt4(INST_L_SPLIT, flags, L->frame->envPtr);
+ TclAdjustStackDepth(n-1, L->frame->envPtr);
+ expr->type = type_mkArray(0, L_string);
+ return (1); // stack effect
+}
+
+private int
+compile_push(Expr *expr)
+{
+ int flags = 0, i, idx;
+ Expr *arg, *array;
+ Type *base_type;
+ Tmp *tmp;
+
+ expr->type = L_void;
+ unless (expr->b && expr->b->next) {
+ L_errf(expr, "too few arguments to push");
+ return (0);
+ }
+ unless (isaddrof(expr->b)) {
+ L_errf(expr, "first arg to push not an array reference (&)");
+ return (0);
+ }
+ ASSERT(expr->b->a);
+ array = expr->b->a;
+ arg = expr->b->next;
+ compile_expr(array, L_PUSH_PTR | L_LVALUE);
+ unless (isarray(array) || ispoly(array)) {
+ L_errf(expr,
+ "first arg to push not an array reference (&)");
+ return (0);
+ }
+ unless (array->sym) {
+ L_errf(expr, "invalid l-value in push");
+ return (0);
+ }
+ idx = array->sym->idx; // local slot # for array
+ if (isarray(array)) {
+ base_type = array->type->base_type;
+ } else {
+ base_type = L_poly;
+ }
+ if (arg->next) {
+ /* Build up a list of the args to push. */
+ tmp = tmp_get(TMP_REUSE);
+ push_lit("");
+ emit_store_scalar(tmp->idx);
+ emit_pop();
+ for (i = 2; arg; arg = arg->next, ++i) {
+ compile_expr(arg, L_PUSH_VAL);
+ /* We allow base_type or an array of base_type. */
+ if (L_typeck_compat(base_type, arg->type)) {
+ flags = L_INSERT_ELT;
+ } else if (L_typeck_compat(array->type, arg->type)) {
+ flags = L_INSERT_LIST;
+ } else {
+ L_errf(expr, "arg #%d to push has type "
+ "incompatible with array", i);
+ }
+ push_lit("-1"); // -1 means append
+ TclEmitInstInt4(INST_L_LIST_INSERT, tmp->idx,
+ L->frame->envPtr);
+ TclEmitInt4(flags, L->frame->envPtr);
+ }
+ emit_load_scalar(tmp->idx);
+ tmp_free(tmp);
+ flags = L_INSERT_LIST;
+ } else {
+ compile_expr(arg, L_PUSH_VAL);
+ /* We allow base_type or an array of base_type. */
+ if (L_typeck_compat(base_type, arg->type)) {
+ flags = L_INSERT_ELT;
+ } else if (L_typeck_compat(array->type, arg->type)) {
+ flags = L_INSERT_LIST;
+ } else {
+ L_errf(expr, "arg #2 to push has type "
+ "incompatible with array");
+ }
+ }
+ if (array->flags & L_EXPR_DEEP) {
+ // deep-ptr rval
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ // rval deep-ptr
+ push_lit("-1"); // -1 means append
+ TclEmitInstInt4(INST_L_DEEP_WRITE, idx,
+ L->frame->envPtr);
+ TclEmitInt4(flags | L_DISCARD, L->frame->envPtr);
+ } else {
+ push_lit("-1"); // -1 means append
+ TclEmitInstInt4(INST_L_LIST_INSERT, idx,
+ L->frame->envPtr);
+ TclEmitInt4(flags, L->frame->envPtr);
+ }
+ return (0); // stack effect
+}
+
+private int
+compile_pop_shift(Expr *expr)
+{
+ int idx;
+ Expr *arg = NULL;
+ char *opNm = expr->a->str;
+ Expr *toDelete;
+ YYLTYPE loc;
+
+ expr->type = L_poly;
+ unless (expr->b && !expr->b->next) {
+ L_errf(expr, "incorrect # arguments to %s", opNm);
+ return (0);
+ }
+ unless (isaddrof(expr->b)) {
+ L_errf(expr, "arg to %s not an array reference (&)", opNm);
+ return (0);
+ }
+ /*
+ * For pop, change arg from &arr to &arr[END] and then delete
+ * that element. For shift, use &arr[0].
+ */
+ ASSERT(expr->b->a);
+ loc = expr->b->a->node.loc;
+ if (!strcmp(opNm, "pop")) {
+ toDelete = mkId("END");
+ } else {
+ toDelete = ast_mkConst(L_int, ckstrdup("0"), loc, loc);
+ }
+ arg = ast_mkBinOp(L_OP_ARRAY_INDEX,
+ expr->b->a,
+ toDelete,
+ loc,
+ loc);
+ expr->b->a = arg;
+ /* L_NEG_OK here permits indexing element -1 (array already empty). */
+ compile_expr(arg, L_PUSH_PTR | L_DELETE | L_NEG_OK | L_LVALUE);
+ unless (isarray(arg->a) || ispoly(arg->a)) {
+ L_errf(expr, "arg to %s not an array reference (&)", opNm);
+ return (0);
+ }
+ unless (arg->sym) {
+ L_errf(expr, "invalid l-value in %s", opNm);
+ return (0);
+ }
+ idx = arg->sym->idx; // local slot # for array
+ TclEmitInstInt4(INST_L_DEEP_WRITE, idx, L->frame->envPtr);
+ TclEmitInt4(L_DELETE | L_PUSH_OLD, L->frame->envPtr);
+ TclAdjustStackDepth(1, L->frame->envPtr);
+ expr->type = arg->type;
+ return (1); // stack effect
+}
+
+private int
+compile_insert_unshift(Expr *expr)
+{
+ int flags, i, idx;
+ Expr *arg, *array, *index;
+ Type *base_type;
+ Tmp *argTmp = NULL, *idxTmp = NULL;
+ char *opNm = expr->a->str;
+
+ /*
+ * Make unshift(arg1, arg2, ...) look like insert(arg1, "0", arg2, ...)
+ */
+ if (!strcmp(opNm, "unshift")) {
+ if (expr->b) {
+ arg = ast_mkConst(L_int, ckstrdup("0"), expr->node.loc,
+ expr->node.loc);
+ arg->next = expr->b->next;
+ expr->b->next = arg;
+ }
+ i = 2; // where data args start
+ } else {
+ i = 3; // where data args start
+ }
+
+ expr->type = L_void;
+ unless (expr->b && expr->b->next && expr->b->next->next) {
+ L_errf(expr, "too few arguments to %s", opNm);
+ return (0);
+ }
+ ASSERT(expr->b->a);
+ array = expr->b->a;
+ index = expr->b->next;
+ arg = expr->b->next->next;
+ unless (isaddrof(expr->b)) {
+ L_errf(expr, "first arg to %s not an array reference (&)", opNm);
+ return (0);
+ }
+ compile_expr(array, L_PUSH_PTR | L_LVALUE);
+ unless (isarray(array) || ispoly(array)) {
+ L_errf(expr,
+ "first arg to %s not an array reference (&)", opNm);
+ return (0);
+ }
+ unless (array->sym) {
+ L_errf(expr, "invalid l-value in %s", opNm);
+ return (0);
+ }
+ idx = array->sym->idx; // local slot # for array
+ if (isarray(array)) {
+ base_type = array->type->base_type;
+ } else {
+ base_type = L_poly;
+ }
+
+ /*
+ * If >1 arg, concat them all into a temp and insert that. We
+ * can't just insert them one by one like we do in
+ * compile_push(), since that would insert them backwards.
+ * We could reverse the arg list, but building the temp is
+ * about as fast as re-indexing into the array for each element.
+ */
+ if (arg->next) {
+ idxTmp = tmp_get(TMP_REUSE);
+ compile_expr(index, L_PUSH_VAL);
+ emit_store_scalar(idxTmp->idx);
+ emit_pop();
+ unless (isint(index)) {
+ L_errf(expr, "second arg to %s not an int", opNm);
+ return (0);
+ }
+ argTmp = tmp_get(TMP_REUSE);
+ push_lit("");
+ emit_store_scalar(argTmp->idx);
+ emit_pop();
+ for (; arg; arg = arg->next, ++i) {
+ compile_expr(arg, L_PUSH_VAL);
+ /* For an arg, allow base_type or array of base_type. */
+ unless (L_typeck_compat(base_type, arg->type) ||
+ L_typeck_compat(array->type, arg->type)) {
+ L_errf(expr, "arg #%d to %s has type "
+ "incompatible with array", i, opNm);
+ }
+ if (isarray(arg) || islist(arg)) {
+ flags = L_INSERT_LIST;
+ } else {
+ flags = L_INSERT_ELT;
+ }
+ push_lit("-1"); // -1 means append
+ TclEmitInstInt4(INST_L_LIST_INSERT, argTmp->idx,
+ L->frame->envPtr);
+ TclEmitInt4(flags, L->frame->envPtr);
+ }
+ if (array->flags & L_EXPR_DEEP) {
+ emit_load_scalar(argTmp->idx);
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ emit_load_scalar(idxTmp->idx);
+ TclEmitInstInt4(INST_L_DEEP_WRITE, idx,
+ L->frame->envPtr);
+ TclEmitInt4(L_INSERT_LIST | L_DISCARD,
+ L->frame->envPtr);
+ } else {
+ emit_load_scalar(argTmp->idx);
+ emit_load_scalar(idxTmp->idx);
+ TclEmitInstInt4(INST_L_LIST_INSERT, idx,
+ L->frame->envPtr);
+ TclEmitInt4(L_INSERT_LIST, L->frame->envPtr);
+ }
+ } else {
+ compile_expr(arg, L_PUSH_VAL);
+ /* For the arg, we allow base_type or an array of base_type. */
+ unless (L_typeck_compat(base_type, arg->type) ||
+ L_typeck_compat(array->type, arg->type)) {
+ L_errf(expr, "arg #%d to %s has type incompatible "
+ "with array", i, opNm);
+ }
+ if (isarray(arg) || islist(arg)) {
+ flags = L_INSERT_LIST;
+ } else {
+ flags = L_INSERT_ELT;
+ }
+ if (array->flags & L_EXPR_DEEP) {
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ }
+ compile_expr(index, L_PUSH_VAL);
+ unless (isint(index)) {
+ L_errf(expr, "second arg to %s not an int", opNm);
+ return (0);
+ }
+ if (array->flags & L_EXPR_DEEP) {
+ TclEmitInstInt4(INST_L_DEEP_WRITE, idx,
+ L->frame->envPtr);
+ TclEmitInt4(flags | L_DISCARD, L->frame->envPtr);
+ } else {
+ TclEmitInstInt4(INST_L_LIST_INSERT, idx,
+ L->frame->envPtr);
+ TclEmitInt4(flags, L->frame->envPtr);
+ }
+ }
+ tmp_free(idxTmp);
+ tmp_free(argTmp);
+ return (0); // stack effect
+}
+
+private void
+compile_eq_stack(Expr *expr, Type *type)
+{
+ int i, top_off;
+ Tmp *itmp, *ltmp, *rtmp;
+ Jmp *out = NULL;
+ Jmp *out_false = NULL, *out_false2 = NULL, *out_true = NULL;
+ VarDecl *v;
+
+ unless (type->kind & (L_ARRAY|L_STRUCT|L_HASH)) {
+ /* Scalar -- just need a single bytecode. */
+ emit_instrForLOp(expr, type);
+ return;
+ }
+
+ /* Put lhs and rhs into temps. */
+ ltmp = tmp_get(TMP_REUSE);
+ rtmp = tmp_get(TMP_REUSE);
+ emit_store_scalar(rtmp->idx);
+ emit_pop();
+ emit_store_scalar(ltmp->idx);
+ emit_pop();
+
+ switch (type->kind) {
+ case L_ARRAY:
+ itmp = tmp_get(TMP_UNSET);
+ /*
+ * if (length(lhs) != length(rhs)) goto out_false
+ * itmp = length(rhs)
+ * top_off:
+ * if (itmp == 0) goto out_true
+ * --itmp
+ * if (lhs[itmp] != rhs[itmp]) goto out_false
+ * goto top_off
+ * out_true:
+ * push 1
+ * goto out
+ * out_false:
+ * push 0
+ * out:
+ */
+ emit_load_scalar(ltmp->idx);
+ TclEmitOpcode(INST_LIST_LENGTH, L->frame->envPtr);
+ emit_load_scalar(rtmp->idx);
+ TclEmitOpcode(INST_LIST_LENGTH, L->frame->envPtr);
+ emit_store_scalar(itmp->idx);
+ TclEmitOpcode(INST_EQ, L->frame->envPtr);
+ out_false = emit_jmp_fwd(INST_JUMP_FALSE4, out_false);
+ top_off = currOffset(L->frame->envPtr);
+ emit_load_scalar(itmp->idx);
+ out_true = emit_jmp_fwd(INST_JUMP_FALSE4, out_true);
+ TclEmitInstInt1(INST_INCR_SCALAR1_IMM, itmp->idx,
+ L->frame->envPtr);
+ TclEmitInt1(-1, L->frame->envPtr);
+ emit_pop();
+ emit_load_scalar(ltmp->idx);
+ emit_load_scalar(itmp->idx);
+ TclEmitOpcode(INST_LIST_INDEX, L->frame->envPtr);
+ emit_load_scalar(rtmp->idx);
+ emit_load_scalar(itmp->idx);
+ TclEmitOpcode(INST_LIST_INDEX, L->frame->envPtr);
+ compile_eq_stack(expr, type->base_type);
+ out_false = emit_jmp_fwd(INST_JUMP_FALSE4, out_false);
+ emit_jmp_back(TCL_UNCONDITIONAL_JUMP, top_off);
+ fixup_jmps(&out_true);
+ push_lit("1");
+ out = emit_jmp_fwd(INST_JUMP1, out);
+ fixup_jmps(&out_false);
+ push_lit("0");
+ fixup_jmps(&out);
+ tmp_free(itmp);
+ break;
+ case L_STRUCT:
+ /*
+ * The structs are of compatible types, so we know
+ * they have the same number of members. Compare
+ * them one by one.
+ */
+ i = 0;
+ for (v = type->u.struc.members; v; v = v->next) {
+ emit_load_scalar(ltmp->idx);
+ TclEmitInstInt4(INST_LIST_INDEX_IMM, i,
+ L->frame->envPtr);
+ emit_load_scalar(rtmp->idx);
+ TclEmitInstInt4(INST_LIST_INDEX_IMM, i,
+ L->frame->envPtr);
+ ++i;
+ compile_eq_stack(expr, v->type);
+ out_false = emit_jmp_fwd(INST_JUMP_FALSE4, out_false);
+ }
+ push_lit("1");
+ out = emit_jmp_fwd(INST_JUMP1, out);
+ fixup_jmps(&out_false);
+ push_lit("0");
+ fixup_jmps(&out);
+ break;
+ case L_HASH:
+ /*
+ * if (length(lhs) != length(rhs)) goto out_false2
+ * if [dict first lhs] goto out_true
+ * top_off:
+ * // stack: val key (key is on top)
+ * unless [::dict exists rhs key] goto out_false
+ * unless [::dict get rhs key] == val goto out_false2
+ * unless [dict next] goto top_off
+ * out_true:
+ * pop // pop key
+ * pop // pop val
+ * push 1
+ * goto out
+ * out_false:
+ * pop // pop key
+ * pop // pop val
+ * out_false2:
+ * push 0
+ * out:
+ */
+ itmp = tmp_get(TMP_UNSET);
+ push_lit("::dict");
+ push_lit("size");
+ emit_load_scalar(ltmp->idx);
+ // ::dict size lhs
+ emit_invoke(3);
+ // <lhs-size>
+ push_lit("::dict");
+ push_lit("size");
+ emit_load_scalar(rtmp->idx);
+ // <lhs-size> ::dict size rhs
+ emit_invoke(3);
+ // <lhs-size> <rhs-size>
+ TclEmitOpcode(INST_EQ, L->frame->envPtr);
+ // <true/false>
+ out_false2 = emit_jmp_fwd(INST_JUMP_FALSE4, out_false2);
+ emit_load_scalar(ltmp->idx);
+ // lhs
+ TclEmitInstInt4(INST_DICT_FIRST, itmp->idx, L->frame->envPtr);
+ // <lhs-val> <lhs-key> <done-flag>
+ out_true = emit_jmp_fwd(INST_JUMP_TRUE4, out_true);
+ top_off = currOffset(L->frame->envPtr);
+ // <lhs-val> <lhs-key>
+ TclEmitOpcode(INST_DUP, L->frame->envPtr);
+ // <lhs-val> <lhs-key> <lhs-key>
+ push_lit("::dict");
+ push_lit("exists");
+ emit_load_scalar(rtmp->idx);
+ // <lhs-val> <lhs-key> <lhs-key> ::dict exists rhs
+ TclEmitInstInt1(INST_ROT, 3, L->frame->envPtr);
+ // <lhs-val> <lhs-key> ::dict exists rhs <lhs-key>
+ emit_invoke(4);
+ // <lhs-val> <lhs-key> <rhs-exists-flag>
+ out_false = emit_jmp_fwd(INST_JUMP_FALSE4, out_false);
+ // <lhs-val> <lhs-key>
+ push_lit("::dict");
+ push_lit("get");
+ emit_load_scalar(rtmp->idx);
+ // <lhs-val> <lhs-key> ::dict get rhs
+ TclEmitInstInt1(INST_ROT, 3, L->frame->envPtr);
+ // <lhs-val> ::dict get rhs <lhs-key>
+ emit_invoke(4);
+ // <lhs-val> <rhs-val>
+ compile_eq_stack(expr, type->base_type);
+ // <equals-flag>
+ out_false2 = emit_jmp_fwd(INST_JUMP_FALSE4, out_false2);
+ TclEmitInstInt4(INST_DICT_NEXT, itmp->idx, L->frame->envPtr);
+ // <lhs-val> <lhs-key> <done-flag>
+ emit_jmp_back(TCL_FALSE_JUMP, top_off);
+ fixup_jmps(&out_true);
+ // <lhs-val> <lhs-key>
+ emit_pop();
+ emit_pop();
+ push_lit("1");
+ out = emit_jmp_fwd(INST_JUMP1, out);
+ // <lhs-val> <lhs-key>
+ fixup_jmps(&out_false);
+ emit_pop();
+ emit_pop();
+ fixup_jmps(&out_false2);
+ push_lit("0");
+ fixup_jmps(&out);
+ tmp_free(itmp);
+ break;
+ default: ASSERT(0);
+ }
+ tmp_free(ltmp);
+ tmp_free(rtmp);
+}
+
+private int
+compile_keys(Expr *expr)
+{
+ int n;
+
+ push_lit("::dict");
+ push_lit("keys");
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+ unless (n == 1) {
+ L_errf(expr, "incorrect # args to keys");
+ expr->type = L_poly;
+ return (0); // stack effect
+ }
+ unless (ishash(expr->b) || ispoly(expr->b)) {
+ L_errf(expr, "arg to keys is not a hash");
+ expr->type = L_poly;
+ return (0); // stack effect
+ }
+ emit_invoke(3);
+ if (ispoly(expr->b)) {
+ expr->type = L_poly;
+ } else {
+ expr->type = type_mkArray(0, expr->b->type->u.hash.idx_type);
+ }
+ return (1); // stack effect
+}
+
+private int
+compile_length(Expr *expr)
+{
+ int n;
+ Jmp *jmp1, *jmp2;
+
+ expr->type = L_int;
+
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+ unless (n == 1) {
+ L_errf(expr, "incorrect # args to length");
+ return (0); // stack effect
+ }
+ if (isstring(expr->b) || iswidget(expr->b)) {
+ TclEmitOpcode(INST_STR_LEN, L->frame->envPtr);
+ } else if (isarray(expr->b) || islist(expr->b) || ispoly(expr->b)) {
+ TclEmitOpcode(INST_LIST_LENGTH, L->frame->envPtr);
+ } else if (ishash(expr->b)) {
+ /*
+ * <arg is on stack from above compile_exprs>
+ * dup
+ * l_defined
+ * jmpFalse 1
+ * ::dict size (rot arg into place before the invoke)
+ * jmp 2
+ * 1: pop
+ * push 0
+ * 2:
+ */
+ TclEmitOpcode(INST_DUP, L->frame->envPtr);
+ TclEmitOpcode(INST_L_DEFINED, L->frame->envPtr);
+ jmp1 = emit_jmp_fwd(INST_JUMP_FALSE1, NULL);
+ push_lit("::dict");
+ push_lit("size");
+ TclEmitInstInt1(INST_ROT, 2, L->frame->envPtr);
+ emit_invoke(3);
+ jmp2 = emit_jmp_fwd(INST_JUMP1, NULL);
+ fixup_jmps(&jmp1);
+ emit_pop();
+ push_lit("0");
+ fixup_jmps(&jmp2);
+ } else {
+ L_errf(expr, "arg to length has illegal type");
+ }
+ return (1); // stack effect
+}
+
+private int
+compile_min_max(Expr *expr)
+{
+ push_litf("::tcl::mathfunc::%s", expr->a->str);
+ unless (compile_exprs(expr->b, L_PUSH_VAL) == 2) {
+ L_errf(expr, "incorrect # args to %s", expr->a->str);
+ expr->type = L_poly;
+ return (0);
+ }
+ L_typeck_expect(L_INT|L_FLOAT, expr->b, "in min/max");
+ L_typeck_expect(L_INT|L_FLOAT, expr->b->next, "in min/max");
+ emit_invoke(3);
+ if (isfloat(expr->b) || isfloat(expr->b->next)) {
+ expr->type = L_float;
+ } else {
+ expr->type = L_int;
+ }
+ return (1); // stack effect
+}
+
+private int
+compile_sort(Expr *expr)
+{
+ int custom_compar = 0, i, n;
+ Expr *e, *l;
+ Type *t;
+
+ /*
+ * Do some gymnastics to get this on the run-time stack:
+ * ::lsort
+ * <all args except last one>
+ * -integer, -real, or -ascii depending on list type, unless
+ * the -compare option was given
+ * <last arg (the thing to be sorted)>
+ */
+
+ push_lit("::lsort");
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+ unless (n >= 1) {
+ L_errf(expr, "incorrect # args to sort");
+ expr->type = L_poly;
+ return (0); // stack effect
+ }
+ /* See if there's a "-command" argument. */
+ for (i = 0, l = expr->b; i < (n-1); ++i, l = l->next) {
+ unless (isconst(l) && l->str && !strcmp(l->str, "-command")) {
+ continue;
+ }
+ /* Type check the arg to -command. */
+ e = l->next;
+ unless (e && (e->type->kind == L_NAMEOF) &&
+ (e->type->base_type->kind == L_FUNCTION)) {
+ L_errf(e, "'command:' arg to sort must be &function");
+ }
+ custom_compar = 1;
+ }
+ /* The last argument to sort must be an array, list, or poly. */
+ if (isarray(l) || islist(l)) {
+ t = l->type->base_type;
+ } else if (ispoly(l)) {
+ t = L_poly;
+ } else {
+ L_errf(expr, "last arg to sort not an array or list");
+ expr->type = L_poly;
+ return (0); // stack effect
+ }
+ unless (custom_compar) {
+ switch (t->kind) {
+ case L_INT:
+ push_lit("-integer");
+ break;
+ case L_FLOAT:
+ push_lit("-real");
+ break;
+ default:
+ push_lit("-ascii");
+ break;
+ }
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ ++n;
+ }
+ if (n > 255) L_errf(expr, "sort cannot have >255 args");
+ emit_invoke(n+1);
+ expr->type = type_mkArray(0, t);
+ return (1); // stack effect
+}
+
+private int
+compile_join(Expr *expr)
+{
+ Expr *array, *sep;
+
+ expr->type = L_string;
+ push_lit("::join");
+ unless ((sep=expr->b) && (array=sep->next) && !array->next) {
+ L_errf(expr, "incorrect # args to join");
+ return (0); // stack effect
+ }
+ compile_expr(array, L_PUSH_VAL);
+ unless (isarray(array) || islist(array) || ispoly(array)) {
+ L_errf(expr, "second arg to join not an array or list");
+ return (0); // stack effect
+ }
+ compile_expr(sep, L_PUSH_VAL);
+ unless (isstring(sep) || iswidget(sep) || ispoly(sep)) {
+ L_errf(expr, "first arg to join not a string");
+ return (0); // stack effect
+ }
+ emit_invoke(3);
+ return (1); // stack effect
+}
+
+private int
+compile_abs(Expr *expr)
+{
+ int n;
+
+ push_lit("::tcl::mathfunc::abs");
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+ unless (n == 1) {
+ L_errf(expr, "incorrect # args to abs");
+ expr->type = L_poly;
+ return (0);
+ }
+ unless (isint(expr->b) || isfloat(expr->b) || ispoly(expr->b)) {
+ L_errf(expr, "must pass int or float to abs");
+ }
+ emit_invoke(2);
+ expr->type = expr->b->type;
+ return (1); // stack effect
+}
+
+private int
+compile_assert(Expr *expr)
+{
+ Jmp *jmp;
+ char *cond_txt;
+
+ expr->type = L_void;
+ unless (expr->b && !expr->b->next) {
+ L_errf(expr, "incorrect # args to assert");
+ return (0); // stack effect
+ }
+ compile_condition(expr->b);
+ jmp = emit_jmp_fwd(INST_JUMP_TRUE4, NULL);
+ cond_txt = get_text(expr->b);
+ push_lit("die_");
+ push_lit(frame_name());
+ push_litf("%d", expr->node.loc.line);
+ push_litf("ASSERTION FAILED %s:%d: %s\n", expr->node.loc.file,
+ expr->node.loc.line, cond_txt);
+ emit_invoke(4);
+ emit_pop();
+ ckfree(cond_txt);
+ fixup_jmps(&jmp);
+ return (0); // stack effect
+}
+
+private int
+compile_catch(Expr *expr)
+{
+ L_errf(expr, "catch() is reserved for try/catch; "
+ "use ::catch() for Tcl's catch");
+ return (0);
+}
+
+/*
+ * Change die(fmt, ...args) into die_(__FILE__, __LINE__, fmt, ...args)
+ */
+private int
+compile_die(Expr *expr)
+{
+ Expr *arg;
+
+ ckfree(expr->a->str);
+ expr->a->str = ckstrdup("die_");
+ arg = ast_mkId("__FILE__", expr->node.loc, expr->node.loc);
+ arg->next = ast_mkId("__LINE__", expr->node.loc, expr->node.loc);
+ arg->next->next = expr->b;
+ expr->b = arg;
+ return (compile_expr(expr, L_PUSH_VAL));
+}
+
+/*
+ * Change warn(fmt, ...args) into warn_(__FILE__, __LINE__, fmt, ...args)
+ */
+private int
+compile_warn(Expr *expr)
+{
+ Expr *arg;
+
+ ckfree(expr->a->str);
+ expr->a->str = ckstrdup("warn_");
+ arg = ast_mkId("__FILE__", expr->node.loc, expr->node.loc);
+ arg->next = ast_mkId("__LINE__", expr->node.loc, expr->node.loc);
+ arg->next->next = expr->b;
+ expr->b = arg;
+ return (compile_expr(expr, L_PUSH_VAL));
+}
+
+/*
+ * Change here() into here_(__FILE__, __LINE__, __FUNC__)
+ */
+private int
+compile_here(Expr *expr)
+{
+ Expr *arg;
+
+ if (expr->b) {
+ L_errf(expr, "here() takes no arguments");
+ }
+ ckfree(expr->a->str);
+ expr->a->str = ckstrdup("here_");
+ arg = ast_mkId("__FILE__", expr->node.loc, expr->node.loc);
+ arg->next = ast_mkId("__LINE__", expr->node.loc, expr->node.loc);
+ arg->next->next = ast_mkId("__FUNC__", expr->node.loc, expr->node.loc);
+ expr->b = arg;
+ return (compile_expr(expr, L_PUSH_VAL));
+}
+
+private int
+compile_undef(Expr *expr)
+{
+ int n;
+ Expr *arg = expr->b;
+
+ n = compile_exprs(arg, L_PUSH_PTR | L_DELETE | L_LVALUE);
+ unless (n == 1) {
+ L_errf(expr, "incorrect # args to undef");
+ goto done;
+ }
+ unless (arg->sym) {
+ L_errf(expr, "illegal l-value in undef()");
+ goto done;
+ }
+ if (((arg->op == L_OP_DOT) || (arg->op == L_OP_POINTS)) &&
+ isstruct(arg->a)) {
+ L_errf(expr, "cannot undef() a struct field");
+ goto done;
+ }
+ /*
+ * If arg is a deep dive, delete the hash or array element.
+ * If arg is a variable, treat undef(var) like var=undef.
+ */
+ if (arg->flags & L_EXPR_DEEP) {
+ TclEmitInstInt4(INST_L_DEEP_WRITE,
+ arg->sym->idx,
+ L->frame->envPtr);
+ TclEmitInt4(L_DELETE | L_DISCARD, L->frame->envPtr);
+ } else {
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ emit_store_scalar(arg->sym->idx);
+ emit_pop();
+ }
+ done:
+ expr->type = L_void;
+ return (0); // stack effect
+}
+
+private int
+compile_typeof(Expr *expr)
+{
+ Sym *sym;
+
+ expr->type = L_string;
+ unless (expr->b->kind == L_EXPR_ID) {
+ L_errf(expr, "argument to typeof() not a variable");
+ return (0);
+ }
+ sym = sym_lookup(expr->b, 0);
+ if (sym) {
+ if (sym->type->name) {
+ push_lit(sym->type->name);
+ } else {
+ push_lit(L_type_str(sym->type->kind));
+ }
+ }
+ return (1); // stack effect
+}
+
+private int
+compile_read(Expr *expr)
+{
+ int n;
+ Expr *buf, *fd, *nbytes;
+
+ expr->type = L_int;
+ push_lit("Lread_");
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+ unless ((n == 2) || (n == 3)) {
+ L_errf(expr, "incorrect # args to read()");
+ return (0);
+ }
+ fd = expr->b;
+ unless (typeisf(fd, "FILE") || ispoly(fd)) {
+ L_errf(expr, "first arg to read() must have type FILE");
+ return (0);
+ }
+ buf = fd->next;
+ unless (isaddrof(buf) && (isstring(buf->a) || ispoly(buf->a))) {
+ L_errf(expr, "second arg to read() must have type string&");
+ return (0);
+ }
+ nbytes = buf->next;
+ if (nbytes) {
+ unless (isint(nbytes) || ispoly(nbytes)) {
+ L_errf(expr, "third arg to read() must have type int");
+ return (0);
+ }
+ }
+ emit_invoke(n+1);
+ return (1); // stack effect
+}
+
+private int
+compile_write(Expr *expr)
+{
+ int n;
+ Expr *buf, *fd, *nbytes;
+
+ expr->type = L_int;
+ push_lit("Lwrite_");
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+ unless (n == 3) {
+ L_errf(expr, "incorrect # args to write()");
+ return (0);
+ }
+ fd = expr->b;
+ unless (typeisf(fd, "FILE") || ispoly(fd)) {
+ L_errf(expr, "first arg to write() must have type FILE");
+ return (0);
+ }
+ buf = fd->next;
+ unless (isstring(buf) || iswidget(buf) || ispoly(buf)) {
+ L_errf(expr, "second arg to write() must have type string");
+ return (0);
+ }
+ nbytes = buf->next;
+ unless (isint(nbytes) || ispoly(nbytes)) {
+ L_errf(expr, "third arg to write() must have type int");
+ return (0);
+ }
+ emit_invoke(4);
+ return (1); // stack effect
+}
+
+/*
+ * Allowable forms of system():
+ *
+ * int system(string cmd)
+ * int system(string cmd, STATUS &s)
+ * int system(string argv[])
+ * int system(string argv[], STATUS &s)
+ * int system(cmd | argv[], string in, string &out, string &err)
+ * int system(cmd | argv[], string in, string &out, string &err, STATUS &)
+ * int system(cmd | argv[], string[] in, string[] &out, string[] &err)
+ * int system(cmd | argv[], string[] in, string[] &out, string[] &err,STATUS &)
+ * int system(cmd | argv[], "input", "${outf}", "errors")
+ * int system(cmd | argv[], "input", "${outf}", "errors", STATUS &s)
+ * int system(cmd | argv[], FILE in, FILE out, FILE err);
+ * int system(cmd | argv[], FILE in, FILE out, FILE err, STATUS &s);
+ *
+ * and spawn():
+ *
+ * int spawn(string cmd)
+ * int spawn(string cmd, STATUS &s)
+ * int spawn(string argv[])
+ * int spawn(string argv[], STATUS &s)
+ * int spawn(cmd | argv[], string in, FILE out, FILE err)
+ * int spawn(cmd | argv[], string in, FILE out, FILE err, STATUS &s)
+ * int spawn(cmd | argv[], string[] in, FILE out, FILE err)
+ * int spawn(cmd | argv[], string[] in, FILE out, FILE err, STATUS &s)
+ * int spawn(cmd | argv[], "input", "${outf}", "errors")
+ * int spawn(cmd | argv[], "input", "${outf}", "errors", STATUS &s)
+ * int spawn(cmd | argv[], FILE in, FILE out, FILE err)
+ * int spawn(cmd | argv[], FILE in, FILE out, FILE err, STATUS &s)
+ *
+ * Convert these into a call to system_ or spawn_ that has exactly
+ * seven args, the last being flags indicating the number and type of
+ * what the user supplied.
+ */
+
+private int
+compile_spawn_system(Expr *expr)
+{
+ int flags = 0, n;
+ Expr *cmd;
+ Expr *err = NULL, *in = NULL, *out = NULL, *status = NULL;
+ enum { SYSTEM, SPAWN } kind;
+
+ kind = isid(expr->a, "system") ? SYSTEM : SPAWN;
+
+ push_lit("system_");
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+
+ expr->type = L_poly;
+ cmd = expr->b;
+ switch (n) {
+ case 1:
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ break;
+ case 2:
+ status = cmd->next;
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ TclEmitInstInt1(INST_ROT, 3, L->frame->envPtr);
+ break;
+ case 4:
+ in = cmd->next;
+ out = in->next;
+ err = out->next;
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ break;
+ case 5:
+ in = cmd->next;
+ out = in->next;
+ err = out->next;
+ status = err->next;
+ break;
+ default:
+ L_errf(expr, "incorrect # args");
+ return (0);
+ }
+ if (isstring(cmd) || ispoly(cmd)) {
+ } else if (isarrayof(cmd, L_STRING | L_POLY) || islist(cmd)) {
+ flags |= SYSTEM_ARGV;
+ } else {
+ L_errf(expr, "first arg must be string or string array");
+ }
+ switch (kind) {
+ case SYSTEM: flags |= typeck_system(in, out, err); break;
+ case SPAWN: flags |= typeck_spawn(in, out, err); break;
+ }
+ if (status) {
+ Type *base_type = status->type->base_type;
+ unless (isid(status, "undef") ||
+ (isnameoftype(status->type) &&
+ (ispolytype(base_type) || typeis(base_type, "STATUS")))) {
+ L_errf(expr, "last arg must be of type STATUS &");
+ return (0);
+ }
+ }
+ push_litf("0x%x", flags);
+ emit_invoke(7);
+ expr->type = L_int;
+ return (1);
+}
+
+private int
+typeck_spawn(Expr *in, Expr *out, Expr *err)
+{
+ int flags = 0;
+
+ if (!in || isid(in, "undef")) {
+ } else if (typeisf(in, "FILE")) {
+ flags |= SYSTEM_IN_HANDLE;
+ } else if (isstring(in) && (isconst(in) || isinterp(in))) {
+ flags |= SYSTEM_IN_FILENAME;
+ } else if (isstring(in) || ispoly(in)) {
+ flags |= SYSTEM_IN_STRING;
+ } else if (isarrayof(in, L_STRING | L_POLY) || islist(in)) {
+ flags |= SYSTEM_IN_ARRAY;
+ } else {
+ L_errf(in, "second arg must be FILE, or "
+ "string constant/variable/array");
+ }
+ if (!out || isid(out, "undef")) {
+ } else if (typeisf(out, "FILE")) {
+ flags |= SYSTEM_OUT_HANDLE;
+ } else if (isstring(out) && (isconst(out) || isinterp(out))) {
+ flags |= SYSTEM_OUT_FILENAME;
+ } else {
+ L_errf(out, "third arg must be FILE, or string constant");
+ }
+ if (!err || isid(err, "undef")) {
+ } else if (typeisf(err, "FILE")) {
+ flags |= SYSTEM_ERR_HANDLE;
+ } else if (isstring(err) && (isconst(err) || isinterp(err))) {
+ flags |= SYSTEM_ERR_FILENAME;
+ } else {
+ L_errf(err, "fourth arg must be FILE, or string constant");
+ }
+
+ return (flags | SYSTEM_BACKGROUND);
+}
+
+private int
+typeck_system(Expr *in, Expr *out, Expr *err)
+{
+ int flags = 0;
+
+ if (!in || isid(in, "undef")) {
+ } else if (typeisf(in, "FILE")) {
+ flags |= SYSTEM_IN_HANDLE;
+ } else if (isstring(in) && (isconst(in) || isinterp(in))) {
+ flags |= SYSTEM_IN_FILENAME;
+ } else if (isstring(in) || ispoly(in)) {
+ flags |= SYSTEM_IN_STRING;
+ } else if (isarrayof(in, L_STRING | L_POLY) || islist(in)) {
+ flags |= SYSTEM_IN_ARRAY;
+ } else {
+ L_errf(in, "second arg must be FILE, or "
+ "string constant/variable/array");
+ }
+ if (!out || isid(out, "undef")) {
+ } else if (typeisf(out, "FILE")) {
+ flags |= SYSTEM_OUT_HANDLE;
+ } else if (isstring(out) && (isconst(out) || isinterp(out))) {
+ flags |= SYSTEM_OUT_FILENAME;
+ } else if (isaddrof(out) && (isstring(out->a) || ispoly(out->a))) {
+ flags |= SYSTEM_OUT_STRING;
+ } else if (isaddrof(out) && isarrayof(out->a, L_STRING | L_POLY)) {
+ flags |= SYSTEM_OUT_ARRAY;
+ } else {
+ L_errf(out, "third arg must be FILE, string "
+ "constant, or reference to string or string array");
+ }
+ if (!err || isid(err, "undef")) {
+ } else if (typeisf(err, "FILE")) {
+ flags |= SYSTEM_ERR_HANDLE;
+ } else if (isstring(err) && (isconst(err) || isinterp(err))) {
+ flags |= SYSTEM_ERR_FILENAME;
+ } else if (isaddrof(err) && (isstring(err->a) || ispoly(err->a))) {
+ flags |= SYSTEM_ERR_STRING;
+ } else if (isaddrof(err) && isarrayof(err->a, L_STRING | L_POLY)) {
+ flags |= SYSTEM_ERR_ARRAY;
+ } else {
+ L_errf(err, "fourth arg must be FILE, string "
+ "constant, or reference to string or string array");
+ }
+
+ return (flags);
+}
+
+private int
+compile_popen(Expr *expr)
+{
+ int flags = 0, n;
+ Expr *cb, *cmd, *mode;
+ VarDecl *args;
+ Type *want;
+ YYLTYPE loc = { 0 };
+
+ push_lit("popen_");
+ expr->type = L_poly;
+
+ n = compile_exprs(expr->b, L_PUSH_VAL);
+ unless ((n == 2) || (n == 3)) {
+ L_errf(expr, "incorrect # args to popen");
+ return (0);
+ }
+ cmd = expr->b;
+ mode = cmd->next;
+ cb = mode->next;
+
+ if (isarrayof(cmd, L_STRING | L_POLY) || islist(cmd)) {
+ flags |= SYSTEM_ARGV;
+ } else unless (isstring(cmd) || ispoly(cmd)) {
+ L_errf(cmd, "first arg to popen must be string or string array");
+ }
+
+ L_typeck_expect(L_STRING, mode, "in second arg to popen");
+
+ // To typecheck the optional stderr-callback arg, build a
+ // type descriptor and let L_typeck_same() do the work.
+ if (cb) {
+ args = ast_mkVarDecl(L_string, NULL, loc, loc);
+ args->next = ast_mkVarDecl(L_string, NULL, loc, loc);
+ want = type_mkNameOf(type_mkFunc(L_void, args));
+ unless (L_typeck_same(want, cb->type)) {
+ L_errf(cb, "illegal type for stderr callback");
+ }
+ flags |= SYSTEM_OUT_HANDLE;
+ } else {
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ }
+
+ push_litf("0x%x", flags);
+ emit_invoke(5);
+ expr->type = L_typedef_lookup("FILE");
+ ASSERT(expr->type);
+ return (1);
+}
+
+/*
+ * Return a copy of the source text for the given expression. Caller
+ * must free.
+ */
+private char *
+get_text(Expr *expr)
+{
+ int beg = expr->node.loc.beg;
+ int end = expr->node.loc.end;
+ int len = end - beg;
+ char *s;
+
+ s = ckalloc(len + 1);
+ strncpy(s, Tcl_GetString(L->script)+beg, len);
+ s[len] = 0;
+ return (s);
+}
+
+/*
+ * Emit code to compute the value of the given expression. The flags
+ * say in what form the generated code should produce the value. The
+ * caller chooses these flags based on whether
+ * 1. expr will be read, written, or both; and whether
+ * 2. expr is a deep dive or something else (an object dereference,
+ * a variable, or an expression).
+ * The flags are bit-masks (see below) and can be combined.
+ *
+ * Passing in one of the pointer flags means that IF the expr is a
+ * deep dive, leave a deep-ptr to it and possibly also its value on
+ * the run-time stack. If the expr is not, evaluate it (so that
+ * expr->sym etc is valid) but don't push anything. You use this when
+ * expr is an l-value.
+ *
+ * Passing in L_PUSH_VAL and none of the pointer flags means that
+ * the expr's value is left on the stack.
+ *
+ * Passing in both L_PUSH_VAL and one of the pointer flags is done
+ * when the caller needs a deep-ptr if expr is a deep dive but
+ * just wants the value otherwise. You use this when expr is
+ * an l-value but you also need the r-value, such as when
+ * compiling ++/-- or =~.
+ *
+ * Passing in L_PUSH_NAME means the fully qualified name of the
+ * variable is left on the stack and is valid only for certain
+ * kinds of variables (globals, locals, class variables, or class
+ * instance variables).
+ *
+ * L_PUSH_VAL push value onto stack, unless deep dive and
+ * you also request a deep-ptr
+ * L_PUSH_PTR if deep dive, push deep-ptr onto stack
+ * L_PUSH_PTRVAL if deep dive, push deep-ptr then value onto stack
+ * L_PUSH_VALPTR if deep dive, push value then deep-ptr onto stack
+ * L_LVALUE if deep dive, create an un-shared copy for writing
+ * L_DISCARD evaluate expr then discard its value
+ * L_PUSH_NAME push fully qualified name of variable, not the value
+ */
+private int
+compile_expr(Expr *expr, Expr_f flags)
+{
+ int n = 0;
+ int start_off = currOffset(L->frame->envPtr);
+
+ ++L->expr_level;
+
+ /* The compile_xxx returns indicate whether they pushed anything. */
+ unless (expr) return (0);
+ switch (expr->kind) {
+ case L_EXPR_FUNCALL:
+ n = compile_fnCall(expr);
+ break;
+ case L_EXPR_CONST:
+ case L_EXPR_RE:
+ push_lit(expr->str);
+ n = 1;
+ break;
+ case L_EXPR_ID:
+ n = compile_var(expr, flags);
+ break;
+ case L_EXPR_UNOP:
+ n = compile_unOp(expr);
+ break;
+ case L_EXPR_BINOP:
+ n = compile_binOp(expr, flags);
+ break;
+ case L_EXPR_TRINOP:
+ n = compile_trinOp(expr);
+ break;
+ default:
+ L_bomb("Unknown expression type %d", expr->kind);
+ }
+
+ /*
+ * Throw away the value if requested by the caller. This is done
+ * for expressions that are statements, in for-loop pre and
+ * post expressions, etc.
+ */
+ if (flags & L_DISCARD) {
+ while (n--) emit_pop();
+ }
+
+ track_cmd(start_off, expr);
+
+ --L->expr_level;
+ return (n);
+}
+
+/*
+ * If a function-call name begins with a cap and has an _ inside, it
+ * looks like a pattern call. From a name like "Foo_barBazBlech"
+ * create Expr const nodes "foo", "Foo_*" and a linked list of Expr
+ * const nodes for "bar", "baz", and "blech". Note that the returned
+ * Expr's need not be freed explicitly since all AST nodes are
+ * deallocated by the compiler.
+ */
+private int
+ispatternfn(char *name, Expr **foo, Expr **Foo_star, Expr **opts, int *nopts)
+{
+ int i;
+ char *buf, *p, *under;
+ Expr *e;
+
+ unless ((name[0] >= 'A') && (name[0] <= 'Z') &&
+ (p = strchr(name, '_')) && p[1]) { // _ cannot be last
+ return (FALSE);
+ }
+
+ under = p;
+ *under = '\0';
+
+ /* Build foo from Foo_bar. */
+ buf = cksprintf("%s", name);
+ buf[0] = tolower(buf[0]);
+ *foo = mkId(buf);
+ ckfree(buf);
+
+ /* Build Foo_* from Foo_bar. */
+ buf = cksprintf("%s_*", name);
+ *Foo_star = mkId(buf);
+ ckfree(buf);
+
+ /* Build a list of bar,baz,blech nodes from barBazBlech. */
+ ++p;
+ *opts = NULL;
+ *nopts = 0;
+ while (*p) {
+ YYLTYPE loc = { 0 };
+ *p = tolower(*p);
+ buf = ckalloc(strlen(p) + 1);
+ for (i = 0; *p && !isupper(*p); ++p, ++i) {
+ buf[i] = *p;
+ }
+ buf[i] = 0;
+ e = ast_mkConst(L_string, buf, loc, loc);
+ APPEND_OR_SET(Expr, next, *opts, e);
+ ++(*nopts);
+ }
+
+ *under = '_';
+
+ return (TRUE);
+}
+
+/*
+ * Rules for compiling a function call like "foo(arg)":
+ *
+ * - If foo is a variable of type name-of function, assume it contains
+ * the name of the function to call.
+ *
+ * - Otherwise call foo. If foo isn't declared, that's OK, we just
+ * won't have a prototype to type-check against.
+ *
+ * For a function call like "Foo_bar(a,b,c)" or "Foo_barBazBlech(a,b,c)",
+ * where the name starts with [A-Z] and has an _ in it (except at the
+ * end), we have what's called a "pattern function". The "bar", "baz",
+ * and "blech" are the "options", and "a", "b", and "c" are the "arguments".
+ *
+ * - If Foo_bar happens to be a declared function, handle as above.
+ *
+ * - If the function Foo_* is defined, change the call to
+ * Foo_*(bar,baz,blech,a,b,c).
+ *
+ * - If "a" is not of widget type, change the call to
+ * foo(bar,baz,blech,a,b,c).
+ *
+ * - If "a" is a widget type, change the call to *a(bar,baz,blech,b,c)
+ * where *a means that the value of the argument "a" becomes the
+ * function name.
+ */
+private int
+compile_fnCall(Expr *expr)
+{
+ int expand, i, level, nopts;
+ int num_parms = 0, typchk = FALSE;
+ char *name;
+ char *defchk = NULL; // name for definedness chk before main() runs
+ Expr *foo, *Foo_star, *opts, *p;
+ Sym *sym;
+ VarDecl *formals = NULL;
+
+ ASSERT(expr->a->kind == L_EXPR_ID);
+ name = expr->a->str;
+
+ /* Check for an (expand) in the arg list. */
+ expand = 0;
+ for (p = expr->b; p; p = p->next) {
+ if (isexpand(p)) {
+ TclEmitOpcode(INST_EXPAND_START, L->frame->envPtr);
+ expand = 1;
+ break;
+ }
+ }
+
+ /*
+ * Check for an L built-in function. XXX change the array to
+ * a hash if the number of built-ins grows much more.
+ */
+ for (i = 0; i < sizeof(builtins)/sizeof(builtins[0]); ++i) {
+ if (!strcmp(builtins[i].name, name)) {
+ if (expand) {
+ L_errf(expr, "(expand) illegal with "
+ "this function");
+ }
+ i = builtins[i].fn(expr);
+ /* Copy out hash/array elements passed by reference. */
+ copyout_parms(expr->b);
+ return (i);
+ }
+ }
+
+ level = fnCallBegin();
+ sym = sym_lookup(expr->a, L_NOWARN);
+
+ if (sym && isfntype(sym->type)) {
+ /* A regular call -- the name is the fn name. */
+ push_lit(sym->tclname);
+ formals = sym->type->u.func.formals;
+ typchk = TRUE;
+ defchk = name;
+ expr->type = sym->type->base_type;
+ } else if (sym && (sym->type->kind == L_NAMEOF) &&
+ (sym->type->base_type->kind == L_FUNCTION)) {
+ /*
+ * Name is a function "pointer". It holds the function
+ * name and its type is the function proto.
+ */
+ emit_load_scalar(sym->idx);
+ formals = sym->type->base_type->u.func.formals;
+ typchk = TRUE;
+ expr->type = sym->type->base_type->base_type;
+ } else if (sym) {
+ /* Name is declared but isn't a function or fn pointer. */
+ L_errf(expr, "'%s' is declared but not as a function", name);
+ expr->type = L_poly;
+ } else if (ispatternfn(name, &foo, &Foo_star, &opts, &nopts)) {
+ /* Pattern function. Figure out which kind. */
+ if ((sym = sym_lookup(Foo_star, L_NOWARN))) {
+ /* Foo_* is defined -- compile Foo_*(opts,a,b,c). */
+ push_lit(Foo_star->str);
+ APPEND(Expr, next, opts, expr->b);
+ expr->b = opts;
+ formals = sym->type->u.func.formals;
+ typchk = TRUE;
+ defchk = Foo_star->str;
+ expr->type = sym->type->base_type;
+ } else {
+ /* Push first arg, then check its type. */
+ compile_expr(expr->b, L_PUSH_VAL);
+ if (!expr->b) {
+ /* No args, compile as foo(opts). */
+ push_lit(foo->str);
+ num_parms = push_parms(opts, NULL);
+ defchk = foo->str;
+ } else if (iswidget(expr->b)) {
+ /* Compile as *a(opts,b,c). */
+ APPEND(Expr, next, opts, expr->b->next);
+ expr->b = opts;
+ } else {
+ /* Compile as foo(opts,a,b,c). */
+ // a
+ push_lit(foo->str);
+ num_parms = push_parms(opts, NULL);
+ ASSERT(num_parms == nopts);
+ // a foo <opts>
+ TclEmitInstInt1(isexpand(expr->b)?
+ INST_EXPAND_ROT : INST_ROT,
+ nopts + 1,
+ L->frame->envPtr);
+ // foo <opts> a
+ expr->b = expr->b->next;
+ ++num_parms;
+ defchk = foo->str;
+ }
+ expr->type = L_poly;
+ }
+ } else {
+ /* Call to an undeclared function. */
+ push_lit(name);
+ expr->type = L_poly;
+ defchk = name;
+ }
+ num_parms += push_parms(expr->b, formals);
+ if (expand) {
+ emit_invoke_expanded();
+ } else {
+ emit_invoke(num_parms+1);
+ }
+
+ /*
+ * Handle the copy-out part of copy in/out parameters.
+ * These are any deep-dive expressions that are passed by reference.
+ */
+ copyout_parms(expr->b);
+
+ if (typchk) L_typeck_fncall(formals, expr);
+ fnCallEnd(level);
+ /*
+ * If the call is to a function name that is known now (e.g.,
+ * not a function pointer), add it to the L->fn_calls list
+ * which is walked before main() is called to verify that the
+ * function exists.
+ */
+ if (defchk) {
+ Tcl_Obj *nm = Tcl_NewStringObj(defchk, -1);
+ Tcl_Obj *val = Tcl_NewObj();
+ Tcl_DictObjPut(L->interp, L->fn_calls, nm, val);
+ Tcl_SetVar2Ex(L->interp, "%%L_fnsCalled", NULL, L->fn_calls,
+ TCL_GLOBAL_ONLY);
+ }
+ return (1); // stack effect
+}
+
+private void
+copyout_parms(Expr *actuals)
+{
+ Expr *actual, *arg;
+
+ /*
+ * Copy out any deep-dive expressions that were passed with &.
+ * For these, the actual's value was copied into a temp var
+ * and its name passed. Copy that temp back out.
+ */
+ for (actual = actuals; actual; actual = actual->next) {
+ arg = actual->a;
+ unless (isaddrof(actual) && (arg->flags & L_SAVE_IDX)) {
+ continue;
+ }
+ emit_load_scalar(arg->u.deepdive.val->idx);
+ compile_assignFromStack(arg, arg->type, NULL, L_REUSE_IDX);
+ emit_pop();
+ tmp_free(arg->u.deepdive.val);
+ arg->u.deepdive.val = NULL;
+ }
+}
+
+private int
+compile_var(Expr *expr, Expr_f flags)
+{
+ Sym *self, *sym;
+
+ ASSERT(expr->kind == L_EXPR_ID);
+
+ /* Check for pre-defined identifiers first. */
+ if (isid(expr, "END")) {
+ TclEmitOpcode(INST_L_READ_SIZE, L->frame->envPtr);
+ unless ((L->idx_op == L_OP_ARRAY_INDEX) |
+ (L->idx_op == L_OP_ARRAY_SLICE)) {
+ L_errf(expr,
+ "END illegal outside of a string or array index");
+ }
+ expr->type = L_int;
+ return (1);
+ } else if (isid(expr, "undef")) {
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ expr->type = L_poly;
+ return (1);
+ } else if (isid(expr, "__FILE__")) {
+ push_lit(expr->node.loc.file);
+ expr->type = L_string;
+ return (1);
+ } else if (isid(expr, "__LINE__")) {
+ push_litf("%d", expr->node.loc.line);
+ expr->type = L_int;
+ return (1);
+ } else if (isid(expr, "__FUNC__")) {
+ push_lit(frame_name());
+ expr->type = L_string;
+ return (1);
+ }
+
+ unless ((sym = sym_lookup(expr, flags))) {
+ // Undeclared variable.
+ expr->type = L_poly;
+ return (1);
+ }
+ expr->type = sym->type;
+ if (flags & L_PUSH_VAL) {
+ if (sym->kind & L_SYM_FN) {
+ L_errf(expr, "cannot use a function name as a value");
+ } else {
+ emit_load_scalar(sym->idx);
+ }
+ return (1);
+ } else if (flags & L_PUSH_NAME) {
+ switch (canDeref(sym)) {
+ case DECL_GLOBAL_VAR:
+ if (sym->decl->flags & DECL_PRIVATE) {
+ push_litf("::_%s_%s", L->toplev, sym->name);
+ } else {
+ push_litf("::%s", sym->name);
+ }
+ break;
+ case DECL_LOCAL_VAR:
+ push_lit(sym->tclname);
+ break;
+ case DECL_FN:
+ push_lit(sym->tclname);
+ break;
+ case DECL_CLASS_VAR:
+ push_litf("::L::_class_%s::%s",
+ sym->decl->clsdecl->decl->id->str,
+ sym->name);
+ break;
+ case DECL_CLASS_INST_VAR:
+ self = sym_lookup(mkId("self"), L_NOWARN);
+ ASSERT(self);
+ emit_load_scalar(self->idx);
+ push_litf("::%s", sym->name);
+ TclEmitInstInt1(INST_STR_CONCAT1, 2, L->frame->envPtr);
+ break;
+ default:
+ ASSERT(0);
+ }
+ return (1);
+ } else {
+ /* Push nothing. */
+ return (0);
+ }
+ /* Not reached. */
+ ASSERT(0);
+ return (1);
+}
+
+private int
+compile_exprs(Expr *expr, Expr_f flags)
+{
+ int num_exprs;
+
+ for (num_exprs = 0; expr; expr = expr->next, ++num_exprs) {
+ compile_expr(expr, flags);
+ }
+ return (num_exprs);
+}
+
+/*
+ * Emit code to push the parameters to a function call and return the
+ * # pushed. Rules:
+ *
+ * - For two consecutive parms like "-foovariable, &foo", push "-foovariable"
+ * and then the name of "foo". This is legal only for globals, class
+ * variables, and class instance variables.
+ *
+ * - If undef is passed as a reference parameter, pass the name of the
+ * special variable L_undef_ref_parm_. Code in lib L sets read and
+ * write traces on this variable as a way to cause a run-time error
+ * upon access to it.
+ *
+ * - For everything else, push the value or name as indicated by whether
+ * the parm has the & operator; compile_expr() handles that. The type
+ * checker sorts out any mis-matches with the declared formals.
+ */
+private int
+push_parms(Expr *actuals, VarDecl *formals)
+{
+ int i;
+ int widget_flag = FALSE;
+ int strlen_of_variable = strlen("variable");
+ char *s;
+ Expr *a, *v;
+ Sym *sym;
+
+ for (i = 0, a = actuals; a; a = a->next, ++i) {
+ if (isaddrof(a) && (a->a->kind == L_EXPR_ID) &&
+ (sym = sym_lookup(a->a, L_NOWARN)) &&
+ (sym->decl->flags & DECL_REF)) {
+ push_lit(sym->tclname);
+ a->type = type_mkNameOf(a->a->type);
+ } else if (isid(a, "undef") &&
+ formals && isnameoftype(formals->type) &&
+ !isfntype(formals->type->base_type)) {
+ push_lit("::L_undef_ref_parm_");
+ a->type = L_poly;
+ } else {
+ compile_expr(a, L_PUSH_VAL);
+ }
+ if (widget_flag && isaddrof(a)) {
+ a->type = L_poly;
+ v = a->a;
+ /* can't use local vars or functions from a widget */
+ if (v->sym &&
+ ((v->sym->decl->flags & (DECL_LOCAL_VAR|DECL_FN)) ||
+ !canDeref(v->sym))) {
+ L_errf(a, "illegal operand to &");
+ }
+ }
+ s = a->str;
+ widget_flag = ((a->kind == L_EXPR_CONST) &&
+ isstring(a) &&
+ /* has at least the minimum length */
+ (strlen(s) > strlen_of_variable) &&
+ /* starts with '-' */
+ (s[0] == '-') &&
+ /* ends with "variable" */
+ !strcmp("variable", s + (strlen(s) - strlen_of_variable)));
+ if (formals) formals = formals->next;
+ }
+ return (i);
+}
+
+private int
+compile_unOp(Expr *expr)
+{
+ switch (expr->op) {
+ case L_OP_BANG:
+ case L_OP_BITNOT:
+ if (expr->op == L_OP_BANG) {
+ compile_condition(expr->a);
+ } else {
+ compile_expr(expr->a, L_PUSH_VAL);
+ }
+ L_typeck_expect(L_INT, expr->a, "in unary ! or ~");
+ emit_instrForLOp(expr, expr->type);
+ expr->type = expr->a->type;
+ break;
+ case L_OP_UPLUS:
+ case L_OP_UMINUS:
+ compile_expr(expr->a, L_PUSH_VAL);
+ L_typeck_expect(L_INT|L_FLOAT, expr->a, "in unary +/-");
+ emit_instrForLOp(expr, expr->type);
+ expr->type = expr->a->type;
+ break;
+ case L_OP_DEFINED:
+ compile_defined(expr->a);
+ expr->type = L_int;
+ break;
+ case L_OP_ADDROF:
+ /*
+ * Compile &<expr>. For function names, regular
+ * variables, and class variables (&x,
+ * &classname->var, &obj->var), this is just the name
+ * of the Tcl variable. For a deep-dive expr,
+ * it's the name of a temp var that holds the value.
+ */
+ compile_expr(expr->a, L_PUSH_NAME);
+ expr->type = type_mkNameOf(expr->a->type);
+ unless (expr->a->sym) {
+ L_errf(expr->a, "illegal operand to &");
+ expr->type = L_poly;
+ }
+ break;
+ case L_OP_PLUSPLUS_PRE:
+ case L_OP_PLUSPLUS_POST:
+ case L_OP_MINUSMINUS_PRE:
+ case L_OP_MINUSMINUS_POST:
+ compile_incdec(expr);
+ expr->type = expr->a->type;
+ break;
+ case L_OP_EXPAND:
+ unless (fnInArgList()) {
+ L_errf(expr, "(expand) illegal in this context");
+ }
+ compile_expr(expr->a, L_PUSH_VAL);
+ TclEmitInstInt4(INST_EXPAND_STKTOP,
+ L->frame->envPtr->currStackDepth,
+ L->frame->envPtr);
+ expr->type = L_poly;
+ break;
+ case L_OP_CMDSUBST:
+ push_lit("::backtick_");
+ if (expr->a) {
+ compile_expr(expr->a, L_PUSH_VAL);
+ push_lit(expr->str);
+ TclEmitInstInt1(INST_STR_CONCAT1, 2, L->frame->envPtr);
+ } else {
+ push_lit(expr->str);
+ }
+ emit_invoke(2);
+ expr->type = L_string;
+ break;
+ case L_OP_FILE:
+ if (expr->a) {
+ push_lit("fgetline");
+ compile_expr(expr->a, L_PUSH_VAL);
+ if (typeisf(expr->a, "FILE")) {
+ emit_invoke(2);
+ } else {
+ L_errf(expr->a, "expect FILE in <>");
+ }
+ } else {
+ push_lit("angle_read_");
+ emit_invoke(1);
+ }
+ expr->type = L_string;
+ break;
+ default:
+ L_bomb("Unknown unary operator %d", expr->op);
+ break;
+ }
+ return (1); // stack effect
+}
+
+private int
+compile_binOp(Expr *expr, Expr_f flags)
+{
+ int expand, level, n;
+ Type *type;
+ Expr *e;
+
+ /* Return the net run-time stack effect (i.e., how much was pushed). */
+
+ switch (expr->op) {
+ case L_OP_EQUALS:
+ compile_assign(expr);
+ expr->type = expr->a->type;
+ return (1);
+ case L_OP_EQPLUS:
+ case L_OP_EQMINUS:
+ case L_OP_EQSTAR:
+ case L_OP_EQSLASH:
+ compile_assign(expr);
+ L_typeck_expect(L_INT|L_FLOAT, expr->a,
+ "in arithmetic assignment");
+ expr->type = expr->a->type;
+ return (1);
+ case L_OP_EQPERC:
+ case L_OP_EQBITAND:
+ case L_OP_EQBITOR:
+ case L_OP_EQBITXOR:
+ case L_OP_EQLSHIFT:
+ case L_OP_EQRSHIFT:
+ compile_assign(expr);
+ L_typeck_expect(L_INT, expr->a, "in arithmetic assignment");
+ expr->type = expr->a->type;
+ return (1);
+ case L_OP_EQDOT:
+ compile_assign(expr);
+ L_typeck_expect(L_STRING|L_WIDGET, expr->a, "in .=");
+ expr->type = expr->a->type;
+ return (1);
+ case L_OP_ANDAND:
+ case L_OP_OROR:
+ compile_shortCircuit(expr);
+ expr->type = L_int;
+ return (1);
+ case L_OP_STR_EQ:
+ case L_OP_STR_NE:
+ case L_OP_STR_GT:
+ case L_OP_STR_GE:
+ case L_OP_STR_LT:
+ case L_OP_STR_LE:
+ unless (hash_get(L->options, "allow_eq_ops")) {
+ L_errf(expr, "illegal comparison operator");
+ }
+ /* Warn on things like "s eq undef". */
+ if (isid(e=expr->a, "undef") || isid(e=expr->b, "undef")) {
+ L_errf(e, "undef illegal in comparison");
+ }
+ compile_expr(expr->a, L_PUSH_VAL);
+ compile_expr(expr->b, L_PUSH_VAL);
+ L_typeck_expect(L_STRING|L_WIDGET, expr->a,
+ "in string comparison");
+ L_typeck_expect(L_STRING|L_WIDGET, expr->b,
+ "in string comparison");
+ emit_instrForLOp(expr, expr->type);
+ expr->type = L_int;
+ return (1);
+ case L_OP_EQUALEQUAL:
+ case L_OP_NOTEQUAL:
+ case L_OP_GREATER:
+ case L_OP_GREATEREQ:
+ case L_OP_LESSTHAN:
+ case L_OP_LESSTHANEQ:
+ expr->type = L_int;
+ /* Warn on things like "i == undef". */
+ if (isid(e=expr->a, "undef") || isid(e=expr->b, "undef")) {
+ L_errf(e, "undef illegal in comparison");
+ }
+ compile_expr(expr->a, L_PUSH_VAL);
+ compile_expr(expr->b, L_PUSH_VAL);
+ L_typeck_deny(L_VOID, expr->a);
+ L_typeck_deny(L_VOID, expr->b);
+ unless (L_typeck_compat(expr->a->type, expr->b->type) ||
+ L_typeck_compat(expr->b->type, expr->a->type)) {
+ L_errf(expr, "incompatible types in comparison");
+ return (0);
+ }
+ if (!isscalar(expr->a) && (expr->op != L_OP_EQUALEQUAL)) {
+ L_errf(expr, "only eq() allowed on non-scalar types");
+ return (0);
+ }
+ compile_eq_stack(expr, expr->a->type);
+ return (1); // stack effect
+ case L_OP_PLUS:
+ case L_OP_MINUS:
+ case L_OP_STAR:
+ case L_OP_SLASH:
+ compile_expr(expr->a, L_PUSH_VAL);
+ compile_expr(expr->b, L_PUSH_VAL);
+ L_typeck_expect(L_INT|L_FLOAT, expr->a,
+ "in arithmetic operator");
+ L_typeck_expect(L_INT|L_FLOAT, expr->b,
+ "in arithmetic operator");
+ emit_instrForLOp(expr, expr->type);
+ if (isfloat(expr->a) || isfloat(expr->b)) {
+ expr->type = L_float;
+ } else {
+ expr->type = L_int;
+ }
+ return (1);
+ case L_OP_PERC:
+ case L_OP_BITAND:
+ case L_OP_BITOR:
+ case L_OP_BITXOR:
+ case L_OP_LSHIFT:
+ case L_OP_RSHIFT:
+ compile_expr(expr->a, L_PUSH_VAL);
+ compile_expr(expr->b, L_PUSH_VAL);
+ L_typeck_expect(L_INT, expr->a, "in arithmetic operator");
+ L_typeck_expect(L_INT, expr->b, "in arithmetic operator");
+ emit_instrForLOp(expr, expr->type);
+ expr->type = L_int;
+ return (1);
+ case L_OP_ARRAY_INDEX:
+ case L_OP_HASH_INDEX:
+ case L_OP_DOT:
+ case L_OP_POINTS:
+ return (compile_idxOp(expr, flags));
+ case L_OP_CLASS_INDEX:
+ return (compile_clsDeref(expr, flags));
+ case L_OP_INTERP_STRING:
+ case L_OP_INTERP_RE:
+ compile_expr(expr->a, L_PUSH_VAL);
+ compile_expr(expr->b, L_PUSH_VAL);
+ TclEmitInstInt1(INST_STR_CONCAT1, 2, L->frame->envPtr);
+ expr->type = L_string;
+ return (1);
+ case L_OP_LIST:
+ level = fnCallBegin();
+ for (e = expr, expand = 0; e; e = e->b) {
+ if (e->a && isexpand(e->a)) {
+ TclEmitOpcode(INST_EXPAND_START,
+ L->frame->envPtr);
+ expand = 1;
+ break;
+ }
+ }
+ push_lit("::list");
+ n = compile_expr(expr->a, L_PUSH_VAL);
+ if (n == 0) { // empty list {}
+ ASSERT(!expr->a && !expr->b);
+ type = L_poly;
+ } else if (iskv(expr->a)) {
+ ASSERT((n == 2) && ishash(expr->a));
+ type = expr->a->type;
+ } else {
+ type = type_mkList(expr->a->type);
+ }
+ for (e = expr->b; e; e = e->b) {
+ ASSERT(e->op == L_OP_LIST);
+ n += compile_expr(e->a, L_PUSH_VAL);
+ if (ishashtype(type) && iskv(e->a)) {
+ } else if (islisttype(type) && !iskv(e->a)) {
+ /*
+ * The list type is literally a list of all the
+ * individual element types linked together.
+ */
+ Type *t = type_mkList(e->a->type);
+ APPEND(Type, next, type, t);
+ } else unless (ispolytype(type)) {
+ L_errf(expr, "cannot mix hash and "
+ "non-hash elements");
+ type = L_poly;
+ }
+ }
+ if (expand) {
+ emit_invoke_expanded();
+ } else {
+ emit_invoke(n+1);
+ }
+ expr->type = type;
+ fnCallEnd(level);
+ return (1);
+ case L_OP_KV:
+ n = compile_expr(expr->a, L_PUSH_VAL);
+ n += compile_expr(expr->b, L_PUSH_VAL);
+ ASSERT(n == 2);
+ unless (isscalar(expr->a)) {
+ L_errf(expr->a, "hash keys must be scalar");
+ }
+ expr->type = type_mkHash(expr->a->type, expr->b->type);
+ return (n);
+ case L_OP_EQTWID:
+ case L_OP_BANGTWID:
+ compile_twiddle(expr);
+ expr->type = L_int;
+ return (1);
+ case L_OP_COMMA:
+ compile_expr(expr->a, L_DISCARD);
+ compile_expr(expr->b, L_PUSH_VAL);
+ expr->type = expr->b->type;
+ return (1);
+ case L_OP_CAST:
+ return (compile_cast(expr, flags));
+ case L_OP_CONCAT:
+ compile_expr(expr->a, L_PUSH_VAL);
+ compile_expr(expr->b, L_PUSH_VAL);
+ L_typeck_expect(L_STRING|L_WIDGET, expr->a,
+ "in lhs of . operator");
+ L_typeck_expect(L_STRING|L_WIDGET, expr->b,
+ "in rhs of . operator");
+ TclEmitInstInt1(INST_STR_CONCAT1, 2, L->frame->envPtr);
+ expr->type = L_string;
+ return (1);
+ default:
+ L_bomb("compile_binOp: malformed AST");
+ return (1);
+ }
+}
+
+private int
+compile_cast(Expr *expr, Expr_f flags)
+{
+ int range;
+ Jmp *jmp;
+ Type *type = (Type *)expr->a;
+
+ flags &= ~L_DISCARD;
+ if (flags & L_LVALUE) {
+ compile_expr(expr->b, flags);
+ } else if ((type->kind == L_INT) || (type->kind == L_FLOAT)) {
+ range = TclCreateExceptRange(CATCH_EXCEPTION_RANGE,
+ L->frame->envPtr);
+ TclEmitInstInt4(INST_BEGIN_CATCH4, range, L->frame->envPtr);
+ ExceptionRangeStarts(L->frame->envPtr, range);
+ if (type->kind == L_INT) {
+ push_lit("::tcl::mathfunc::int");
+ compile_expr(expr->b, flags);
+ emit_invoke(2);
+ } else if (type->kind == L_FLOAT) {
+ push_lit("::tcl::mathfunc::double");
+ compile_expr(expr->b, flags);
+ emit_invoke(2);
+ }
+ ExceptionRangeEnds(L->frame->envPtr, range);
+ jmp = emit_jmp_fwd(INST_JUMP4, 0);
+ /* error case */
+ ExceptionRangeTarget(L->frame->envPtr, range, catchOffset);
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ /* out */
+ fixup_jmps(&jmp);
+ TclEmitOpcode(INST_END_CATCH, L->frame->envPtr);
+ } else {
+ compile_expr(expr->b, flags);
+ }
+ L_typeck_deny(L_VOID|L_FUNCTION, expr->b);
+ expr->sym = expr->b->sym;
+ expr->flags = expr->b->flags;
+ expr->type = type;
+ return (1);
+}
+
+private int
+compile_trinOp(Expr *expr)
+{
+ int save, start_off;
+ int i = 0, n = 0;
+ Jmp *end_jmp, *false_jmp;
+
+ switch (expr->op) {
+ case L_OP_EQTWID:
+ compile_twiddleSubst(expr);
+ expr->type = L_int;
+ n = 1;
+ break;
+ case L_OP_INTERP_STRING:
+ case L_OP_INTERP_RE:
+ compile_expr(expr->a, L_PUSH_VAL);
+ compile_expr(expr->b, L_PUSH_VAL);
+ compile_expr(expr->c, L_PUSH_VAL);
+ TclEmitInstInt1(INST_STR_CONCAT1, 3, L->frame->envPtr);
+ expr->type = L_string;
+ n = 1;
+ break;
+ case L_OP_ARRAY_SLICE:
+ compile_expr(expr->a, L_PUSH_VAL);
+ if (isstring(expr->a) || iswidget(expr->a)) {
+ push_lit("::string");
+ push_lit("range");
+ TclEmitInstInt1(INST_ROT, 2, L->frame->envPtr);
+ expr->type = L_string;
+ i = 5;
+ } else if (isarray(expr->a) || islist(expr->a)) {
+ push_lit("::lrange");
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ expr->type = expr->a->type;
+ i = 4;
+ } else {
+ L_errf(expr->a, "illegal type for slice");
+ expr->type = L_poly;
+ }
+ if (has_END(expr->b) || has_END(expr->c)) {
+ if (isstring(expr->a) || iswidget(expr->a)) {
+ TclEmitOpcode(INST_L_PUSH_STR_SIZE,
+ L->frame->envPtr);
+ } else {
+ TclEmitOpcode(INST_L_PUSH_LIST_SIZE,
+ L->frame->envPtr);
+ }
+ }
+ save = L->idx_op;
+ L->idx_op = L_OP_ARRAY_SLICE;
+ compile_expr(expr->b, L_PUSH_VAL);
+ unless (isint(expr->b)) {
+ L_errf(expr->b, "first slice index not an int");
+ }
+ compile_expr(expr->c, L_PUSH_VAL);
+ unless (isint(expr->c)) {
+ L_errf(expr->c, "second slice index not an int");
+ }
+ L->idx_op = save;
+ if (has_END(expr->b) || has_END(expr->c)) {
+ TclEmitOpcode(INST_L_POP_SIZE, L->frame->envPtr);
+ }
+ emit_invoke(i);
+ n = 1;
+ break;
+ case L_OP_TERNARY_COND:
+ compile_condition(expr->a);
+ false_jmp = emit_jmp_fwd(INST_JUMP_FALSE4, NULL);
+ start_off = currOffset(L->frame->envPtr);
+ n = compile_expr(expr->b, L_PUSH_VAL);
+ end_jmp = emit_jmp_fwd(INST_JUMP4, NULL);
+ track_cmd(start_off, expr->b);
+ fixup_jmps(&false_jmp);
+ start_off = currOffset(L->frame->envPtr);
+ compile_expr(expr->c, L_PUSH_VAL);
+ track_cmd(start_off, expr->c);
+ fixup_jmps(&end_jmp);
+ if (ispoly(expr->b) || ispoly(expr->c)) {
+ expr->type = L_poly;
+ } else if (L_typeck_same(expr->b->type, expr->c->type)) {
+ expr->type = expr->b->type;
+ } else if ((expr->b->type->kind & (L_INT|L_FLOAT)) &&
+ (expr->c->type->kind & (L_INT|L_FLOAT))) {
+ expr->type = L_float;
+ } else {
+ L_errf(expr, "incompatible types in ? : expressions");
+ expr->type = L_poly;
+ }
+ break;
+ default:
+ L_bomb("compile_trinOp: malformed AST");
+ }
+ return (n); // stack effect
+}
+
+
+/*
+ * There are two kinds of defined():
+ * defined(&var) - var is a call-by-reference formal
+ * defined(expr) - otherwise
+ */
+private void
+compile_defined(Expr *expr)
+{
+ Sym *sym;
+
+ if (isaddrof(expr)) {
+ unless (expr->a->kind == L_EXPR_ID) {
+ L_errf(expr, "arg to & not a call-by-reference parm");
+ return;
+ }
+ sym = sym_lookup(expr->a, L_NOWARN);
+ unless (sym && (sym->decl->flags & DECL_REF)) {
+ L_errf(expr, "%s undeclared or not a "
+ "call-by-reference parm", expr->a->str);
+ return;
+ }
+ push_lit("::L_undef_ref_parm_");
+ TclEmitInstInt4(INST_DIFFERENT_OBJ, sym->idx, L->frame->envPtr);
+ } else {
+ compile_expr(expr, L_PUSH_VAL);
+ L_typeck_deny(L_VOID, expr);
+ TclEmitOpcode(INST_L_DEFINED, L->frame->envPtr);
+ }
+}
+
+/*
+ * Estimate how many submatches are in the given regexp. These are
+ * the sub-expressions within parens. If the regexp includes an
+ * interpolated string, we can't get this exact, so just assume
+ * the maximum (9) in that case.
+ */
+private int
+re_submatchCnt(Expr *re)
+{
+ int n = 9;
+ Tcl_Obj *const_regexp;
+ Tcl_RegExp compiled;
+
+ if (re->kind == L_EXPR_RE) {
+ const_regexp = Tcl_NewStringObj(re->str, -1);
+ Tcl_IncrRefCount(const_regexp);
+ compiled = Tcl_GetRegExpFromObj(L->interp, const_regexp,
+ TCL_REG_ADVANCED);
+ Tcl_DecrRefCount(const_regexp);
+ if (compiled) n = ((TclRegexp *)compiled)->re.re_nsub;
+ }
+ return (n);
+}
+
+/*
+ * Determine whether a regexp is a constant (which can be matched with
+ * a string comparison), a glob (use string-match bytecode), a simpler
+ * regexp (no submatches, use the regexp bytecode), or a more complex
+ * regexp which requires the ::regexp command. If the regexp is
+ * interpolated, we can't tell for sure, so assume the worst. Also
+ * return flags indicating whether the re expr needs to be compiled.
+ *
+ * If ds is non-NULL return the equivalent glob in *ds; this becomes
+ * an operand to INST_STR_EQ or INST_STR_MATCH.
+ */
+private ReKind
+re_kind(Expr *re, Tcl_DString *ds)
+{
+ Tcl_DString myds;
+ int exact, ret = 0;
+
+ unless ((re->kind == L_EXPR_RE) || (re->op == L_OP_INTERP_RE)) {
+ return (RE_NOT_AN_RE);
+ }
+ unless (ds) ds = &myds; // to accommodate passing in ds==NULL
+
+ if (re->op == L_OP_INTERP_RE) {
+ ret |= RE_NEEDS_EVAL;
+ }
+ if (re->flags & L_EXPR_RE_L) {
+ ret |= RE_NEEDS_EVAL | RE_GLOB;
+ } else if (re_submatchCnt(re) || (re->flags & L_EXPR_RE_G)) {
+ ret |= RE_NEEDS_EVAL | RE_COMPLEX;
+ } else if (isstring(re) &&
+ (TclReToGlob(NULL, re->str, strlen(re->str),
+ ds, &exact, NULL) == TCL_OK) &&
+ exact) {
+ if (ds == &myds) Tcl_DStringFree(&myds);
+ ret |= RE_CONST;
+ } else {
+ ret |= RE_NEEDS_EVAL | RE_SIMPLE;
+ }
+ return (ret);
+}
+
+private void
+compile_twiddle(Expr *expr)
+{
+ compile_expr(expr->a, L_PUSH_VAL);
+ compile_reMatch(expr->b);
+ if (expr->op == L_OP_BANGTWID) {
+ TclEmitOpcode(INST_LNOT, L->frame->envPtr);
+ L_typeck_expect(L_STRING|L_WIDGET, expr->a, "in !~");
+ } else {
+ L_typeck_expect(L_STRING|L_WIDGET, expr->a, "in =~");
+ }
+}
+
+/*
+ * Compile a regexp match. It is assumed that the value to compare
+ * the regexp against will already be on the run-time stack. Code to
+ * push the regexp is generated here. When run, these are replaced
+ * with the match Boolean.
+ */
+private void
+compile_reMatch(Expr *re)
+{
+ int i, cflags, mod_cnt, submatch_cnt;
+ int nocase = (re->flags & L_EXPR_RE_I);
+ Sym *s;
+ Expr *id;
+ ReKind kind;
+ Tcl_DString ds;
+
+ kind = re_kind(re, &ds);
+ /* First push the regexp. */
+ if (kind & RE_NEEDS_EVAL) {
+ compile_expr(re, L_PUSH_VAL);
+ } else {
+ push_lit(Tcl_DStringValue(&ds));
+ Tcl_DStringFree(&ds);
+ }
+ /* Now emit the appropriate match instruction. */
+ switch (kind & (RE_CONST|RE_GLOB|RE_SIMPLE|RE_COMPLEX)) {
+ case RE_CONST:
+ TclEmitOpcode(INST_STR_EQ, L->frame->envPtr);
+ break;
+ case RE_GLOB:
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ TclEmitInstInt1(INST_STR_MATCH, nocase, L->frame->envPtr);
+ break;
+ case RE_SIMPLE:
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ cflags = TCL_REG_ADVANCED | TCL_REG_NLSTOP |
+ (nocase ? TCL_REG_NOCASE : 0);
+ TclEmitInstInt1(INST_REGEXP, cflags, L->frame->envPtr);
+ break;
+ case RE_COMPLEX:
+ // val re
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ // re val
+ push_lit("::regexp");
+ mod_cnt = push_regexpModifiers(re);
+ push_lit("--");
+ // re val ::regexp <mods> --
+ TclEmitInstInt1(INST_ROT, mod_cnt+3, L->frame->envPtr);
+ // val ::regexp <mods> -- re
+ TclEmitInstInt1(INST_ROT, mod_cnt+3, L->frame->envPtr);
+ // ::regexp <mods> -- re val
+ /* Submatch vars. This loop always iterates at least once. */
+ submatch_cnt = re_submatchCnt(re);
+ for (i = 0; i <= submatch_cnt; i++) {
+ char buf[32];
+ snprintf(buf, sizeof(buf), "$%d", i);
+ id = mkId(buf);
+ unless (sym_lookup(id, L_NOWARN)) {
+ s = sym_mk(buf, L_string,
+ SCOPE_LOCAL | DECL_LOCAL_VAR);
+ s->used_p = TRUE; // suppress unused var warning
+ }
+ push_lit(buf);
+ }
+ emit_invoke(5 + submatch_cnt + mod_cnt);
+ break;
+ default: ASSERT(0);
+ }
+}
+
+private void
+compile_twiddleSubst(Expr *expr)
+{
+ Expr *id, *lhs = expr->a;
+ int i, modCount, submatchCount;
+ Sym *s;
+ Tmp *tmp = NULL;
+ Tcl_Obj *varList;
+
+ push_lit("::regsub");
+ modCount = push_regexpModifiers(expr->b);
+ /* Submatch vars. This loop always iterates at least once. */
+ push_lit("-submatches");
+ submatchCount = re_submatchCnt(expr->b);
+ varList = Tcl_NewObj();
+ Tcl_IncrRefCount(varList);
+ for (i = 0; i <= submatchCount; i++) {
+ char buf[32];
+ snprintf(buf, sizeof(buf), "$%d", i);
+ id = mkId(buf);
+ unless (sym_lookup(id, L_NOWARN)) {
+ s = sym_mk(buf, L_string,
+ SCOPE_LOCAL | DECL_LOCAL_VAR);
+ s->used_p = TRUE; // suppress unused var warning
+ }
+ Tcl_AppendPrintfToObj(varList, "$%d ", i);
+ }
+ push_lit(Tcl_GetString(varList));
+ Tcl_DecrRefCount(varList);
+ push_lit("-line");
+ push_lit("--");
+ compile_expr(expr->b, L_PUSH_VAL);
+ // ::regsub <mods> -submatches <varlist> -line -- <re>
+ compile_expr(expr->c, L_PUSH_VAL);
+ // ::regsub <mods> -submatches <varlist> -line -- <re> <subst>
+ compile_expr(lhs, L_PUSH_VALPTR | L_PUSH_VAL | L_LVALUE);
+ unless (lhs->sym) {
+ L_errf(expr, "invalid l-value in =~");
+ return;
+ }
+ if (isdeepdive(lhs)) {
+ tmp = tmp_get(TMP_REUSE);
+ // ::regsub <mods> -submatches <varlist>
+ // -line -- <re> <subst> <lhs-val> <lhs-ptr>
+ TclEmitInstInt1(INST_ROT, -(8+modCount), L->frame->envPtr);
+ // <lhs-ptr> ::regsub <mods> -submatches <varlist>
+ // -line -- <re> <subst> <lhs-val>
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ // <lhs-ptr> ::regsub <mods> -submatches <varlist>
+ // -line -- <re> <lhs-val> <subst>
+ push_lit(tmp->name);
+ // <lhs-ptr> ::regsub <mods> -submatches <varlits>
+ // -line -- <re> <lhs-val> <subst> <tmp-name>
+ } else {
+ // ::regsub <mods> -submatches <varlist>
+ // -line -- <re> <subst> <lhs-val>
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ // ::regsub <mods> -submatches <varlist>
+ // -line -- <re> <lhs-val> <subst>
+ push_lit(lhs->sym->tclname);
+ // ::regsub <mods> -submatches <varlist>
+ // -line -- <re> <lhs-val> <subst> <lhs-name>
+ }
+ emit_invoke(modCount + 9);
+ if (isdeepdive(lhs)) {
+ // <lhs-ptr> <match>
+ emit_load_scalar(tmp->idx);
+ tmp_free(tmp);
+ // <lhs-ptr> <match> <new-val>
+ TclEmitInstInt1(INST_ROT, 2, L->frame->envPtr);
+ // <match> <new-val> <lhs-ptr>
+ TclEmitInstInt4(INST_L_DEEP_WRITE,
+ lhs->sym->idx,
+ L->frame->envPtr);
+ TclEmitInt4(L_PUSH_NEW, L->frame->envPtr);
+ // <match> <new-val>
+ emit_pop();
+ }
+ L_typeck_expect(L_STRING|L_WIDGET, lhs, "in =~");
+ // <match>
+}
+
+private void
+compile_shortCircuit(Expr *expr)
+{
+ Jmp *jmp;
+ unsigned char op;
+
+ /*
+ * In case the operator "a op b" short-circuits, we need one
+ * value of "a" on the stack for the test and one for the value of
+ * the expression. If the operator doesn't short-circuit, we
+ * pop one of these off and move on to evaluating "b".
+ */
+ ASSERT((expr->op == L_OP_ANDAND) || (expr->op == L_OP_OROR));
+ op = (expr->op == L_OP_ANDAND) ? INST_JUMP_FALSE4 : INST_JUMP_TRUE4;
+ compile_condition(expr->a);
+ // <a-val>
+ TclEmitOpcode(INST_DUP, L->frame->envPtr);
+ // <a-val> <a-val>
+ jmp = emit_jmp_fwd(op, NULL);
+ // <a-val> if short-circuit and we jumped out
+ // <a-val> if did not short-circuit and we're still going
+ emit_pop();
+ compile_condition(expr->b);
+ fixup_jmps(&jmp);
+ // <a-val> if short-circuit
+ // <b-val> if did not short-circuit
+}
+
+/*
+ * Compile an expression that is used as a conditional test.
+ * This is compiled like a normal expression except that if it's
+ * of string type the expression is tested for defined.
+ */
+private void
+compile_condition(Expr *cond)
+{
+ unless (cond) {
+ push_lit("1");
+ return;
+ }
+ if (isaddrof(cond)) {
+ compile_defined(cond);
+ } else {
+ compile_expr(cond, L_PUSH_VAL);
+ if (isvoid(cond)) {
+ L_errf(cond, "void type illegal in predicate");
+ }
+ unless (isint(cond) || isfloat(cond) || ispoly(cond)) {
+ TclEmitOpcode(INST_L_DEFINED, L->frame->envPtr);
+ }
+ }
+ cond->type = L_int;
+}
+
+/*
+ * Compile if-unless as follows.
+ *
+ * No "else" leg: "Else" leg present:
+ * <eval cond> <eval cond>
+ * jmpFalse 1 jmpFalse 1
+ * <if leg> <if leg>
+ * 1: jmp 2
+ * 1: <else leg>
+ * 2:
+ */
+private void
+compile_ifUnless(Cond *cond)
+{
+ Jmp *endjmp, *falsejmp;
+
+ /* Test the condition and jmp if false. */
+ compile_condition(cond->cond);
+ falsejmp = emit_jmp_fwd(INST_JUMP_FALSE4, NULL);
+
+ /* Compile the "if" leg. */
+ frame_push(cond, NULL, SEARCH);
+ compile_stmts(cond->if_body);
+
+ if (cond->else_body) {
+ /* "Else" leg present. */
+ frame_pop();
+ frame_push(cond, NULL, SEARCH);
+ endjmp = emit_jmp_fwd(INST_JUMP4, NULL);
+ fixup_jmps(&falsejmp);
+ compile_stmts(cond->else_body);
+ fixup_jmps(&endjmp);
+ } else {
+ /* No "else" leg. */
+ fixup_jmps(&falsejmp);
+ }
+ frame_pop();
+}
+
+private void
+compile_loop(Loop *loop)
+{
+ switch (loop->kind) {
+ case L_LOOP_DO:
+ compile_do(loop);
+ break;
+ case L_LOOP_FOR:
+ case L_LOOP_WHILE:
+ compile_for_while(loop);
+ break;
+ default:
+ L_bomb("bad loop type");
+ break;
+ }
+}
+
+/*
+ * Do loop:
+ *
+ * 1: <body>
+ * <cond>
+ * jmpTrue 1
+ */
+private void
+compile_do(Loop *loop)
+{
+ int body_off;
+ Jmp *break_jmps, *continue_jmps;
+
+ body_off = currOffset(L->frame->envPtr);
+ frame_push(loop, NULL, LOOP|SEARCH);
+ compile_stmts(loop->body);
+ break_jmps = L->frame->break_jumps;
+ continue_jmps = L->frame->continue_jumps;
+ frame_pop();
+ fixup_jmps(&continue_jmps);
+
+ compile_condition(loop->cond);
+ emit_jmp_back(TCL_TRUE_JUMP, body_off);
+ fixup_jmps(&break_jmps);
+}
+
+/*
+ * While loop: For loop:
+ *
+ * <pre>
+ * 1: <cond> 1: <cond>
+ * jmpFalse 2 jmpFalse 2
+ * <body> <body>
+ * <post>
+ * jmp 1 jmp 1
+ * 2: 2:
+ */
+private void
+compile_for_while(Loop *loop)
+{
+ int cond_off;
+ Jmp *break_jmps, *continue_jmps, *out_jmp;
+
+ if (loop->kind == L_LOOP_FOR) compile_exprs(loop->pre, L_DISCARD);
+
+ cond_off = currOffset(L->frame->envPtr);
+ compile_condition(loop->cond);
+ out_jmp = emit_jmp_fwd(INST_JUMP_FALSE4, NULL);
+
+ frame_push(loop, NULL, LOOP|SEARCH);
+ compile_stmts(loop->body);
+ break_jmps = L->frame->break_jumps;
+ continue_jmps = L->frame->continue_jumps;
+ frame_pop();
+ fixup_jmps(&continue_jmps);
+
+ if (loop->kind == L_LOOP_FOR) compile_exprs(loop->post, L_DISCARD);
+
+ emit_jmp_back(TCL_UNCONDITIONAL_JUMP, cond_off);
+ fixup_jmps(&out_jmp);
+ fixup_jmps(&break_jmps);
+}
+
+/*
+ * Emit a jump instruction to a backwards target. jmp_type is one of
+ * TCL_UNCONDITIONAL, TCL_TRUE_JUMP, or TCL_FALSE_JUMP. The jump
+ * opcope is appropriately selected for the jump distance.
+ */
+private void
+emit_jmp_back(TclJumpType jmp_type, int offset)
+{
+ int op = 0;
+ int dist = currOffset(L->frame->envPtr) - offset;
+
+ if (dist > 127) {
+ switch (jmp_type) {
+ case TCL_UNCONDITIONAL_JUMP:
+ op = INST_JUMP4;
+ break;
+ case TCL_TRUE_JUMP:
+ op = INST_JUMP_TRUE4;
+ break;
+ case TCL_FALSE_JUMP:
+ op = INST_JUMP_FALSE4;
+ break;
+ default:
+ L_bomb("bad jmp type");
+ break;
+ }
+ TclEmitInstInt4(op, -dist, L->frame->envPtr);
+ } else {
+ switch (jmp_type) {
+ case TCL_UNCONDITIONAL_JUMP:
+ op = INST_JUMP1;
+ break;
+ case TCL_TRUE_JUMP:
+ op = INST_JUMP_TRUE1;
+ break;
+ case TCL_FALSE_JUMP:
+ op = INST_JUMP_FALSE1;
+ break;
+ default:
+ L_bomb("bad jmp type");
+ break;
+ }
+ TclEmitInstInt1(op, -dist, L->frame->envPtr);
+ }
+}
+
+/*
+ * Emit a jump instruction with an unknown target offset and return a
+ * structure that can be passed in to fixup_jmps() to later fix-up the
+ * target to any desired bytecode offset. Caller must free the
+ * returned structure.
+ */
+private Jmp *
+emit_jmp_fwd(int op, Jmp *next)
+{
+ Jmp *ret = (Jmp *)ckalloc(sizeof(Jmp));
+
+ ret->op = op;
+ ret->offset = currOffset(L->frame->envPtr);
+ ret->next = next;
+ switch (op) {
+ case INST_JUMP1:
+ case INST_JUMP_TRUE1:
+ case INST_JUMP_FALSE1:
+ ret->size = 1;
+ TclEmitInstInt1(op, 0, L->frame->envPtr);
+ break;
+ case INST_JUMP4:
+ case INST_JUMP_TRUE4:
+ case INST_JUMP_FALSE4:
+ ret->size = 4;
+ TclEmitInstInt4(op, 0, L->frame->envPtr);
+ break;
+ default:
+ L_bomb("unexpected jump instruction");
+ break;
+ }
+ return (ret);
+}
+
+/*
+ * Fix up jump targets to point to the current PC, free the
+ * passed-in fix-ups list and then set it to NULL.
+ */
+private void
+fixup_jmps(Jmp **p)
+{
+ int target;
+ Jmp *t;
+ Jmp *j = *p;
+ unsigned char *jmp_pc;
+
+ while (j) {
+ target = currOffset(L->frame->envPtr) - j->offset;
+ jmp_pc = L->frame->envPtr->codeStart + j->offset;
+ switch (j->size) {
+ case 1:
+ ASSERT(*jmp_pc == j->op);
+ TclUpdateInstInt1AtPc(j->op, target, jmp_pc);
+ break;
+ case 4:
+ ASSERT(*jmp_pc == j->op);
+ TclUpdateInstInt4AtPc(j->op, target, jmp_pc);
+ break;
+ default:
+ L_bomb("unexpected jump fixup");
+ break;
+ }
+ t = j->next;
+ ckfree((char *)j);
+ j = t;
+ }
+ *p = NULL;
+}
+
+private void
+compile_foreach(ForEach *loop)
+{
+ /*
+ * Handle foreach(s in <expr>).
+ */
+ if (loop->expr->op == L_OP_FILE) {
+ compile_foreachAngle(loop);
+ return;
+ }
+
+ compile_expr(loop->expr, L_PUSH_VAL);
+
+ switch (loop->expr->type->kind) {
+ case L_ARRAY:
+ case L_LIST:
+ compile_foreachArray(loop);
+ break;
+ case L_HASH:
+ compile_foreachHash(loop);
+ break;
+ case L_STRING:
+ compile_foreachString(loop);
+ break;
+ default:
+ L_errf(loop->expr, "foreach expression must be"
+ " array, hash, or string");
+ break;
+ }
+}
+
+/*
+ * Most of the following function came from tclCompCmds.c
+ * TclCompileForEachCmd(), modified in various ways for L.
+ */
+private void
+compile_foreachArray(ForEach *loop)
+{
+ int i, continue_off, num_vars;
+ Expr *var;
+ ForeachInfo *info;
+ ForeachVarList *varlist;
+ Jmp *break_jumps, *continue_jumps, *false_jump;
+ int jumpBackDist, jumpBackOffset, infoIndex;
+ Tmp *loopctrTmp, *valTmp;
+
+ /* The foreach(k=>v in expr) form is illegal in array iteration. */
+ if (loop->value) {
+ L_errf(loop, "=> illegal in foreach over arrays");
+ }
+
+ /*
+ * Type-check the value variables. In "foreach (v1,v2,v3 in
+ * a)", v* are the value variables or variable list, and a is
+ * the value list, in tcl terminology.
+ */
+ for (var = loop->key, num_vars = 0; var; var = var->next, ++num_vars) {
+ unless (sym_lookup(var, 0)) return; // undeclared var
+ unless (L_typeck_arrElt(var->type, loop->expr->type)) {
+ L_errf(var, "loop index type incompatible with"
+ " array element type");
+ }
+ }
+
+ /* Temps for value list value and loop counter. */
+ valTmp = tmp_get(TMP_UNSET);
+ loopctrTmp = tmp_get(TMP_UNSET);
+
+ /*
+ * ForeachInfo and ForeachVarList are structures required by
+ * the bytecode interpreter for foreach bytecodes. In our
+ * case, we have only one value and one variable list
+ * consisting of num_vars variables.
+ */
+ info = (ForeachInfo *)ckalloc(sizeof(ForeachInfo) +
+ sizeof(ForeachVarList *));
+ info->numLists = 1;
+ info->firstValueTemp = valTmp->idx;
+ info->loopCtTemp = loopctrTmp->idx;
+ varlist = (ForeachVarList *)ckalloc(sizeof(ForeachVarList) +
+ num_vars * sizeof(int));
+ varlist->numVars = num_vars;
+ for (i = 0, var = loop->key; var; var = var->next, ++i) {
+ Sym *s = sym_lookup(var, 0);
+ varlist->varIndexes[i] = s->idx;
+ }
+ info->varLists[0] = varlist;
+ infoIndex = TclCreateAuxData(info, &tclForeachInfoType,
+ L->frame->envPtr);
+
+ /* The values to iterate through are already on the stack (the
+ * caller evaluated loop->expr). Assign to the value temp. */
+ emit_store_scalar(valTmp->idx);
+ emit_pop();
+
+ /* Initialize the loop state. */
+ TclEmitInstInt4(INST_FOREACH_START4, infoIndex, L->frame->envPtr);
+
+ /* Top of the loop. Step, and jump out if done. */
+ continue_off = currOffset(L->frame->envPtr);
+ TclEmitInstInt4(INST_FOREACH_STEP4, infoIndex, L->frame->envPtr);
+ false_jump = emit_jmp_fwd(INST_JUMP_FALSE4, NULL);
+
+ /* Loop body. */
+ frame_push(loop, NULL, LOOP|SEARCH);
+ compile_stmts(loop->body);
+ break_jumps = L->frame->break_jumps;
+ continue_jumps = L->frame->continue_jumps;
+ frame_pop();
+ fixup_jmps(&continue_jumps);
+
+ /* End of loop -- jump back to top. */
+ jumpBackOffset = currOffset(L->frame->envPtr);
+ jumpBackDist = jumpBackOffset - continue_off;
+ if (jumpBackDist > 120) {
+ TclEmitInstInt4(INST_JUMP4, -jumpBackDist, L->frame->envPtr);
+ } else {
+ TclEmitInstInt1(INST_JUMP1, -jumpBackDist, L->frame->envPtr);
+ }
+
+ fixup_jmps(&false_jump);
+
+ /* Set the value variables to undef. */
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ for (var = loop->key; var; var = var->next) {
+ Sym *s = sym_lookup(var, 0);
+ ASSERT(s);
+ emit_store_scalar(s->idx);
+ }
+ emit_pop();
+
+ fixup_jmps(&break_jumps);
+ tmp_free(valTmp);
+ tmp_free(loopctrTmp);
+}
+
+private void
+compile_foreachHash(ForEach *loop)
+{
+ Sym *key;
+ Sym *val = NULL;
+ int body_off, disp;
+ Jmp *break_jumps, *continue_jumps, *out_jmp;
+ Tmp *itTmp;
+
+ /* Check types and ensure variables are declared etc. */
+ unless ((key = sym_lookup(loop->key, 0))) return;
+ if (loop->value) {
+ unless ((val = sym_lookup(loop->value, 0))) return;
+ unless (L_typeck_compat(val->type,
+ loop->expr->type->base_type)) {
+ L_errf(loop->value, "loop index value type "
+ "incompatible with hash element type");
+ }
+ }
+ unless (L_typeck_compat(key->type, loop->expr->type->u.hash.idx_type)) {
+ L_errf(loop->key,
+ "loop index key type incompatible with hash index type");
+ }
+ if (loop->key->next) {
+ L_errf(loop, "multiple variables illegal in foreach over hash");
+ }
+
+ /* A temp to hold the iterator state.*/
+ itTmp = tmp_get(TMP_UNSET);
+
+ /*
+ * Both DICT_FIRST and DICT_NEXT leave value, key, and done-p
+ * on the stack. Check done-p and jump out of the loop if
+ * it's true. (We fixup the jump target once we know the size
+ * of the loop body.)
+ */
+ TclEmitInstInt4(INST_DICT_FIRST, itTmp->idx, L->frame->envPtr);
+ out_jmp = emit_jmp_fwd(INST_JUMP_TRUE4, NULL);
+
+ /*
+ * Update the key and value variables. We save the offset of
+ * this code so we can jump back to it after DICT_NEXT.
+ * Note: the caller already pushed loop->expr.
+ */
+ body_off = currOffset(L->frame->envPtr);
+ emit_store_scalar(key->idx);
+ emit_pop();
+ if (loop->value) emit_store_scalar(val->idx);
+ emit_pop();
+
+ /*
+ * Compile loop body. Note that we must grab the jump fix-ups
+ * out of the frame before popping it.
+ */
+ frame_push(loop, NULL, LOOP|SEARCH);
+ compile_stmts(loop->body);
+ break_jumps = L->frame->break_jumps;
+ continue_jumps = L->frame->continue_jumps;
+ frame_pop();
+ fixup_jmps(&continue_jumps);
+
+ /* If there's another entry in the hash, go around again. */
+ TclEmitInstInt4(INST_DICT_NEXT, itTmp->idx, L->frame->envPtr);
+ disp = body_off - currOffset(L->frame->envPtr);
+ TclEmitInstInt4(INST_JUMP_FALSE4, disp, L->frame->envPtr);
+
+ /* End of the loop. Point the jump after the DICT_FIRST to here. */
+ fixup_jmps(&out_jmp);
+
+ /* All done. Cleanup the values that DICT_FIRST/DICT_NEXT left. */
+ emit_pop();
+ emit_pop();
+
+ /* Set key and/or value counters to undef. */
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ emit_store_scalar(key->idx);
+ if (val) emit_store_scalar(val->idx);
+ emit_pop();
+
+ fixup_jmps(&break_jumps);
+ /* XXX We need to ensure that DICT_DONE happens in the face of
+ exceptions, so that the refcount on the dict will be
+ decremented, and the iterator freed. See the
+ implementation of "dict for" in tclCompCmds.c. --timjr
+ 2006.11.3 */
+ TclEmitInstInt4(INST_DICT_DONE, itTmp->idx, L->frame->envPtr);
+ tmp_free(itTmp);
+}
+
+/*
+ * Foreach over a string uses three temp variables (str_idx, len_idx,
+ * and it_idx) and compiles to this:
+ *
+ * str_idx = string value already on stack
+ * len_idx = [::string length $str_idx]
+ * it_idx = 0
+ * jmp 2
+ * 1: loopvar1 = str_idx[it_idx++]
+ * loopvar2 = str_idx[it_idx++]
+ * ...
+ * loopvarn = str_idx[it_idx++]
+ * <loop body>
+ * 2: test it_idx < len_idx
+ * jmp if true to 1
+ */
+private void
+compile_foreachString(ForEach *loop)
+{
+ int body_off, jmp_dist;
+ Jmp *break_jmps, *continue_jmps;
+ Jmp *cond_jmp = 0;
+ Expr *id;
+ Tmp *itTmp, *lenTmp, *strTmp;
+
+ /* The foreach(k=>v in expr) form is illegal in string iteration. */
+ if (loop->value) {
+ L_errf(loop, "=> illegal in foreach over strings");
+ }
+
+ /* Temps for the loop index, string value, and string length. */
+ itTmp = tmp_get(TMP_REUSE);
+ lenTmp = tmp_get(TMP_REUSE);
+ strTmp = tmp_get(TMP_REUSE);
+
+ emit_store_scalar(strTmp->idx);
+
+ push_lit("::string");
+ push_lit("length");
+ TclEmitInstInt1(INST_ROT, 2, L->frame->envPtr);
+ emit_invoke(3);
+ emit_store_scalar(lenTmp->idx);
+ emit_pop();
+
+ push_lit("0");
+ emit_store_scalar(itTmp->idx);
+ emit_pop();
+
+ cond_jmp = emit_jmp_fwd(INST_JUMP4, NULL);
+ body_off = currOffset(L->frame->envPtr);
+
+ for (id = loop->key; id; id = id->next) {
+ unless (sym_lookup(id, 0)) return; // undeclared var
+ unless (L_typeck_compat(id->type, L_string)) {
+ L_errf(id, "loop index not of string type");
+ }
+ emit_load_scalar(strTmp->idx);
+ emit_load_scalar(itTmp->idx);
+ TclEmitInstInt4(INST_L_INDEX, L_IDX_STRING | L_PUSH_VAL,
+ L->frame->envPtr);
+ emit_store_scalar(id->sym->idx);
+ emit_pop();
+ TclEmitInstInt1(INST_INCR_SCALAR1_IMM, itTmp->idx,
+ L->frame->envPtr);
+ TclEmitInt1(1, L->frame->envPtr);
+ emit_pop();
+ }
+
+ frame_push(loop, NULL, LOOP|SEARCH);
+ compile_stmts(loop->body);
+ break_jmps = L->frame->break_jumps;
+ continue_jmps = L->frame->continue_jumps;
+ frame_pop();
+ fixup_jmps(&continue_jmps);
+
+ fixup_jmps(&cond_jmp);
+ emit_load_scalar(itTmp->idx);
+ emit_load_scalar(lenTmp->idx);
+ TclEmitOpcode(INST_LT, L->frame->envPtr);
+ jmp_dist = currOffset(L->frame->envPtr) - body_off;
+ TclEmitInstInt4(INST_JUMP_TRUE4, -jmp_dist, L->frame->envPtr);
+
+ /* Set the loop counters to undef. */
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+ for (id = loop->key; id; id = id->next) {
+ emit_store_scalar(id->sym->idx);
+ }
+ emit_pop();
+
+ fixup_jmps(&break_jmps);
+ tmp_free(itTmp);
+ tmp_free(lenTmp);
+ tmp_free(strTmp);
+}
+
+private void
+compile_foreachAngle(ForEach *loop)
+{
+ Expr *expr = loop->expr->a;
+ Expr *id;
+ Tmp *tmp;
+ Jmp *break_jmps, *continue_jmps, *out_jmp;
+ int top_off;
+
+ /* Outlaw foreach(s in <>). */
+ unless (expr) {
+ L_errf(loop, "this form is disallowed; did you mean "
+ "while (buf = <>)?");
+ return;
+ }
+
+ /* The foreach(k=>v in expr) form is illegal in string iteration. */
+ if (loop->value) {
+ L_errf(loop, "=> illegal in foreach over strings");
+ }
+
+ push_lit("LgetNextLineInit_");
+ compile_expr(expr, L_PUSH_VAL);
+
+ /* Outlaw foreach(s in <a_FILE>). */
+ if (typeisf(expr, "FILE")) {
+ L_errf(loop->expr,
+ "this form is disallowed; did you mean "
+ "while (buf = <F>)?");
+ return;
+ }
+ unless (isstring(expr)) {
+ L_errf(expr, "in foreach, arg to <> must be a string");
+ return;
+ }
+
+ for (id = loop->key; id; id = id->next) {
+ unless (sym_lookup(id, 0)) return; // undeclared var
+ unless (L_typeck_compat(id->type, L_string)) {
+ L_errf(id, "loop index %s not of string type", id->str);
+ }
+ }
+
+ /*
+ * tmp = LgetNextLineInit_(expr)
+ * 1: s1 = LgetNextLine_(tmp)
+ * s2 = LgetNextLine_(tmp)
+ * ...
+ * s<n> = LgetNextLine_(tmp)
+ * if (s1 is undef) jmp 2
+ * <loop body>
+ * jmp 1
+ * 2:
+ */
+
+ tmp = tmp_get(TMP_REUSE);
+ emit_invoke(2);
+ emit_store_scalar(tmp->idx);
+ emit_pop();
+ top_off = currOffset(L->frame->envPtr);
+ for (id = loop->key; id; id = id->next) {
+ push_lit("LgetNextLine_");
+ emit_load_scalar(tmp->idx);
+ emit_invoke(2);
+ emit_store_scalar(id->sym->idx);
+ emit_pop();
+ }
+ emit_load_scalar(loop->key->sym->idx);
+ TclEmitOpcode(INST_L_DEFINED, L->frame->envPtr);
+ out_jmp = emit_jmp_fwd(INST_JUMP_FALSE4, NULL);
+ frame_push(loop, NULL, LOOP|SEARCH);
+ compile_stmts(loop->body);
+ break_jmps = L->frame->break_jumps;
+ continue_jmps = L->frame->continue_jumps;
+ frame_pop();
+ fixup_jmps(&continue_jmps);
+ emit_jmp_back(TCL_UNCONDITIONAL_JUMP, top_off);
+ fixup_jmps(&break_jmps);
+ fixup_jmps(&out_jmp);
+}
+
+private void
+compile_switch(Switch *sw)
+{
+ Case *c;
+
+ /*
+ * If all cases are constant, compile a jump table (fast),
+ * otherwise compile if-then-else code (slower).
+ */
+ for (c = sw->cases; c; c = c->next) {
+ if (c->expr && !isconst(c->expr)) break;
+ }
+ if (c) {
+ compile_switch_slow(sw);
+ } else {
+ compile_switch_fast(sw);
+ }
+}
+
+/*
+ * Generate if-then-else code like the following for a switch statement.
+ *
+ * local_tmp = <switch expression>
+ * # The following is generated for each case except the default case.
+ * # All jmps are forward jmps.
+ * next-test:
+ * load local_tmp
+ * <case expression>
+ * <appropriate compare opcode>
+ * jmp-false next-test
+ * next-body:
+ * <case body>
+ * jmp next-body
+ * # The following is generated for the default case.
+ * jmp next-test
+ * next-body:
+ * default:
+ * <case body>
+ * jmp next-body
+ * # Statement prologue.
+ * next-test:
+ * jmp default # backward jmp, only if default case present
+ * next-body:
+ * break-label: # where break stmts jmp to
+ * pop
+ */
+private void
+compile_switch_slow(Switch *sw)
+{
+ Expr *e = sw->expr;
+ Case *c;
+ int def_off = -1;
+ int start_off;
+ Jmp *break_jmps;
+ Jmp *next_body_jmp = NULL, *next_test_jmp = NULL, *undef_jmp = NULL;
+ Tmp *tmp;
+
+ compile_expr(e, L_PUSH_VAL);
+ tmp = tmp_get(TMP_REUSE);
+ emit_store_scalar(tmp->idx);
+ emit_pop();
+ unless (istype(e, L_INT|L_STRING|L_WIDGET|L_POLY)) {
+ L_errf(e, "switch expression must be int or string");
+ return;
+ }
+
+ frame_push(sw, NULL, SWITCH|SEARCH);
+ /*
+ * If there's a case undef, check that first, because if the
+ * switch expr is undef, Tcl will still let us get its value
+ * and it would match a "" case and we don't want that.
+ */
+ for (c = sw->cases; c; c = c->next) {
+ if (c->expr && isid(c->expr, "undef")) {
+ start_off = currOffset(L->frame->envPtr);
+ emit_load_scalar(tmp->idx);
+ TclEmitOpcode(INST_L_DEFINED, L->frame->envPtr);
+ undef_jmp = emit_jmp_fwd(INST_JUMP_FALSE4, NULL);
+ track_cmd(start_off, c->expr);
+ break;
+ }
+ }
+ for (c = sw->cases; c; c = c->next) {
+ start_off = currOffset(L->frame->envPtr);
+ if (c->expr && isid(c->expr, "undef")) {
+ next_test_jmp = emit_jmp_fwd(INST_JUMP4, next_test_jmp);
+ fixup_jmps(&undef_jmp);
+ } else if (c->expr) {
+ fixup_jmps(&next_test_jmp);
+ emit_load_scalar(tmp->idx);
+ if (isregexp(c->expr)) {
+ compile_reMatch(c->expr);
+ } else if (isint(e)) {
+ compile_expr(c->expr, L_PUSH_VAL);
+ TclEmitOpcode(INST_EQ, L->frame->envPtr);
+ } else {
+ compile_expr(c->expr, L_PUSH_VAL);
+ TclEmitOpcode(INST_STR_EQ, L->frame->envPtr);
+ }
+ unless (L_typeck_compat(e->type, c->expr->type)) {
+ L_errf(c, "case type incompatible"
+ " with switch expression");
+ }
+ next_test_jmp = emit_jmp_fwd(INST_JUMP_FALSE4,
+ next_test_jmp);
+ track_cmd(start_off, c->expr);
+ } else { // default case (grammar ensures there's at most one)
+ next_test_jmp = emit_jmp_fwd(INST_JUMP4, next_test_jmp);
+ ASSERT(def_off == -1);
+ def_off = currOffset(L->frame->envPtr);
+ track_cmd(start_off, c);
+ }
+ fixup_jmps(&next_body_jmp);
+ compile_stmts(c->body);
+ next_body_jmp = emit_jmp_fwd(INST_JUMP4, NULL);
+ }
+ fixup_jmps(&next_test_jmp);
+ if (def_off != -1) {
+ emit_jmp_back(TCL_UNCONDITIONAL_JUMP, def_off);
+ }
+ fixup_jmps(&next_body_jmp);
+ break_jmps = L->frame->break_jumps;
+ frame_pop();
+ fixup_jmps(&break_jmps);
+ tmp_free(tmp);
+}
+
+/*
+ * Generate jump-table code like the following for a switch statement.
+ *
+ * <switch expression>
+ * INST_JUMP_TABLE
+ * jmp default
+ * # The following is generated for each case except the default case.
+ * # All jmps are forward jmps.
+ * next-body:
+ * <case body>
+ * jmp next-body
+ * # The following is the default case.
+ * default:
+ * next-body:
+ * <case body> (only if default case present)
+ * jmp next-body (only if default case present)
+ * # Statement prologue.
+ * next-body:
+ * break-label: # where break stmts jmp to
+ */
+private void
+compile_switch_fast(Switch *sw)
+{
+ Expr *e = sw->expr;
+ Case *c;
+ int jt_idx, new, start_off;
+ Jmp *break_jmps;
+ Jmp *default_jmp;
+ Jmp *next_body_jmp = NULL;
+ Tcl_HashEntry *hPtr;
+ JumptableInfo *jt;
+
+ jt = (JumptableInfo *)ckalloc(sizeof(JumptableInfo));
+ Tcl_InitHashTable(&jt->hashTable, TCL_STRING_KEYS);
+ jt_idx = TclCreateAuxData(jt, &tclJumptableInfoType, L->frame->envPtr);
+
+ compile_expr(e, L_PUSH_VAL);
+ unless (istype(e, L_INT|L_STRING|L_WIDGET|L_POLY)) {
+ L_errf(e, "switch expression must be int or string");
+ return;
+ }
+ if (isint(e)) {
+ /*
+ * Since the jump table keys are strings, add 0 to
+ * guarantee a canonicalized string rep of an int.
+ */
+ push_lit("0");
+ TclEmitOpcode(INST_ADD, L->frame->envPtr);
+ }
+
+ frame_push(sw, NULL, SWITCH|SEARCH);
+
+ start_off = currOffset(L->frame->envPtr);
+ TclEmitInstInt4(INST_JUMP_TABLE, jt_idx, L->frame->envPtr);
+ default_jmp = emit_jmp_fwd(INST_JUMP4, NULL);
+
+ for (c = sw->cases; c; c = c->next) {
+ if (c->expr) {
+ ASSERT(isconst(c->expr));
+ hPtr = Tcl_CreateHashEntry(&jt->hashTable,
+ c->expr->str,
+ &new);
+ if (new) {
+ Tcl_SetHashValue(hPtr,
+ INT2PTR(currOffset(L->frame->envPtr) -
+ start_off));
+ } else {
+ L_errf(c, "duplicate case value");
+ }
+ unless (L_typeck_compat(e->type, c->expr->type)) {
+ L_errf(c,
+ "case type incompatible with switch expression");
+ }
+ } else { // default case (grammar ensures there's at most one)
+ fixup_jmps(&default_jmp);
+ }
+ fixup_jmps(&next_body_jmp);
+ compile_stmts(c->body);
+ next_body_jmp = emit_jmp_fwd(INST_JUMP4, NULL);
+ }
+ fixup_jmps(&default_jmp); // no-op if default exists (already fixed up)
+ fixup_jmps(&next_body_jmp);
+ break_jmps = L->frame->break_jumps;
+ frame_pop();
+ fixup_jmps(&break_jmps);
+}
+
+private VarDecl *
+struct_lookupMember(Type *t, Expr *idx, int *offset)
+{
+ VarDecl *m;
+
+ ASSERT((idx->op == L_OP_DOT) || (idx->op == L_OP_POINTS));
+
+ unless (t->u.struc.members) {
+ L_errf(idx, "incomplete struct type %s", t->u.struc.tag);
+ return (NULL);
+ }
+ for (*offset = 0, m = t->u.struc.members; m; m = m->next, ++*offset) {
+ if (!strcmp(idx->str, m->id->str)) {
+ return (m);
+ }
+ }
+ return (NULL);
+}
+
+/*
+ * Determine whether an array index expression contains a reference to
+ * the array's END index.
+ */
+private int
+has_END(Expr *expr)
+{
+ Expr *p;
+
+ unless (expr) return (0);
+ switch (expr->kind) {
+ case L_EXPR_FUNCALL:
+ for (p = expr->b; p; p = p->next) {
+ if (has_END(p)) return (1);
+ }
+ return (0);
+ case L_EXPR_CONST:
+ case L_EXPR_RE:
+ return (0);
+ case L_EXPR_ID:
+ return (isid(expr, "END"));
+ case L_EXPR_UNOP:
+ return (has_END(expr->a));
+ case L_EXPR_BINOP:
+ switch (expr->op) {
+ case L_OP_ARRAY_INDEX:
+ /* END in a nested index refers to another array. */
+ return (has_END(expr->a));
+ case L_OP_CAST:
+ /* A cast is special: expr->a is a type not an expr. */
+ return (has_END(expr->b));
+ default:
+ return (has_END(expr->a) || has_END(expr->b));
+ }
+ case L_EXPR_TRINOP:
+ if (expr->op == L_OP_ARRAY_SLICE) {
+ /* END in a nested index refers to another array. */
+ return (has_END(expr->a));
+ } else {
+ return (has_END(expr->a) || has_END(expr->b) ||
+ has_END(expr->c));
+ }
+ default: ASSERT(0);
+ }
+ /*NOTREACHED*/
+ return (0);
+}
+
+/*
+ * Generate code to push an array/hash/struct/string index onto the stack.
+ * Return flags suitable for the INST_L_INDEX instruction which indicate
+ * whether the operator is an array, hash, struct, or string index.
+ */
+private int
+push_index(Expr *expr, int flags)
+{
+ int ret;
+ int reuse = flags & L_REUSE_IDX;
+ int save = flags & L_SAVE_IDX;
+ Type *type;
+ VarDecl *member;
+ Tmp *idxTmp;
+ int offset;
+
+ /* Error-path return values. */
+ ret = 0;
+ type = L_poly;
+
+ ASSERT(type);
+ switch (expr->op) {
+ case L_OP_DOT:
+ case L_OP_POINTS:
+ unless (isstruct(expr->a)) {
+ L_errf(expr, "not a struct");
+ goto out;
+ }
+ member = struct_lookupMember(expr->a->type,
+ expr,
+ &offset);
+ if (member) {
+ unless (reuse) push_litf("%i", offset);
+ type = member->type;
+ } else {
+ L_errf(expr, "struct field %s not found", expr->str);
+ }
+ ret = L_IDX_ARRAY;
+ break;
+ case L_OP_ARRAY_INDEX:
+ unless (reuse) {
+ compile_expr(expr->b, L_PUSH_VAL);
+ if (isid(expr->b, "undef")) {
+ L_errf(expr->b, "cannot use undef as an "
+ "array/string index");
+ }
+ }
+ L_typeck_expect(L_INT, expr->b, "in array/string index");
+ if (isarray(expr->a) || islist(expr->a)) {
+ type = expr->a->type->base_type;
+ ret = L_IDX_ARRAY;
+ } else if (isstring(expr->a) || iswidget(expr->a)) {
+ /*
+ * Disallow stringvar[0][0] = "x". It doesn't make much
+ * sense and INST_L_DEEP_WRITE can't handle it anyway.
+ */
+ if ((expr->a->op == L_OP_ARRAY_INDEX) &&
+ expr->a->sym &&
+ isstring(expr->a->a) &&
+ (expr->a->flags & L_LVALUE)) {
+ L_errf(expr, "cannot index a string index");
+ }
+ type = L_string;
+ ret = L_IDX_STRING;
+ } else if (ispoly(expr->a)) {
+ type = L_poly;
+ ret = L_IDX_ARRAY;
+ } else {
+ L_errf(expr, "not an array or string");
+ }
+ break;
+ case L_OP_HASH_INDEX: {
+ unless (reuse) {
+ compile_expr(expr->b, L_PUSH_VAL);
+ if (isid(expr->b, "undef")) {
+ L_errf(expr->b, "cannot use undef as a "
+ "hash index");
+ }
+ }
+ if (ishash(expr->a)) {
+ L_typeck_expect(expr->a->type->u.hash.idx_type->kind,
+ expr->b,
+ "in hash index");
+ type = expr->a->type->base_type;
+ } else if (ispoly(expr->a)) {
+ type = L_poly;
+ } else {
+ L_errf(expr, "not a hash");
+ }
+ ret = L_IDX_HASH;
+ break;
+ }
+ default:
+ L_bomb("Invalid index op, %d", expr->op);
+ break;
+ }
+ out:
+ if (save) {
+ // save copy of index to a temp
+ idxTmp = tmp_get(TMP_REUSE);
+ expr->u.deepdive.idx = idxTmp;
+ emit_store_scalar(idxTmp->idx);
+ } else if (reuse) {
+ // get index value from temp
+ idxTmp = expr->u.deepdive.idx;
+ ASSERT(idxTmp);
+ emit_load_scalar(idxTmp->idx);
+ tmp_free(idxTmp);
+ expr->u.deepdive.idx = NULL;
+ }
+ expr->type = type;
+ return (ret);
+}
+
+/*
+ * Compile a hash/array/struct/class or string index. These are the
+ * L_OP_HASH_INDEX, L_OP_ARRAY_INDEX, L_OP_DOT, and L_OP_POINTS nodes.
+ *
+ * The resulting stack depends on the flags which specify whether the
+ * indexed element's value, pointer, or both (and in what order) are
+ * wanted. We get one of
+ *
+ * <elem-obj> if flags & L_PUSH_VAL
+ * <deep-ptr> if flags & L_PUSH_PTR
+ * <elem-obj> <deep-ptr> if flags & L_PUSH_VAL_PTR
+ * <deep-ptr> <elem-obj> if flags & L_PUSH_PTR_VAL
+ * <tmp-name> if flags & L_PUSH_NAME
+ *
+ * For L_PUSH_NAME, we evaluate the indexed expression and store its
+ * value and all the indices in local temp variables, then use the
+ * value temp's name as the value of the expression. The expr nodes
+ * store information about the temps so they can be accessed later,
+ * such as for the copy-out part of copy in/out parameters.
+ */
+private int
+compile_idxOp(Expr *expr, Expr_f flags)
+{
+ int ret;
+ Tmp *valTmp;
+
+ if ((flags & L_PUSH_NAME) && !(flags & L_SAVE_IDX)) {
+ /* First time through for L_PUSH_NAME. */
+ ret = compile_idxOp2(expr, flags | L_PUSH_VAL | L_SAVE_IDX);
+ /*
+ * Check whether this was really an object index (we
+ * don't know until now).
+ */
+ if (isclass(expr->a)) return (ret);
+ valTmp = tmp_get(TMP_REUSE);
+ expr->u.deepdive.val = valTmp;
+ emit_store_scalar(valTmp->idx);
+ emit_pop();
+ push_lit(valTmp->name);
+ } else {
+ ret = compile_idxOp2(expr, flags);
+ }
+ return (ret);
+}
+
+private int
+compile_idxOp2(Expr *expr, Expr_f flags)
+{
+ int save;
+
+ /*
+ * Eval the thing being indexed. The flags magic here is
+ * because we always want its value if it's a variable, or a
+ * deep-pointer if it's the result of another deep-dive index,
+ * regardless of in what form we want expr.
+ */
+ compile_expr(expr->a, L_PUSH_PTR | L_PUSH_VAL |
+ (flags & ~(L_PUSH_VALPTR |
+ L_PUSH_PTRVAL |
+ L_DISCARD |
+ L_PUSH_NAME)));
+
+ /*
+ * Require "->" for all objects and call-by-reference structures.
+ * Require "." for all call-by-value and non-parameter structures.
+ */
+ if (isclass(expr->a)) {
+ unless (expr->op == L_OP_POINTS) {
+ L_errf(expr, "must access object only with ->");
+ }
+ } else if (expr->a->sym &&
+ (expr->a->sym->decl->flags & DECL_REF) &&
+ !(expr->a->flags & L_EXPR_DEEP)) {
+ if (expr->op == L_OP_DOT) {
+ L_errf(expr, ". illegal on call-by-reference "
+ "parms; use -> instead");
+ }
+ } else {
+ if (expr->op == L_OP_POINTS) {
+ L_errf(expr, "-> illegal except on call-by-reference "
+ "parms; use . instead");
+ }
+ }
+
+ /*
+ * Handle obj->var. We check here because, in general, we
+ * don't know until now whether expr->a has type class.
+ */
+ if (isclass(expr->a) && ((expr->op == L_OP_DOT) ||
+ (expr->op == L_OP_POINTS))) {
+ return (compile_clsInstDeref(expr, flags));
+ }
+
+ if (has_END(expr->b)) {
+ if (flags & L_REUSE_IDX) {
+ } else if (isstring(expr->a) || iswidget(expr->a)) {
+ TclEmitOpcode(INST_L_PUSH_STR_SIZE, L->frame->envPtr);
+ } else {
+ TclEmitOpcode(INST_L_PUSH_LIST_SIZE, L->frame->envPtr);
+ }
+ }
+
+ save = L->idx_op;
+ L->idx_op = expr->op;
+ flags |= push_index(expr, flags);
+ L->idx_op = save;
+
+ if (has_END(expr->b)) {
+ TclEmitOpcode(INST_L_POP_SIZE, L->frame->envPtr);
+ }
+
+ /*
+ * Perform an optimization and don't create a deep pointer if
+ * the caller won't be doing a deep dive into the expression
+ * being evaluated but instead just needs its value. This
+ * happens when the deep dive we're doing now results in
+ * something of type class and the caller requested a value.
+ * See the comments in compile_expr().
+ *
+ * This wart is here because the caller can't know in general
+ * whether expr is a deep dive or a class deref. Their
+ * expressions look identical but are evaluated in drastically
+ * different ways.
+ */
+ if (isclass(expr) && (flags & (L_PUSH_VAL | L_DISCARD))) {
+ flags &= ~(L_PUSH_PTR | L_PUSH_VALPTR | L_PUSH_PTRVAL |
+ L_LVALUE);
+ } else if (flags & (L_PUSH_PTR | L_PUSH_VALPTR | L_PUSH_PTRVAL)) {
+ flags &= ~L_PUSH_VAL;
+ }
+
+ TclEmitInstInt4(INST_L_INDEX, flags, L->frame->envPtr);
+
+ /*
+ * Adjust the stack depth that Tcl tracks (debug build) to
+ * reflect when two objs are left on the stack instead of one
+ * as indicated by the entry in the tclInstructionTable in
+ * tclCompile.c
+ */
+ if (flags & (L_PUSH_PTRVAL | L_PUSH_VALPTR)) {
+ TclAdjustStackDepth(1, L->frame->envPtr);
+ }
+
+ expr->sym = expr->a->sym; // propagate sym table ptr up the tree
+ expr->flags = flags | L_EXPR_DEEP;
+ return ((flags & L_DISCARD) ? 0 : 1);
+}
+
+/* Compile classname->var. */
+private int
+compile_clsDeref(Expr *expr, Expr_f flags)
+{
+ int in_class = 0;
+ char *clsnm, *varnm;
+ Sym *sym, *tmpsym;
+ Tmp *tmp;
+ Type *type = (Type *)expr->a;
+ ClsDecl *clsdecl = type->u.class.clsdecl;
+ Tcl_HashEntry *hPtr;
+
+ expr->type = L_poly;
+ unless (isclasstype(type)) {
+ L_errf(expr, "can dereference only class types");
+ return (0);
+ }
+
+ ASSERT(type && clsdecl);
+
+ clsnm = clsdecl->decl->id->str;
+ varnm = expr->str;
+ if (L->enclosing_func) {
+ in_class = L->enclosing_func->decl->flags & DECL_CLASS_FN;
+ }
+
+ hPtr = Tcl_FindHashEntry(clsdecl->symtab, varnm);
+ unless (hPtr) {
+ L_errf(expr, "%s is not a member of class %s", varnm, clsnm);
+ return (0);
+ }
+ sym = (Sym *)Tcl_GetHashValue(hPtr);
+ unless (in_class || (sym->decl->flags & DECL_PUBLIC)) {
+ L_errf(expr, "%s is not a public variable of class %s",
+ varnm, clsnm);
+ }
+ unless (sym->decl->flags & DECL_CLASS_VAR) {
+ L_errf(expr, "%s is not a class variable of class %s",
+ varnm, clsnm);
+ }
+
+ if (flags & L_PUSH_NAME) {
+ push_litf("::L::_class_%s::%s", clsnm, sym->name);
+ expr->sym = sym;
+ expr->type = sym->type;
+ return (1); // stack effect
+ }
+
+ tmp = tmp_get(TMP_UNSET);
+ tmpsym = sym_mk(tmp->name, sym->type, SCOPE_LOCAL | DECL_LOCAL_VAR);
+ ASSERT(tmpsym); // cannot be multiply declared
+ tmpsym->used_p = TRUE;
+
+ push_litf("::L::_class_%s", clsnm);
+ push_lit(sym->name);
+ TclEmitInstInt4(INST_NSUPVAR, tmp->idx, L->frame->envPtr);
+ emit_pop();
+
+ expr->sym = tmpsym;
+ expr->type = sym->type;
+
+ if (flags & L_PUSH_VAL) {
+ emit_load_scalar(tmp->idx);
+ return (1); // stack effect
+ } else {
+ return (0); // stack effect
+ }
+}
+
+/*
+ * Compile obj->var. Code to push the value of obj on the run-time
+ * stack already has been generated by compile_idxOp().
+ */
+private int
+compile_clsInstDeref(Expr *expr, Expr_f flags)
+{
+ int in_class = 0;
+ char *clsnm, *varnm;
+ Tmp *tmp;
+ Sym *sym, *tmpsym;
+ ClsDecl *clsdecl = expr->a->type->u.class.clsdecl;
+ Tcl_HashEntry *hPtr;
+
+ ASSERT(isclass(expr->a) && clsdecl);
+ ASSERT(clsdecl->symtab);
+
+ clsnm = clsdecl->decl->id->str;
+ varnm = expr->str;
+ if (L->enclosing_func) {
+ in_class = L->enclosing_func->decl->flags & DECL_CLASS_FN;
+ }
+
+ hPtr = Tcl_FindHashEntry(clsdecl->symtab, varnm);
+ unless (hPtr) {
+ L_errf(expr, "%s is not a member of class %s", varnm, clsnm);
+ expr->type = L_poly;
+ return (0); // stack effect
+ }
+ sym = (Sym *)Tcl_GetHashValue(hPtr);
+ unless (in_class || (sym->decl->flags & DECL_PUBLIC)) {
+ L_errf(expr, "%s is not a public variable of class %s",
+ varnm, clsnm);
+ }
+ unless (sym->decl->flags & DECL_CLASS_INST_VAR) {
+ L_errf(expr, "%s is not an instance variable of class %s",
+ varnm, clsnm);
+ }
+
+ if (flags & L_PUSH_NAME) {
+ // Caller already pushed obj value, so concat var name to it.
+ push_litf("::%s", sym->name);
+ TclEmitInstInt1(INST_STR_CONCAT1, 2, L->frame->envPtr);
+ expr->sym = sym;
+ expr->type = sym->type;
+ return (1); // stack effect
+ }
+
+ tmp = tmp_get(TMP_UNSET);
+ tmpsym = sym_mk(tmp->name, sym->type, SCOPE_LOCAL | DECL_LOCAL_VAR);
+ ASSERT(tmpsym); // cannot be multiply declared
+ tmpsym->used_p = TRUE;
+
+ push_lit(sym->name);
+ TclEmitInstInt4(INST_NSUPVAR, tmp->idx, L->frame->envPtr);
+ emit_pop();
+
+ expr->sym = tmpsym;
+ expr->type = sym->type;
+
+ if (flags & L_PUSH_VAL) {
+ emit_load_scalar(tmp->idx);
+ return (1); // stack effect
+ } else {
+ return (0); // stack effect
+ }
+}
+
+private void
+compile_assign(Expr *expr)
+{
+ Expr *lhs = expr->a;
+ Expr *rhs = expr->b;
+
+ if (lhs->op == L_OP_LIST) {
+ /* Handle {a,b,c} = ... */
+ compile_assignComposite(expr);
+ } else {
+ /* Handle regular assignment. */
+ compile_expr(rhs, L_PUSH_VAL);
+ compile_assignFromStack(lhs, rhs->type, expr, 0);
+ }
+}
+
+private void
+compile_assignFromStack(Expr *lhs, Type *rhs_type, Expr *expr, int flags)
+{
+ /* Whether it's an arithmetic assignment (lhs op= rhs). */
+ int arith = (expr && (expr->op != L_OP_EQUALS));
+
+ compile_expr(lhs, (arith?L_PUSH_VALPTR:L_PUSH_PTR) | L_LVALUE | flags);
+ unless (lhs->sym) {
+ L_errf(lhs, "invalid l-value in assignment");
+ return;
+ }
+ L_typeck_assign(lhs, rhs_type);
+
+ if (isdeepdive(lhs)) {
+ // <rval> <lhs-ptr> if !arith
+ // <rval> <lhs-val> <lhs-ptr> if arith
+ if (arith) {
+ // <rval> <lhs-val> <lhs-ptr>
+ TclEmitInstInt4(INST_REVERSE, 3, L->frame->envPtr);
+ // <lhs-ptr> <lhs-val> <rval>
+ emit_instrForLOp(expr, expr->type);
+ // <lhs-ptr> <new-val>
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ }
+ // <rval> <lhs-ptr> or <new-val> <lhs-ptr>
+ TclEmitInstInt4(INST_L_DEEP_WRITE,
+ lhs->sym->idx,
+ L->frame->envPtr);
+ TclEmitInt4(L_PUSH_NEW, L->frame->envPtr);
+ } else {
+ // <rval>
+ if (arith) {
+ emit_load_scalar(lhs->sym->idx);
+ // <rval> <old-val>
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ // <old-val> <rval>
+ emit_instrForLOp(expr, expr->type);
+ // <new-val>
+ }
+ // <rval> or <new-val>
+ emit_store_scalar(lhs->sym->idx);
+ }
+ // <rval>
+}
+
+private void
+compile_assignComposite(Expr *expr)
+{
+ int i;
+ Expr *lhs = expr->a;
+ Expr *rhs = expr->b;
+ Type *list = NULL, *rhs_elt_type;
+ VarDecl *member = NULL;
+
+ expr->type = L_poly;
+ unless (expr->op == L_OP_EQUALS) {
+ L_errf(expr, "arithmetic assignment illegal");
+ lhs->type = L_poly;
+ rhs->type = L_poly;
+ return;
+ }
+ ASSERT(lhs->op == L_OP_LIST);
+
+ compile_expr(rhs, L_PUSH_VAL);
+
+ /* rhs_elt_type stores the current rhs type as we walk the elts. */
+ switch (rhs->type->kind) {
+ case L_POLY:
+ rhs_elt_type = L_poly;
+ break;
+ case L_ARRAY:
+ rhs_elt_type = rhs->type->base_type;
+ break;
+ case L_STRUCT:
+ member = rhs->type->u.struc.members;
+ ASSERT(member);
+ rhs_elt_type = member->type;
+ break;
+ case L_LIST:
+ list = rhs->type;
+ rhs_elt_type = list->base_type;
+ break;
+ default:
+ L_errf(expr,
+ "right-hand side incompatible with composite assign");
+ return;
+ }
+ /* Assign lhs <- rhs elements (left to right). */
+ for (i = 0, lhs = expr->a; lhs; ++i, lhs = lhs->b) {
+ ASSERT(lhs->op == L_OP_LIST);
+ /* A lhs undef means skip the corresponding rhs element. */
+ unless (isid(lhs->a, "undef")) {
+ TclEmitInstInt1(INST_L_LINDEX_STK, i, L->frame->envPtr);
+ compile_assignFromStack(lhs->a, rhs_elt_type, expr, 0);
+ emit_pop();
+ }
+ /* Advance rhs_elt_type to type of next elt, if known. */
+ if (member) {
+ member = member->next;
+ rhs_elt_type = member? member->type: NULL;
+ } else if (list) {
+ list = list->next;
+ rhs_elt_type = list? list->base_type: NULL;
+ }
+ }
+ /* Pop rhs. */
+ emit_pop();
+ /* The value of the assignment is undef. */
+ TclEmitOpcode(INST_L_PUSH_UNDEF, L->frame->envPtr);
+}
+
+private void
+compile_incdec(Expr *expr)
+{
+ Expr *lhs = expr->a;
+ /* Whether expr is a postfix operator. */
+ int post = ((expr->op == L_OP_PLUSPLUS_POST) ||
+ (expr->op == L_OP_MINUSMINUS_POST));
+ /* Whether expr is a ++ operator. */
+ int inc = ((expr->op == L_OP_PLUSPLUS_PRE) ||
+ (expr->op == L_OP_PLUSPLUS_POST));
+
+ compile_expr(lhs, L_PUSH_PTRVAL | (post?L_PUSH_VAL:0) | L_LVALUE);
+ unless (lhs->sym) {
+ L_errf(expr, "invalid l-value in inc/dec");
+ return;
+ }
+ L_typeck_expect(L_INT|L_FLOAT, lhs, "in ++/--");
+
+ if (isdeepdive(lhs)) {
+ // <lhs-ptr> <lhs-val>
+ push_lit("1");
+ // <hs-ptr> <lhs-val> 1
+ TclEmitOpcode(inc?INST_ADD:INST_SUB, L->frame->envPtr);
+ // <lhs-ptr> <new-val>
+ TclEmitInstInt1(INST_ROT, 1, L->frame->envPtr);
+ // <new-val> <lhs-ptr>
+ TclEmitInstInt4(INST_L_DEEP_WRITE,
+ lhs->sym->idx,
+ L->frame->envPtr);
+ TclEmitInt4(post?L_PUSH_OLD:L_PUSH_NEW, L->frame->envPtr);
+ } else {
+ // <old-val> if post
+ TclEmitInstInt1(INST_INCR_SCALAR1_IMM, lhs->sym->idx,
+ L->frame->envPtr);
+ TclEmitInt1(inc? 1 : -1, L->frame->envPtr);
+ // <old-val> <new-val> if post
+ // <new-val> if !post
+ if (post) emit_pop();
+ }
+ // <old-val> if post
+ // <new-val> if !post
+}
+
+private int
+push_regexpModifiers(Expr *regexp)
+{
+ int n = 0;
+
+ push_lit("-linestop");
+ n++;
+ if (regexp->flags & L_EXPR_RE_I) {
+ push_lit("-nocase");
+ n++;
+ }
+ if (regexp->flags & L_EXPR_RE_G) {
+ push_lit("-all");
+ n++;
+ }
+ return (n);
+}
+
+private void
+emit_instrForLOp(Expr *expr, Type *type)
+{
+ int arg = 0;
+ int op = 0;
+
+ switch (expr->op) {
+ case L_OP_EQUALEQUAL:
+ case L_OP_NOTEQUAL:
+ case L_OP_GREATER:
+ case L_OP_GREATEREQ:
+ case L_OP_LESSTHAN:
+ case L_OP_LESSTHANEQ:
+ switch (type->kind) {
+ case L_INT:
+ case L_FLOAT:
+ case L_POLY:
+ switch (expr->op) {
+ case L_OP_EQUALEQUAL:
+ op = INST_EQ;
+ break;
+ case L_OP_NOTEQUAL:
+ op = INST_NEQ;
+ break;
+ case L_OP_GREATER:
+ op = INST_GT;
+ break;
+ case L_OP_GREATEREQ:
+ op = INST_GE;
+ break;
+ case L_OP_LESSTHAN:
+ op = INST_LT;
+ break;
+ case L_OP_LESSTHANEQ:
+ op = INST_LE;
+ break;
+ default: ASSERT(0);
+ }
+ break;
+ case L_STRING:
+ case L_WIDGET:
+ switch (expr->op) {
+ case L_OP_EQUALEQUAL:
+ op = INST_STR_EQ;
+ break;
+ case L_OP_NOTEQUAL:
+ op = INST_STR_NEQ;
+ break;
+ default:
+ TclEmitOpcode(INST_STR_CMP, L->frame->envPtr);
+ switch (expr->op) {
+ case L_OP_GREATER:
+ push_lit("1");
+ op = INST_EQ;
+ break;
+ case L_OP_LESSTHAN:
+ push_lit("-1");
+ op = INST_EQ;
+ break;
+ case L_OP_GREATEREQ:
+ push_lit("0");
+ op = INST_GE;
+ break;
+ case L_OP_LESSTHANEQ:
+ push_lit("0");
+ op = INST_LE;
+ break;
+ default: ASSERT(0);
+ }
+ break;
+ }
+ break;
+ default:
+ // We get here only for eq() of a composite type
+ // w/no numerics.
+ op = INST_STR_EQ;
+ break;
+ }
+ break;
+ case L_OP_STR_EQ:
+ op = INST_STR_EQ;
+ break;
+ case L_OP_STR_NE:
+ op = INST_STR_NEQ;
+ break;
+ case L_OP_STR_GT:
+ case L_OP_STR_GE:
+ case L_OP_STR_LT:
+ case L_OP_STR_LE:
+ TclEmitOpcode(INST_STR_CMP, L->frame->envPtr);
+ switch (expr->op) {
+ case L_OP_STR_GT:
+ push_lit("1");
+ op = INST_EQ;
+ break;
+ case L_OP_STR_LT:
+ push_lit("-1");
+ op = INST_EQ;
+ break;
+ case L_OP_STR_GE:
+ push_lit("0");
+ op = INST_GE;
+ break;
+ case L_OP_STR_LE:
+ push_lit("0");
+ op = INST_LE;
+ break;
+ default: ASSERT(0);
+ }
+ break;
+ case L_OP_PLUS:
+ case L_OP_EQPLUS:
+ op = INST_ADD;
+ break;
+ case L_OP_MINUS:
+ case L_OP_EQMINUS:
+ op = INST_SUB;
+ break;
+ case L_OP_STAR:
+ case L_OP_EQSTAR:
+ op = INST_MULT;
+ break;
+ case L_OP_SLASH:
+ case L_OP_EQSLASH:
+ op = INST_DIV;
+ break;
+ case L_OP_PERC:
+ case L_OP_EQPERC:
+ op = INST_MOD;
+ break;
+ case L_OP_BITAND:
+ case L_OP_EQBITAND:
+ op = INST_BITAND;
+ break;
+ case L_OP_BITOR:
+ case L_OP_EQBITOR:
+ op = INST_BITOR;
+ break;
+ case L_OP_BITXOR:
+ case L_OP_EQBITXOR:
+ op = INST_BITXOR;
+ break;
+ case L_OP_LSHIFT:
+ case L_OP_EQLSHIFT:
+ op = INST_LSHIFT;
+ break;
+ case L_OP_RSHIFT:
+ case L_OP_EQRSHIFT:
+ op = INST_RSHIFT;
+ break;
+ case L_OP_UMINUS:
+ op = INST_UMINUS;
+ break;
+ case L_OP_UPLUS:
+ op = INST_UPLUS;
+ break;
+ case L_OP_BANG:
+ op = INST_LNOT;
+ break;
+ case L_OP_BITNOT:
+ op = INST_BITNOT;
+ break;
+ default:
+ break;
+ }
+ if (op) {
+ TclEmitOpcode(op, L->frame->envPtr);
+ return;
+ }
+ switch (expr->op) {
+ case L_OP_EQDOT:
+ op = INST_STR_CONCAT1;
+ arg = 2;
+ break;
+ default:
+ L_bomb("Unable to map operator %d to an instruction", expr->op);
+ break;
+ }
+ if (op) {
+ TclEmitInstInt1(op, arg, L->frame->envPtr);
+ }
+}
+
+private void
+compile_continue(Stmt *stmt)
+{
+ Frame *loop_frame = frame_find(LOOP);
+
+ unless (loop_frame) {
+ L_errf(stmt, "continue allowed only inside loops");
+ return;
+ }
+ loop_frame->continue_jumps = emit_jmp_fwd(INST_JUMP4,
+ loop_frame->continue_jumps);
+}
+
+private void
+compile_break(Stmt *stmt)
+{
+ Frame *loop_frame = frame_find(LOOP|SWITCH);
+
+ unless (loop_frame) {
+ L_errf(stmt,
+ "break allowed only inside switch and loop statements");
+ return;
+ }
+ loop_frame->break_jumps = emit_jmp_fwd(INST_JUMP4,
+ loop_frame->break_jumps);
+}
+
+private void
+compile_label(Stmt *stmt)
+{
+ Label *label;
+
+ if (!strcmp(stmt->u.label, "break")) {
+ L_errf(stmt, "break is not a legal label");
+ }
+ label = label_lookup(stmt, LABEL_DEF);
+ fixup_jmps(&label->fixups);
+ label->fixups = NULL;
+ label->offset = currOffset(L->frame->envPtr);
+}
+
+private void
+compile_goto(Stmt *stmt)
+{
+ Label *label;
+
+ label = label_lookup(stmt, LABEL_USE);
+ if (label->offset >= 0) {
+ emit_jmp_back(TCL_UNCONDITIONAL_JUMP, label->offset);
+ } else {
+ label->fixups = emit_jmp_fwd(INST_JUMP4, label->fixups);
+ }
+}
+
+private Label *
+label_lookup(Stmt *stmt, Label_f flags)
+{
+ int new;
+ char *name = stmt->u.label;
+ Label *label = NULL;
+ Frame *frame;
+ Tcl_HashEntry *hPtr = NULL;
+
+ /* Labels are restricted to the enclosing proc's labeltab. */
+ frame = frame_find(FUNC);
+ ASSERT(frame);
+
+ hPtr = Tcl_FindHashEntry(frame->labeltab, name);
+ if (hPtr) {
+ label = (Label *)Tcl_GetHashValue(hPtr);
+ } else {
+ label = (Label *)ckalloc(sizeof(Label));
+ memset(label, 0, sizeof(Label));
+ label->name = name;
+ label->offset = -1;
+ hPtr = Tcl_CreateHashEntry(frame->labeltab, name, &new);
+ ASSERT(new);
+ Tcl_SetHashValue(hPtr, label);
+ }
+ if ((flags & LABEL_DEF) && (label->offset >= 0)) {
+ L_errf(stmt, "label %s already defined", name);
+ }
+ return (label);
+}
+
+private void
+emit_globalUpvar(Sym *sym)
+{
+ VarDecl *decl = sym->decl;
+ char *id = sym->name;
+
+ /*
+ * Tim comment: We attempt to detect whether L global
+ * variables should be true globals, or should be shared with
+ * the calling proc, by checking if the current variable frame
+ * pointer in interp is the same as the global frame pointer.
+ * (Sharing variables with the calling proc is useful if you
+ * want to use L as an expr replacement).
+ */
+ if (((Interp *)L->interp)->rootFramePtr !=
+ ((Interp *)L->interp)->varFramePtr) {
+ ASSERT(!(decl->flags & (DECL_CLASS_VAR | DECL_CLASS_INST_VAR)));
+ frame_resumePrologue();
+ push_lit("#0");
+ push_lit(id);
+ TclEmitInstInt4(INST_UPVAR, sym->idx, L->frame->envPtr);
+ emit_pop();
+ frame_resumeBody();
+ return;
+ }
+
+ /*
+ * The namespace of the var we're creating an upvar alias to is
+ * either ::, an L class namespace, or an L class instance namespace
+ * where the local "self" holds the namespace name.
+ */
+ frame_resumePrologue();
+ switch (decl->flags &
+ (DECL_GLOBAL_VAR | DECL_CLASS_VAR | DECL_CLASS_INST_VAR)) {
+ case DECL_GLOBAL_VAR:
+ push_lit("::");
+ /* Private globals get mangled to avoid clashes. */
+ if (decl->flags & DECL_PRIVATE) {
+ push_litf("_%s_%s", L->toplev, id);
+ } else {
+ push_lit(id);
+ }
+ break;
+ case DECL_CLASS_VAR:
+ push_litf("::L::_class_%s", decl->clsdecl->decl->id->str);
+ push_lit(id);
+ break;
+ case DECL_CLASS_INST_VAR: {
+ Sym *self = sym_lookup(mkId("self"), L_NOWARN);
+ ASSERT(self);
+ emit_load_scalar(self->idx);
+ push_lit(id);
+ break;
+ }
+ }
+ TclEmitInstInt4(INST_NSUPVAR, sym->idx, L->frame->envPtr);
+ emit_pop();
+ frame_resumeBody();
+}
+
+/*
+ * Add a variable or function name to the symbol table. If it's a
+ * local variable, allocate a slot for it in the current proc.
+ *
+ * Print an error if the symbol is already defined. The rules are
+ *
+ * - Multiply defined globals are illegal, with the exception that
+ * main() can be re-defined.
+ * - A local cannot shadow any other local in the proc.
+ * - A local can shadow a global.
+ * - A local can shadow a global upvar shadow (which is a local
+ * with special status).
+ *
+ * Scopes are created as follows. The complexity stems from Tcl
+ * requiring local upvar shadows as the only way to access globals.
+ * So we have a scope in which the global symbol is stored and a
+ * nested scope for the proc in which the local upvar shadow is
+ * stored.
+ *
+ * There is one scope hierarchy per Tcl Interp in which L code
+ * appears, as illustrated next. OUTER,SCRIPT,TOPLEV,SKIP etc are frame
+ * flags (Frame_f); SKIP means that the scope is skipped when
+ * searching enclosing scopes.
+ *
+ * [ outer-most scope (OUTER): public globals go in this frame's symtab
+ * [ file scope (SCRIPT): private globals go in this frame's symtab
+ * [ * (%%n_toplevel proc) (TOPLEV|SKIP)
+ * global initializers get compiled in this scope, causing the
+ * local upvar shadows to go in this scope's symtab
+ * [ class outer-most (CLS_OUTER): class/instance vars & private
+ * member fns go in this frame's symtab
+ * [ * class top-level (CLS_TOPLEV|SKIP)
+ * class variable initializers get compiled in this scope
+ * (note that this is still in the %%n_toplevel proc)
+ * [ (constructor proc)
+ * instance var initializers get compiled here
+ * ]
+ * [ (destructor proc)
+ * ]
+ * [ (member fn proc): public fn names go in outer-most
+ * scope's, symtable, private fn names go in class
+ * outer-most scope, fn locals go in this frame's
+ * symtab
+ * [ block
+ * [ nested blocks...
+ * ]
+ * ]
+ * ]
+ * ]
+ * ]
+ * [ regular function (proc): public fn name goes in outer-most
+ * scope's symtab, private fn name goes in file scope's symtab,
+ * fn locals go in this frame's symtab
+ * [ block
+ * [ nested blocks...
+ * ]
+ * ]
+ * ]
+ * ]
+ * ]
+ * ]
+ */
+private Sym *
+sym_store(VarDecl *decl)
+{
+ int new;
+ char *name = decl->id->str;
+ Sym *sym = NULL;
+ Sym *sym2;
+ Frame *frame = NULL;
+ Tcl_HashEntry *hPtr;
+
+ /* Check for multiple declaration. */
+ switch (decl->flags &
+ (SCOPE_LOCAL | SCOPE_GLOBAL | SCOPE_SCRIPT | SCOPE_CLASS)) {
+ case SCOPE_GLOBAL:
+ case SCOPE_SCRIPT:
+ /* Declaring a global -- search outer-most and file frames. */
+ frame = frame_find(OUTER);
+ hPtr = Tcl_FindHashEntry(frame->symtab, name);
+ unless (hPtr) {
+ frame = frame_find(SCRIPT);
+ hPtr = Tcl_FindHashEntry(frame->symtab, name);
+ }
+ if (hPtr) {
+ sym2 = (Sym *)Tcl_GetHashValue(hPtr);
+ if (decl->flags & DECL_EXTERN) {
+ sym = (Sym *)Tcl_GetHashValue(hPtr);
+ if (L_typeck_same(decl->type, sym->type)) {
+ return (sym);
+ }
+ L_errf(decl,
+ "extern re-declaration type does not "
+ "match other declaration");
+ return (NULL);
+ } else if (sym2->decl->flags & DECL_ERR) {
+ Tcl_DeleteHashEntry(hPtr);
+ } else {
+ L_errf(decl,
+ "multiple declaration of global %s", name);
+ return (NULL);
+ }
+ }
+ break;
+ case SCOPE_CLASS:
+ /* Declaring class var -- search up thru class outer scope. */
+ for (frame = L->frame; frame; frame = frame->prevFrame) {
+ hPtr = Tcl_FindHashEntry(frame->symtab, name);
+ if (hPtr) {
+ sym2 = (Sym *)Tcl_GetHashValue(hPtr);
+ if (sym2->decl->flags & DECL_ERR) {
+ Tcl_DeleteHashEntry(hPtr);
+ } else {
+ L_errf(decl, "multiple declaration of %s",
+ name);
+ return (NULL);
+ }
+ }
+ if (frame->flags & CLS_OUTER) break;
+ }
+ break;
+ case SCOPE_LOCAL:
+ /*
+ * Declaring a local -- search current proc's local
+ * scopes, then the global scope so we can issue a warning
+ * if this is a local that shadows a class or global var.
+ */
+ for (frame = L->frame; frame; frame = frame->prevFrame) {
+ unless (frame->envPtr == L->frame->envPtr) break;
+ hPtr = Tcl_FindHashEntry(frame->symtab, name);
+ if (hPtr) {
+ sym = (Sym *)Tcl_GetHashValue(hPtr);
+ ASSERT(sym->kind & L_SYM_LVAR);
+ unless (sym->kind & L_SYM_LSHADOW) {
+ L_errf(decl, "multiple declaration "
+ "of local %s", name);
+ return (NULL);
+ }
+ }
+ }
+ for (; frame; frame = frame->prevFrame) {
+ hPtr = Tcl_FindHashEntry(frame->symtab, name);
+ unless (hPtr && (frame->flags & SEARCH)) continue;
+ sym2 = (Sym *)Tcl_GetHashValue(hPtr);
+ if (sym2->decl->flags & DECL_GLOBAL_VAR) {
+ L_warnf(decl, "local variable %s shadows "
+ "a global declared at %s:%d",
+ name, sym2->decl->node.loc.file,
+ sym2->decl->node.loc.line);
+ } else if (sym2->decl->flags & DECL_CLASS_VAR) {
+ L_warnf(decl, "local variable %s shadows "
+ "a class variable declared at %s:%d",
+ name, sym2->decl->node.loc.file,
+ sym2->decl->node.loc.line);
+ } else if (sym2->decl->flags & DECL_CLASS_INST_VAR) {
+ L_warnf(decl, "local variable %s shadows a "
+ "class instance variable declared "
+ "at %s:%d", name,
+ sym2->decl->node.loc.file,
+ sym2->decl->node.loc.line);
+ }
+ }
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+
+ /* Select the frame to add the symbol to. */
+ switch (decl->flags &
+ (SCOPE_LOCAL | SCOPE_GLOBAL | SCOPE_SCRIPT | SCOPE_CLASS)) {
+ case SCOPE_GLOBAL:
+ frame = frame_find(OUTER);
+ break;
+ case SCOPE_SCRIPT:
+ frame = frame_find(SCRIPT);
+ break;
+ case SCOPE_CLASS:
+ frame = frame_find(CLS_OUTER);
+ break;
+ case SCOPE_LOCAL:
+ frame = L->frame;
+ break;
+ default:
+ ASSERT(0);
+ break;
+ }
+ hPtr = Tcl_CreateHashEntry(frame->symtab, name, &new);
+ /* If it's not new, it must be shadowing a global. */
+ ASSERT(new || (sym && (sym->kind & L_SYM_LSHADOW) &&
+ (decl->flags & (DECL_LOCAL_VAR | DECL_CLASS_INST_VAR))));
+ sym = (Sym *)ckalloc(sizeof(Sym));
+ memset(sym, 0, sizeof(*sym));
+ sym->name = ckstrdup(name);
+ sym->type = decl->type;
+ sym->decl = decl;
+
+ /*
+ * Set the name of the tcl variable, mangling it to avoid
+ * clashes.
+ */
+ if (isfntype(decl->type)) {
+ ASSERT(decl->flags & (DECL_FN | DECL_CLASS_FN));
+ sym->kind = L_SYM_FN;
+ if (decl->tclprefix) {
+ sym->tclname = cksprintf("%s%s", decl->tclprefix, name);
+ } else {
+ sym->tclname = ckstrdup(name);
+ }
+ } else if (decl->flags & DECL_GLOBAL_VAR) {
+ sym->kind = L_SYM_GVAR;
+ sym->tclname = cksprintf("_%s", name);
+ } else if (decl->flags & (DECL_CLASS_VAR | DECL_CLASS_INST_VAR)) {
+ sym->kind = L_SYM_GVAR;
+ sym->tclname = cksprintf("_%s_%s",
+ decl->clsdecl->decl->id->str,
+ name);
+ } else {
+ ASSERT(decl->flags & DECL_LOCAL_VAR);
+ sym->kind = L_SYM_LVAR;
+ sym->tclname = ckstrdup(name);
+ }
+
+ /* If a local, allocate a slot for it. */
+ if (sym->kind & L_SYM_LVAR) {
+ sym->idx = TclFindCompiledLocal(name, strlen(name),
+ 1, L->frame->envPtr);
+ } else {
+ sym->idx = -1;
+ }
+
+ decl->id->sym = sym;
+ decl->id->type = decl->type;
+ Tcl_SetHashValue(hPtr, sym);
+
+ return (sym);
+}
+
+/*
+ * Lookup id in the symbol table.
+ *
+ * flags & L_NOTUSED ==> don't mark the id as having been referenced
+ * (used for warning which variables are unused).
+ *
+ * flags & L_NOWARN ==> don't print error message if id not found.
+ *
+ * The first time a global is referenced within a scope, an upvar is
+ * created for it.
+ */
+private Sym *
+sym_lookup(Expr *id, Expr_f flags)
+{
+ int new;
+ char *name;
+ Sym *shw;
+ Sym *sym = NULL;
+ Frame *frame;
+ Tcl_HashEntry *hPtr = NULL;
+
+ unless (id->kind == L_EXPR_ID) return (NULL);
+ name = id->str;
+
+ for (frame = L->frame; frame; frame = frame->prevFrame) {
+ if ((frame->envPtr == L->frame->envPtr) ||
+ (frame->flags & SEARCH)) {
+ hPtr = Tcl_FindHashEntry(frame->symtab, name);
+ if (hPtr) break;
+ }
+ }
+ if (hPtr) sym = (Sym *)Tcl_GetHashValue(hPtr);
+ if (sym) {
+ /*
+ * If a global is being referenced for the first time
+ * in this scope, create a local upvar to shadow it
+ * in the symtab of the enclosing proc or top-level.
+ */
+ if ((sym->kind & L_SYM_GVAR) && (sym->idx == -1)) {
+ Frame *proc_frame;
+ // assert global => in outer-most or file frame
+ ASSERT(!(sym->decl->flags & DECL_GLOBAL_VAR) ||
+ (frame->flags & (OUTER|SCRIPT)));
+ // assert class var => in class outer-most frame
+ ASSERT(!(sym->decl->flags & DECL_CLASS_VAR) ||
+ (frame->flags & CLS_OUTER));
+ // assert class instance var => class outer-most frame
+ ASSERT(!(sym->decl->flags & DECL_CLASS_INST_VAR) ||
+ (frame->flags & CLS_OUTER));
+ proc_frame = frame_find(TOPLEV|CLS_TOPLEV|FUNC);
+ ASSERT(proc_frame);
+ hPtr = Tcl_CreateHashEntry(proc_frame->symtab, name,
+ &new);
+ ASSERT(new);
+ shw = (Sym *)ckalloc(sizeof(Sym));
+ memset(shw, 0, sizeof(*shw));
+ shw->kind = L_SYM_LVAR | L_SYM_LSHADOW;
+ shw->name = ckstrdup(name);
+ shw->tclname = ckstrdup(sym->tclname);
+ shw->type = sym->decl->type;
+ shw->decl = sym->decl;
+ shw->used_p = TRUE;
+ shw->idx = TclFindCompiledLocal(shw->tclname,
+ strlen(shw->tclname),
+ 1,
+ L->frame->envPtr);
+ emit_globalUpvar(shw);
+ Tcl_SetHashValue(hPtr, shw);
+ sym = shw;
+ }
+ unless (flags & L_NOTUSED) sym->used_p = TRUE;
+ id->sym = sym;
+ id->type = sym->type;
+ return (sym);
+ } else {
+ ASSERT(id->sym == NULL);
+ unless (flags & L_NOWARN) {
+ /*
+ * Add the undeclared variable to the symtab to avoid
+ * cascading errors.
+ */
+ YYLTYPE loc = id->node.loc;
+ VarDecl *decl = ast_mkVarDecl(L_poly, id, loc, loc);
+ decl->flags = DECL_ERR | DECL_ARGUSED;
+ switch (L->frame->flags & (FUNC|CLS_TOPLEV|TOPLEV)) {
+ case TOPLEV | FUNC:
+ decl->flags |= SCOPE_GLOBAL | DECL_GLOBAL_VAR;
+ break;
+ case CLS_TOPLEV:
+ decl->flags |= SCOPE_CLASS | DECL_CLASS_VAR;
+ ASSERT(L->frame->clsdecl);
+ decl->clsdecl = L->frame->clsdecl;
+ break;
+ case FUNC:
+ case 0: // stmt block
+ decl->flags |= SCOPE_LOCAL | DECL_LOCAL_VAR;
+ break;
+ default: ASSERT(0);
+ }
+ L_errf(id, "undeclared variable: %s", name);
+ id->sym = sym_store(decl);
+ }
+ id->type = L_poly;
+ return (NULL);
+ }
+}
+
+private Sym *
+sym_mk(char *name, Type *t, Decl_f flags)
+{
+ YYLTYPE loc = { 0 };
+ Expr *id = mkId(name);
+ VarDecl *decl = ast_mkVarDecl(t, id, loc, loc);
+
+ decl->flags = flags;
+ return (sym_store(decl));
+}
+
+private Tmp *
+tmp_get(TmpKind kind)
+{
+ Tmp *tmp;
+
+ for (tmp = L->frame->tmps; tmp; tmp = tmp->next) {
+ if (tmp->free) break;
+ }
+ unless (tmp) {
+ tmp = (Tmp *)ckalloc(sizeof(*tmp));
+ tmp->next = L->frame->tmps;
+ L->frame->tmps = tmp;
+ tmp->name = cksprintf("=temp%d", L->tmpnum++);
+ tmp->idx = TclFindCompiledLocal(tmp->name, strlen(tmp->name),
+ 1, L->frame->envPtr);
+ }
+ tmp->free = 0;
+ /*
+ * Sometimes we need a tmp var that is not set to anything.
+ * For example, to create an upvar or to use the INST_DICT_*
+ * bytecodes.
+ */
+ if (kind == TMP_UNSET) {
+ TclEmitInstInt4(INST_UNSET_LOCAL, tmp->idx, L->frame->envPtr);
+ }
+ return (tmp);
+}
+
+private void
+tmp_free(Tmp *tmp)
+{
+ if (tmp) tmp->free = 1;
+}
+
+private void
+tmp_freeAll(Tmp *tmp)
+{
+ while (tmp) {
+ Tmp *next = tmp->next;
+ ckfree((char *)tmp);
+ tmp = next;
+ }
+}
+
+void
+L_bomb(const char *format, ...)
+{
+ va_list ap;
+
+ va_start(ap, format);
+ fprintf(stderr, "L Internal Error: ");
+ vfprintf(stderr, format, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+ exit(1);
+}
+
+/*
+ * L_synerr is Bison's yyerror and is called by the parser for syntax
+ * errors. Bail out by longjumping back to Tcl_LObjCmd, as a way
+ * to work-around a possible compiler bug in our Windows build where
+ * the Bison-generated parser's own internal longjmp causes a crash.
+ */
+void
+L_synerr(const char *s)
+{
+ int i, off;
+ char *beg = Tcl_GetString(L->script);
+ char *end = beg + L->script_len;
+ char *line, *stop;
+
+ unless (L->errs) {
+ L->errs = Tcl_NewObj();
+ L->err = 1;
+ }
+ Tcl_AppendPrintfToObj(L->errs, "%s:%d: L Error: %s\n",
+ L->file, L->line, s);
+
+ /* Search backwards to find the start of the offending line. */
+ off = L_lloc.beg;
+ ASSERT(off >= 0);
+ ASSERT(beg);
+ for (line = beg+off; (line > beg) && (line[-1] != '\n'); --line) ;
+ off = beg+off - line; // is now offset from start of offending line
+
+ /* Print the offending line with a ^ pointing to the current token. */
+ stop = line + off;
+ for (i = 1; (*line != '\n') && (line < end); ++i) {
+ // adjust for tab printing >1 char
+ if ((*line == '\t') && (line <= stop)) {
+ off += 8 - i%8;
+ i += 7;
+ }
+ Tcl_AppendToObj(L->errs, line++, 1);
+ }
+ Tcl_AppendToObj(L->errs, "\n", 1);
+ ASSERT(off >= 0);
+ while (off--) Tcl_AppendToObj(L->errs, " ", 1);
+ Tcl_AppendToObj(L->errs, "^\n", 2);
+
+ longjmp(L->jmp, 0);
+}
+
+/*
+ * Like L_synerr() above but take the offset of the offending token
+ * instead of using the current token.
+ */
+void
+L_synerr2(const char *s, int offset)
+{
+ L_lloc.beg = offset;
+ L_synerr(s);
+}
+
+void
+L_warnf(void *node, const char *format, ...)
+{
+ va_list ap;
+ int len = 64;
+ char *buf, *fmt;
+
+ if (hash_get(L->options, "nowarn")) return;
+
+ fmt = cksprintf("%s:%d: L Warning: %s\n",
+ ((Ast *)node)->loc.file, ((Ast *)node)->loc.line,
+ format);
+ va_start(ap, format);
+ while (!(buf = ckvsprintf(fmt, ap, len))) {
+ va_end(ap);
+ va_start(ap, format);
+ len *= 2;
+ }
+ va_end(ap);
+ unless (L->errs) {
+ L->errs = Tcl_NewObj();
+ L->err = 1;
+ }
+ Tcl_AppendToObj(L->errs, buf, -1);
+ ckfree(fmt);
+ ckfree(buf);
+}
+
+void
+L_err(const char *format, ...)
+{
+ va_list ap;
+ int len = 64;
+ char *buf, *fmt;
+
+ fmt = cksprintf("%s:%d: L Error: %s\n", L->file, L->line, format);
+ va_start(ap, format);
+ while (!(buf = ckvsprintf(fmt, ap, len))) {
+ va_end(ap);
+ va_start(ap, format);
+ len *= 2;
+ }
+ va_end(ap);
+ unless (L->errs) {
+ L->errs = Tcl_NewObj();
+ L->err = 1;
+ }
+ Tcl_AppendToObj(L->errs, buf, -1);
+ ckfree(fmt);
+ ckfree(buf);
+}
+
+void
+L_errf(void *node, const char *format, ...)
+{
+ va_list ap;
+ int len = 64;
+ char *buf, *fmt;
+
+ if (node) {
+ fmt = cksprintf("%s:%d: L Error: %s\n",
+ ((Ast *)node)->loc.file,
+ ((Ast *)node)->loc.line,
+ format);
+ } else {
+ fmt = cksprintf("L Error: %s\n", format);
+ }
+ va_start(ap, format);
+ while (!(buf = ckvsprintf(fmt, ap, len))) {
+ va_end(ap);
+ va_start(ap, format);
+ len *= 2;
+ }
+ va_end(ap);
+ unless (L->errs) {
+ L->errs = Tcl_NewObj();
+ L->err = 1;
+ }
+ Tcl_AppendToObj(L->errs, buf, -1);
+ ckfree(fmt);
+}
+
+private void
+ast_free(Ast *ast_list)
+{
+ while (ast_list) {
+ Ast *node = ast_list;
+ ast_list = ast_list->next;
+ switch (node->type) {
+ case L_NODE_STMT: {
+ Stmt *s = (Stmt *)node;
+ if ((s->kind == L_STMT_LABEL) ||
+ (s->kind == L_STMT_GOTO)) {
+ ckfree(s->u.label);
+ }
+ break;
+ }
+ case L_NODE_EXPR:
+ ckfree(((Expr *)node)->str);
+ break;
+ case L_NODE_VAR_DECL:
+ ckfree(((VarDecl *)node)->tclprefix);
+ break;
+ default:
+ break;
+ }
+ ckfree((char *)node);
+ }
+}
+
+private void
+type_free(Type *type_list)
+{
+ while (type_list) {
+ Type *type = type_list;
+ type_list = type_list->list;
+ if (type->kind == L_STRUCT) ckfree(type->u.struc.tag);
+ ckfree(type->name);
+ ckfree((char *)type);
+ }
+}
+
+/*
+ * This is basically a whacked version of EnterCmdStartData and
+ * EnterCmdWordData from tclCompile.c.
+ */
+private void
+track_cmd(int codeOffset, void *node)
+{
+ int cmdIndex = L->frame->envPtr->numCommands++;
+ Ast *ast = (Ast *)node;
+ int len = ast->loc.end - ast->loc.beg;
+ int srcOffset = ast->loc.beg;
+ ECL *ePtr;
+ CmdLocation *cmdLocPtr;
+ CompileEnv *envPtr = L->frame->envPtr;
+ ExtCmdLoc *eclPtr = envPtr->extCmdMapPtr;
+
+ if ((cmdIndex < 0) || (cmdIndex >= envPtr->numCommands)) {
+ Tcl_Panic("track_cmd: bad command index %d", cmdIndex);
+ }
+ if (cmdIndex >= envPtr->cmdMapEnd) {
+ /*
+ * Expand the command location array by allocating
+ * more storage from the heap. The currently allocated
+ * CmdLocation entries are stored from cmdMapPtr[0] up
+ * to cmdMapPtr[envPtr->cmdMapEnd] (inclusive).
+ */
+ size_t currElems = envPtr->cmdMapEnd;
+ size_t newElems = 2*currElems;
+ size_t currBytes = currElems * sizeof(CmdLocation);
+ size_t newBytes = newElems * sizeof(CmdLocation);
+ CmdLocation *newPtr = (CmdLocation *)ckalloc((int)newBytes);
+
+ /*
+ * Copy from old command location array to new, free
+ * old command location array if needed, and mark new
+ * array as malloced.
+ */
+ memcpy(newPtr, envPtr->cmdMapPtr, currBytes);
+ if (envPtr->mallocedCmdMap) ckfree((char *)envPtr->cmdMapPtr);
+ envPtr->cmdMapPtr = (CmdLocation *)newPtr;
+ envPtr->cmdMapEnd = newElems;
+ envPtr->mallocedCmdMap = 1;
+ }
+
+ cmdLocPtr = &(envPtr->cmdMapPtr[cmdIndex]);
+ cmdLocPtr->codeOffset = codeOffset;
+ cmdLocPtr->srcOffset = srcOffset;
+ cmdLocPtr->numSrcBytes = len;
+ cmdLocPtr->numCodeBytes = currOffset(envPtr) - codeOffset;
+
+ /*
+ * The command locations have to be sorted in ascending order
+ * by codeOffset. (Or Tcl panics in GetCmdLocEncodingSize(),
+ * if nothing else). However, when L compiles nested function
+ * calls, the outer one will get tracked second, even though
+ * it begins first. So we walk the new CmdLocation entry back
+ * from the end until it lands where it belongs.
+ */
+ while ((cmdIndex > 0) && (envPtr->cmdMapPtr[cmdIndex-1].codeOffset >
+ envPtr->cmdMapPtr[cmdIndex].codeOffset)) {
+ CmdLocation cmdLoc = envPtr->cmdMapPtr[cmdIndex];
+ envPtr->cmdMapPtr[cmdIndex] = envPtr->cmdMapPtr[cmdIndex-1];
+ envPtr->cmdMapPtr[cmdIndex-1] = cmdLoc;
+ cmdIndex--;
+ }
+
+ if (eclPtr->nuloc >= eclPtr->nloc) {
+ /*
+ * Expand the ECL array by allocating more storage
+ * from the heap. The currently allocated ECL entries
+ * are stored from eclPtr->loc[0] up to
+ * eclPtr->loc[eclPtr->nuloc-1] (inclusive).
+ */
+ size_t currElems = eclPtr->nloc;
+ size_t newElems = (currElems ? 2*currElems : 1);
+ size_t newBytes = newElems * sizeof(ECL);
+ eclPtr->loc = (ECL *) ckrealloc((char *) eclPtr->loc, newBytes);
+ eclPtr->nloc = newElems;
+ }
+
+ /* We enter only one word for the L command. */
+ ePtr = &eclPtr->loc[eclPtr->nuloc];
+ ePtr->srcOffset = srcOffset;
+ ePtr->line = (int *) ckalloc(sizeof(int));
+ ePtr->nline = 1;
+ eclPtr->nuloc ++;
+}
+
+/*
+ * API for tracking when we are compiling a function argument. This is
+ * used to check whether an (expand) operator is being used as a
+ * function argument (OK) or as something else (error).
+ *
+ * fnCallBegin: call just before compiling a fn call
+ * fnCallEnd: call just after compiling a fn call
+ * fnInArgList: returns 1 if we are just starting to compile a
+ * fn call arg; returns 0 if we're either outside of a
+ * fn call or nested within an expression inside of
+ * an arg:
+ * foo(x) -- true
+ * foo(x+y) -- false
+ */
+private int
+fnCallBegin()
+{
+ int old = L->call_level;
+ L->call_level = L->expr_level;
+ return (old);
+}
+private void
+fnCallEnd(int lev)
+{
+ L->call_level = lev;
+}
+private int
+fnInArgList()
+{
+ return (L->expr_level == (L->call_level + 1));
+}
+
+private Expr *
+mkId(char *name)
+{
+ YYLTYPE loc = { 0 };
+
+ return (ast_mkId(name, loc, loc));
+}
+
+char *
+ckstrdup(const char *str)
+{
+ if (str) {
+ return (ckstrndup(str, strlen(str)));
+ } else {
+ return (NULL);
+ }
+}
+
+char *
+ckstrndup(const char *str, int len)
+{
+ char *newStr = ckalloc(len+1);
+
+ strncpy(newStr, str, len);
+ newStr[len] = '\0';
+ return (newStr);
+}
+
+char *
+cksprintf(const char *fmt, ...)
+{
+ va_list ap;
+ int len = 64;
+ char *buf;
+
+ va_start(ap, fmt);
+ while (!(buf = ckvsprintf(fmt, ap, len))) {
+ va_end(ap);
+ va_start(ap, fmt);
+ len *= 2;
+ }
+ va_end(ap);
+ return (buf);
+}
+
+/*
+ * Allocate a buffer of len bytes and attempt a vsnprintf and fail
+ * (return NULL) if len isn't enough. The caller should double len
+ * and re-try. We require the caller to re-try instead of re-trying
+ * here because on some platforms "ap" is changed by the vsnprintf
+ * call and there is no portable way to save and restore it.
+ */
+char *
+ckvsprintf(const char *fmt, va_list ap, int len)
+{
+ char *buf = ckalloc(len);
+ int ret = vsnprintf(buf, len, fmt, ap);
+ /*
+ * The meaning of the return value depends on the platform.
+ * Some return the needed length (minus 1), some return -1,
+ * some truncate the buffer. For the latter, ret will be
+ * len-1 and we won't know whether it barely fit or wasn't
+ * enough, so just fail on that case.
+ */
+ if ((ret >= (len-1)) || (ret < 0)) {
+ ckfree(buf);
+ return (NULL);
+ }
+ return (buf);
+}
+
+/*
+ * Since we have C-like variable declarations in L, when hashes and
+ * arrays are declared, the base type is parsed separately from the
+ * array sizes or hash-element types. The next two functions put them
+ * back together. E.g., in
+ *
+ * string h{int};
+ *
+ * the main type passed in to these functions is a hash type
+ * (w/index type of "int") but the hash type doesn't yet have its
+ * base type set, which in this example is "string".
+ *
+ * For simple declarations (like "string s") where there is no
+ * explicit array or hash, decl->type won't be set by the parser, so
+ * the base type goes there. For arrays/hashes, decl->type points to
+ * the first level of array or hash, and the base type must go onto
+ * the last nested hash or array type.
+ */
+
+void
+L_set_baseType(Type *type, Type *base_type)
+{
+ while (type->base_type) {
+ ASSERT((type->kind == L_ARRAY) ||
+ (type->kind == L_HASH) ||
+ (type->kind == L_NAMEOF));
+ type = type->base_type;
+ }
+ type->base_type = base_type;
+}
+
+void
+L_set_declBaseType(VarDecl *decl, Type *base_type)
+{
+ if (decl->type) {
+ L_set_baseType(decl->type, base_type);
+ } else {
+ decl->type = base_type;
+ }
+ if (isnameoftype(base_type)) decl->flags |= DECL_REF;
+}
+
+/*
+ * These are called before each Tcl interp is created (see
+ * tclInterp.c) and after it is deleted. Set up a top-level scope and
+ * call frame in order to persist typedefs, struct types, and globals
+ * across all the L programs compiled inside the interp.
+ */
+void
+TclLInitCompiler(Tcl_Interp *interp)
+{
+ static Lglobal global; // L global state
+
+// putenv("MallocStackLogging=1");
+
+ /* Associate the L interp state with this interp. */
+ L = (Linterp *)ckalloc(sizeof(Linterp));
+ memset(L, 0, sizeof(Linterp));
+ Tcl_SetAssocData(interp, "L", TclLCleanupCompiler, L);
+
+ L->global = &global;
+ L->interp = interp;
+ frame_push(NULL, NULL, OUTER|SEARCH);
+ L_scope_enter();
+ L->fn_calls = Tcl_NewObj();
+ Tcl_SetVar2Ex(L->interp, "%%L_fnsCalled", NULL, L->fn_calls,
+ TCL_GLOBAL_ONLY);
+ L->fn_decls = Tcl_NewObj();
+ Tcl_SetVar2Ex(L->interp, "L_fnsDeclared", NULL, L->fn_decls,
+ TCL_GLOBAL_ONLY);
+}
+
+void
+TclLCleanupCompiler(ClientData clientData, Tcl_Interp *interp)
+{
+ char buf[32];
+
+ L = (Linterp *)clientData;
+ L_scope_leave();
+ frame_pop();
+ ast_free(L->ast_list);
+ type_free(L->type_list);
+ if (L->include_table) {
+ Tcl_DeleteHashTable(L->include_table);
+ ckfree((char *)L->include_table);
+ }
+ ckfree(L->file);
+ ckfree(L->toplev);
+ if (L->script) Tcl_DecrRefCount(L->script);
+ ckfree((char *)L);
+ L = NULL;
+
+ snprintf(buf, sizeof(buf), "/usr/bin/leaks %u", getpid());
+// system(buf);
+}
+
+void
+L_scope_enter()
+{
+ Scope *new_scope = (Scope *)ckalloc(sizeof(*new_scope));
+
+ new_scope->structs = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
+ Tcl_InitHashTable(new_scope->structs, TCL_STRING_KEYS);
+
+ new_scope->typedefs = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
+ Tcl_InitHashTable(new_scope->typedefs, TCL_STRING_KEYS);
+
+ new_scope->prev = L->curr_scope;
+ L->curr_scope = new_scope;
+}
+
+void
+L_scope_leave()
+{
+ Scope *prev = L->curr_scope->prev;
+
+ Tcl_DeleteHashTable(L->curr_scope->structs);
+ ckfree((char *)L->curr_scope->structs);
+
+ Tcl_DeleteHashTable(L->curr_scope->typedefs);
+ ckfree((char *)L->curr_scope->typedefs);
+
+ ckfree((char *)L->curr_scope);
+
+ L->curr_scope = prev;
+}
+
+/*
+ * Called by parser to look up a reference to "struct tag". If
+ * "local" is true, check only the current scope. If the struct
+ * hasn't yet been declared, add an incomplete type to the current
+ * scope's struct table whose members will get filled up later when
+ * the struct is fully declared.
+ */
+Type *
+L_struct_lookup(char *tag, int local)
+{
+ int new;
+ Type *type;
+ Tcl_HashEntry *hPtr = NULL;
+ Scope *scope;
+
+ for (scope = L->curr_scope; !hPtr && scope; scope = scope->prev) {
+ hPtr = Tcl_FindHashEntry(scope->structs, tag);
+ if (local) break;
+ }
+ if (hPtr) {
+ type = (Type *)Tcl_GetHashValue(hPtr);
+ } else {
+ hPtr = Tcl_CreateHashEntry(L->curr_scope->structs, tag, &new);
+ type = type_mkStruct(tag, NULL);
+ Tcl_SetHashValue(hPtr, type);
+ }
+ return (type);
+}
+
+/*
+ * Called by parser to declare a new struct type. If the struct
+ * already has been declared but without any members, fill them in
+ * now and return the existing type pointer. If tag is NULL, just
+ * sanity check the members' types (checking for void etc).
+ */
+Type *
+L_struct_store(char *tag, VarDecl *m)
+{
+ Type *type = NULL;
+
+ ASSERT(m);
+
+ if (tag) {
+ type = L_struct_lookup(tag, TRUE);
+ if (type->u.struc.members) {
+ L_errf(m, "multiple declaration of struct %s", tag);
+ } else {
+ type->u.struc.members = m;
+ }
+ }
+
+ /* Check member types for legality. */
+ for (; m; m = m->next) {
+ L_typeck_declType(m);
+ }
+
+ return (type);
+}
+
+/*
+ * Called by parser to look up an ID in the typedef table to see if
+ * it's been previously declared as a type name.
+ */
+Type *
+L_typedef_lookup(char *name)
+{
+ Tcl_HashEntry *hPtr = NULL;
+ Scope *scope;
+
+ for (scope = L->curr_scope; !hPtr && scope; scope = scope->prev) {
+ hPtr = Tcl_FindHashEntry(scope->typedefs, name);
+ }
+ if (hPtr) {
+ return ((Type *)Tcl_GetHashValue(hPtr));
+ } else {
+ return (NULL);
+ }
+}
+
+/*
+ * Called by parser to define a new type name.
+ */
+void
+L_typedef_store(VarDecl *decl)
+{
+ int new;
+ Tcl_HashEntry *hPtr;
+ Type *new_type;
+ char *name = decl->id->str;
+
+ hPtr = Tcl_CreateHashEntry(L->curr_scope->typedefs, name, &new);
+ if (new) {
+ new_type = type_dup(decl->type);
+ if (new_type->name) ckfree(new_type->name);
+ new_type->name = ckstrdup(name);
+ Tcl_SetHashValue(hPtr, new_type);
+ } else {
+ Type *t = Tcl_GetHashValue(hPtr);
+ unless (L_typeck_same(decl->type, t)) {
+ L_errf(decl, "Cannot redefine type %s", name);
+ }
+ }
+}
+
+void
+hash_put(Tcl_Obj *hash, char *key, char *val)
+{
+ Tcl_Obj *keyObj, *valObj;
+
+ ASSERT(hash && key);
+ keyObj = Tcl_NewStringObj(key, -1);
+ Tcl_IncrRefCount(keyObj);
+ if (val) {
+ valObj = Tcl_NewStringObj(val, -1);
+ } else {
+ valObj = *L_undefObjPtrPtr();
+ }
+ Tcl_DictObjPut(L->interp, hash, keyObj, valObj);
+ Tcl_DecrRefCount(keyObj);
+}
+
+void
+hash_rm(Tcl_Obj *hash, char *key)
+{
+ Tcl_Obj *keyObj;
+
+ ASSERT(hash && key);
+ keyObj = Tcl_NewStringObj(key, -1);
+ Tcl_IncrRefCount(keyObj);
+ Tcl_DictObjRemove(L->interp, hash, keyObj);
+ Tcl_DecrRefCount(keyObj);
+}
+
+char *
+hash_get(Tcl_Obj *hash, char *key)
+{
+ int ret;
+ Tcl_Obj *keyObj = Tcl_NewStringObj(key, -1);
+ Tcl_Obj *valObj;
+
+ ASSERT(hash);
+ Tcl_IncrRefCount(keyObj);
+ ret = Tcl_DictObjGet(L->interp, hash, keyObj, &valObj);
+ unless (ret == TCL_OK) return (NULL);
+ Tcl_DecrRefCount(keyObj);
+ if (valObj) {
+ return (Tcl_GetString(valObj));
+ } else {
+ return (NULL);
+ }
+}
+
+/* For debugging. */
+void
+hash_dump(Tcl_Obj *hash)
+{
+ int done, ret;
+ Tcl_Obj *key, *val;
+ Tcl_DictSearch ctxt;
+
+ ret = Tcl_DictObjFirst(L->interp, hash, &ctxt, &key, &val, &done);
+ if ((ret != TCL_OK) || done) return;
+ do {
+ printf("%s -> %s\n", Tcl_GetString(key),
+ val->undef ? "<undef>" : Tcl_GetString(val));
+ Tcl_DictObjNext(&ctxt, &key, &val, &done);
+ } while (!done);
+}
+
+private char *
+basenm(char *s)
+{
+ char *t;
+
+ for (t = s; *t; t++);
+ do {
+ t--;
+ } while (*t != '/' && t > s);
+ if (*t == '/') t++;
+ return (t);
+}
+
+/*
+ * Return the dirname of a path. The caller must ckfree() it.
+ */
+char *
+L_dirname(char *path)
+{
+ Tcl_Obj *pathObj = Tcl_NewStringObj(path, -1);
+ Tcl_Obj *dirObj, *tmpObj;
+ char *ret = NULL;
+
+ Tcl_IncrRefCount(pathObj);
+ tmpObj = Tcl_FSGetNormalizedPath(NULL, pathObj);
+ if (tmpObj == NULL) goto err;
+ dirObj = TclPathPart(L->interp, tmpObj, TCL_PATH_DIRNAME);
+ if (dirObj == NULL) goto err;
+ ret = ckstrdup(Tcl_GetString(dirObj));
+ Tcl_DecrRefCount(dirObj);
+ err: Tcl_DecrRefCount(pathObj);
+ return (ret);
+}
+
+/*
+ * This function executes the INST_L_SPLIT bytecode and is based on
+ * pieces from tclCmdMZ.c.
+ *
+ * For edge cases, some of Perl's "split" semantics are obeyed:
+ *
+ * - A limit <= 0 means no limit.
+ *
+ * - Trailing null fields in the result are always suppressed.
+ *
+ * - If there is no delim, split on white space and trim any leading
+ * null fields from the result.
+ *
+ * - If the delim is /regexp/t, trim any leading null fields.
+ *
+ * - If all result fields are null, they are considered to be trailing
+ * and are all suppressed.
+ */
+Tcl_Obj *
+L_split(Tcl_Interp *interp, Tcl_Obj *strobj, Tcl_Obj *delimobj,
+ Tcl_Obj *limobj, Expr_f flags)
+{
+ int chlen, i, leading, len, lim, matches, nocase, off, ret;
+ int trim = (flags & L_EXPR_RE_T);
+ int start = 0, end = 0;
+ Tcl_RegExp regExpr = NULL;
+ Tcl_RegExpInfo info;
+ Tcl_Obj **elems, *resultPtr, *objPtr, *listPtr;
+ Tcl_UniChar ch;
+ char *str;
+
+ if (limobj) {
+ Tcl_GetIntFromObj(interp, limobj, &lim);
+ if (lim <= 0) {
+ lim = INT_MAX;
+ } else {
+ /* The lim is the max # fields to return,
+ * which is one less than the max # matches to
+ * allow. */
+ --lim;
+ }
+ } else {
+ lim = INT_MAX;
+ }
+
+ /*
+ * Make sure to avoid problems where the objects are shared. This can
+ * cause RegExpObj <> UnicodeObj shimmering that causes data corruption.
+ * [Bug #461322]
+ */
+ if (strobj == delimobj) {
+ objPtr = Tcl_DuplicateObj(strobj);
+ } else {
+ objPtr = strobj;
+ }
+ if (objPtr->typePtr == &tclByteArrayType) {
+ str = (char *)Tcl_GetByteArrayFromObj(objPtr, &len);
+ } else {
+ str = Tcl_GetStringFromObj(objPtr, &len);
+ }
+
+ listPtr = Tcl_NewObj();
+ matches = 0;
+ leading = 1;
+ off = 0;
+
+ /*
+ * Split on white space if no delim was specified.
+ */
+ unless (delimobj) {
+ int skip = 0;
+ for (start = 0; (off < len) && (matches < lim); off += chlen) {
+ chlen = TclUtfToUniChar(str+off, &ch);
+ if (skip) {
+ unless (Tcl_UniCharIsSpace(ch)) {
+ start = off;
+ skip = 0;
+ ++matches;
+ }
+ } else {
+ if (Tcl_UniCharIsSpace(ch)) {
+ /* Suppress leading null field
+ * in result. */
+ if (off || start) {
+ resultPtr = Tcl_NewStringObj(
+ str+start,
+ off-start);
+ Tcl_ListObjAppendElement(
+ NULL, listPtr,
+ resultPtr);
+ }
+ skip = 1;
+ }
+ }
+ }
+ unless (skip) {
+ resultPtr = Tcl_NewStringObj(str+start, len-start);
+ Tcl_ListObjAppendElement(NULL, listPtr, resultPtr);
+ }
+ goto done;
+ }
+
+ /*
+ * Split on a regular expression.
+ */
+ nocase = (flags & L_EXPR_RE_I) ? TCL_REG_NOCASE : 0;
+ regExpr = Tcl_GetRegExpFromObj(interp, delimobj,
+ TCL_REG_ADVANCED | TCL_REG_PCRE | nocase);
+ unless (regExpr) { // bad regexp
+ listPtr = NULL;
+ goto done;
+ }
+ while ((off < len) && (matches < lim)) {
+ int flags = TCL_REG_BYTEOFFSET;
+
+ if ((off > 0) && (str[off-1] != '\n')) flags |= TCL_REG_NOTBOL;
+ ret = Tcl_RegExpExecObj(interp, regExpr, objPtr, off, 1, flags);
+ if (ret < 0) goto done;
+ if (ret == 0) break;
+ Tcl_RegExpGetInfo(regExpr, &info);
+ start = info.matches[0].start;
+ end = info.matches[0].end;
+ matches++;
+
+ /*
+ * Copy to the result list the portion of the source
+ * string before the match. If we matched the empty
+ * string, split after the current char. Don't add
+ * leading null fields if specified.
+ */
+ if (leading && trim && (start == 0)) {
+ if (start == end) ++off;
+ off += end;
+ continue;
+ }
+ if (start == end) {
+ ASSERT(start == 0);
+ resultPtr = Tcl_NewStringObj(str+off, 1);
+ ++off;
+ } else {
+ resultPtr = Tcl_NewStringObj(str+off, start);
+ }
+ leading = 0;
+ Tcl_ListObjAppendElement(NULL, listPtr, resultPtr);
+ off += end;
+ }
+ /*
+ * Copy to the result list the portion of the source string after
+ * the last match, unless we matched the last char.
+ */
+ if (off < len) {
+ resultPtr = Tcl_NewStringObj(str+off, len-off);
+ Tcl_ListObjAppendElement(NULL, listPtr, resultPtr);
+ }
+
+ done:
+ if (objPtr && (strobj == delimobj)) {
+ Tcl_DecrRefCount(objPtr);
+ }
+ unless (listPtr) return (NULL);
+
+ /*
+ * Strip any trailing empty fields in the result. This is
+ * to be consistent with Perl's split semantics.
+ */
+ TclListObjGetElements(NULL, listPtr, &len, &elems);
+ for (i = len-1; i >= 0; --i) {
+ if (Tcl_GetCharLength(elems[i])) break;
+ Tcl_ListObjReplace(interp, listPtr, i, 1, 0, NULL);
+ }
+ return (listPtr);
+}
+
+/*
+ * This command splits the given arguments according to bash-style
+ * quoting, returning a string[] array.
+ *
+ * xyz -- all escapes are processed except \<newline> ignored
+ * 'xyz' -- no single quotes allowed inside, no escapes processed
+ * "xyz" -- only \\ and \" are processed, \<newline> ignored
+ */
+int
+Tcl_ShSplitObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ char *cmd;
+ int i, j, len;
+ Tcl_Obj *arg = NULL, *argv;
+ enum { LOOKING, ARG, SINGLE, DOUBLE } state;
+
+ unless (objc >= 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "string ?string ...?");
+ return (TCL_ERROR);
+ }
+ argv = Tcl_NewObj();
+ for (i = 1; i < objc; ++i) {
+ cmd = TclGetStringFromObj(objv[i], &len);
+ state = LOOKING;
+ for (j = 0; j < len; ++j) {
+ char c = cmd[j];
+ switch (state) {
+ case LOOKING:
+ if (isspace(c)) {
+ continue;
+ } else {
+ arg = Tcl_NewObj();
+ state = ARG;
+ /*FALLTHRU*/
+ }
+ case ARG:
+ if (isspace(c)) {
+ Tcl_ListObjAppendElement(interp,
+ argv, arg);
+ state = LOOKING;
+ } else if (c == '\\') {
+ char e = 0;
+ if ((j+1) < len) e = cmd[j+1];
+ // escape anything but ignore \<newline>
+ if (!e) {
+ Tcl_AppendResult(interp,
+ "trailing \\",
+ NULL);
+ return (TCL_ERROR);
+ } else if (e == '\n') {
+ ++j;
+ } else {
+ Tcl_AppendToObj(arg, &e, 1);
+ ++j;
+ }
+ } else if (c == '\'') {
+ state = SINGLE;
+ } else if (c == '"') {
+ state = DOUBLE;
+ } else {
+ Tcl_AppendToObj(arg, &c, 1);
+ }
+ break;
+ case SINGLE:
+ if (c == '\'') {
+ state = ARG;
+ } else {
+ Tcl_AppendToObj(arg, &c, 1);
+ }
+ break;
+ case DOUBLE:
+ if (c == '\\') {
+ char e = 0;
+ if ((j+1) < len) e = cmd[j+1];
+ // escape \ and " but ignore \<newline>
+ if ((e == '\\') || (e == '"')) {
+ Tcl_AppendToObj(arg, &e, 1);
+ ++j;
+ } else if (e == '\n') {
+ ++j;
+ } else {
+ Tcl_AppendToObj(arg, &c, 1);
+ }
+ } else if (c == '"') {
+ state = ARG;
+ } else {
+ Tcl_AppendToObj(arg, &c, 1);
+ }
+ break;
+ }
+ }
+ switch (state) {
+ case LOOKING:
+ break;
+ case ARG:
+ Tcl_ListObjAppendElement(interp, argv, arg);
+ break;
+ case SINGLE:
+ Tcl_AppendResult(interp, "unterminated \'", NULL);
+ return (TCL_ERROR);
+ case DOUBLE:
+ Tcl_AppendResult(interp, "unterminated \"", NULL);
+ return (TCL_ERROR);
+ }
+ }
+ Tcl_SetObjResult(interp, argv);
+ return (TCL_OK);
+}
+
+int
+Tcl_GetOptObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int ac, i, n, ret = TCL_OK;
+ char **av, *opts, *s;
+ longopt *lopts = NULL;
+ Tcl_Obj **objs;
+
+ /*
+ * This is all about converting the L args to C args for the
+ * getopt() call and then mapping back for the return value.
+ */
+
+ unless (objc == 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "av opts lopts");
+ return (TCL_ERROR);
+ }
+
+ /* Set the C optind variable from its L counterpart. */
+ s = (char *)Tcl_GetVar(interp, "optind", TCL_GLOBAL_ONLY);
+ if (s) optind = atoi(s);
+
+ if (Tcl_ListObjGetElements(interp, objv[1], &ac, &objs) != TCL_OK) {
+ return (TCL_ERROR);
+ }
+ av = (char **)ckalloc(ac * sizeof(char *));
+ for (i = 0; i < ac; ++i) {
+ av[i] = TclGetString(objs[i]);
+ }
+ opts = (objv[2]->undef ? "" : TclGetString(objv[2]));
+ /*
+ * For long opts, the C API wants an array of <char*,int>, and
+ * the L call sent in a string array, so map the long opt name to
+ * its L array index + 300 (values <= 256 are reserved for the
+ * short opts and GETOPT_ERR).
+ */
+ if (Tcl_ListObjGetElements(interp, objv[3], &n, &objs) != TCL_OK) {
+ ret = TCL_ERROR;
+ goto done;
+ }
+ if (n) {
+ lopts = (longopt *)ckalloc((n+1) * sizeof(longopt));
+ for (i = 0; i < n; ++i) {
+ lopts[i].name = TclGetString(objs[i]);
+ lopts[i].ret = 300 + i;
+ }
+ lopts[i].name = NULL;
+ }
+ i = getopt(ac, av, opts, lopts);
+ switch (i) {
+ case GETOPT_EOF:
+ Tcl_SetObjResult(interp, *L_undefObjPtrPtr());
+ break;
+ case GETOPT_ERR:
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("", 0));
+ break;
+ default:
+ if (i < 300) {
+ // short opt
+ char str[1];
+ str[0] = i;
+ Tcl_SetObjResult(interp, Tcl_NewStringObj(str, 1));
+ } else {
+ // long opt -- map back to the longopts array entry
+ // and strip any trailing :;|
+ s = TclGetStringFromObj(objs[i-300], &n);
+ if ((s[n-1] == ':') || (s[n-1] == ';') ||
+ (s[n-1] == '|')) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj(s,n-1));
+ } else {
+ Tcl_SetObjResult(interp, objs[i-300]);
+ }
+ }
+ break;
+ }
+ /* Set the optind, optopt, and optarg globals from the C variables. */
+ s = cksprintf("%d", optind);
+ Tcl_SetVar(interp, "optind", s, TCL_GLOBAL_ONLY);
+ ckfree(s);
+ s = cksprintf("%c", optopt);
+ Tcl_SetVar(interp, "optopt", s, TCL_GLOBAL_ONLY);
+ ckfree(s);
+ if (optarg) {
+ Tcl_SetVar(interp, "optarg", optarg, TCL_GLOBAL_ONLY);
+ } else {
+ Tcl_SetVar2Ex(interp, "optarg", NULL, *L_undefObjPtrPtr(),
+ TCL_GLOBAL_ONLY);
+ }
+ done:
+ ckfree((char *)av);
+ ckfree((char *)lopts);
+ return (ret);
+}
+
+int
+Tcl_GetOptResetObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ unless (objc == 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ getoptReset();
+ Tcl_SetVar(interp, "optind", "0", TCL_GLOBAL_ONLY);
+ Tcl_SetVar(interp, "optopt", "", TCL_GLOBAL_ONLY);
+ Tcl_SetVar2Ex(interp, "optarg", NULL, *L_undefObjPtrPtr(),
+ TCL_GLOBAL_ONLY);
+ return (TCL_OK);
+}
+
+/*
+ * Parts of the next two functions are taken from Tcl_GetsObjCmd().
+ * do_getline() is like Tcl_GetsObjCmd() except that it results in
+ * undef on error or EOF, and it returns the result object so you
+ * don't have to pull it out of the interp to see what happened.
+ */
+
+private Tcl_Obj *
+do_getline(Tcl_Interp *interp, Tcl_Channel chan)
+{
+ Tcl_Obj *ret;
+
+ ret = Tcl_NewObj();
+ if (Tcl_GetsObj(chan, ret) < 0) {
+ Tcl_DecrRefCount(ret);
+ if (!Tcl_Eof(chan) && !Tcl_InputBlocked(chan)) {
+ /*
+ * TIP #219. Capture error messages put by the
+ * driver into the bypass area and put them
+ * into the regular interpreter result. Fall
+ * back to the regular message if nothing was
+ * found in the bypass.
+ */
+ if (!TclChanCaughtErrorBypass(interp, chan)) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, Tcl_PosixError(interp),
+ NULL);
+ }
+ Tcl_SetVar2Ex(interp, "::stdio_lasterr", NULL,
+ Tcl_GetObjResult(interp),
+ TCL_GLOBAL_ONLY);
+ return (NULL);
+ }
+ ret = *L_undefObjPtrPtr();
+ }
+ Tcl_SetObjResult(interp, ret);
+ return (ret);
+}
+
+int
+Tcl_FGetlineObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int mode;
+ Tcl_Channel chan;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "channelId");
+ return (TCL_ERROR);
+ }
+ if (TclGetChannelFromObj(interp, objv[1], &chan,
+ &mode, 0) != TCL_OK) {
+ goto err;
+ }
+ unless (mode & TCL_READABLE) {
+ Tcl_AppendResult(interp, "channel \"", TclGetString(objv[1]),
+ "\" wasn't opened for reading", NULL);
+ goto err;
+ }
+ unless (do_getline(interp, chan)) {
+ goto err;
+ }
+ return (TCL_OK);
+ err:
+ Tcl_SetVar2Ex(interp, "::stdio_lasterr", NULL,
+ Tcl_GetObjResult(interp),
+ TCL_GLOBAL_ONLY);
+ Tcl_SetObjResult(interp, *L_undefObjPtrPtr());
+ return (TCL_OK);
+}
+
+int
+Tcl_LAngleReadObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ Tcl_Obj *ret = NULL;
+ int argc, res;
+ Tcl_Obj **argv;
+ static int cur = 0;
+ static Tcl_Channel chan = NULL;
+
+ if (objc != 1) {
+ Tcl_WrongNumArgs(interp, 1, objv, NULL);
+ return (TCL_ERROR);
+ }
+ unless (L->global->script_argc) {
+ Tcl_Obj *objv[2];
+
+ objv[0] = Tcl_NewStringObj("angle_read_", -1);
+ objv[1] = Tcl_NewStringObj("stdin", -1);
+ res = Tcl_FGetlineObjCmd(dummy, interp, 2, objv);
+ Tcl_DecrRefCount(objv[0]);
+ Tcl_DecrRefCount(objv[1]);
+ return (res);
+ }
+ Tcl_ListObjGetElements(L->interp, L->global->script_argv, &argc, &argv);
+ while (1) {
+ if (chan) {
+ ret = do_getline(interp, chan);
+ if (ret && !ret->undef) break;
+ Tcl_UnregisterChannel(interp, chan);
+ chan = NULL;
+ }
+ if (cur >= argc) {
+ Tcl_SetObjResult(interp, *L_undefObjPtrPtr());
+ break;
+ }
+ chan = Tcl_FSOpenFileChannel(interp, argv[cur++], "r", 0);
+ if (chan) {
+ Tcl_RegisterChannel(interp, chan);
+ } else {
+ fprintf(stderr, "%s\n", Tcl_GetStringResult(interp));
+ Tcl_ResetResult(interp);
+ }
+ }
+ return (TCL_OK);
+}
+
+extern int Tcl_WriteObjN(Tcl_Channel chan, Tcl_Obj *objPtr, int numBytes);
+
+int
+Tcl_LWriteCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int mode, nbytes;
+ char *errmsg = "";
+ Tcl_Channel chan;
+
+ if (objc != 4) {
+ Tcl_WrongNumArgs(interp, 1, objv, "channel buffer numBytes");
+ return (TCL_ERROR);
+ }
+ if (TclGetChannelFromObj(interp, objv[1], &chan, &mode, 0) != TCL_OK) {
+ return (TCL_ERROR);
+ }
+ if (!(mode & TCL_WRITABLE)) {
+ errmsg = "channel wasn't opened for writing";
+ goto err;
+ }
+ if (Tcl_GetIntFromObj(interp, objv[3], &nbytes) != TCL_OK) {
+ return (TCL_ERROR);
+ }
+ nbytes = Tcl_WriteObjN(chan, objv[2], nbytes);
+ if (nbytes < 0) {
+ if (!TclChanCaughtErrorBypass(interp, chan)) {
+ errmsg = (char *)Tcl_PosixError(interp);
+ }
+ goto err;
+ }
+ out:
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+ return (TCL_OK);
+ err:
+ Tcl_SetVar2(interp, "::stdio_lasterr", NULL, errmsg, TCL_GLOBAL_ONLY);
+ nbytes = -1;
+ goto out;
+}
+
+int
+Tcl_LReadCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int mode, nbytes = -1;
+ char *errmsg = "";
+ Tcl_Channel chan;
+ Tcl_Obj *buf;
+
+ if ((objc != 4) && (objc != 3)) {
+ Tcl_WrongNumArgs(interp, 1, objv, "channel varName ?numBytes");
+ return (TCL_ERROR);
+ }
+ if (TclGetChannelFromObj(interp, objv[1], &chan, &mode, 0) != TCL_OK) {
+ return (TCL_ERROR);
+ }
+ if (!(mode & TCL_READABLE)) {
+ errmsg = "channel wasn't opened for reading";
+ goto err;
+ }
+ if (Tcl_Eof(chan)) {
+ errmsg = "end of file";
+ goto err;
+ }
+ if (objc == 4) {
+ if (Tcl_GetIntFromObj(interp, objv[3], &nbytes) != TCL_OK) {
+ return (TCL_ERROR);
+ }
+ }
+ buf = Tcl_NewObj();
+ Tcl_IncrRefCount(buf);
+ nbytes = Tcl_ReadChars(chan, buf, nbytes, 0);
+ if (nbytes < 0) {
+ if (!TclChanCaughtErrorBypass(interp, chan)) {
+ errmsg = (char *)Tcl_PosixError(interp);
+ }
+ Tcl_DecrRefCount(buf);
+ goto err;
+ }
+ Tcl_ObjSetVar2(interp, objv[2], NULL, buf, TCL_LEAVE_ERR_MSG);
+ Tcl_DecrRefCount(buf);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(nbytes));
+ return (TCL_OK);
+ err:
+ Tcl_SetVar(interp, "::stdio_lasterr", errmsg, TCL_GLOBAL_ONLY);
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(-1));
+ return (TCL_OK);
+}
+
+int
+Tcl_LRefCnt(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "object");
+ return (TCL_ERROR);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(objv[1]->refCount));
+ return (TCL_OK);
+}
+
+/*
+ * This defines a defined() proc even though it also is a compiler
+ * built-in. When L code uses defined(), it gets the built-in.
+ * Having the proc allows access to this functionality from Tcl code.
+ */
+int
+Tcl_LDefined(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "object");
+ return (TCL_ERROR);
+ }
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(objv[1]->undef ? 0 : 1));
+ return (TCL_OK);
+}
+
+/*
+ * This evaluates an Lhtml document. All input is passed through
+ * to Tcl's stdout channel with two kinds of interpolation:
+ *
+ * - Anything between <? and ?> is taken to be L statements
+ * and is replaced by whatever that L code outputs.
+ *
+ * - Anything between <?= and ?> is taken to be an L expression and is
+ * replaced by whatever it evaluates to (this is just like regular L
+ * string interpolation).
+ *
+ * This works by putting the scanner into an Lhtml mode where
+ * <?, <?=, and ?> are recognized. The parser contains rules for
+ * wrapping the html in puts() calls.
+ */
+int
+Tcl_LHtmlObjCmd(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int ret;
+
+ L_lex_begLhtml();
+ ret = Tcl_LObjCmd(NULL, interp, objc, objv);
+ L_lex_endLhtml();
+ return (ret);
+}
+
+/*
+ * A Tcl_Obj type to store a pointer into a string buffer that we can
+ * walk down over time. The twpPtrValue internalrep is used, with the
+ * first ptr pointing to a ckalloc'd Bufptr struct (defined below) and
+ * the second ptr pointing to a copy of the buffer.
+ */
+static Tcl_ObjType L_bufPtrType = {
+ "l-bufPtrType",
+ NULL, /* freeIntRepProc */
+ NULL, /* dupIntRepProc */
+ NULL, /* updateStringProc */
+ NULL /* setFromAnyProc */
+};
+typedef struct {
+ char *p;
+ char *end;
+} Bufptr;
+
+int
+Tcl_LGetNextLineInit(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int len;
+ char *beg, *s;
+ Tcl_Obj *tmp;
+ Bufptr *bufptr;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "object");
+ return (TCL_ERROR);
+ }
+ if (objv[1]->undef) {
+ Tcl_SetObjResult(interp, *L_undefObjPtrPtr());
+ return (TCL_OK);
+ }
+
+ /*
+ * Make a copy of the string whose lines we will walk. Do
+ * this instead of copying the Tcl_Obj to avoid problems with
+ * possible shimmering (i.e., the Tcl_Obj's string-rep buffer is
+ * not guaranteed to remain).
+ */
+ s = Tcl_GetStringFromObj(objv[1], &len);
+ beg = ckalloc(len + 1);
+ memcpy(beg, s, len);
+ beg[len] = '\0';
+
+ /*
+ * Stash the copied string and a Bufptr into it inside of a
+ * tmp Tcl_Obj that will live for the duration of the walk.
+ * Tcl_LGetNextLine() will process it.
+ */
+ tmp = Tcl_NewObj();
+ tmp->typePtr = &L_bufPtrType;
+ bufptr = (Bufptr *)ckalloc(sizeof(Bufptr));
+ bufptr->p = beg;
+ bufptr->end = beg + len;
+ tmp->internalRep.twoPtrValue.ptr1 = bufptr;
+ tmp->internalRep.twoPtrValue.ptr2 = beg;
+
+ Tcl_SetObjResult(interp, tmp);
+ return (TCL_OK);
+}
+
+int
+Tcl_LGetNextLine(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ Tcl_Obj *ret, *tmp;
+ char *beg, *p;
+ Bufptr *bufptr;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "tmp");
+ return (TCL_ERROR);
+ }
+ tmp = objv[1];
+ if (tmp->undef) goto nomore;
+ unless (tmp->typePtr == &L_bufPtrType) {
+ Tcl_SetObjResult(interp,
+ Tcl_NewStringObj("invalid tmp object", -1));
+ return (TCL_ERROR);
+ }
+ bufptr = (Bufptr *)tmp->internalRep.twoPtrValue.ptr1;
+ unless (bufptr) goto nomore;
+
+ beg = bufptr->p;
+ if (beg >= bufptr->end) goto nomore;
+
+ for (p = beg; p < bufptr->end; ++p) {
+ if (p[0] == '\n') {
+ bufptr->p = p + 1;
+ break;
+ }
+ if (((p+1) < bufptr->end) && (p[0] == '\r') && (p[1] == '\n')) {
+ bufptr->p = p + 2;
+ break;
+ }
+ }
+ ret = Tcl_NewStringObj(beg, p - beg);
+ if (p == bufptr->end) {
+ ckfree(tmp->internalRep.twoPtrValue.ptr2);
+ ckfree((char *)bufptr);
+ tmp->internalRep.twoPtrValue.ptr1 = NULL;
+ tmp->internalRep.twoPtrValue.ptr2 = NULL;
+ }
+ Tcl_SetObjResult(interp, ret);
+ return (TCL_OK);
+ nomore:
+ Tcl_SetObjResult(interp, *L_undefObjPtrPtr());
+ return (TCL_OK);
+}
+
+#ifdef _WIN32
+
+int
+Tcl_LGetDirX(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int len, ret;
+ Tcl_Obj *argv[2], *dirObjs, *eltObjs[3], *fileObjs, *listObj;
+ char *buf, *dir, *type, *utfname;
+ Tcl_DString ds;
+ HANDLE hFind;
+ WIN32_FIND_DATA f;
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "directory");
+ return (TCL_ERROR);
+ }
+
+ // Append \* to the given directory path.
+ dir = cksprintf("%s\\*", Tcl_GetString(objv[1]));
+ Tcl_WinUtfToTChar(dir, -1, &ds);
+
+ hFind = FindFirstFile((TCHAR *)Tcl_DStringValue(&ds), &f);
+ if (hFind == INVALID_HANDLE_VALUE) {
+ TclWinConvertError(GetLastError());
+ FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError(),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (char *)&buf,
+ 0, NULL);
+ // Chomp the cr,lf that windows added to buf.
+ len = strlen(buf);
+ if (len > 2) buf[len-2] = 0;
+ Tcl_SetVar(interp, "::stdio_lasterr",
+ buf,
+ TCL_GLOBAL_ONLY);
+ Tcl_SetObjResult(interp, *L_undefObjPtrPtr());
+ LocalFree(buf);
+ return (TCL_OK);
+ }
+ ckfree(dir);
+ Tcl_DStringFree(&ds);
+
+ fileObjs = Tcl_NewListObj(0, NULL);
+ dirObjs = Tcl_NewListObj(0, NULL);
+ do {
+ utfname = Tcl_WinTCharToUtf(f.cFileName, -1, &ds);
+ eltObjs[0] = Tcl_NewStringObj(utfname, -1);
+ if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ type = "directory";
+ } else {
+ type = "file";
+ }
+ eltObjs[1] = Tcl_NewStringObj(type, -1);
+ if ((f.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) ||
+ (*utfname == '.')) {
+ eltObjs[2] = Tcl_NewIntObj(1);
+ } else {
+ eltObjs[2] = Tcl_NewIntObj(0);
+ }
+ listObj = Tcl_NewListObj(3, eltObjs);
+ if (f.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
+ Tcl_ListObjAppendElement(interp, dirObjs, listObj);
+ } else {
+ Tcl_ListObjAppendElement(interp, fileObjs, listObj);
+ }
+ Tcl_DStringFree(&ds);
+ } while (FindNextFile(hFind, &f));
+ FindClose(hFind);
+
+ // Sort the lists.
+ argv[1] = dirObjs;
+ Tcl_IncrRefCount(dirObjs);
+ Tcl_ResetResult(interp);
+ ret = Tcl_LsortObjCmd(NULL, interp, 2, argv);
+ Tcl_DecrRefCount(dirObjs);
+ if (ret == TCL_OK) {
+ dirObjs = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
+ }
+
+ argv[1] = fileObjs;
+ Tcl_IncrRefCount(fileObjs);
+ Tcl_ResetResult(interp);
+ ret = Tcl_LsortObjCmd(NULL, interp, 2, argv);
+ Tcl_DecrRefCount(fileObjs);
+ if (ret == TCL_OK) {
+ fileObjs = Tcl_GetObjResult(interp);
+ }
+
+ // Return a list with the file names after all the dir names.
+ Tcl_ListObjAppendList(interp, dirObjs, fileObjs);
+ Tcl_SetObjResult(interp, dirObjs);
+ return (TCL_OK);
+}
+
+#else // #ifdef WIN32
+
+int
+Tcl_LGetDirX(
+ ClientData dummy, /* Not used. */
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *const objv[]) /* Argument objects. */
+{
+ int ret;
+ Tcl_Obj *argv[2], *dirObjs, *eltObjs[3], *fileObjs, *listObj;
+ DIR *d;
+ struct dirent *dent;
+ char *dir, *type;
+#ifndef HAVE_STRUCT_DIRENT_D_TYPE
+ char *path;
+ struct stat st;
+#endif
+
+ if (objc != 2) {
+ Tcl_WrongNumArgs(interp, 1, objv, "directory");
+ return (TCL_ERROR);
+ }
+
+ dir = Tcl_GetString(objv[1]);
+ d = opendir(dir);
+ unless (d) {
+ Tcl_SetVar(interp, "::stdio_lasterr",
+ strerror(errno),
+ TCL_GLOBAL_ONLY);
+ Tcl_SetObjResult(interp, *L_undefObjPtrPtr());
+ return (TCL_OK);
+ }
+
+ fileObjs = Tcl_NewListObj(0, NULL);
+ dirObjs = Tcl_NewListObj(0, NULL);
+ while (dent = readdir(d)) {
+ eltObjs[0] = Tcl_NewStringObj(dent->d_name, -1);
+#ifdef HAVE_STRUCT_DIRENT_D_TYPE
+ switch (dent->d_type) {
+ case DT_REG: type = "file"; break;
+ case DT_DIR: type = "directory"; break;
+ default: type = "other"; break;
+ }
+#else
+ path = cksprintf("%s/%s", dir, dent->d_name);
+ if (stat(path, &st)) {
+ type = "unknown";
+ } else if (S_ISREG(st.st_mode)) {
+ type = "file";
+ } else if (S_ISDIR(st.st_mode)) {
+ type = "directory";
+ } else {
+ type = "other";
+ }
+ ckfree(path);
+#endif
+ eltObjs[1] = Tcl_NewStringObj(type, -1);
+ if (*dent->d_name == '.') {
+ eltObjs[2] = Tcl_NewIntObj(1);
+ } else {
+ eltObjs[2] = Tcl_NewIntObj(0);
+ }
+ listObj = Tcl_NewListObj(3, eltObjs);
+ if (*type == 'd') {
+ Tcl_ListObjAppendElement(interp, dirObjs, listObj);
+ } else {
+ Tcl_ListObjAppendElement(interp, fileObjs, listObj);
+ }
+ }
+ closedir(d);
+
+ // Sort the lists.
+ argv[1] = dirObjs;
+ Tcl_IncrRefCount(dirObjs);
+ Tcl_ResetResult(interp);
+ ret = Tcl_LsortObjCmd(NULL, interp, 2, argv);
+ Tcl_DecrRefCount(dirObjs);
+ if (ret == TCL_OK) {
+ dirObjs = Tcl_DuplicateObj(Tcl_GetObjResult(interp));
+ }
+
+ argv[1] = fileObjs;
+ Tcl_IncrRefCount(fileObjs);
+ Tcl_ResetResult(interp);
+ ret = Tcl_LsortObjCmd(NULL, interp, 2, argv);
+ Tcl_DecrRefCount(fileObjs);
+ if (ret == TCL_OK) {
+ fileObjs = Tcl_GetObjResult(interp);
+ }
+
+ // Return a list with the file names after all the dir names.
+ Tcl_ListObjAppendList(interp, dirObjs, fileObjs);
+ Tcl_SetObjResult(interp, dirObjs);
+ return (TCL_OK);
+}
+
+#endif // #ifdef WIN32
diff --git a/generic/Lcompile.h b/generic/Lcompile.h
new file mode 100644
index 0000000..8d0b422
--- /dev/null
+++ b/generic/Lcompile.h
@@ -0,0 +1,606 @@
+/*
+ * Copyright (c) 2006-2008 BitMover, Inc.
+ */
+#ifndef L_COMPILE_H
+#define L_COMPILE_H
+
+#include <setjmp.h>
+#include "tclInt.h"
+#include "tclCompile.h"
+#include "Last.h"
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+/* For jump fix-ups. */
+typedef struct Jmp Jmp;
+struct Jmp {
+ int op; // jmp instruction bytecode (e.g., INST_JUMP1)
+ int size; // size of jmp instruction (1 or 4 bytes)
+ int offset; // bytecode offset of jmp instruction
+ Jmp *next;
+};
+
+/* Semantic stack frame. */
+typedef enum {
+ OUTER = 0x0001, // is outer-most
+ SCRIPT = 0x0002, // is file scope
+ TOPLEV = 0x0004, // is for file top-levels
+ CLS_OUTER = 0x0008, // is class outer-most
+ CLS_TOPLEV = 0x0010, // is for class top-levels
+ FUNC = 0x0020, // frame is at top level of a proc
+ LOOP = 0x0040, // frame is for a loop
+ SWITCH = 0x0080, // frame is for a switch stmt
+ SKIP = 0x0100, // skip frame when searching enclosing scopes
+ SEARCH = 0x0200, // don't skip this frame
+ KEEPSYMS = 0x0400, // don't free symtab when scope is closed
+} Frame_f;
+typedef enum {
+ LABEL_USE = 0x01, // label is being referenced
+ LABEL_DEF = 0x02, // label is being defined
+} Label_f;
+typedef struct Label {
+ char *name;
+ int offset;
+ Jmp *fixups;
+} Label;
+typedef struct Frame {
+ CompileEnv *envPtr;
+ CompileEnv *bodyEnvPtr;
+ CompileEnv *prologueEnvPtr;
+ Proc *proc;
+ char *name;
+ Tcl_HashTable *symtab;
+ Tcl_HashTable *labeltab;
+ ClsDecl *clsdecl;
+ Frame_f flags;
+ // When a compile frame corresponds to a block in the code, we
+ // store the AST node of the block here.
+ Ast *block;
+ // We collect jump fix-ups for all of the jumps emitted for break and
+ // continue statements, so that we can stuff in the correct jump targets
+ // once we're done compiling the loops.
+ Jmp *continue_jumps;
+ Jmp *break_jumps;
+ // Jump fix-up for the jump to the prologue code at the end of a proc,
+ // and the bytecode offset for the jump back.
+ Jmp *end_jmp;
+ int proc_top;
+ // Fix-ups for return stmts which all jmp to the end.
+ Jmp *ret_jmps;
+ // List of temps allocated in this frame.
+ Tmp *tmps;
+ struct Frame *prevFrame;
+} Frame;
+
+/* Per-scope tables. Scopes are opened and close at parse time. */
+typedef struct scope Scope;
+struct scope {
+ Tcl_HashTable *structs;
+ Tcl_HashTable *typedefs;
+ Scope *prev;
+};
+
+/*
+ * Global L state. There is only one of these, reachable via L->global.
+ * The general L command line is
+ * tclsh [-tclsh_opt1] ... [-tclsh_optn] script_name [-script_opt1] ... [-script_optm]
+ */
+typedef struct {
+ int tclsh_argc;
+ Tcl_Obj *tclsh_argv;
+ int script_argc;
+ Tcl_Obj *script_argv;
+ int forceL; // wrap input in #lang L directive
+} Lglobal;
+
+/*
+ * Per-interp L state. When an interp is created, one of these is
+ * allocated for each interp and associated with the interp. Whenever
+ * the compiler is entered, it is extracted from the interp.
+ */
+typedef struct {
+ Lglobal *global; // L global state
+ Frame *frame; // current semantic stack frame
+ Scope *curr_scope;
+ Ast *ast_list; // list of all AST nodes
+ Type *type_list; // list of all type descriptors
+ void *ast; // ptr to AST root, set by parser
+ Tcl_Obj *errs;
+ int err; // =1 if there was any compile error
+ char *dir; // absolute path to dir containing L->file
+ char *file;
+ int line;
+ int prev_token_len;
+ int token_off; // offset of curr token from start of input
+ int prev_token_off; // offset of prev token from start of input
+ Tcl_Obj *script; // src of script being compiled
+ int script_len;
+ Tcl_Obj *options; // hash of command-line options
+ FnDecl *enclosing_func;
+ Frame *enclosing_func_frame;
+ Ast *mains_ast; // root of AST when main() last seen
+ Tcl_HashTable *include_table;
+ Tcl_Interp *interp;
+ Op_k idx_op; // kind of enclosing index (. -> [] {})
+ int tmpnum; // for creating tmp variables
+ char *toplev; // name of toplevel proc
+ jmp_buf jmp; // for syntax error longjmp bail out
+ int expr_level; // compile_expr() recursion depth
+ int call_level; // compile_expr() level of last fn call
+ Tcl_Obj *fn_calls; // list of all fn calls compiled
+ Tcl_Obj *fn_decls; // hash of all L fns
+} Linterp;
+
+/*
+ * Symbol table entry, for variables and functions (typedef and struct
+ * names have their own tables). The tclname can be different from
+ * the L name if we have to mangle the name as we do for L globals.
+ * The decl pointer is used to get line# info for error messages.
+ */
+typedef enum {
+ L_SYM_LVAR = 0x0001, // a local variable
+ L_SYM_GVAR = 0x0002, // a global variable
+ L_SYM_LSHADOW = 0x0004, // a global upvar shadow (these
+ // are also locals)
+ L_SYM_FN = 0x0008, // a function
+ L_SYM_FNBODY = 0x0010, // function body has been declared
+} Sym_k;
+struct Sym {
+ Sym_k kind;
+ char *name; // the L name
+ char *tclname; // the tcl name (can be same as L name)
+ Type *type;
+ int idx; // slot# for local var
+ int used_p; // TRUE iff var has been referenced
+ VarDecl *decl;
+};
+
+/*
+ * For our getopt. Note that this renders libc's getopt unusable,
+ * but the #define's are kept for compatibility with our getopt.
+ */
+
+#define getopt mygetopt
+#define optind myoptind
+#define optarg myoptarg
+#define optopt myoptopt
+
+extern int optind;
+extern int optopt;
+extern char *optarg;
+
+typedef struct {
+ char *name; /* name w args ex: "url:" */
+ int ret; /* return value from getopt */
+} longopt;
+
+#define GETOPT_EOF -1
+#define GETOPT_ERR 256
+
+extern char *cksprintf(const char *fmt, ...);
+extern char *ckstrdup(const char *str);
+extern char *ckstrndup(const char *str, int len);
+extern char *ckvsprintf(const char *fmt, va_list ap, int len);
+extern int getopt(int ac, char **av, char *opts, longopt *lopts);
+extern void getoptReset(void);
+extern void L_bomb(const char *format, ...);
+extern void L_compile_attributes(Tcl_Obj *hash, Expr *expr,
+ char *allowed[]);
+extern char *L_dirname(char *path);
+extern void L_err(const char *s, ...);
+extern void L_errf(void *node, const char *format, ...);
+extern int L_isUndef(Tcl_Obj *o);
+extern void L_lex_begLhtml();
+extern void L_lex_endLhtml();
+extern void L_lex_begReArg(int kind);
+extern void L_lex_start(void);
+extern int L_parse(void); // yyparse
+extern void L_scope_enter();
+extern void L_scope_leave();
+extern void L_set_baseType(Type *type, Type *base_type);
+extern void L_set_declBaseType(VarDecl *decl, Type *base_type);
+extern Tcl_Obj *L_split(Tcl_Interp *interp, Tcl_Obj *strobj,
+ Tcl_Obj *delimobj, Tcl_Obj *limobj, Expr_f flags);
+extern Type *L_struct_lookup(char *tag, int local);
+extern Type *L_struct_store(char *tag, VarDecl *members);
+extern void L_synerr(const char *s); // yyerror
+extern void L_synerr2(const char *s, int offset);
+extern void L_trace(const char *format, ...);
+extern char *L_type_str(Type_k kind);
+extern void L_typeck_init();
+extern int L_typeck_arrElt(Type *var, Type *array);
+extern void L_typeck_assign(Expr *lhs, Type *rhs);
+extern int L_typeck_compat(Type *lhs, Type *rhs);
+extern int L_typeck_declType(VarDecl *decl);
+extern void L_typeck_deny(Type_k deny, Expr *expr);
+extern void L_typeck_expect(Type_k want, Expr *expr, char *msg);
+extern void L_typeck_fncall(VarDecl *formals, Expr *call);
+extern void L_typeck_main(VarDecl *decl);
+extern int L_typeck_same(Type *a, Type *b);
+extern Type *L_typedef_lookup(char *name);
+extern void L_typedef_store(VarDecl *decl);
+extern Tcl_Obj **L_undefObjPtrPtr();
+extern void L_warnf(void *node, const char *format, ...);
+
+extern Linterp *L;
+extern char *L_attrs_attribute[];
+extern char *L_attrs_cmdLine[];
+extern char *L_attrs_pragma[];
+extern Tcl_ObjType L_undefType;
+extern Type *L_int;
+extern Type *L_float;
+extern Type *L_string;
+extern Type *L_void;
+extern Type *L_poly;
+extern Type *L_widget;
+
+static inline int
+istype(Expr *expr, int type_flags)
+{
+ return (expr->type && (expr->type->kind & type_flags));
+}
+static inline int
+isarray(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_ARRAY));
+}
+static inline int
+ishash(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_HASH));
+}
+static inline int
+isstruct(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_STRUCT));
+}
+static inline int
+isint(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_INT));
+}
+static inline int
+isfloat(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_FLOAT));
+}
+static inline int
+isstring(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_STRING));
+}
+static inline int
+iswidget(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_WIDGET));
+}
+static inline int
+isvoid(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_VOID));
+}
+static inline int
+ispoly(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_POLY));
+}
+static inline int
+isscalar(Expr *expr)
+{
+ return (expr->type && (expr->type->kind & (L_INT |
+ L_FLOAT |
+ L_STRING |
+ L_WIDGET |
+ L_POLY)));
+}
+static inline int
+isconst(Expr *expr)
+{
+ return (expr->kind == L_EXPR_CONST);
+}
+static inline int
+islist(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_LIST));
+}
+static inline int
+isclass(Expr *expr)
+{
+ return (expr->type && (expr->type->kind == L_CLASS));
+}
+static inline int
+isregexp(Expr *expr)
+{
+ return ((expr->kind == L_EXPR_RE) ||
+ ((expr->kind == L_EXPR_BINOP) && (expr->op == L_OP_INTERP_RE)));
+}
+static inline int
+ispolytype(Type *type)
+{
+ return (type->kind == L_POLY);
+}
+static inline int
+islisttype(Type *type)
+{
+ return (type->kind == L_LIST);
+}
+static inline int
+ishashtype(Type *type)
+{
+ return (type->kind == L_HASH);
+}
+static inline int
+isfntype(Type *type)
+{
+ return (type->kind == L_FUNCTION);
+}
+static inline int
+isinttype(Type *type)
+{
+ return (type->kind == L_INT);
+}
+static inline int
+isvoidtype(Type *type)
+{
+ return (type->kind == L_VOID);
+}
+static inline int
+isnameoftype(Type *type)
+{
+ return (type->kind == L_NAMEOF);
+}
+static inline int
+isclasstype(Type *type)
+{
+ return (type->kind == L_CLASS);
+}
+static inline int
+isarrayoftype(Type *type, Type_k kind)
+{
+ return ((type->kind == L_ARRAY) && (type->base_type->kind & kind));
+}
+static inline int
+ishashoftype(Type *type, Type_k base, Type_k elt)
+{
+ return ((type->kind == L_HASH) &&
+ (type->base_type->kind & base) &&
+ (type->u.hash.idx_type->kind & elt));
+}
+static inline int
+isaddrof(Expr *expr)
+{
+ return ((expr->kind == L_EXPR_UNOP) && (expr->op == L_OP_ADDROF));
+}
+static inline int
+isexpand(Expr *expr)
+{
+ return ((expr->kind == L_EXPR_UNOP) && (expr->op == L_OP_EXPAND));
+}
+static inline int
+iskv(Expr *expr)
+{
+ return ((expr->kind == L_EXPR_BINOP) && (expr->op == L_OP_KV));
+}
+static inline int
+isinterp(Expr *expr)
+{
+ return ((expr->kind == L_EXPR_BINOP) && (expr->op == L_OP_INTERP_STRING));
+}
+static inline int
+isid(Expr *expr, char *s)
+{
+ return ((expr->kind == L_EXPR_ID) && !strcmp(expr->str, s));
+}
+static inline int
+isarrayof(Expr *expr, Type_k kind)
+{
+ return (isarray(expr) && (expr->type->base_type->kind & kind));
+}
+/*
+ * Return the flags that match the kind of variable we can
+ * dereference: globals, locals, class variables, and class instance
+ * variables.
+ */
+static inline int
+canDeref(Sym *sym)
+{
+ return (sym->decl->flags & (DECL_GLOBAL_VAR | DECL_LOCAL_VAR |
+ DECL_FN | DECL_CLASS_INST_VAR |
+ DECL_CLASS_VAR));
+}
+/*
+ * This checks whether the Expr node is a deep-dive operation that has
+ * left a deep-ptr on the run-time stack.
+ */
+static inline int
+isdeepdive(Expr *expr)
+{
+ return (expr->flags & (L_PUSH_PTR | L_PUSH_PTRVAL | L_PUSH_VALPTR));
+}
+static inline int
+isClsConstructor(VarDecl *decl)
+{
+ return (decl->flags & DECL_CLASS_CONST);
+}
+static inline int
+isClsDestructor(VarDecl *decl)
+{
+ return (decl->flags & DECL_CLASS_DESTR);
+}
+static inline int
+isClsFnPublic(VarDecl *decl)
+{
+ return ((decl->flags & (DECL_CLASS_FN | DECL_PUBLIC)) ==
+ (DECL_CLASS_FN | DECL_PUBLIC));
+}
+static inline int
+isClsFnPrivate(VarDecl *decl)
+{
+ return ((decl->flags & (DECL_CLASS_FN | DECL_PRIVATE)) ==
+ (DECL_CLASS_FN | DECL_PRIVATE));
+}
+static inline int
+typeis(Type *type, char *name)
+{
+ return (type->name && !strcmp(type->name, name));
+}
+static inline int
+typeisf(Expr *expr, char *name)
+{
+ return (expr->type->name && !strcmp(expr->type->name, name));
+}
+static inline void
+emit_load_scalar(int idx)
+{
+ /*
+ * The next line is a hack so we can generate disassemblable
+ * code even in the presence of obscure compilation errors
+ * that cause the value of a function name to be attempted to
+ * be loaded. Without this, tcl will die trying to output a
+ * disassembly since the local # (-1) would be invalid.
+ */
+ if (idx == -1) idx = 0;
+
+ if (idx <= 255) {
+ TclEmitInstInt1(INST_LOAD_SCALAR1, idx, L->frame->envPtr);
+ } else {
+ TclEmitInstInt4(INST_LOAD_SCALAR4, idx, L->frame->envPtr);
+ }
+}
+static inline void
+emit_store_scalar(int idx)
+{
+ if (idx <= 255) {
+ TclEmitInstInt1(INST_STORE_SCALAR1, idx, L->frame->envPtr);
+ } else {
+ TclEmitInstInt4(INST_STORE_SCALAR4, idx, L->frame->envPtr);
+ }
+}
+static inline void
+push_litf(const char *str, ...)
+{
+ va_list ap;
+ int len = 64;
+ char *buf;
+
+ va_start(ap, str);
+ while (!(buf = ckvsprintf(str, ap, len))) {
+ va_end(ap);
+ va_start(ap, str);
+ len *= 2;
+ }
+ va_end(ap);
+ /*
+ * Subtle: register the literal in the body CompileEnv since
+ * all the code ends up there anyway. If we put it in the
+ * prologue CompileEnv, we'd have to fix-up all the literal
+ * numbers when we splice the prologue into the body.
+ */
+ TclEmitPush(TclRegisterNewLiteral(L->frame->bodyEnvPtr, buf, strlen(buf)),
+ L->frame->envPtr);
+ ckfree(buf);
+}
+static inline void
+push_lit(const char *str)
+{
+ /* See comment above about registering in the body CompileEnv. */
+ TclEmitPush(TclRegisterNewLiteral(L->frame->bodyEnvPtr, str,
+ strlen(str)), L->frame->envPtr);
+}
+static inline void
+emit_invoke(int size)
+{
+ if (size < 256) {
+ TclEmitInstInt1(INST_INVOKE_STK1, size, L->frame->envPtr);
+ } else {
+ TclEmitInstInt4(INST_INVOKE_STK4, size, L->frame->envPtr);
+ }
+}
+static inline void
+emit_invoke_expanded()
+{
+ TclEmitOpcode(INST_INVOKE_EXPANDED, L->frame->envPtr);
+}
+static inline void
+emit_pop()
+{
+ TclEmitOpcode(INST_POP, L->frame->envPtr);
+}
+static inline int
+currOffset(CompileEnv *envPtr)
+{
+ /* Offset of the next instruction to be generated. */
+ return (envPtr->codeNext - envPtr->codeStart);
+}
+
+/*
+ * REVERSE() assumes that l is a singly linked list of type type with
+ * forward pointers named ptr. The last element in the list becomes
+ * the first and is stored back into l.
+ */
+#define REVERSE(type,ptr,l) \
+ do { \
+ type *a, *b, *c; \
+ for (a = NULL, b = l, c = (l ? ((type *)l)->ptr : NULL); \
+ b != NULL; \
+ b->ptr = a, a = b, b = c, c = (c ? c->ptr : NULL)) ; \
+ *(type **)&(l) = a; \
+ } while (0)
+
+/*
+ * APPEND() starts at a, walks ptr until the end, and then attaches b
+ * to a. (Note that it's actually NCONC).
+ */
+#define APPEND(type,ptr,a,b) \
+ do { \
+ type *runner; \
+ for (runner = a; runner->ptr; runner = runner->ptr) ; \
+ runner->ptr = b; \
+ } while (0)
+
+/*
+ * Like APPEND() but if a is NULL, set a to b.
+ */
+#define APPEND_OR_SET(type,ptr,a,b) \
+ do { \
+ if (a) { \
+ type *runner; \
+ for (runner = a; runner->ptr; runner = runner->ptr) ; \
+ runner->ptr = b; \
+ } else { \
+ a = b; \
+ } \
+ } while (0)
+
+/*
+ * YYLOC_DEFAULT() is invoked by the scanner after matching a pattern
+ * and before executing its code. It tracks the source-file offset
+ * and line #.
+ */
+extern YYLTYPE L_lloc;
+#define YYLLOC_DEFAULT(c,r,n) \
+ do { \
+ if (n) { \
+ (c).beg = YYRHSLOC(r,1).beg; \
+ (c).end = YYRHSLOC(r,n).end; \
+ } else { \
+ (c).beg = YYRHSLOC(r,0).beg; \
+ (c).end = YYRHSLOC(r,0).end; \
+ } \
+ (c).line = L->line; \
+ (c).file = L->file; \
+ } while (0)
+
+#ifdef TCL_COMPILE_DEBUG
+#define ASSERT(c) unless (c) \
+ L_bomb("Assertion failed: %s:%d: %s\n", __FILE__, __LINE__, #c)
+#else
+#define ASSERT(c) do {} while(0)
+#endif
+
+#endif /* L_COMPILE_H */
diff --git a/generic/Lgetopt.c b/generic/Lgetopt.c
new file mode 100644
index 0000000..27676ec
--- /dev/null
+++ b/generic/Lgetopt.c
@@ -0,0 +1,238 @@
+#include "Lcompile.h"
+
+/* for compat with code below */
+#define streq(a, b) (!strcmp(a, b))
+#define strneq(a, b, n) (!strncmp(a, b, n))
+#define assert(x)
+
+/*
+ * Copyright (c) 1997 L.W.McVoy
+ *
+ * This version handles
+ *
+ * - (leaves it and returns)
+ * -- end of options
+ * -a
+ * -abcd
+ * -r <arg>
+ * -r<arg>
+ * -abcr <arg>
+ * -abcr<arg>
+ * -r<arg> -R<arg>, etc.
+ * --long
+ * --long:<arg>
+ * --long=<arg>
+ * --long <arg>
+ *
+ * Patterns in getopt string:
+ * d boolean option -d
+ * d: required arg -dARG or -d ARG
+ * d; required arg no space -dARG
+ * d| optionial arg no space -dARG or -d
+ *
+ * With long options:
+ * long boolean option --long
+ * long: required arg --long=ARG or --long ARG
+ * long; required arg no space --long=ARG
+ * long| optionial arg no space --long=ARG or --long
+ */
+
+int optopt; /* option that is in error, if we return an error */
+int optind; /* next arg in argv we process */
+char *optarg; /* argument to an option */
+static int n; /* current position == av[optind][n] */
+static int lastn; /* saved copy of last n */
+
+private int doLong(int ac, char **av, longopt *lopts);
+
+void
+getoptReset(void)
+{
+ optopt = optind = 0;
+ optarg = 0;
+}
+
+void
+getoptConsumed(int n1)
+{
+ optind--;
+ unless (optind) optind = 1;
+ n = lastn + n1;
+ // TRACE("optind = %d, n = %d, n1 = %d", optind, n, n1);
+}
+
+/*
+ * Returns:
+ * - char if option found
+ * - GETOPT_EOF(-1) if end of arguments reached
+ * - GETOPT_ERR(256) if unknown option found.
+ */
+int
+getopt(int ac, char **av, char *opts, longopt *lopts)
+{
+ char *t;
+
+ optarg = 0; /* clear out arg from last round */
+ optopt = 0; /* clear error return */
+ if (!optind) {
+ optind = 1;
+ lastn = n;
+ n = 1;
+ }
+ // TRACE("GETOPT ind=%d n=%d av[%d]='%s'", optind, n, optind, av[optind]);
+
+ if ((optind >= ac) || (av[optind][0] != '-') || !av[optind][1]) {
+ return (GETOPT_EOF);
+ }
+ /* Stop processing options at a -- and return arguments after */
+ if (streq(av[optind], "--")) {
+ optind++;
+ lastn = n;
+ n = 1;
+ return (GETOPT_EOF);
+ }
+ if (strneq(av[optind], "--", 2)) return (doLong(ac, av, lopts));
+
+ assert(av[optind][n]);
+ for (t = (char *)opts; *t; t++) {
+ if (*t == av[optind][n]) {
+ break;
+ }
+ }
+ if (!*t) {
+ optopt = av[optind][n];
+ // TRACE("%s", "ran out of option letters");
+ lastn = n;
+ if (av[optind][n+1]) {
+ n++;
+ } else {
+ n = 1;
+ optind++;
+ }
+ return (GETOPT_ERR);
+ }
+
+ /* OK, we found a legit option, let's see what to do with it.
+ * If it isn't one that takes an option, just advance and return.
+ */
+ if (t[1] != ':' && t[1] != '|' && t[1] != ';') {
+ lastn = n;
+ if (!av[optind][n+1]) {
+ optind++;
+ n = 1;
+ } else {
+ n++;
+ }
+ // TRACE("Legit singleton %c", *t);
+ return (*t);
+ }
+
+ /* got one with an option, see if it is cozied up to the flag */
+ if (av[optind][n+1]) {
+ optarg = &av[optind][n+1];
+ optind++;
+ lastn = n;
+ n = 1;
+ // TRACE("%c with %s", *t, optarg);
+ return (*t);
+ }
+
+ /* If it was not there, and it is optional, OK */
+ if (t[1] == '|') {
+ optind++;
+ lastn = n;
+ n = 1;
+ // TRACE("%c without arg", *t);
+ return (*t);
+ }
+
+ /* was it supposed to be there? */
+ if (t[1] == ';') {
+ optind++;
+ optopt = *t;
+ // TRACE("%s", "wanted another word");
+ return (GETOPT_ERR);
+ }
+
+ /* Nope, there had better be another word. */
+ if ((optind + 1 == ac) || (av[optind+1][0] == '-')) {
+ optopt = av[optind][n];
+ // TRACE("%s", "wanted another word");
+ return (GETOPT_ERR);
+ }
+ optarg = av[optind+1];
+ optind += 2;
+ lastn = n;
+ n = 1;
+ // TRACE("%c with arg %s", *t, optarg);
+ return (*t);
+}
+
+private int
+doLong(int ac, char **av, longopt *lopts)
+{
+ char *s, *t;
+ int len1, len2;
+
+ unless (lopts) {
+err: n = 1;
+ optind++;
+ optopt = 0;
+ return (GETOPT_ERR);
+ }
+ /* len of option without =value part */
+ s = av[optind] + 2;
+ unless (t = strchr(s, '=')) t = strchr(s, ':');
+ len1 = t ? (t - s) : strlen(s);
+ for (; (t = lopts->name); lopts++) {
+ s = av[optind] + 2;
+ /* len of lopts array without suffix */
+ len2 = strlen(t);
+ if (strspn(t+len2-1, ":;|") == 1) --len2;
+
+ if ((len1 == len2) && strneq(s, t, len1)) {
+ s += len1;
+ t += len2;
+ break; /* found a match */
+ }
+ }
+ unless (t) goto err;
+
+ /* OK, we found a legit option, let's see what to do with it.
+ * If it isn't one that takes an option, just advance and return.
+ */
+ unless (*t) {
+ /* got option anyway */
+ if ((*s == '=') || (*s == ':')) goto err;
+ optind++;
+ n = 1;
+ return (lopts->ret);
+ }
+
+ /* got one with an option, see if it is cozied up to the flag */
+ if ((*s == '=') || (*s == ':')) {
+ optarg = s + 1;
+ optind++;
+ n = 1;
+ return (lopts->ret);
+ }
+
+ /* If it was not there, and it is optional, OK */
+ if (*t == '|') {
+ optind++;
+ n = 1;
+ return (lopts->ret);
+ }
+
+ /* was it supposed to be there? */
+ if (*t == ';') goto err;
+
+ /* Nope, there had better be another word. */
+ if ((optind + 1 == ac) || (av[optind+1][0] == '-')) {
+ goto err;
+ }
+ optarg = av[optind+1];
+ optind += 2;
+ n = 1;
+ return (lopts->ret);
+}
diff --git a/generic/Lgrammar-pregen.c b/generic/Lgrammar-pregen.c
new file mode 100644
index 0000000..3245646
--- /dev/null
+++ b/generic/Lgrammar-pregen.c
@@ -0,0 +1,6447 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton implementation for Bison GLR parsers in C
+
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* C GLR parser skeleton written by Paul Hilfinger. */
+
+/* Identify Bison output. */
+#define YYBISON 1
+
+/* Bison version. */
+#define YYBISON_VERSION "2.3"
+
+/* Skeleton name. */
+#define YYSKELETON_NAME "glr.c"
+
+/* Pure parsers. */
+#define YYPURE 0
+
+/* Using locations. */
+#define YYLSP_NEEDED 1
+
+
+/* Substitute the variable and function names. */
+#define yyparse L_parse
+#define yylex L_lex
+#define yyerror L_error
+#define yylval L_lval
+#define yychar L_char
+#define yydebug L_debug
+#define yynerrs L_nerrs
+#define yylloc L_lloc
+
+
+
+#include "Lgrammar.h"
+
+/* Enabling traces. */
+#ifndef YYDEBUG
+# define YYDEBUG 0
+#endif
+
+/* Enabling verbose error messages. */
+#ifdef YYERROR_VERBOSE
+# undef YYERROR_VERBOSE
+# define YYERROR_VERBOSE 1
+#else
+# define YYERROR_VERBOSE 0
+#endif
+
+/* Enabling the token table. */
+#ifndef YYTOKEN_TABLE
+# define YYTOKEN_TABLE 0
+#endif
+
+/* Default (constant) value used for initialization for null
+ right-hand sides. Unlike the standard yacc.c template,
+ here we set the default value of $$ to a zeroed-out value.
+ Since the default value is undefined, this behavior is
+ technically correct. */
+static YYSTYPE yyval_default;
+
+/* Copy the second part of user declarations. */
+
+
+/* Line 234 of glr.c. */
+#line 97 "Lgrammar.c"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+
+#ifndef YY_
+# if defined YYENABLE_NLS && YYENABLE_NLS
+# if ENABLE_NLS
+# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
+# define YY_(msgid) dgettext ("bison-runtime", msgid)
+# endif
+# endif
+# ifndef YY_
+# define YY_(msgid) msgid
+# endif
+#endif
+
+/* Suppress unused-variable warnings by "using" E. */
+#if ! defined lint || defined __GNUC__
+# define YYUSE(e) ((void) (e))
+#else
+# define YYUSE(e) /* empty */
+#endif
+
+/* Identity function, used to suppress warnings about constant conditions. */
+#ifndef lint
+# define YYID(n) (n)
+#else
+#if (defined __STDC__ || defined __C99__FUNC__ \
+ || defined __cplusplus || defined _MSC_VER)
+static int
+YYID (int i)
+#else
+static int
+YYID (i)
+ int i;
+#endif
+{
+ return i;
+}
+#endif
+
+#ifndef YYFREE
+# define YYFREE free
+#endif
+#ifndef YYMALLOC
+# define YYMALLOC malloc
+#endif
+#ifndef YYREALLOC
+# define YYREALLOC realloc
+#endif
+
+#define YYSIZEMAX ((size_t) -1)
+
+#ifdef __cplusplus
+ typedef bool yybool;
+#else
+ typedef unsigned char yybool;
+#endif
+#define yytrue 1
+#define yyfalse 0
+
+#ifndef YYSETJMP
+# include <setjmp.h>
+# define YYJMP_BUF jmp_buf
+# define YYSETJMP(env) setjmp (env)
+# define YYLONGJMP(env, val) longjmp (env, val)
+#endif
+
+/*-----------------.
+| GCC extensions. |
+`-----------------*/
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later. */
+# if (! defined __GNUC__ || __GNUC__ < 2 \
+ || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__)
+# define __attribute__(Spec) /* empty */
+# endif
+#endif
+
+#define YYOPTIONAL_LOC(Name) Name
+
+#ifndef YYASSERT
+# define YYASSERT(condition) ((void) ((condition) || (abort (), 0)))
+#endif
+
+/* YYFINAL -- State number of the termination state. */
+#define YYFINAL 3
+/* YYLAST -- Last index in YYTABLE. */
+#define YYLAST 4962
+
+/* YYNTOKENS -- Number of terminals. */
+#define YYNTOKENS 123
+/* YYNNTS -- Number of nonterminals. */
+#define YYNNTS 70
+/* YYNRULES -- Number of rules. */
+#define YYNRULES 262
+/* YYNRULES -- Number of states. */
+#define YYNSTATES 518
+/* YYMAXRHS -- Maximum number of symbols on right-hand side of rule. */
+#define YYMAXRHS 9
+/* YYMAXLEFT -- Maximum number of symbols to the left of a handle
+ accessed by $0, $-1, etc., in any rule. */
+#define YYMAXLEFT 1
+
+/* YYTRANSLATE(X) -- Bison symbol number corresponding to X. */
+#define YYUNDEFTOK 2
+#define YYMAXUTOK 377
+
+#define YYTRANSLATE(YYX) \
+ ((YYX <= 0) ? YYEOF : \
+ (unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
+
+/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */
+static const unsigned char yytranslate[] =
+{
+ 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
+ 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
+ 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
+ 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
+ 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
+ 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
+ 105, 106, 107, 108, 109, 110, 111, 112, 113, 114,
+ 115, 116, 117, 118, 119, 120, 121, 122
+};
+
+#if YYDEBUG
+/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in
+ YYRHS. */
+static const unsigned short int yyprhs[] =
+{
+ 0, 0, 3, 5, 8, 11, 15, 21, 24, 27,
+ 28, 29, 35, 36, 42, 46, 50, 53, 60, 66,
+ 69, 73, 79, 82, 86, 90, 93, 94, 96, 97,
+ 100, 104, 107, 110, 116, 122, 126, 129, 131, 133,
+ 135, 139, 141, 145, 149, 153, 159, 165, 168, 173,
+ 174, 176, 178, 180, 182, 184, 186, 189, 192, 195,
+ 198, 202, 206, 214, 219, 221, 228, 234, 241, 247,
+ 255, 258, 259, 265, 269, 271, 273, 276, 279, 280,
+ 286, 294, 301, 309, 319, 327, 329, 332, 334, 335,
+ 337, 340, 342, 343, 345, 349, 353, 357, 360, 363,
+ 366, 367, 369, 371, 374, 378, 382, 387, 390, 393,
+ 397, 402, 407, 410, 413, 416, 419, 422, 425, 428,
+ 431, 434, 438, 442, 448, 452, 456, 460, 464, 468,
+ 472, 476, 480, 484, 488, 492, 496, 503, 507, 511,
+ 515, 519, 523, 527, 531, 535, 539, 543, 547, 551,
+ 553, 555, 557, 559, 561, 566, 570, 575, 583, 589,
+ 594, 598, 602, 606, 610, 614, 618, 622, 626, 630,
+ 634, 638, 642, 646, 651, 656, 661, 665, 669, 673,
+ 677, 681, 685, 692, 697, 700, 706, 710, 713, 714,
+ 715, 717, 719, 723, 727, 732, 737, 743, 744, 746,
+ 749, 752, 756, 758, 760, 762, 765, 767, 771, 773,
+ 777, 779, 783, 785, 786, 789, 792, 796, 802, 803,
+ 808, 812, 817, 820, 823, 825, 827, 829, 831, 833,
+ 835, 837, 843, 848, 851, 853, 856, 859, 862, 864,
+ 868, 871, 873, 877, 879, 882, 885, 888, 892, 894,
+ 897, 899, 902, 905, 907, 910, 914, 919, 923, 928,
+ 930, 932, 935
+};
+
+/* YYRHS -- A `-1'-separated list of the rules' RHS. */
+static const short int yyrhs[] =
+{
+ 124, 0, -1, 125, -1, 125, 126, -1, 125, 132,
+ -1, 125, 177, 93, -1, 125, 105, 175, 173, 93,
+ -1, 125, 166, -1, 125, 135, -1, -1, -1, 13,
+ 161, 59, 127, 129, -1, -1, 13, 104, 59, 128,
+ 129, -1, 13, 161, 93, -1, 13, 104, 93, -1,
+ 130, 83, -1, 130, 54, 59, 165, 83, 131, -1,
+ 130, 54, 59, 83, 131, -1, 130, 166, -1, 130,
+ 177, 93, -1, 130, 105, 175, 173, 93, -1, 130,
+ 132, -1, 130, 16, 133, -1, 130, 19, 133, -1,
+ 130, 137, -1, -1, 93, -1, -1, 175, 133, -1,
+ 167, 175, 133, -1, 161, 134, -1, 74, 134, -1,
+ 66, 152, 90, 138, 163, -1, 66, 152, 90, 138,
+ 93, -1, 52, 14, 135, -1, 52, 14, -1, 139,
+ -1, 137, -1, 51, -1, 57, 158, 58, -1, 161,
+ -1, 161, 38, 161, -1, 161, 38, 56, -1, 136,
+ 15, 161, -1, 136, 15, 161, 38, 161, -1, 136,
+ 15, 161, 38, 56, -1, 113, 136, -1, 5, 66,
+ 156, 90, -1, -1, 140, -1, 163, -1, 141, -1,
+ 147, -1, 142, -1, 148, -1, 158, 93, -1, 12,
+ 93, -1, 17, 93, -1, 87, 93, -1, 87, 158,
+ 93, -1, 46, 52, 93, -1, 92, 163, 52, 66,
+ 158, 90, 163, -1, 92, 163, 52, 163, -1, 93,
+ -1, 53, 66, 158, 90, 163, 146, -1, 53, 66,
+ 158, 90, 140, -1, 106, 66, 158, 90, 163, 146,
+ -1, 106, 66, 158, 90, 140, -1, 114, 66, 158,
+ 90, 59, 143, 83, -1, 143, 144, -1, -1, 115,
+ 160, 145, 14, 150, -1, 116, 14, 150, -1, 187,
+ -1, 158, -1, 24, 163, -1, 24, 141, -1, -1,
+ 112, 66, 158, 90, 135, -1, 20, 135, 112, 66,
+ 158, 90, 93, -1, 44, 66, 149, 149, 90, 135,
+ -1, 44, 66, 149, 149, 158, 90, 135, -1, 45,
+ 66, 161, 4, 161, 161, 158, 90, 135, -1, 45,
+ 66, 162, 161, 158, 90, 135, -1, 93, -1, 158,
+ 93, -1, 151, -1, -1, 135, -1, 151, 135, -1,
+ 153, -1, -1, 154, -1, 153, 15, 154, -1, 155,
+ 175, 172, -1, 155, 23, 161, -1, 155, 107, -1,
+ 155, 108, -1, 155, 109, -1, -1, 158, -1, 157,
+ -1, 157, 158, -1, 156, 15, 158, -1, 156, 15,
+ 157, -1, 156, 15, 157, 158, -1, 52, 14, -1,
+ 116, 14, -1, 66, 158, 90, -1, 66, 175, 90,
+ 158, -1, 66, 40, 90, 158, -1, 6, 158, -1,
+ 10, 158, -1, 8, 158, -1, 69, 158, -1, 76,
+ 158, -1, 77, 158, -1, 70, 158, -1, 158, 77,
+ -1, 158, 70, -1, 158, 37, 187, -1, 158, 7,
+ 187, -1, 158, 37, 186, 188, 86, -1, 158, 96,
+ 158, -1, 158, 94, 158, -1, 158, 75, 158, -1,
+ 158, 76, 158, -1, 158, 69, 158, -1, 158, 25,
+ 158, -1, 158, 71, 158, -1, 158, 68, 158, -1,
+ 158, 61, 158, -1, 158, 50, 158, -1, 158, 47,
+ 158, -1, 158, 39, 158, -1, 25, 66, 158, 15,
+ 158, 90, -1, 158, 72, 158, -1, 158, 48, 158,
+ -1, 158, 49, 158, -1, 158, 64, 158, -1, 158,
+ 65, 158, -1, 158, 3, 158, -1, 158, 73, 158,
+ -1, 158, 67, 158, -1, 158, 91, 158, -1, 158,
+ 9, 158, -1, 158, 8, 158, -1, 158, 11, 158,
+ -1, 161, -1, 183, -1, 185, -1, 56, -1, 43,
+ -1, 161, 66, 156, 90, -1, 161, 66, 90, -1,
+ 101, 66, 156, 90, -1, 95, 66, 159, 187, 15,
+ 156, 90, -1, 95, 66, 159, 156, 90, -1, 191,
+ 66, 156, 90, -1, 191, 66, 90, -1, 158, 38,
+ 158, -1, 158, 33, 158, -1, 158, 31, 158, -1,
+ 158, 35, 158, -1, 158, 36, 158, -1, 158, 32,
+ 158, -1, 158, 26, 158, -1, 158, 27, 158, -1,
+ 158, 28, 158, -1, 158, 30, 158, -1, 158, 34,
+ 158, -1, 158, 29, 158, -1, 18, 66, 158, 90,
+ -1, 158, 60, 158, 84, -1, 158, 59, 158, 83,
+ -1, 158, 100, 158, -1, 158, 21, 52, -1, 158,
+ 78, 52, -1, 104, 21, 52, -1, 104, 78, 52,
+ -1, 158, 15, 158, -1, 158, 60, 158, 22, 158,
+ 84, -1, 59, 164, 181, 83, -1, 59, 83, -1,
+ 158, 82, 158, 14, 158, -1, 64, 158, 48, -1,
+ 64, 48, -1, -1, -1, 52, -1, 161, -1, 161,
+ 15, 162, -1, 59, 164, 83, -1, 59, 164, 151,
+ 83, -1, 59, 164, 165, 83, -1, 59, 164, 165,
+ 151, 83, -1, -1, 166, -1, 165, 166, -1, 168,
+ 93, -1, 167, 168, 93, -1, 80, -1, 81, -1,
+ 41, -1, 175, 169, -1, 171, -1, 169, 15, 171,
+ -1, 173, -1, 170, 15, 173, -1, 173, -1, 173,
+ 38, 158, -1, 173, -1, -1, 161, 174, -1, 104,
+ 174, -1, 8, 161, 174, -1, 8, 161, 66, 152,
+ 90, -1, -1, 60, 158, 84, 174, -1, 60, 84,
+ 174, -1, 59, 176, 83, 174, -1, 176, 174, -1,
+ 177, 174, -1, 101, -1, 55, -1, 42, -1, 79,
+ -1, 111, -1, 110, -1, 104, -1, 102, 52, 59,
+ 178, 83, -1, 102, 59, 178, 83, -1, 102, 52,
+ -1, 179, -1, 178, 179, -1, 180, 93, -1, 175,
+ 170, -1, 182, -1, 181, 15, 182, -1, 181, 15,
+ -1, 158, -1, 158, 4, 158, -1, 99, -1, 189,
+ 99, -1, 184, 99, -1, 97, 98, -1, 184, 97,
+ 98, -1, 98, -1, 189, 98, -1, 85, -1, 190,
+ 85, -1, 186, 86, -1, 103, -1, 190, 103, -1,
+ 62, 158, 88, -1, 189, 62, 158, 88, -1, 63,
+ 158, 89, -1, 190, 63, 158, 89, -1, 21, -1,
+ 192, -1, 21, 52, -1, 192, 21, 52, -1
+};
+
+/* YYRLINE[YYN] -- source line where rule number YYN was defined. */
+static const unsigned short int yyrline[] =
+{
+ 0, 250, 250, 258, 268, 279, 283, 289, 304, 310,
+ 315, 314, 336, 335, 355, 367, 378, 394, 411, 412,
+ 429, 430, 435, 449, 458, 467, 478, 482, 483, 487,
+ 493, 503, 509, 527, 534, 544, 550, 555, 556, 561,
+ 570, 582, 583, 587, 592, 598, 604, 614, 623, 630,
+ 634, 635, 639, 644, 649, 654, 659, 664, 668, 672,
+ 676, 681, 686, 698, 703, 707, 712, 716, 720, 727,
+ 744, 753, 757, 762, 771, 777, 782, 787, 792, 796,
+ 800, 804, 808, 815, 823, 834, 835, 839, 840, 844,
+ 849, 863, 880, 884, 885, 894, 906, 915, 916, 917,
+ 918, 922, 923, 924, 930, 936, 942, 959, 965, 973,
+ 979, 984, 988, 992, 996, 1000, 1004, 1008, 1012, 1016,
+ 1020, 1024, 1028, 1032, 1039, 1043, 1047, 1051, 1055, 1059,
+ 1063, 1067, 1071, 1075, 1079, 1083, 1087, 1091, 1095, 1099,
+ 1103, 1107, 1111, 1115, 1119, 1123, 1127, 1131, 1135, 1139,
+ 1140, 1141, 1142, 1146, 1150, 1155, 1159, 1165, 1179, 1186,
+ 1191, 1195, 1199, 1203, 1207, 1211, 1215, 1219, 1223, 1227,
+ 1231, 1235, 1239, 1243, 1247, 1251, 1255, 1259, 1264, 1269,
+ 1275, 1281, 1285, 1293, 1300, 1304, 1308, 1312, 1319, 1323,
+ 1327, 1335, 1336, 1345, 1351, 1358, 1369, 1384, 1388, 1389,
+ 1401, 1402, 1414, 1415, 1416, 1420, 1432, 1433, 1441, 1442,
+ 1450, 1451, 1460, 1461, 1465, 1469, 1476, 1482, 1494, 1497,
+ 1501, 1505, 1512, 1521, 1533, 1534, 1535, 1536, 1537, 1538,
+ 1539, 1543, 1549, 1555, 1563, 1564, 1573, 1577, 1589, 1590,
+ 1595, 1599, 1603, 1611, 1615, 1620, 1628, 1635, 1646, 1651,
+ 1659, 1663, 1671, 1684, 1688, 1696, 1701, 1709, 1714, 1722,
+ 1726, 1734, 1742
+};
+#endif
+
+#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE
+/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
+ First, the terminals, then, starting at YYNTOKENS, nonterminals. */
+static const char *const yytname[] =
+{
+ "\"end of file\"", "error", "$undefined", "\"&&\"", "\"=>\"",
+ "\"_attribute\"", "\"!\"", "\"!~\"", "\"&\"", "\"|\"", "\"~\"", "\"^\"",
+ "\"break\"", "\"class\"", "\":\"", "\",\"", "\"constructor\"",
+ "\"continue\"", "\"defined\"", "\"destructor\"", "\"do\"", "\".\"",
+ "\"..\"", "\"...\"", "\"else\"", "\"eq\"", "\"&=\"", "\"|=\"", "\"^=\"",
+ "\".=\"", "\"<<=\"", "\"-=\"", "\"%=\"", "\"+=\"", "\">>=\"", "\"*=\"",
+ "\"/=\"", "\"=~\"", "\"=\"", "\"==\"", "\"(expand)\"", "\"extern\"",
+ "\"float\"", "\"float constant\"", "\"for\"", "\"foreach\"", "\"goto\"",
+ "\"ge\"", "\">\"", "\">=\"", "\"gt\"", "T_HTML", "\"id\"", "\"if\"",
+ "\"instance\"", "\"int\"", "\"integer constant\"", "\"<?=\"", "\"?>\"",
+ "\"{\"", "\"[\"", "\"le\"", "\"${\"", "\"${ (in re)\"", "\"<\"",
+ "\"<=\"", "\"(\"", "\"<<\"", "\"lt\"", "\"-\"", "\"--\"", "\"ne\"",
+ "\"!=\"", "\"||\"", "\"pattern function\"", "\"%\"", "\"+\"", "\"++\"",
+ "\"->\"", "\"poly\"", "\"private\"", "\"public\"", "\"?\"", "\"}\"",
+ "\"]\"", "\"regular expression\"", "\"regexp modifier\"", "\"return\"",
+ "\"} (end of interpolation)\"", "\"} (end of interpolation in re)\"",
+ "\")\"", "\">>\"", "\"try\"", "\";\"", "\"/\"", "\"split\"", "\"*\"",
+ "\"backtick\"", "\"`\"", "\"string constant\"", "\" . \"", "\"string\"",
+ "\"struct\"", "\"=~ s/a/b/\"", "\"type name\"", "\"typedef\"",
+ "\"unless\"", "\"_argused\"", "\"_optional\"", "\"_mustbetype\"",
+ "\"void\"", "\"widget\"", "\"while\"", "\"#pragma\"", "\"switch\"",
+ "\"case\"", "\"default\"", "LOWEST", "ADDRESS", "UMINUS", "UPLUS",
+ "PREFIX_INCDEC", "HIGHEST", "$accept", "start", "toplevel_code",
+ "class_decl", "@1", "@2", "class_decl_tail", "class_code", "opt_semi",
+ "function_decl", "fundecl_tail", "fundecl_tail1", "stmt",
+ "pragma_expr_list", "pragma", "opt_attribute", "unlabeled_stmt",
+ "single_stmt", "selection_stmt", "switch_stmt", "switch_cases",
+ "switch_case", "case_expr", "optional_else", "iteration_stmt",
+ "foreach_stmt", "expression_stmt", "opt_stmt_list", "stmt_list",
+ "parameter_list", "parameter_decl_list", "parameter_decl",
+ "parameter_attrs", "argument_expr_list", "option_arg", "expr",
+ "re_start_split", "re_start_case", "id", "id_list", "compound_stmt",
+ "enter_scope", "declaration_list", "declaration", "decl_qualifier",
+ "declaration2", "init_declarator_list", "declarator_list",
+ "init_declarator", "opt_declarator", "declarator", "array_or_hash_type",
+ "type_specifier", "scalar_type_specifier", "struct_specifier",
+ "struct_decl_list", "struct_decl", "struct_declarator_list", "list",
+ "list_element", "string_literal", "here_doc_backtick",
+ "cmdsubst_literal", "regexp_literal", "regexp_literal_mod",
+ "subst_literal", "interpolated_expr", "interpolated_expr_re",
+ "dotted_id", "dotted_id_1", 0
+};
+#endif
+
+/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
+static const unsigned char yyr1[] =
+{
+ 0, 123, 124, 125, 125, 125, 125, 125, 125, 125,
+ 127, 126, 128, 126, 126, 126, 129, 130, 130, 130,
+ 130, 130, 130, 130, 130, 130, 130, 131, 131, 132,
+ 132, 133, 133, 134, 134, 135, 135, 135, 135, 135,
+ 135, 136, 136, 136, 136, 136, 136, 137, 138, 138,
+ 139, 139, 140, 140, 140, 140, 140, 140, 140, 140,
+ 140, 140, 140, 140, 140, 141, 141, 141, 141, 142,
+ 143, 143, 144, 144, 145, 145, 146, 146, 146, 147,
+ 147, 147, 147, 148, 148, 149, 149, 150, 150, 151,
+ 151, 152, 152, 153, 153, 154, 154, 155, 155, 155,
+ 155, 156, 156, 156, 156, 156, 156, 157, 157, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 159, 160,
+ 161, 162, 162, 163, 163, 163, 163, 164, 165, 165,
+ 166, 166, 167, 167, 167, 168, 169, 169, 170, 170,
+ 171, 171, 172, 172, 173, 173, 173, 173, 174, 174,
+ 174, 174, 175, 175, 176, 176, 176, 176, 176, 176,
+ 176, 177, 177, 177, 178, 178, 179, 180, 181, 181,
+ 181, 182, 182, 183, 183, 183, 184, 184, 185, 185,
+ 186, 186, 187, 188, 188, 189, 189, 190, 190, 191,
+ 191, 192, 192
+};
+
+/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */
+static const unsigned char yyr2[] =
+{
+ 0, 2, 1, 2, 2, 3, 5, 2, 2, 0,
+ 0, 5, 0, 5, 3, 3, 2, 6, 5, 2,
+ 3, 5, 2, 3, 3, 2, 0, 1, 0, 2,
+ 3, 2, 2, 5, 5, 3, 2, 1, 1, 1,
+ 3, 1, 3, 3, 3, 5, 5, 2, 4, 0,
+ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2,
+ 3, 3, 7, 4, 1, 6, 5, 6, 5, 7,
+ 2, 0, 5, 3, 1, 1, 2, 2, 0, 5,
+ 7, 6, 7, 9, 7, 1, 2, 1, 0, 1,
+ 2, 1, 0, 1, 3, 3, 3, 2, 2, 2,
+ 0, 1, 1, 2, 3, 3, 4, 2, 2, 3,
+ 4, 4, 2, 2, 2, 2, 2, 2, 2, 2,
+ 2, 3, 3, 5, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 6, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 1,
+ 1, 1, 1, 1, 4, 3, 4, 7, 5, 4,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 4, 4, 4, 3, 3, 3, 3,
+ 3, 3, 6, 4, 2, 5, 3, 2, 0, 0,
+ 1, 1, 3, 3, 4, 4, 5, 0, 1, 2,
+ 2, 3, 1, 1, 1, 2, 1, 3, 1, 3,
+ 1, 3, 1, 0, 2, 2, 3, 5, 0, 4,
+ 3, 4, 2, 2, 1, 1, 1, 1, 1, 1,
+ 1, 5, 4, 2, 1, 2, 2, 2, 1, 3,
+ 2, 1, 3, 1, 2, 2, 2, 3, 1, 2,
+ 1, 2, 2, 1, 2, 3, 4, 3, 4, 1,
+ 1, 2, 3
+};
+
+/* YYDPREC[RULE-NUM] -- Dynamic precedence of rule #RULE-NUM (0 if none). */
+static const unsigned char yydprec[] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+/* YYMERGER[RULE-NUM] -- Index of merging function for rule #RULE-NUM. */
+static const unsigned char yymerger[] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+/* YYDEFACT[S] -- default rule to reduce with in state S when YYTABLE
+ doesn't specify something else to do. Zero means the default is an
+ error. */
+static const unsigned short int yydefact[] =
+{
+ 9, 0, 2, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 259, 0, 204, 226, 153, 0, 0, 0,
+ 39, 190, 0, 225, 152, 0, 197, 0, 0, 0,
+ 0, 0, 0, 0, 227, 202, 203, 0, 0, 64,
+ 0, 0, 248, 243, 224, 0, 230, 0, 0, 229,
+ 228, 0, 0, 0, 3, 4, 8, 38, 37, 50,
+ 52, 54, 53, 55, 0, 149, 51, 7, 0, 0,
+ 0, 218, 218, 150, 0, 151, 0, 0, 260, 190,
+ 197, 0, 0, 112, 114, 113, 57, 0, 0, 58,
+ 0, 0, 261, 0, 0, 0, 0, 36, 0, 0,
+ 184, 0, 0, 187, 0, 0, 0, 0, 218, 115,
+ 118, 116, 117, 59, 0, 197, 0, 188, 246, 0,
+ 233, 0, 0, 0, 224, 230, 0, 0, 0, 47,
+ 41, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 120, 0, 0, 0,
+ 0, 0, 119, 0, 0, 0, 56, 0, 0, 0,
+ 0, 0, 0, 200, 0, 0, 218, 29, 218, 205,
+ 206, 210, 0, 0, 222, 5, 223, 0, 245, 0,
+ 249, 244, 0, 0, 0, 12, 15, 10, 14, 0,
+ 0, 0, 85, 0, 0, 191, 0, 61, 35, 0,
+ 40, 193, 89, 0, 241, 0, 198, 0, 0, 0,
+ 238, 255, 186, 0, 109, 0, 60, 0, 0, 0,
+ 190, 0, 0, 102, 101, 0, 0, 0, 234, 0,
+ 179, 180, 218, 0, 0, 0, 0, 0, 0, 142,
+ 0, 250, 0, 122, 0, 147, 146, 148, 181, 177,
+ 129, 167, 168, 169, 172, 170, 163, 166, 162, 171,
+ 164, 165, 0, 121, 161, 135, 134, 138, 139, 133,
+ 0, 0, 132, 140, 141, 144, 131, 128, 130, 137,
+ 143, 126, 127, 178, 0, 145, 125, 124, 176, 155,
+ 0, 201, 30, 218, 100, 32, 215, 31, 214, 0,
+ 0, 0, 218, 0, 247, 0, 160, 0, 262, 241,
+ 26, 26, 173, 0, 0, 0, 86, 0, 0, 0,
+ 0, 194, 90, 0, 195, 0, 199, 240, 183, 111,
+ 110, 0, 63, 0, 0, 107, 108, 0, 156, 103,
+ 0, 237, 208, 232, 235, 236, 6, 0, 0, 44,
+ 43, 42, 0, 0, 252, 0, 251, 253, 0, 0,
+ 175, 0, 174, 0, 154, 100, 216, 0, 91, 93,
+ 0, 207, 211, 218, 220, 218, 256, 159, 13, 0,
+ 11, 0, 181, 0, 0, 0, 191, 192, 0, 66,
+ 78, 242, 196, 239, 0, 158, 0, 105, 104, 231,
+ 0, 68, 78, 79, 0, 71, 257, 0, 123, 254,
+ 0, 185, 0, 49, 100, 0, 97, 98, 99, 213,
+ 221, 219, 0, 0, 0, 16, 0, 22, 25, 19,
+ 218, 0, 136, 81, 0, 0, 0, 0, 65, 0,
+ 0, 106, 209, 67, 46, 45, 0, 258, 182, 217,
+ 0, 0, 94, 96, 95, 212, 23, 0, 24, 0,
+ 0, 20, 80, 82, 0, 84, 77, 76, 62, 157,
+ 69, 189, 0, 70, 0, 34, 33, 28, 0, 0,
+ 0, 0, 88, 0, 27, 18, 28, 21, 83, 0,
+ 75, 74, 73, 87, 48, 17, 88, 72
+};
+
+/* YYPDEFGOTO[NTERM-NUM]. */
+static const short int yydefgoto[] =
+{
+ -1, 1, 2, 54, 331, 330, 398, 399, 505, 55,
+ 187, 317, 222, 129, 57, 471, 58, 59, 60, 61,
+ 466, 493, 509, 458, 62, 63, 213, 512, 223, 387,
+ 388, 389, 390, 242, 243, 64, 239, 501, 65, 216,
+ 66, 101, 225, 226, 227, 69, 189, 361, 190, 474,
+ 191, 196, 228, 71, 108, 247, 248, 249, 229, 230,
+ 73, 74, 75, 262, 263, 378, 76, 264, 77, 78
+};
+
+/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
+ STATE-NUM. */
+#define YYPACT_NINF -278
+static const short int yypact[] =
+{
+ -278, 32, 781, -278, 1976, 1976, 1976, -41, -28, -33,
+ 45, 1306, 18, 70, -278, -278, -278, 106, 121, 23,
+ -278, 53, 149, -278, -278, 1976, -278, 1976, 1691, 1569,
+ 1976, 1976, 1976, 1976, -278, -278, -278, 1748, 21, -278,
+ 150, 122, -278, -278, 151, 68, 8, 547, 152, -278,
+ -278, 162, 177, 164, -278, -278, -278, -278, -278, -278,
+ -278, -278, -278, -278, 2135, 167, -278, -278, 547, 142,
+ 14, 143, 19, -278, 96, -278, -7, 170, 216, -278,
+ 157, 151, 8, -6, -6, -6, -278, -12, 64, -278,
+ 1976, 130, -278, 1976, 1805, 177, 159, 1405, 1976, 2212,
+ -278, 890, 2289, -278, 3987, 154, 2367, 169, 143, -6,
+ -6, -6, -6, -278, 2444, -278, 204, -278, -278, 684,
+ 206, 547, 211, 217, -278, -278, 9, 1976, 1976, 255,
+ 233, 1976, 1976, 47, 1976, 1976, 1976, 1976, 220, 1976,
+ 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976,
+ 1976, 47, 1976, 1976, 1976, 1976, 1976, 1976, 1976, 1976,
+ 1976, 1976, 1976, 1976, 1976, 1976, -278, 1976, 1976, 1976,
+ 1976, 1976, -278, 225, 1976, 1976, -278, 1976, 1976, 1976,
+ 534, 185, 14, -278, 177, 213, 143, -278, 132, 265,
+ -278, 243, 172, 1862, -278, -278, -278, 186, -278, 1976,
+ -278, -278, 609, 235, 1976, -278, -278, -278, -278, 2521,
+ 227, 4064, -278, 1805, 2598, 58, 177, -278, -278, 2675,
+ -278, -278, -278, 1108, 2751, 999, -278, 547, 9, 10,
+ -278, -278, 191, 1976, -278, 1976, -278, 890, -9, 450,
+ 280, 286, 11, 1976, 4369, 547, 9, 331, -278, 208,
+ -278, -278, 143, 209, 2828, 2905, 177, 83, 2982, 4593,
+ 1976, -278, 218, -278, 119, 4804, 4665, 4737, 4369, -278,
+ 4862, 4369, 4369, 4369, 4369, 4369, 4369, 4369, 4369, 4369,
+ 4369, 4369, -21, -278, 4369, 4862, 1705, 1705, 1705, 1705,
+ 3059, 2057, 1705, 1705, 1705, 696, 1705, 237, 4862, 4862,
+ 4521, -6, 237, -278, 3137, 696, -6, -6, 237, -278,
+ 12, -278, -278, 166, 215, -278, -278, -278, -278, 9,
+ 1976, 223, 143, 3214, -278, 3292, -278, 13, -278, 4140,
+ -278, -278, -278, 1976, 1976, 1919, -278, 177, 177, 1976,
+ 1504, -278, -278, 1976, -278, 1207, -278, 1976, -278, -6,
+ -6, 1976, -278, 26, 288, -278, -278, 684, -278, 4369,
+ 1079, 293, -278, -278, -278, -278, -278, 1504, 1306, 273,
+ -278, -278, 254, 3370, -278, 1976, -278, -278, 230, -14,
+ -278, 1976, -278, 1976, -278, 215, -278, 229, 306, -278,
+ 268, -278, 4369, 143, -278, 143, -278, -278, -278, 4,
+ -278, 3447, 4216, 1306, 3524, 177, 307, -278, 3601, -278,
+ 300, 4369, -278, -278, 3678, -278, 684, 1976, 4369, -278,
+ 9, -278, 300, -278, 144, -278, -278, 3755, -278, -278,
+ 3832, 4445, 238, 320, -278, 177, -278, -278, -278, 9,
+ -278, -278, 137, 137, 270, -278, 547, -278, -278, -278,
+ 38, 234, -278, -278, 1306, 1976, 1306, 15, -278, 21,
+ 29, 4369, -278, -278, -278, -278, 107, -278, -278, -278,
+ 264, 120, -278, -278, -278, -278, -278, 213, -278, 4667,
+ 9, -278, -278, -278, 3910, -278, -278, -278, -278, -278,
+ -278, -278, 324, -278, 684, -278, -278, 241, 4738, 249,
+ 1306, 1626, 1306, 36, -278, -278, 241, -278, -278, 330,
+ 4293, -278, -278, 1306, -278, -278, 1306, -278
+};
+
+/* YYPGOTO[NTERM-NUM]. */
+static const short int yypgoto[] =
+{
+ -278, -278, -278, -278, -278, -278, 17, -278, -160, -48,
+ -168, 165, -2, -278, -45, -278, -278, -277, -102, -278,
+ -278, -278, -278, -63, -278, -278, 147, -154, -217, -20,
+ -278, -67, -278, -162, 27, 6, -278, -278, 136, 30,
+ -31, -59, -108, -1, 0, -49, -278, -278, 55, -278,
+ -122, -58, 1, 188, 3, 138, -231, -278, -278, 41,
+ -278, -278, -278, 239, -145, -278, -278, 103, -278, -278
+};
+
+/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If
+ positive, shift that token. If negative, reduce the rule which
+ number is the opposite. If zero, do what YYDEFACT says.
+ If YYTABLE_NINF, syntax error. */
+#define YYTABLE_NINF -93
+static const short int yytable[] =
+{
+ 56, 67, 68, 70, 253, 72, 283, 116, 345, 91,
+ 83, 84, 85, 194, 312, 138, 364, 184, 310, 181,
+ 442, 204, 184, 443, 79, 347, 357, 357, 357, 122,
+ 107, 99, 3, 102, 104, 106, 109, 110, 111, 112,
+ 327, 357, 260, 114, 357, 14, 15, 205, 126, 375,
+ 115, 357, 86, 158, 159, 199, 237, 351, 444, 23,
+ 89, 79, 337, 409, 166, 374, 79, 97, 22, 182,
+ 92, 172, 173, 338, 115, 96, 87, 353, 192, 193,
+ 115, 206, 377, 34, 35, 36, 123, 445, 185, 429,
+ 421, 200, 201, 348, 354, 218, 209, 192, 193, 211,
+ 214, 358, 384, 397, 219, 124, 45, 224, 125, 446,
+ 260, 90, 195, 186, 49, 50, 415, 52, 186, 489,
+ 120, 48, 246, 207, 362, 244, 514, 121, 316, 364,
+ 318, 481, 261, 254, 255, 79, 93, 258, 259, 370,
+ 265, 266, 267, 268, 88, 270, 271, 272, 273, 274,
+ 275, 276, 277, 278, 279, 280, 281, 208, 284, 285,
+ 286, 287, 288, 289, 290, 291, 292, 293, 294, 295,
+ 296, 297, 94, 298, 299, 300, 301, 302, 181, 115,
+ 304, 305, 375, 306, 307, 308, 244, 95, 130, 79,
+ 490, 192, 193, 197, 318, 198, 79, 4, 314, 323,
+ 464, 6, 192, 193, 376, 325, 188, 352, 244, 10,
+ 329, 185, 12, 495, 15, 98, 117, 119, 127, 214,
+ 118, 342, 491, 492, 346, 192, 193, 23, 128, 79,
+ 131, 215, 385, 180, 16, 183, 202, 203, 287, 349,
+ 100, 350, 210, 79, 233, 244, 246, 24, 246, 359,
+ 80, 34, 217, 27, 460, 386, 238, 29, 138, 235,
+ 30, 31, 252, 250, 394, 245, 373, 32, 33, 251,
+ 256, 257, 269, 124, 476, 478, 125, 303, 311, 314,
+ 319, 320, 49, 50, 324, 513, 40, 328, 41, 42,
+ 43, 435, 81, 333, 355, 82, 158, 159, 462, 513,
+ 356, 365, 366, 416, 374, -92, 393, 166, 420, 410,
+ 15, 424, 170, 425, 172, 173, 428, 475, 188, 433,
+ 313, 434, 338, 23, 457, 470, 392, 482, 469, 479,
+ 494, 177, 503, 178, 504, 440, 422, 441, 502, 401,
+ 402, 404, 507, 342, 516, 408, 515, 34, 400, 411,
+ 315, 447, 339, 329, 448, 486, 511, 414, 499, 463,
+ 335, 246, 517, 418, 252, 432, 423, 472, 407, 124,
+ 45, 498, 125, 15, 391, 436, 437, 438, 49, 50,
+ 321, 427, 252, 360, 417, 379, 23, 430, 413, 431,
+ 282, 439, 369, 371, 0, 0, 0, 0, 449, 68,
+ 70, 453, 450, 0, 0, 0, 0, 0, 0, 0,
+ 34, 0, 0, 0, 363, 0, 0, 0, 0, 0,
+ 0, 0, 244, 461, 0, 0, 487, 0, 488, 0,
+ 0, 0, 124, 45, 0, 125, 0, 0, 0, 0,
+ 496, 49, 50, 0, 0, 0, 0, 480, 0, 0,
+ 0, 0, 483, 0, 485, 252, 4, 0, 5, 0,
+ 6, 484, 0, 0, 0, 0, 0, 0, 10, 0,
+ 0, 12, 0, 405, 406, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 16, 0, 0, 0, 346, 508, 0,
+ 244, 0, 240, 0, 0, 0, 24, 510, 0, 80,
+ 0, 342, 27, 260, 28, 0, 29, 0, 0, 30,
+ 31, 0, 0, 0, 0, 0, 32, 33, 0, 0,
+ 0, 0, 0, 0, 0, 261, 0, 0, 0, 0,
+ 4, 455, 5, 0, 6, 40, 0, 41, 42, 43,
+ 0, 81, 10, 0, 82, 12, 252, 0, 0, 13,
+ 465, 0, 0, 0, 0, 0, 241, 0, 0, 0,
+ 0, 473, 0, 0, 0, 252, 0, 16, 477, 477,
+ 0, 0, 0, 0, 0, 0, 240, 0, 0, 15,
+ 24, 0, 0, 80, 0, 0, 27, 0, 28, 0,
+ 29, 0, 23, 30, 31, 0, 0, 0, 0, 0,
+ 32, 33, 0, 0, 0, 4, 252, 5, 0, 6,
+ 0, 0, 0, 0, 309, 0, 34, 10, 0, 40,
+ 12, 41, 42, 43, 13, 81, 0, 0, 82, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 124, 45,
+ 241, 125, 16, 0, 0, 0, 0, 49, 50, 0,
+ 0, 240, 0, 0, 0, 24, 0, 0, 80, 0,
+ 0, 27, 0, 28, 0, 29, 0, 0, 30, 31,
+ 0, 0, 0, 0, 0, 32, 33, 0, 0, 0,
+ 4, 0, 5, 0, 6, 0, 0, 0, 0, 326,
+ 0, 0, 10, 0, 40, 12, 41, 42, 43, 13,
+ 81, 0, 0, 82, 0, 0, 0, 138, 0, 0,
+ 0, 0, 0, 0, 0, 241, 0, 16, 0, 0,
+ 0, 0, 0, 0, 0, 0, 240, 0, 0, 0,
+ 24, 0, 0, 80, 0, 0, 27, 0, 28, 0,
+ 29, 0, 0, 30, 31, 158, 159, 0, 0, 0,
+ 32, 33, 0, 0, 0, 165, 166, 0, 0, 0,
+ 0, 170, 171, 172, 173, 0, 0, 0, 0, 40,
+ 0, 41, 42, 43, 0, 81, 0, 4, 82, 5,
+ 177, 6, 178, 7, 8, 0, 179, 0, 9, 10,
+ 241, 11, 12, 0, 0, 0, 13, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 14, 15, 16, 17, 18, 19, 0, 0,
+ 0, 0, 20, 21, 22, 0, 23, 24, 25, 0,
+ 26, 0, 0, 27, 0, 28, 0, 29, 0, 0,
+ 30, 31, 0, 0, 0, 0, 0, 32, 33, 0,
+ 34, 35, 36, 0, 0, 0, 0, 0, 37, 0,
+ 0, 0, 0, 38, 39, 0, 40, 0, 41, 42,
+ 43, 0, 44, 45, 0, 46, 47, 48, 0, 0,
+ 0, 49, 50, 51, 52, 53, 4, 0, 5, 0,
+ 6, 0, 7, 0, 0, 0, 0, 9, 10, 0,
+ 11, 12, 0, 0, 0, 13, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 14, 15, 16, 17, 18, 19, 0, 0, 0,
+ 0, 20, 21, 22, 0, 23, 24, 25, 0, 26,
+ 0, 0, 27, 0, 28, 0, 29, 0, 0, 30,
+ 31, 0, 0, 0, 0, 0, 32, 33, 0, 34,
+ 35, 36, 0, 221, 0, 0, 0, 37, 0, 0,
+ 0, 0, 38, 39, 0, 40, 0, 41, 42, 43,
+ 0, 44, 45, 0, 46, 0, 48, 0, 0, 0,
+ 49, 50, 51, 52, 53, 4, 0, 5, 0, 6,
+ 0, 7, 0, 0, 0, 0, 9, 10, 0, 11,
+ 12, 0, 0, 0, 13, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 14, 15, 16, 17, 18, 19, 0, 0, 0, 0,
+ 20, 21, 22, 0, 23, 24, 25, 0, 26, 0,
+ 0, 27, 0, 28, 0, 29, 0, 0, 30, 31,
+ 0, 0, 0, 0, 0, 32, 33, 0, 34, 35,
+ 36, 0, 344, 0, 0, 0, 37, 0, 0, 0,
+ 0, 38, 39, 0, 40, 0, 41, 42, 43, 0,
+ 44, 45, 0, 46, 0, 48, 0, 0, 0, 49,
+ 50, 51, 52, 53, 4, 0, 5, 0, 6, 0,
+ 7, 15, 0, 0, 0, 9, 10, 0, 11, 12,
+ 0, 0, 0, 13, 23, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 16, 17, 18, 19, 0, 0, 0, 34, 20,
+ 21, 22, 419, 0, 24, 25, 0, 26, 0, 0,
+ 27, 0, 28, 0, 29, 0, 0, 30, 31, 0,
+ 124, 45, 0, 125, 32, 33, 0, 0, 0, 49,
+ 50, 341, 0, 0, 0, 37, 0, 0, 0, 0,
+ 38, 39, 0, 40, 0, 41, 42, 43, 0, 81,
+ 0, 0, 82, 4, 48, 5, 0, 6, 0, 7,
+ 51, 52, 53, 0, 9, 10, 0, 11, 12, 0,
+ 0, 0, 13, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 17, 18, 19, 0, 0, 0, 0, 20, 21,
+ 22, 0, 0, 24, 25, 0, 26, 0, 0, 27,
+ 0, 28, 0, 29, 0, 0, 30, 31, 0, 0,
+ 0, 0, 0, 32, 33, 0, 0, 0, 0, 0,
+ 412, 0, 0, 0, 37, 0, 0, 0, 0, 38,
+ 39, 0, 40, 0, 41, 42, 43, 0, 81, 0,
+ 0, 82, 4, 48, 5, 0, 6, 0, 7, 51,
+ 52, 53, 0, 9, 10, 0, 11, 12, 0, 0,
+ 0, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 16,
+ 17, 18, 19, 0, 0, 0, 0, 20, 21, 22,
+ 0, 0, 24, 25, 0, 26, 0, 0, 27, 0,
+ 28, 0, 29, 0, 0, 30, 31, 0, 0, 0,
+ 0, 0, 32, 33, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 37, 0, 0, 0, 0, 38, 39,
+ 0, 40, 0, 41, 42, 43, 0, 81, 0, 0,
+ 82, 4, 48, 5, 0, 6, 0, 7, 51, 52,
+ 53, 0, 9, 10, 0, 11, 12, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 16, 17,
+ 18, 19, 0, 0, 0, 0, 20, 21, 22, 0,
+ 0, 24, 25, 0, 26, 0, 0, 27, 0, 28,
+ 0, 29, 0, 0, 30, 31, 0, 0, 0, 0,
+ 0, 32, 33, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 37, 0, 0, 0, 0, 38, 39, 0,
+ 40, 0, 41, 42, 43, 0, 81, 0, 0, 82,
+ 4, 48, 5, 0, 6, 0, 7, 51, 52, 53,
+ 0, 9, 10, 0, 11, 12, 0, 0, 0, 13,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 16, 17, 18,
+ 19, 0, 0, 0, 0, 0, 79, 22, 0, 0,
+ 24, 0, 0, 26, 0, 0, 27, 0, 28, 0,
+ 29, 0, 0, 30, 31, 4, 0, 5, 0, 6,
+ 32, 33, 0, 0, 0, 0, 0, 10, 0, 0,
+ 12, 37, 0, 0, 13, 0, 38, 39, 0, 40,
+ 0, 41, 42, 43, 0, 81, 0, 0, 82, 105,
+ 48, 15, 16, 0, 0, 0, 51, 0, 53, 0,
+ 0, 79, 0, 0, 23, 24, 0, 0, 80, 0,
+ 0, 27, 4, 28, 5, 29, 6, 0, 30, 31,
+ 0, 0, 0, 0, 10, 32, 33, 12, 34, 0,
+ 0, 13, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 40, 0, 41, 42, 43, 16,
+ 44, 45, 0, 46, 0, 0, 0, 0, 79, 49,
+ 50, 0, 24, 0, 0, 80, 0, 0, 27, 260,
+ 28, 0, 29, 0, 0, 30, 31, 4, 0, 5,
+ 0, 6, 32, 33, 0, 0, 0, 0, 0, 10,
+ 0, 261, 12, 0, 0, 0, 13, 0, 0, 0,
+ 0, 40, 0, 41, 42, 43, 138, 81, 0, 0,
+ 82, 0, 0, 0, 16, 0, 0, 0, 0, 103,
+ 0, 0, 0, 79, 0, 0, 0, 24, 0, 0,
+ 80, 0, 0, 27, 4, 28, 5, 29, 6, 0,
+ 30, 31, 0, 0, 158, 159, 10, 32, 33, 12,
+ 0, 0, 163, 13, 165, 166, 0, 0, 0, 0,
+ 170, 171, 172, 173, 0, 0, 40, 0, 41, 42,
+ 43, 16, 81, 0, 0, 82, 175, 0, 0, 177,
+ 79, 178, 0, 0, 24, 179, 0, 80, 0, 0,
+ 27, 4, 28, 5, 29, 6, 0, 30, 31, 0,
+ 0, 0, 0, 10, 32, 33, 12, 0, 0, 0,
+ 13, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 113, 0, 40, 0, 41, 42, 43, 16, 81,
+ 0, 0, 82, 0, 0, 0, 0, 79, 0, 0,
+ 0, 24, 0, 0, 80, 0, 0, 27, 4, 28,
+ 5, 29, 6, 0, 30, 31, 0, 0, 0, 0,
+ 10, 32, 33, 12, 0, 0, 0, 13, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 212, 0,
+ 40, 0, 41, 42, 43, 16, 81, 0, 0, 82,
+ 0, 0, 0, 0, 79, 0, 0, 0, 24, 0,
+ 0, 80, 0, 0, 27, 4, 28, 5, 29, 6,
+ 0, 30, 31, 0, 0, 0, 0, 10, 32, 33,
+ 12, 0, 0, 0, 13, 0, 322, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 40, 0, 41,
+ 42, 43, 16, 81, 0, 0, 82, 0, 0, 0,
+ 0, 79, 0, 0, 0, 24, 0, 0, 80, 0,
+ 0, 27, 4, 28, 5, 29, 6, 0, 30, 31,
+ 0, 0, 0, 0, 10, 32, 33, 12, 0, 0,
+ 0, 13, 0, 0, 0, 0, 0, 0, 0, 403,
+ 0, 0, 0, 0, 40, 0, 41, 42, 43, 16,
+ 81, 0, 0, 82, 0, 0, 0, 0, 79, 0,
+ 0, 0, 24, 0, 0, 80, 0, 0, 27, 0,
+ 28, 0, 29, 0, 0, 30, 31, 0, 0, 0,
+ 0, 0, 32, 33, 0, 0, 0, 0, 0, 0,
+ 132, 0, 0, 0, 133, 134, 135, 0, 136, 0,
+ 0, 40, 137, 41, 42, 43, 0, 81, 138, 381,
+ 82, 0, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 148, 149, 150, 151, 152, 153, 0, 0, 0,
+ 0, 0, 0, 0, 154, 155, 156, 157, 0, 0,
+ 0, 0, 0, 0, 0, 0, 158, 159, 160, 0,
+ 0, 161, 162, 0, 163, 164, 165, 166, 167, 168,
+ 169, 0, 170, 171, 172, 173, 0, 0, 132, 174,
+ 0, 382, 133, 134, 135, 0, 136, 0, 175, 0,
+ 137, 177, 0, 178, 0, 0, 138, 179, 0, 0,
+ 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
+ 149, 150, 151, 152, 153, 0, 0, 0, 0, 0,
+ 0, 0, 154, 155, 156, 157, 0, 0, 0, 0,
+ 0, 0, 0, 0, 158, 159, 160, 0, 0, 161,
+ 162, 0, 163, 164, 165, 166, 167, 168, 169, 0,
+ 170, 171, 172, 173, 0, 132, 0, 174, 0, 133,
+ 134, 135, 0, 136, 0, 0, 175, 137, 176, 177,
+ 0, 178, 0, 138, 0, 179, 0, 139, 140, 141,
+ 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 0, 0, 0, 0, 0, 0, 0, 154,
+ 155, 156, 157, 0, 0, 0, 0, 0, 0, 0,
+ 220, 158, 159, 160, 0, 0, 161, 162, 0, 163,
+ 164, 165, 166, 167, 168, 169, 0, 170, 171, 172,
+ 173, 0, 132, 0, 174, 0, 133, 134, 135, 0,
+ 136, 0, 0, 175, 137, 0, 177, 0, 178, 0,
+ 138, 0, 179, 0, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 0,
+ 0, 0, 0, 0, 0, 0, 154, 155, 156, 157,
+ 0, 0, 0, 0, 0, 0, 0, 0, 158, 159,
+ 160, 0, 0, 161, 162, 0, 163, 164, 165, 166,
+ 167, 168, 169, 0, 170, 171, 172, 173, 0, 0,
+ 132, 174, 0, 0, 133, 134, 135, 231, 136, 0,
+ 175, 0, 137, 177, 0, 178, 0, 0, 138, 179,
+ 0, 0, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 148, 149, 150, 151, 152, 153, 0, 0, 0,
+ 0, 0, 0, 0, 154, 155, 156, 157, 0, 0,
+ 0, 0, 0, 0, 0, 0, 158, 159, 160, 0,
+ 0, 161, 162, 0, 163, 164, 165, 166, 167, 168,
+ 169, 0, 170, 171, 172, 173, 0, 132, 0, 174,
+ 0, 133, 134, 135, 0, 136, 0, 234, 175, 137,
+ 0, 177, 0, 178, 0, 138, 0, 179, 0, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 0, 0, 0, 0, 0, 0,
+ 0, 154, 155, 156, 157, 0, 0, 0, 0, 0,
+ 0, 0, 0, 158, 159, 160, 0, 0, 161, 162,
+ 0, 163, 164, 165, 166, 167, 168, 169, 0, 170,
+ 171, 172, 173, 0, 132, 0, 174, 0, 133, 134,
+ 135, 0, 136, 0, 0, 175, 137, 236, 177, 0,
+ 178, 0, 138, 0, 179, 0, 139, 140, 141, 142,
+ 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
+ 153, 0, 0, 0, 0, 0, 0, 0, 154, 155,
+ 156, 157, 0, 0, 0, 0, 0, 0, 0, 0,
+ 158, 159, 160, 0, 0, 161, 162, 0, 163, 164,
+ 165, 166, 167, 168, 169, 0, 170, 171, 172, 173,
+ 0, 132, 0, 174, 0, 133, 134, 135, 0, 136,
+ 0, 332, 175, 137, 0, 177, 0, 178, 0, 138,
+ 0, 179, 0, 139, 140, 141, 142, 143, 144, 145,
+ 146, 147, 148, 149, 150, 151, 152, 153, 0, 0,
+ 0, 0, 0, 0, 0, 154, 155, 156, 157, 0,
+ 0, 0, 0, 0, 0, 0, 0, 158, 159, 160,
+ 0, 0, 161, 162, 0, 163, 164, 165, 166, 167,
+ 168, 169, 0, 170, 171, 172, 173, 0, 132, 0,
+ 174, 0, 133, 134, 135, 0, 136, 0, 0, 175,
+ 137, 336, 177, 0, 178, 0, 138, 0, 179, 0,
+ 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
+ 149, 150, 151, 152, 153, 0, 0, 0, 0, 0,
+ 0, 0, 154, 155, 156, 157, 0, 0, 0, 0,
+ 0, 0, 0, 0, 158, 159, 160, 0, 0, 161,
+ 162, 0, 163, 164, 165, 166, 167, 168, 169, 0,
+ 170, 171, 172, 173, 132, 343, 0, 174, 133, 134,
+ 135, 0, 136, 0, 0, 340, 175, 0, 0, 177,
+ 0, 178, 138, 0, 0, 179, 139, 140, 141, 142,
+ 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
+ 153, 0, 0, 0, 0, 0, 0, 0, 154, 155,
+ 156, 157, 0, 0, 0, 0, 0, 0, 0, 0,
+ 158, 159, 160, 0, 0, 161, 162, 0, 163, 164,
+ 165, 166, 167, 168, 169, 0, 170, 171, 172, 173,
+ 0, 132, 0, 174, 0, 133, 134, 135, 0, 136,
+ 0, 0, 175, 137, 176, 177, 0, 178, 0, 138,
+ 0, 179, 0, 139, 140, 141, 142, 143, 144, 145,
+ 146, 147, 148, 149, 150, 151, 152, 153, 0, 0,
+ 0, 0, 0, 0, 0, 154, 155, 156, 157, 0,
+ 0, 0, 0, 0, 0, 0, 0, 158, 159, 160,
+ 0, 0, 161, 162, 0, 163, 164, 165, 166, 167,
+ 168, 169, 0, 170, 171, 172, 173, 0, 132, 0,
+ 174, 0, 133, 134, 135, 0, 136, 0, 367, 175,
+ 137, 0, 177, 0, 178, 0, 138, 0, 179, 0,
+ 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
+ 149, 150, 151, 152, 153, 0, 0, 0, 0, 0,
+ 0, 0, 154, 155, 156, 157, 0, 0, 0, 0,
+ 0, 0, 0, 0, 158, 159, 160, 0, 0, 161,
+ 162, 0, 163, 164, 165, 166, 167, 168, 169, 0,
+ 170, 171, 172, 173, 0, 132, 0, 174, 0, 133,
+ 134, 135, 0, 136, 0, 368, 175, 137, 0, 177,
+ 0, 178, 0, 138, 0, 179, 0, 139, 140, 141,
+ 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 0, 0, 0, 0, 0, 0, 0, 154,
+ 155, 156, 157, 0, 0, 0, 0, 0, 0, 0,
+ 0, 158, 159, 160, 0, 0, 161, 162, 0, 163,
+ 164, 165, 166, 167, 168, 169, 0, 170, 171, 172,
+ 173, 0, 132, 0, 174, 0, 133, 134, 135, 0,
+ 136, 0, 372, 175, 137, 0, 177, 0, 178, 0,
+ 138, 0, 179, 0, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 0,
+ 0, 0, 0, 0, 0, 0, 154, 155, 156, 157,
+ 0, 0, 0, 0, 0, 0, 0, 0, 158, 159,
+ 160, 0, 0, 161, 162, 0, 163, 164, 165, 166,
+ 167, 168, 169, 0, 170, 171, 172, 173, 0, 0,
+ 132, 174, 380, 0, 133, 134, 135, 0, 136, 0,
+ 175, 383, 137, 177, 0, 178, 0, 0, 138, 179,
+ 0, 0, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 148, 149, 150, 151, 152, 153, 0, 0, 0,
+ 0, 0, 0, 0, 154, 155, 156, 157, 0, 0,
+ 0, 0, 0, 0, 0, 0, 158, 159, 160, 0,
+ 0, 161, 162, 0, 163, 164, 165, 166, 167, 168,
+ 169, 0, 170, 171, 172, 173, 0, 132, 0, 174,
+ 0, 133, 134, 135, 0, 136, 0, 0, 175, 137,
+ 0, 177, 0, 178, 0, 138, 0, 179, 0, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 0, 0, 0, 0, 0, 0,
+ 0, 154, 155, 156, 157, 0, 0, 0, 0, 0,
+ 0, 0, 0, 158, 159, 160, 0, 0, 161, 162,
+ 0, 163, 164, 165, 166, 167, 168, 169, 0, 170,
+ 171, 172, 173, 0, 0, 132, 174, 0, 395, 133,
+ 134, 135, 0, 136, 0, 175, 0, 137, 177, 0,
+ 178, 0, 0, 138, 179, 0, 0, 139, 140, 141,
+ 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 0, 0, 0, 0, 0, 0, 0, 154,
+ 155, 156, 157, 0, 0, 0, 0, 0, 0, 0,
+ 0, 158, 159, 160, 0, 0, 161, 162, 0, 163,
+ 164, 165, 166, 167, 168, 169, 0, 170, 171, 172,
+ 173, 0, 0, 132, 174, 0, 0, 133, 134, 135,
+ 396, 136, 0, 175, 0, 137, 177, 0, 178, 0,
+ 0, 138, 179, 0, 0, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
+ 0, 0, 0, 0, 0, 0, 0, 154, 155, 156,
+ 157, 0, 0, 0, 0, 0, 0, 0, 0, 158,
+ 159, 160, 0, 0, 161, 162, 0, 163, 164, 165,
+ 166, 167, 168, 169, 0, 170, 171, 172, 173, 0,
+ 132, 0, 174, 0, 133, 134, 135, 0, 136, 426,
+ 0, 175, 137, 0, 177, 0, 178, 0, 138, 0,
+ 179, 0, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 148, 149, 150, 151, 152, 153, 0, 0, 0,
+ 0, 0, 0, 0, 154, 155, 156, 157, 0, 0,
+ 0, 0, 0, 0, 0, 0, 158, 159, 160, 0,
+ 0, 161, 162, 0, 163, 164, 165, 166, 167, 168,
+ 169, 0, 170, 171, 172, 173, 0, 132, 0, 174,
+ 0, 133, 134, 135, 0, 136, 0, 451, 175, 137,
+ 0, 177, 0, 178, 0, 138, 0, 179, 0, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 0, 0, 0, 0, 0, 0,
+ 0, 154, 155, 156, 157, 0, 0, 0, 0, 0,
+ 0, 0, 0, 158, 159, 160, 0, 0, 161, 162,
+ 0, 163, 164, 165, 166, 167, 168, 169, 0, 170,
+ 171, 172, 173, 0, 132, 0, 174, 0, 133, 134,
+ 135, 0, 136, 0, 454, 175, 137, 0, 177, 0,
+ 178, 0, 138, 0, 179, 0, 139, 140, 141, 142,
+ 143, 144, 145, 146, 147, 148, 149, 150, 151, 152,
+ 153, 0, 0, 0, 0, 0, 0, 0, 154, 155,
+ 156, 157, 0, 0, 0, 0, 0, 0, 0, 0,
+ 158, 159, 160, 0, 0, 161, 162, 0, 163, 164,
+ 165, 166, 167, 168, 169, 0, 170, 171, 172, 173,
+ 0, 132, 0, 174, 0, 133, 134, 135, 0, 136,
+ 0, 456, 175, 137, 0, 177, 0, 178, 0, 138,
+ 0, 179, 0, 139, 140, 141, 142, 143, 144, 145,
+ 146, 147, 148, 149, 150, 151, 152, 153, 0, 0,
+ 0, 0, 0, 0, 0, 154, 155, 156, 157, 0,
+ 0, 0, 0, 0, 0, 0, 0, 158, 159, 160,
+ 0, 0, 161, 162, 0, 163, 164, 165, 166, 167,
+ 168, 169, 0, 170, 171, 172, 173, 0, 132, 0,
+ 174, 0, 133, 134, 135, 0, 136, 0, 459, 175,
+ 137, 0, 177, 0, 178, 0, 138, 0, 179, 0,
+ 139, 140, 141, 142, 143, 144, 145, 146, 147, 148,
+ 149, 150, 151, 152, 153, 0, 0, 0, 0, 0,
+ 0, 0, 154, 155, 156, 157, 0, 0, 0, 0,
+ 0, 0, 0, 0, 158, 159, 160, 0, 0, 161,
+ 162, 0, 163, 164, 165, 166, 167, 168, 169, 0,
+ 170, 171, 172, 173, 0, 132, 0, 174, 0, 133,
+ 134, 135, 0, 136, 467, 0, 175, 137, 0, 177,
+ 0, 178, 0, 138, 0, 179, 0, 139, 140, 141,
+ 142, 143, 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 0, 0, 0, 0, 0, 0, 0, 154,
+ 155, 156, 157, 0, 0, 0, 0, 0, 0, 0,
+ 0, 158, 159, 160, 0, 0, 161, 162, 0, 163,
+ 164, 165, 166, 167, 168, 169, 0, 170, 171, 172,
+ 173, 0, 0, 132, 174, 0, 468, 133, 134, 135,
+ 0, 136, 0, 175, 0, 137, 177, 0, 178, 0,
+ 0, 138, 179, 0, 0, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
+ 0, 0, 0, 0, 0, 0, 0, 154, 155, 156,
+ 157, 0, 0, 0, 0, 0, 0, 0, 0, 158,
+ 159, 160, 0, 0, 161, 162, 0, 163, 164, 165,
+ 166, 167, 168, 169, 0, 170, 171, 172, 173, 0,
+ 132, 0, 174, 0, 133, 134, 135, 0, 136, 0,
+ 500, 175, 137, 0, 177, 0, 178, 0, 138, 0,
+ 179, 0, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 148, 149, 150, 151, 152, 153, 0, 0, 0,
+ 0, 0, 0, 0, 154, 232, 156, 157, 0, 0,
+ 0, 0, 0, 0, 0, 0, 158, 159, 160, 0,
+ 0, 161, 162, 0, 163, 164, 165, 166, 167, 168,
+ 169, 0, 170, 171, 172, 173, 0, 132, 0, 174,
+ 0, 133, 134, 135, 0, 136, 0, 0, 175, 334,
+ 0, 177, 0, 178, 0, 138, 0, 179, 0, 139,
+ 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
+ 150, 151, 152, 153, 0, 0, 0, 0, 0, 0,
+ 0, 154, 155, 156, 157, 0, 0, 0, 0, 0,
+ 0, 0, 0, 158, 159, 160, 0, 0, 161, 162,
+ 0, 163, 164, 165, 166, 167, 168, 169, 0, 170,
+ 171, 172, 173, 132, 343, 0, 174, 133, 134, 135,
+ 0, 136, 0, 0, 0, 175, 0, 0, 177, 0,
+ 178, 138, 0, 0, 179, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151, 152, 153,
+ 0, 0, 0, 0, 0, 0, 0, 154, 155, 156,
+ 157, 0, 0, 0, 0, 0, 0, 0, 0, 158,
+ 159, 160, 0, 0, 161, 162, 0, 163, 164, 165,
+ 166, 167, 168, 169, 0, 170, 171, 172, 173, 132,
+ 0, 0, 174, 133, 134, 135, 0, 136, 0, 0,
+ 0, 175, 0, 0, 177, 0, 178, 138, 0, 0,
+ 179, 139, 140, 141, 142, 143, 144, 145, 146, 147,
+ 148, 149, 150, 151, 152, 153, 0, 0, 0, 0,
+ 0, 0, 0, 154, 155, 156, 157, 0, 0, 0,
+ 0, 0, 0, 0, 0, 158, 159, 160, 0, 0,
+ 161, 162, 0, 163, 164, 165, 166, 167, 168, 169,
+ 0, 170, 171, 172, 173, 0, 132, 0, 174, 0,
+ 133, 134, 135, 0, 136, 0, 452, 175, 137, 0,
+ 177, 0, 178, 0, 138, 0, 179, 0, 139, 140,
+ 141, 142, 143, 144, 145, 146, 147, 148, 149, 150,
+ 151, 152, 153, 0, 0, 0, 0, 0, 0, 0,
+ 154, 155, 156, 157, 0, 0, 0, 0, 0, 0,
+ 0, 0, 158, 159, 160, 0, 0, 161, 162, 0,
+ 163, 164, 165, 166, 167, 168, 169, 0, 170, 171,
+ 172, 173, 132, 0, 0, 174, 133, 134, 135, 0,
+ 136, 0, 0, 0, 175, 0, 0, 177, 0, 178,
+ 138, 0, 0, 179, 139, 140, 141, 142, 143, 144,
+ 145, 146, 147, 148, 149, 150, 151, 152, 153, 0,
+ 0, 0, 0, 0, 0, 0, 154, 155, 156, 157,
+ 0, 0, 0, 0, 0, 0, 0, 0, 158, 159,
+ 160, 0, 0, 161, 162, 0, 163, 164, 165, 166,
+ 167, 168, 169, 0, 170, 171, 172, 173, 132, 0,
+ 0, 174, 133, 134, 135, 0, 136, 0, 0, 0,
+ 175, 0, 0, 177, 0, 178, 138, 0, 0, 179,
+ 139, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 151, 0, 153, 0, 0, 0, 0, 0,
+ 0, 0, 154, 155, 156, 157, 0, 0, 0, 0,
+ 0, 0, 0, 0, 158, 159, 160, 0, 0, 161,
+ 162, 0, 163, 164, 165, 166, 167, 168, 169, 0,
+ 170, 171, 172, 173, 132, 0, 0, 174, 133, 134,
+ 135, 0, 136, 0, 0, 0, 175, 0, 0, 177,
+ 0, 178, 138, 0, 0, 179, 139, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 151, 0,
+ 153, 0, 0, 0, 0, 0, 0, 0, 154, 155,
+ 156, 157, 0, 0, 0, 0, 0, 0, 0, 0,
+ 158, 159, 160, 0, 0, 161, 162, 0, 163, 164,
+ 165, 166, 167, 168, 0, 0, 170, 171, 172, 173,
+ 133, 134, 135, 0, 136, 0, 0, 0, 0, 0,
+ 0, 0, 175, 0, 138, 177, 0, 178, 139, 0,
+ 0, 179, 0, 0, 0, 0, 0, 0, 0, 0,
+ 151, 0, 153, 0, 0, 0, 0, 0, 0, 0,
+ 154, 155, 156, 157, 0, 0, 0, 0, 0, 0,
+ 0, 0, 158, 159, 160, 0, 0, 161, 162, 0,
+ 163, 164, 165, 166, 167, 168, 0, 0, 170, 171,
+ 172, 173, 133, 134, 0, 0, 136, 0, 0, 0,
+ 0, 0, 0, 0, 175, 0, 138, 177, 0, 178,
+ 139, 0, 0, 179, 0, 0, 0, 0, 0, 0,
+ 0, 0, 151, 0, 153, 0, 0, 0, 14, 15,
+ 0, 0, 154, 155, 156, 157, 0, 0, 0, 0,
+ 0, 0, 23, 0, 158, 159, 160, 0, 0, 161,
+ 162, 0, 163, 164, 165, 166, 167, 168, 0, 0,
+ 170, 171, 172, 173, 133, 134, 34, 35, 36, 0,
+ 497, 0, 0, 0, 0, 0, 175, 0, 138, 177,
+ 0, 178, 139, 0, 0, 179, 0, 0, 124, 45,
+ 0, 125, 0, 0, 151, 0, 153, 49, 50, 14,
+ 15, 0, 0, 0, 154, 155, 156, 157, 0, 0,
+ 0, 0, 0, 23, 0, 0, 158, 159, 160, 0,
+ 0, 161, 162, 0, 163, 164, 165, 166, 167, 168,
+ 0, 133, 170, 171, 172, 173, 0, 34, 35, 36,
+ 0, 506, 0, 0, 0, 138, 0, 0, 175, 139,
+ 0, 177, 0, 178, 0, 0, 0, 179, 0, 124,
+ 45, 151, 125, 153, 0, 0, 0, 0, 49, 50,
+ 0, 154, 155, 156, 157, 0, 0, 0, 0, 0,
+ 0, 0, 0, 158, 159, 160, 0, 0, 161, 162,
+ 0, 163, 164, 165, 166, 167, 168, 0, 0, 170,
+ 171, 172, 173, 138, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 175, 0, 0, 177, 0,
+ 178, 0, 0, 0, 179, 0, 0, 0, 0, 154,
+ 155, 156, 157, 0, 0, 0, 0, 0, 0, 0,
+ 0, 158, 159, 160, 0, 0, 161, 162, 0, 163,
+ 164, 165, 166, 0, 0, 0, 0, 170, 171, 172,
+ 173, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 175, 0, 0, 177, 0, 178, 0,
+ 0, 0, 179
+};
+
+/* YYCONFLP[YYPACT[STATE-NUM]] -- Pointer into YYCONFL of start of
+ list of conflicting reductions corresponding to action entry for
+ state STATE-NUM in yytable. 0 means no conflicts. The list in
+ yyconfl is terminated by a rule number of 0. */
+static const unsigned char yyconflp[] =
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0
+};
+
+/* YYCONFL[I] -- lists of conflicting rule numbers, each terminated by
+ 0, pointed into by YYCONFLP. */
+static const short int yyconfl[] =
+{
+ 0, 36, 0
+};
+
+static const short int yycheck[] =
+{
+ 2, 2, 2, 2, 126, 2, 151, 38, 225, 11,
+ 4, 5, 6, 71, 182, 21, 247, 8, 180, 68,
+ 16, 80, 8, 19, 52, 15, 15, 15, 15, 21,
+ 29, 25, 0, 27, 28, 29, 30, 31, 32, 33,
+ 202, 15, 63, 37, 15, 41, 42, 59, 47, 63,
+ 59, 15, 93, 59, 60, 62, 115, 66, 54, 55,
+ 93, 52, 4, 340, 70, 86, 52, 14, 53, 68,
+ 52, 77, 78, 15, 59, 52, 104, 239, 59, 60,
+ 59, 93, 103, 79, 80, 81, 78, 83, 74, 103,
+ 367, 98, 99, 83, 239, 97, 90, 59, 60, 93,
+ 94, 90, 90, 90, 98, 101, 102, 101, 104, 105,
+ 63, 66, 93, 104, 110, 111, 90, 113, 104, 90,
+ 52, 106, 121, 59, 246, 119, 90, 59, 186, 360,
+ 188, 93, 85, 127, 128, 52, 66, 131, 132, 56,
+ 134, 135, 136, 137, 8, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 93, 152, 153,
+ 154, 155, 156, 157, 158, 159, 160, 161, 162, 163,
+ 164, 165, 66, 167, 168, 169, 170, 171, 227, 59,
+ 174, 175, 63, 177, 178, 179, 180, 66, 52, 52,
+ 83, 59, 60, 97, 252, 99, 52, 6, 66, 193,
+ 56, 10, 59, 60, 85, 199, 70, 238, 202, 18,
+ 204, 74, 21, 93, 42, 66, 66, 66, 66, 213,
+ 98, 223, 115, 116, 225, 59, 60, 55, 66, 52,
+ 66, 95, 66, 66, 43, 93, 66, 21, 232, 233,
+ 83, 235, 112, 52, 90, 239, 245, 56, 247, 243,
+ 59, 79, 93, 62, 416, 313, 52, 66, 21, 90,
+ 69, 70, 126, 52, 322, 59, 260, 76, 77, 52,
+ 15, 38, 52, 101, 442, 443, 104, 52, 93, 66,
+ 15, 38, 110, 111, 98, 502, 95, 52, 97, 98,
+ 99, 23, 101, 66, 14, 104, 59, 60, 420, 516,
+ 14, 93, 93, 15, 86, 90, 83, 70, 15, 340,
+ 42, 38, 75, 59, 77, 78, 86, 439, 182, 90,
+ 184, 15, 15, 55, 24, 5, 320, 93, 90, 59,
+ 66, 94, 494, 96, 93, 393, 367, 395, 14, 333,
+ 334, 335, 93, 345, 14, 339, 506, 79, 331, 343,
+ 185, 399, 216, 347, 399, 457, 501, 351, 480, 422,
+ 213, 360, 516, 357, 228, 385, 368, 434, 338, 101,
+ 102, 479, 104, 42, 319, 107, 108, 109, 110, 111,
+ 192, 375, 246, 245, 357, 282, 55, 381, 347, 383,
+ 151, 390, 256, 257, -1, -1, -1, -1, 399, 399,
+ 399, 403, 399, -1, -1, -1, -1, -1, -1, -1,
+ 79, -1, -1, -1, 83, -1, -1, -1, -1, -1,
+ -1, -1, 416, 417, -1, -1, 457, -1, 459, -1,
+ -1, -1, 101, 102, -1, 104, -1, -1, -1, -1,
+ 471, 110, 111, -1, -1, -1, -1, 446, -1, -1,
+ -1, -1, 454, -1, 456, 319, 6, -1, 8, -1,
+ 10, 455, -1, -1, -1, -1, -1, -1, 18, -1,
+ -1, 21, -1, 337, 338, 25, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 43, -1, -1, -1, 498, 500, -1,
+ 494, -1, 52, -1, -1, -1, 56, 501, -1, 59,
+ -1, 513, 62, 63, 64, -1, 66, -1, -1, 69,
+ 70, -1, -1, -1, -1, -1, 76, 77, -1, -1,
+ -1, -1, -1, -1, -1, 85, -1, -1, -1, -1,
+ 6, 405, 8, -1, 10, 95, -1, 97, 98, 99,
+ -1, 101, 18, -1, 104, 21, 420, -1, -1, 25,
+ 424, -1, -1, -1, -1, -1, 116, -1, -1, -1,
+ -1, 435, -1, -1, -1, 439, -1, 43, 442, 443,
+ -1, -1, -1, -1, -1, -1, 52, -1, -1, 42,
+ 56, -1, -1, 59, -1, -1, 62, -1, 64, -1,
+ 66, -1, 55, 69, 70, -1, -1, -1, -1, -1,
+ 76, 77, -1, -1, -1, 6, 480, 8, -1, 10,
+ -1, -1, -1, -1, 90, -1, 79, 18, -1, 95,
+ 21, 97, 98, 99, 25, 101, -1, -1, 104, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 101, 102,
+ 116, 104, 43, -1, -1, -1, -1, 110, 111, -1,
+ -1, 52, -1, -1, -1, 56, -1, -1, 59, -1,
+ -1, 62, -1, 64, -1, 66, -1, -1, 69, 70,
+ -1, -1, -1, -1, -1, 76, 77, -1, -1, -1,
+ 6, -1, 8, -1, 10, -1, -1, -1, -1, 90,
+ -1, -1, 18, -1, 95, 21, 97, 98, 99, 25,
+ 101, -1, -1, 104, -1, -1, -1, 21, -1, -1,
+ -1, -1, -1, -1, -1, 116, -1, 43, -1, -1,
+ -1, -1, -1, -1, -1, -1, 52, -1, -1, -1,
+ 56, -1, -1, 59, -1, -1, 62, -1, 64, -1,
+ 66, -1, -1, 69, 70, 59, 60, -1, -1, -1,
+ 76, 77, -1, -1, -1, 69, 70, -1, -1, -1,
+ -1, 75, 76, 77, 78, -1, -1, -1, -1, 95,
+ -1, 97, 98, 99, -1, 101, -1, 6, 104, 8,
+ 94, 10, 96, 12, 13, -1, 100, -1, 17, 18,
+ 116, 20, 21, -1, -1, -1, 25, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 41, 42, 43, 44, 45, 46, -1, -1,
+ -1, -1, 51, 52, 53, -1, 55, 56, 57, -1,
+ 59, -1, -1, 62, -1, 64, -1, 66, -1, -1,
+ 69, 70, -1, -1, -1, -1, -1, 76, 77, -1,
+ 79, 80, 81, -1, -1, -1, -1, -1, 87, -1,
+ -1, -1, -1, 92, 93, -1, 95, -1, 97, 98,
+ 99, -1, 101, 102, -1, 104, 105, 106, -1, -1,
+ -1, 110, 111, 112, 113, 114, 6, -1, 8, -1,
+ 10, -1, 12, -1, -1, -1, -1, 17, 18, -1,
+ 20, 21, -1, -1, -1, 25, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 41, 42, 43, 44, 45, 46, -1, -1, -1,
+ -1, 51, 52, 53, -1, 55, 56, 57, -1, 59,
+ -1, -1, 62, -1, 64, -1, 66, -1, -1, 69,
+ 70, -1, -1, -1, -1, -1, 76, 77, -1, 79,
+ 80, 81, -1, 83, -1, -1, -1, 87, -1, -1,
+ -1, -1, 92, 93, -1, 95, -1, 97, 98, 99,
+ -1, 101, 102, -1, 104, -1, 106, -1, -1, -1,
+ 110, 111, 112, 113, 114, 6, -1, 8, -1, 10,
+ -1, 12, -1, -1, -1, -1, 17, 18, -1, 20,
+ 21, -1, -1, -1, 25, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 41, 42, 43, 44, 45, 46, -1, -1, -1, -1,
+ 51, 52, 53, -1, 55, 56, 57, -1, 59, -1,
+ -1, 62, -1, 64, -1, 66, -1, -1, 69, 70,
+ -1, -1, -1, -1, -1, 76, 77, -1, 79, 80,
+ 81, -1, 83, -1, -1, -1, 87, -1, -1, -1,
+ -1, 92, 93, -1, 95, -1, 97, 98, 99, -1,
+ 101, 102, -1, 104, -1, 106, -1, -1, -1, 110,
+ 111, 112, 113, 114, 6, -1, 8, -1, 10, -1,
+ 12, 42, -1, -1, -1, 17, 18, -1, 20, 21,
+ -1, -1, -1, 25, 55, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 43, 44, 45, 46, -1, -1, -1, 79, 51,
+ 52, 53, 83, -1, 56, 57, -1, 59, -1, -1,
+ 62, -1, 64, -1, 66, -1, -1, 69, 70, -1,
+ 101, 102, -1, 104, 76, 77, -1, -1, -1, 110,
+ 111, 83, -1, -1, -1, 87, -1, -1, -1, -1,
+ 92, 93, -1, 95, -1, 97, 98, 99, -1, 101,
+ -1, -1, 104, 6, 106, 8, -1, 10, -1, 12,
+ 112, 113, 114, -1, 17, 18, -1, 20, 21, -1,
+ -1, -1, 25, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ 43, 44, 45, 46, -1, -1, -1, -1, 51, 52,
+ 53, -1, -1, 56, 57, -1, 59, -1, -1, 62,
+ -1, 64, -1, 66, -1, -1, 69, 70, -1, -1,
+ -1, -1, -1, 76, 77, -1, -1, -1, -1, -1,
+ 83, -1, -1, -1, 87, -1, -1, -1, -1, 92,
+ 93, -1, 95, -1, 97, 98, 99, -1, 101, -1,
+ -1, 104, 6, 106, 8, -1, 10, -1, 12, 112,
+ 113, 114, -1, 17, 18, -1, 20, 21, -1, -1,
+ -1, 25, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, 43,
+ 44, 45, 46, -1, -1, -1, -1, 51, 52, 53,
+ -1, -1, 56, 57, -1, 59, -1, -1, 62, -1,
+ 64, -1, 66, -1, -1, 69, 70, -1, -1, -1,
+ -1, -1, 76, 77, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 87, -1, -1, -1, -1, 92, 93,
+ -1, 95, -1, 97, 98, 99, -1, 101, -1, -1,
+ 104, 6, 106, 8, -1, 10, -1, 12, 112, 113,
+ 114, -1, 17, 18, -1, 20, 21, -1, -1, -1,
+ 25, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 43, 44,
+ 45, 46, -1, -1, -1, -1, 51, 52, 53, -1,
+ -1, 56, 57, -1, 59, -1, -1, 62, -1, 64,
+ -1, 66, -1, -1, 69, 70, -1, -1, -1, -1,
+ -1, 76, 77, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 87, -1, -1, -1, -1, 92, 93, -1,
+ 95, -1, 97, 98, 99, -1, 101, -1, -1, 104,
+ 6, 106, 8, -1, 10, -1, 12, 112, 113, 114,
+ -1, 17, 18, -1, 20, 21, -1, -1, -1, 25,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 43, 44, 45,
+ 46, -1, -1, -1, -1, -1, 52, 53, -1, -1,
+ 56, -1, -1, 59, -1, -1, 62, -1, 64, -1,
+ 66, -1, -1, 69, 70, 6, -1, 8, -1, 10,
+ 76, 77, -1, -1, -1, -1, -1, 18, -1, -1,
+ 21, 87, -1, -1, 25, -1, 92, 93, -1, 95,
+ -1, 97, 98, 99, -1, 101, -1, -1, 104, 40,
+ 106, 42, 43, -1, -1, -1, 112, -1, 114, -1,
+ -1, 52, -1, -1, 55, 56, -1, -1, 59, -1,
+ -1, 62, 6, 64, 8, 66, 10, -1, 69, 70,
+ -1, -1, -1, -1, 18, 76, 77, 21, 79, -1,
+ -1, 25, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, 95, -1, 97, 98, 99, 43,
+ 101, 102, -1, 104, -1, -1, -1, -1, 52, 110,
+ 111, -1, 56, -1, -1, 59, -1, -1, 62, 63,
+ 64, -1, 66, -1, -1, 69, 70, 6, -1, 8,
+ -1, 10, 76, 77, -1, -1, -1, -1, -1, 18,
+ -1, 85, 21, -1, -1, -1, 25, -1, -1, -1,
+ -1, 95, -1, 97, 98, 99, 21, 101, -1, -1,
+ 104, -1, -1, -1, 43, -1, -1, -1, -1, 48,
+ -1, -1, -1, 52, -1, -1, -1, 56, -1, -1,
+ 59, -1, -1, 62, 6, 64, 8, 66, 10, -1,
+ 69, 70, -1, -1, 59, 60, 18, 76, 77, 21,
+ -1, -1, 67, 25, 69, 70, -1, -1, -1, -1,
+ 75, 76, 77, 78, -1, -1, 95, -1, 97, 98,
+ 99, 43, 101, -1, -1, 104, 91, -1, -1, 94,
+ 52, 96, -1, -1, 56, 100, -1, 59, -1, -1,
+ 62, 6, 64, 8, 66, 10, -1, 69, 70, -1,
+ -1, -1, -1, 18, 76, 77, 21, -1, -1, -1,
+ 25, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, 93, -1, 95, -1, 97, 98, 99, 43, 101,
+ -1, -1, 104, -1, -1, -1, -1, 52, -1, -1,
+ -1, 56, -1, -1, 59, -1, -1, 62, 6, 64,
+ 8, 66, 10, -1, 69, 70, -1, -1, -1, -1,
+ 18, 76, 77, 21, -1, -1, -1, 25, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 93, -1,
+ 95, -1, 97, 98, 99, 43, 101, -1, -1, 104,
+ -1, -1, -1, -1, 52, -1, -1, -1, 56, -1,
+ -1, 59, -1, -1, 62, 6, 64, 8, 66, 10,
+ -1, 69, 70, -1, -1, -1, -1, 18, 76, 77,
+ 21, -1, -1, -1, 25, -1, 84, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, 95, -1, 97,
+ 98, 99, 43, 101, -1, -1, 104, -1, -1, -1,
+ -1, 52, -1, -1, -1, 56, -1, -1, 59, -1,
+ -1, 62, 6, 64, 8, 66, 10, -1, 69, 70,
+ -1, -1, -1, -1, 18, 76, 77, 21, -1, -1,
+ -1, 25, -1, -1, -1, -1, -1, -1, -1, 90,
+ -1, -1, -1, -1, 95, -1, 97, 98, 99, 43,
+ 101, -1, -1, 104, -1, -1, -1, -1, 52, -1,
+ -1, -1, 56, -1, -1, 59, -1, -1, 62, -1,
+ 64, -1, 66, -1, -1, 69, 70, -1, -1, -1,
+ -1, -1, 76, 77, -1, -1, -1, -1, -1, -1,
+ 3, -1, -1, -1, 7, 8, 9, -1, 11, -1,
+ -1, 95, 15, 97, 98, 99, -1, 101, 21, 22,
+ 104, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, -1, -1, -1,
+ -1, -1, -1, -1, 47, 48, 49, 50, -1, -1,
+ -1, -1, -1, -1, -1, -1, 59, 60, 61, -1,
+ -1, 64, 65, -1, 67, 68, 69, 70, 71, 72,
+ 73, -1, 75, 76, 77, 78, -1, -1, 3, 82,
+ -1, 84, 7, 8, 9, -1, 11, -1, 91, -1,
+ 15, 94, -1, 96, -1, -1, 21, 100, -1, -1,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, -1, -1, -1, -1, -1,
+ -1, -1, 47, 48, 49, 50, -1, -1, -1, -1,
+ -1, -1, -1, -1, 59, 60, 61, -1, -1, 64,
+ 65, -1, 67, 68, 69, 70, 71, 72, 73, -1,
+ 75, 76, 77, 78, -1, 3, -1, 82, -1, 7,
+ 8, 9, -1, 11, -1, -1, 91, 15, 93, 94,
+ -1, 96, -1, 21, -1, 100, -1, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, -1, -1, -1, -1, -1, -1, -1, 47,
+ 48, 49, 50, -1, -1, -1, -1, -1, -1, -1,
+ 58, 59, 60, 61, -1, -1, 64, 65, -1, 67,
+ 68, 69, 70, 71, 72, 73, -1, 75, 76, 77,
+ 78, -1, 3, -1, 82, -1, 7, 8, 9, -1,
+ 11, -1, -1, 91, 15, -1, 94, -1, 96, -1,
+ 21, -1, 100, -1, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, -1,
+ -1, -1, -1, -1, -1, -1, 47, 48, 49, 50,
+ -1, -1, -1, -1, -1, -1, -1, -1, 59, 60,
+ 61, -1, -1, 64, 65, -1, 67, 68, 69, 70,
+ 71, 72, 73, -1, 75, 76, 77, 78, -1, -1,
+ 3, 82, -1, -1, 7, 8, 9, 88, 11, -1,
+ 91, -1, 15, 94, -1, 96, -1, -1, 21, 100,
+ -1, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, -1, -1, -1,
+ -1, -1, -1, -1, 47, 48, 49, 50, -1, -1,
+ -1, -1, -1, -1, -1, -1, 59, 60, 61, -1,
+ -1, 64, 65, -1, 67, 68, 69, 70, 71, 72,
+ 73, -1, 75, 76, 77, 78, -1, 3, -1, 82,
+ -1, 7, 8, 9, -1, 11, -1, 90, 91, 15,
+ -1, 94, -1, 96, -1, 21, -1, 100, -1, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, -1, -1, -1, -1, -1, -1,
+ -1, 47, 48, 49, 50, -1, -1, -1, -1, -1,
+ -1, -1, -1, 59, 60, 61, -1, -1, 64, 65,
+ -1, 67, 68, 69, 70, 71, 72, 73, -1, 75,
+ 76, 77, 78, -1, 3, -1, 82, -1, 7, 8,
+ 9, -1, 11, -1, -1, 91, 15, 93, 94, -1,
+ 96, -1, 21, -1, 100, -1, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, -1, -1, -1, -1, -1, -1, -1, 47, 48,
+ 49, 50, -1, -1, -1, -1, -1, -1, -1, -1,
+ 59, 60, 61, -1, -1, 64, 65, -1, 67, 68,
+ 69, 70, 71, 72, 73, -1, 75, 76, 77, 78,
+ -1, 3, -1, 82, -1, 7, 8, 9, -1, 11,
+ -1, 90, 91, 15, -1, 94, -1, 96, -1, 21,
+ -1, 100, -1, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, -1, -1,
+ -1, -1, -1, -1, -1, 47, 48, 49, 50, -1,
+ -1, -1, -1, -1, -1, -1, -1, 59, 60, 61,
+ -1, -1, 64, 65, -1, 67, 68, 69, 70, 71,
+ 72, 73, -1, 75, 76, 77, 78, -1, 3, -1,
+ 82, -1, 7, 8, 9, -1, 11, -1, -1, 91,
+ 15, 93, 94, -1, 96, -1, 21, -1, 100, -1,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, -1, -1, -1, -1, -1,
+ -1, -1, 47, 48, 49, 50, -1, -1, -1, -1,
+ -1, -1, -1, -1, 59, 60, 61, -1, -1, 64,
+ 65, -1, 67, 68, 69, 70, 71, 72, 73, -1,
+ 75, 76, 77, 78, 3, 4, -1, 82, 7, 8,
+ 9, -1, 11, -1, -1, 90, 91, -1, -1, 94,
+ -1, 96, 21, -1, -1, 100, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, -1, -1, -1, -1, -1, -1, -1, 47, 48,
+ 49, 50, -1, -1, -1, -1, -1, -1, -1, -1,
+ 59, 60, 61, -1, -1, 64, 65, -1, 67, 68,
+ 69, 70, 71, 72, 73, -1, 75, 76, 77, 78,
+ -1, 3, -1, 82, -1, 7, 8, 9, -1, 11,
+ -1, -1, 91, 15, 93, 94, -1, 96, -1, 21,
+ -1, 100, -1, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, -1, -1,
+ -1, -1, -1, -1, -1, 47, 48, 49, 50, -1,
+ -1, -1, -1, -1, -1, -1, -1, 59, 60, 61,
+ -1, -1, 64, 65, -1, 67, 68, 69, 70, 71,
+ 72, 73, -1, 75, 76, 77, 78, -1, 3, -1,
+ 82, -1, 7, 8, 9, -1, 11, -1, 90, 91,
+ 15, -1, 94, -1, 96, -1, 21, -1, 100, -1,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, -1, -1, -1, -1, -1,
+ -1, -1, 47, 48, 49, 50, -1, -1, -1, -1,
+ -1, -1, -1, -1, 59, 60, 61, -1, -1, 64,
+ 65, -1, 67, 68, 69, 70, 71, 72, 73, -1,
+ 75, 76, 77, 78, -1, 3, -1, 82, -1, 7,
+ 8, 9, -1, 11, -1, 90, 91, 15, -1, 94,
+ -1, 96, -1, 21, -1, 100, -1, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, -1, -1, -1, -1, -1, -1, -1, 47,
+ 48, 49, 50, -1, -1, -1, -1, -1, -1, -1,
+ -1, 59, 60, 61, -1, -1, 64, 65, -1, 67,
+ 68, 69, 70, 71, 72, 73, -1, 75, 76, 77,
+ 78, -1, 3, -1, 82, -1, 7, 8, 9, -1,
+ 11, -1, 90, 91, 15, -1, 94, -1, 96, -1,
+ 21, -1, 100, -1, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, -1,
+ -1, -1, -1, -1, -1, -1, 47, 48, 49, 50,
+ -1, -1, -1, -1, -1, -1, -1, -1, 59, 60,
+ 61, -1, -1, 64, 65, -1, 67, 68, 69, 70,
+ 71, 72, 73, -1, 75, 76, 77, 78, -1, -1,
+ 3, 82, 83, -1, 7, 8, 9, -1, 11, -1,
+ 91, 14, 15, 94, -1, 96, -1, -1, 21, 100,
+ -1, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, -1, -1, -1,
+ -1, -1, -1, -1, 47, 48, 49, 50, -1, -1,
+ -1, -1, -1, -1, -1, -1, 59, 60, 61, -1,
+ -1, 64, 65, -1, 67, 68, 69, 70, 71, 72,
+ 73, -1, 75, 76, 77, 78, -1, 3, -1, 82,
+ -1, 7, 8, 9, -1, 11, -1, -1, 91, 15,
+ -1, 94, -1, 96, -1, 21, -1, 100, -1, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, -1, -1, -1, -1, -1, -1,
+ -1, 47, 48, 49, 50, -1, -1, -1, -1, -1,
+ -1, -1, -1, 59, 60, 61, -1, -1, 64, 65,
+ -1, 67, 68, 69, 70, 71, 72, 73, -1, 75,
+ 76, 77, 78, -1, -1, 3, 82, -1, 84, 7,
+ 8, 9, -1, 11, -1, 91, -1, 15, 94, -1,
+ 96, -1, -1, 21, 100, -1, -1, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, -1, -1, -1, -1, -1, -1, -1, 47,
+ 48, 49, 50, -1, -1, -1, -1, -1, -1, -1,
+ -1, 59, 60, 61, -1, -1, 64, 65, -1, 67,
+ 68, 69, 70, 71, 72, 73, -1, 75, 76, 77,
+ 78, -1, -1, 3, 82, -1, -1, 7, 8, 9,
+ 88, 11, -1, 91, -1, 15, 94, -1, 96, -1,
+ -1, 21, 100, -1, -1, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ -1, -1, -1, -1, -1, -1, -1, 47, 48, 49,
+ 50, -1, -1, -1, -1, -1, -1, -1, -1, 59,
+ 60, 61, -1, -1, 64, 65, -1, 67, 68, 69,
+ 70, 71, 72, 73, -1, 75, 76, 77, 78, -1,
+ 3, -1, 82, -1, 7, 8, 9, -1, 11, 89,
+ -1, 91, 15, -1, 94, -1, 96, -1, 21, -1,
+ 100, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, -1, -1, -1,
+ -1, -1, -1, -1, 47, 48, 49, 50, -1, -1,
+ -1, -1, -1, -1, -1, -1, 59, 60, 61, -1,
+ -1, 64, 65, -1, 67, 68, 69, 70, 71, 72,
+ 73, -1, 75, 76, 77, 78, -1, 3, -1, 82,
+ -1, 7, 8, 9, -1, 11, -1, 90, 91, 15,
+ -1, 94, -1, 96, -1, 21, -1, 100, -1, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, -1, -1, -1, -1, -1, -1,
+ -1, 47, 48, 49, 50, -1, -1, -1, -1, -1,
+ -1, -1, -1, 59, 60, 61, -1, -1, 64, 65,
+ -1, 67, 68, 69, 70, 71, 72, 73, -1, 75,
+ 76, 77, 78, -1, 3, -1, 82, -1, 7, 8,
+ 9, -1, 11, -1, 90, 91, 15, -1, 94, -1,
+ 96, -1, 21, -1, 100, -1, 25, 26, 27, 28,
+ 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,
+ 39, -1, -1, -1, -1, -1, -1, -1, 47, 48,
+ 49, 50, -1, -1, -1, -1, -1, -1, -1, -1,
+ 59, 60, 61, -1, -1, 64, 65, -1, 67, 68,
+ 69, 70, 71, 72, 73, -1, 75, 76, 77, 78,
+ -1, 3, -1, 82, -1, 7, 8, 9, -1, 11,
+ -1, 90, 91, 15, -1, 94, -1, 96, -1, 21,
+ -1, 100, -1, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, -1, -1,
+ -1, -1, -1, -1, -1, 47, 48, 49, 50, -1,
+ -1, -1, -1, -1, -1, -1, -1, 59, 60, 61,
+ -1, -1, 64, 65, -1, 67, 68, 69, 70, 71,
+ 72, 73, -1, 75, 76, 77, 78, -1, 3, -1,
+ 82, -1, 7, 8, 9, -1, 11, -1, 90, 91,
+ 15, -1, 94, -1, 96, -1, 21, -1, 100, -1,
+ 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
+ 35, 36, 37, 38, 39, -1, -1, -1, -1, -1,
+ -1, -1, 47, 48, 49, 50, -1, -1, -1, -1,
+ -1, -1, -1, -1, 59, 60, 61, -1, -1, 64,
+ 65, -1, 67, 68, 69, 70, 71, 72, 73, -1,
+ 75, 76, 77, 78, -1, 3, -1, 82, -1, 7,
+ 8, 9, -1, 11, 89, -1, 91, 15, -1, 94,
+ -1, 96, -1, 21, -1, 100, -1, 25, 26, 27,
+ 28, 29, 30, 31, 32, 33, 34, 35, 36, 37,
+ 38, 39, -1, -1, -1, -1, -1, -1, -1, 47,
+ 48, 49, 50, -1, -1, -1, -1, -1, -1, -1,
+ -1, 59, 60, 61, -1, -1, 64, 65, -1, 67,
+ 68, 69, 70, 71, 72, 73, -1, 75, 76, 77,
+ 78, -1, -1, 3, 82, -1, 84, 7, 8, 9,
+ -1, 11, -1, 91, -1, 15, 94, -1, 96, -1,
+ -1, 21, 100, -1, -1, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ -1, -1, -1, -1, -1, -1, -1, 47, 48, 49,
+ 50, -1, -1, -1, -1, -1, -1, -1, -1, 59,
+ 60, 61, -1, -1, 64, 65, -1, 67, 68, 69,
+ 70, 71, 72, 73, -1, 75, 76, 77, 78, -1,
+ 3, -1, 82, -1, 7, 8, 9, -1, 11, -1,
+ 90, 91, 15, -1, 94, -1, 96, -1, 21, -1,
+ 100, -1, 25, 26, 27, 28, 29, 30, 31, 32,
+ 33, 34, 35, 36, 37, 38, 39, -1, -1, -1,
+ -1, -1, -1, -1, 47, 48, 49, 50, -1, -1,
+ -1, -1, -1, -1, -1, -1, 59, 60, 61, -1,
+ -1, 64, 65, -1, 67, 68, 69, 70, 71, 72,
+ 73, -1, 75, 76, 77, 78, -1, 3, -1, 82,
+ -1, 7, 8, 9, -1, 11, -1, -1, 91, 15,
+ -1, 94, -1, 96, -1, 21, -1, 100, -1, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, -1, -1, -1, -1, -1, -1,
+ -1, 47, 48, 49, 50, -1, -1, -1, -1, -1,
+ -1, -1, -1, 59, 60, 61, -1, -1, 64, 65,
+ -1, 67, 68, 69, 70, 71, 72, 73, -1, 75,
+ 76, 77, 78, 3, 4, -1, 82, 7, 8, 9,
+ -1, 11, -1, -1, -1, 91, -1, -1, 94, -1,
+ 96, 21, -1, -1, 100, 25, 26, 27, 28, 29,
+ 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,
+ -1, -1, -1, -1, -1, -1, -1, 47, 48, 49,
+ 50, -1, -1, -1, -1, -1, -1, -1, -1, 59,
+ 60, 61, -1, -1, 64, 65, -1, 67, 68, 69,
+ 70, 71, 72, 73, -1, 75, 76, 77, 78, 3,
+ -1, -1, 82, 7, 8, 9, -1, 11, -1, -1,
+ -1, 91, -1, -1, 94, -1, 96, 21, -1, -1,
+ 100, 25, 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, -1, -1, -1, -1,
+ -1, -1, -1, 47, 48, 49, 50, -1, -1, -1,
+ -1, -1, -1, -1, -1, 59, 60, 61, -1, -1,
+ 64, 65, -1, 67, 68, 69, 70, 71, 72, 73,
+ -1, 75, 76, 77, 78, -1, 3, -1, 82, -1,
+ 7, 8, 9, -1, 11, -1, 90, 91, 15, -1,
+ 94, -1, 96, -1, 21, -1, 100, -1, 25, 26,
+ 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
+ 37, 38, 39, -1, -1, -1, -1, -1, -1, -1,
+ 47, 48, 49, 50, -1, -1, -1, -1, -1, -1,
+ -1, -1, 59, 60, 61, -1, -1, 64, 65, -1,
+ 67, 68, 69, 70, 71, 72, 73, -1, 75, 76,
+ 77, 78, 3, -1, -1, 82, 7, 8, 9, -1,
+ 11, -1, -1, -1, 91, -1, -1, 94, -1, 96,
+ 21, -1, -1, 100, 25, 26, 27, 28, 29, 30,
+ 31, 32, 33, 34, 35, 36, 37, 38, 39, -1,
+ -1, -1, -1, -1, -1, -1, 47, 48, 49, 50,
+ -1, -1, -1, -1, -1, -1, -1, -1, 59, 60,
+ 61, -1, -1, 64, 65, -1, 67, 68, 69, 70,
+ 71, 72, 73, -1, 75, 76, 77, 78, 3, -1,
+ -1, 82, 7, 8, 9, -1, 11, -1, -1, -1,
+ 91, -1, -1, 94, -1, 96, 21, -1, -1, 100,
+ 25, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, 37, -1, 39, -1, -1, -1, -1, -1,
+ -1, -1, 47, 48, 49, 50, -1, -1, -1, -1,
+ -1, -1, -1, -1, 59, 60, 61, -1, -1, 64,
+ 65, -1, 67, 68, 69, 70, 71, 72, 73, -1,
+ 75, 76, 77, 78, 3, -1, -1, 82, 7, 8,
+ 9, -1, 11, -1, -1, -1, 91, -1, -1, 94,
+ -1, 96, 21, -1, -1, 100, 25, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, 37, -1,
+ 39, -1, -1, -1, -1, -1, -1, -1, 47, 48,
+ 49, 50, -1, -1, -1, -1, -1, -1, -1, -1,
+ 59, 60, 61, -1, -1, 64, 65, -1, 67, 68,
+ 69, 70, 71, 72, -1, -1, 75, 76, 77, 78,
+ 7, 8, 9, -1, 11, -1, -1, -1, -1, -1,
+ -1, -1, 91, -1, 21, 94, -1, 96, 25, -1,
+ -1, 100, -1, -1, -1, -1, -1, -1, -1, -1,
+ 37, -1, 39, -1, -1, -1, -1, -1, -1, -1,
+ 47, 48, 49, 50, -1, -1, -1, -1, -1, -1,
+ -1, -1, 59, 60, 61, -1, -1, 64, 65, -1,
+ 67, 68, 69, 70, 71, 72, -1, -1, 75, 76,
+ 77, 78, 7, 8, -1, -1, 11, -1, -1, -1,
+ -1, -1, -1, -1, 91, -1, 21, 94, -1, 96,
+ 25, -1, -1, 100, -1, -1, -1, -1, -1, -1,
+ -1, -1, 37, -1, 39, -1, -1, -1, 41, 42,
+ -1, -1, 47, 48, 49, 50, -1, -1, -1, -1,
+ -1, -1, 55, -1, 59, 60, 61, -1, -1, 64,
+ 65, -1, 67, 68, 69, 70, 71, 72, -1, -1,
+ 75, 76, 77, 78, 7, 8, 79, 80, 81, -1,
+ 83, -1, -1, -1, -1, -1, 91, -1, 21, 94,
+ -1, 96, 25, -1, -1, 100, -1, -1, 101, 102,
+ -1, 104, -1, -1, 37, -1, 39, 110, 111, 41,
+ 42, -1, -1, -1, 47, 48, 49, 50, -1, -1,
+ -1, -1, -1, 55, -1, -1, 59, 60, 61, -1,
+ -1, 64, 65, -1, 67, 68, 69, 70, 71, 72,
+ -1, 7, 75, 76, 77, 78, -1, 79, 80, 81,
+ -1, 83, -1, -1, -1, 21, -1, -1, 91, 25,
+ -1, 94, -1, 96, -1, -1, -1, 100, -1, 101,
+ 102, 37, 104, 39, -1, -1, -1, -1, 110, 111,
+ -1, 47, 48, 49, 50, -1, -1, -1, -1, -1,
+ -1, -1, -1, 59, 60, 61, -1, -1, 64, 65,
+ -1, 67, 68, 69, 70, 71, 72, -1, -1, 75,
+ 76, 77, 78, 21, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, 91, -1, -1, 94, -1,
+ 96, -1, -1, -1, 100, -1, -1, -1, -1, 47,
+ 48, 49, 50, -1, -1, -1, -1, -1, -1, -1,
+ -1, 59, 60, 61, -1, -1, 64, 65, -1, 67,
+ 68, 69, 70, -1, -1, -1, -1, 75, 76, 77,
+ 78, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, 91, -1, -1, 94, -1, 96, -1,
+ -1, -1, 100
+};
+
+/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
+ symbol of state STATE-NUM. */
+static const unsigned char yystos[] =
+{
+ 0, 124, 125, 0, 6, 8, 10, 12, 13, 17,
+ 18, 20, 21, 25, 41, 42, 43, 44, 45, 46,
+ 51, 52, 53, 55, 56, 57, 59, 62, 64, 66,
+ 69, 70, 76, 77, 79, 80, 81, 87, 92, 93,
+ 95, 97, 98, 99, 101, 102, 104, 105, 106, 110,
+ 111, 112, 113, 114, 126, 132, 135, 137, 139, 140,
+ 141, 142, 147, 148, 158, 161, 163, 166, 167, 168,
+ 175, 176, 177, 183, 184, 185, 189, 191, 192, 52,
+ 59, 101, 104, 158, 158, 158, 93, 104, 161, 93,
+ 66, 135, 52, 66, 66, 66, 52, 14, 66, 158,
+ 83, 164, 158, 48, 158, 40, 158, 175, 177, 158,
+ 158, 158, 158, 93, 158, 59, 163, 66, 98, 66,
+ 52, 59, 21, 78, 101, 104, 175, 66, 66, 136,
+ 161, 66, 3, 7, 8, 9, 11, 15, 21, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+ 36, 37, 38, 39, 47, 48, 49, 50, 59, 60,
+ 61, 64, 65, 67, 68, 69, 70, 71, 72, 73,
+ 75, 76, 77, 78, 82, 91, 93, 94, 96, 100,
+ 66, 168, 175, 93, 8, 74, 104, 133, 161, 169,
+ 171, 173, 59, 60, 174, 93, 174, 97, 99, 62,
+ 98, 99, 66, 21, 164, 59, 93, 59, 93, 158,
+ 112, 158, 93, 149, 158, 161, 162, 93, 135, 158,
+ 58, 83, 135, 151, 158, 165, 166, 167, 175, 181,
+ 182, 88, 48, 90, 90, 90, 93, 164, 52, 159,
+ 52, 116, 156, 157, 158, 59, 175, 178, 179, 180,
+ 52, 52, 161, 173, 158, 158, 15, 38, 158, 158,
+ 63, 85, 186, 187, 190, 158, 158, 158, 158, 52,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 186, 187, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 158, 158, 158, 158, 158, 158, 158,
+ 158, 158, 158, 52, 158, 158, 158, 158, 158, 90,
+ 156, 93, 133, 161, 66, 134, 174, 134, 174, 15,
+ 38, 176, 84, 158, 98, 158, 90, 156, 52, 158,
+ 128, 127, 90, 66, 15, 149, 93, 4, 15, 161,
+ 90, 83, 135, 4, 83, 151, 166, 15, 83, 158,
+ 158, 66, 163, 156, 187, 14, 14, 15, 90, 158,
+ 178, 170, 173, 83, 179, 93, 93, 90, 90, 161,
+ 56, 161, 90, 158, 86, 63, 85, 103, 188, 190,
+ 83, 22, 84, 14, 90, 66, 174, 152, 153, 154,
+ 155, 171, 158, 83, 174, 84, 88, 90, 129, 130,
+ 129, 158, 158, 90, 158, 161, 161, 162, 158, 140,
+ 163, 158, 83, 182, 158, 90, 15, 157, 158, 83,
+ 15, 140, 163, 135, 38, 59, 89, 158, 86, 103,
+ 158, 158, 152, 90, 15, 23, 107, 108, 109, 175,
+ 174, 174, 16, 19, 54, 83, 105, 132, 137, 166,
+ 177, 90, 90, 135, 90, 161, 90, 24, 146, 90,
+ 156, 158, 173, 146, 56, 161, 143, 89, 84, 90,
+ 5, 138, 154, 161, 172, 173, 133, 161, 133, 59,
+ 175, 93, 93, 135, 158, 135, 141, 163, 163, 90,
+ 83, 115, 116, 144, 66, 93, 163, 83, 165, 173,
+ 90, 160, 14, 156, 93, 131, 83, 93, 135, 145,
+ 158, 187, 150, 151, 90, 131, 14, 150
+};
+
+
+/* Prevent warning if -Wmissing-prototypes. */
+int yyparse (void);
+
+/* Error token number */
+#define YYTERROR 1
+
+/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N].
+ If N is 0, then set CURRENT to the empty location which ends
+ the previous symbol: RHS[0] (always defined). */
+
+
+#define YYRHSLOC(Rhs, K) ((Rhs)[K].yystate.yyloc)
+#ifndef YYLLOC_DEFAULT
+# define YYLLOC_DEFAULT(Current, Rhs, N) \
+ do \
+ if (YYID (N)) \
+ { \
+ (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \
+ (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \
+ (Current).last_line = YYRHSLOC (Rhs, N).last_line; \
+ (Current).last_column = YYRHSLOC (Rhs, N).last_column; \
+ } \
+ else \
+ { \
+ (Current).first_line = (Current).last_line = \
+ YYRHSLOC (Rhs, 0).last_line; \
+ (Current).first_column = (Current).last_column = \
+ YYRHSLOC (Rhs, 0).last_column; \
+ } \
+ while (YYID (0))
+
+/* YY_LOCATION_PRINT -- Print the location on the stream.
+ This macro was not mandated originally: define only if we know
+ we won't break user code: when these are the locations we know. */
+
+# define YY_LOCATION_PRINT(File, Loc) \
+ fprintf (File, "%d.%d-%d.%d", \
+ (Loc).first_line, (Loc).first_column, \
+ (Loc).last_line, (Loc).last_column)
+#endif
+
+
+#ifndef YY_LOCATION_PRINT
+# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
+#endif
+
+
+/* YYLEX -- calling `yylex' with the right arguments. */
+#define YYLEX yylex ()
+
+YYSTYPE yylval;
+
+YYLTYPE yylloc;
+
+int yynerrs;
+int yychar;
+
+static const int YYEOF = 0;
+static const int YYEMPTY = -2;
+
+typedef enum { yyok, yyaccept, yyabort, yyerr } YYRESULTTAG;
+
+#define YYCHK(YYE) \
+ do { YYRESULTTAG yyflag = YYE; if (yyflag != yyok) return yyflag; } \
+ while (YYID (0))
+
+#if YYDEBUG
+
+# ifndef YYFPRINTF
+# define YYFPRINTF fprintf
+# endif
+
+# define YYDPRINTF(Args) \
+do { \
+ if (yydebug) \
+ YYFPRINTF Args; \
+} while (YYID (0))
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+/*ARGSUSED*/
+static void
+yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+{
+ if (!yyvaluep)
+ return;
+ YYUSE (yylocationp);
+# ifdef YYPRINT
+ if (yytype < YYNTOKENS)
+ YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
+# else
+ YYUSE (yyoutput);
+# endif
+ switch (yytype)
+ {
+ default:
+ break;
+ }
+}
+
+
+/*--------------------------------.
+| Print this symbol on YYOUTPUT. |
+`--------------------------------*/
+
+static void
+yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep, YYLTYPE const * const yylocationp)
+{
+ if (yytype < YYNTOKENS)
+ YYFPRINTF (yyoutput, "token %s (", yytname[yytype]);
+ else
+ YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]);
+
+ YY_LOCATION_PRINT (yyoutput, *yylocationp);
+ YYFPRINTF (yyoutput, ": ");
+ yy_symbol_value_print (yyoutput, yytype, yyvaluep, yylocationp);
+ YYFPRINTF (yyoutput, ")");
+}
+
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
+do { \
+ if (yydebug) \
+ { \
+ YYFPRINTF (stderr, "%s ", Title); \
+ yy_symbol_print (stderr, Type, \
+ Value, Location); \
+ YYFPRINTF (stderr, "\n"); \
+ } \
+} while (YYID (0))
+
+/* Nonzero means print parse trace. It is left uninitialized so that
+ multiple parsers can coexist. */
+int yydebug;
+
+#else /* !YYDEBUG */
+
+# define YYDPRINTF(Args)
+# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
+
+#endif /* !YYDEBUG */
+
+/* YYINITDEPTH -- initial size of the parser's stacks. */
+#ifndef YYINITDEPTH
+# define YYINITDEPTH 200
+#endif
+
+/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
+ if the built-in stack extension method is used).
+
+ Do not make this value too large; the results are undefined if
+ SIZE_MAX < YYMAXDEPTH * sizeof (GLRStackItem)
+ evaluated with infinite-precision integer arithmetic. */
+
+#ifndef YYMAXDEPTH
+# define YYMAXDEPTH 10000
+#endif
+
+/* Minimum number of free items on the stack allowed after an
+ allocation. This is to allow allocation and initialization
+ to be completed by functions that call yyexpandGLRStack before the
+ stack is expanded, thus insuring that all necessary pointers get
+ properly redirected to new data. */
+#define YYHEADROOM 2
+
+#ifndef YYSTACKEXPANDABLE
+# if (! defined __cplusplus \
+ || (defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL \
+ && defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))
+# define YYSTACKEXPANDABLE 1
+# else
+# define YYSTACKEXPANDABLE 0
+# endif
+#endif
+
+#if YYSTACKEXPANDABLE
+# define YY_RESERVE_GLRSTACK(Yystack) \
+ do { \
+ if (Yystack->yyspaceLeft < YYHEADROOM) \
+ yyexpandGLRStack (Yystack); \
+ } while (YYID (0))
+#else
+# define YY_RESERVE_GLRSTACK(Yystack) \
+ do { \
+ if (Yystack->yyspaceLeft < YYHEADROOM) \
+ yyMemoryExhausted (Yystack); \
+ } while (YYID (0))
+#endif
+
+
+#if YYERROR_VERBOSE
+
+# ifndef yystpcpy
+# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
+# define yystpcpy stpcpy
+# else
+/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
+ YYDEST. */
+static char *
+yystpcpy (char *yydest, const char *yysrc)
+{
+ char *yyd = yydest;
+ const char *yys = yysrc;
+
+ while ((*yyd++ = *yys++) != '\0')
+ continue;
+
+ return yyd - 1;
+}
+# endif
+# endif
+
+# ifndef yytnamerr
+/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
+ quotes and backslashes, so that it's suitable for yyerror. The
+ heuristic is that double-quoting is unnecessary unless the string
+ contains an apostrophe, a comma, or backslash (other than
+ backslash-backslash). YYSTR is taken from yytname. If YYRES is
+ null, do not copy; instead, return the length of what the result
+ would have been. */
+static size_t
+yytnamerr (char *yyres, const char *yystr)
+{
+ if (*yystr == '"')
+ {
+ size_t yyn = 0;
+ char const *yyp = yystr;
+
+ for (;;)
+ switch (*++yyp)
+ {
+ case '\'':
+ case ',':
+ goto do_not_strip_quotes;
+
+ case '\\':
+ if (*++yyp != '\\')
+ goto do_not_strip_quotes;
+ /* Fall through. */
+ default:
+ if (yyres)
+ yyres[yyn] = *yyp;
+ yyn++;
+ break;
+
+ case '"':
+ if (yyres)
+ yyres[yyn] = '\0';
+ return yyn;
+ }
+ do_not_strip_quotes: ;
+ }
+
+ if (! yyres)
+ return strlen (yystr);
+
+ return yystpcpy (yyres, yystr) - yyres;
+}
+# endif
+
+#endif /* !YYERROR_VERBOSE */
+
+/** State numbers, as in LALR(1) machine */
+typedef int yyStateNum;
+
+/** Rule numbers, as in LALR(1) machine */
+typedef int yyRuleNum;
+
+/** Grammar symbol */
+typedef short int yySymbol;
+
+/** Item references, as in LALR(1) machine */
+typedef short int yyItemNum;
+
+typedef struct yyGLRState yyGLRState;
+typedef struct yyGLRStateSet yyGLRStateSet;
+typedef struct yySemanticOption yySemanticOption;
+typedef union yyGLRStackItem yyGLRStackItem;
+typedef struct yyGLRStack yyGLRStack;
+
+struct yyGLRState {
+ /** Type tag: always true. */
+ yybool yyisState;
+ /** Type tag for yysemantics. If true, yysval applies, otherwise
+ * yyfirstVal applies. */
+ yybool yyresolved;
+ /** Number of corresponding LALR(1) machine state. */
+ yyStateNum yylrState;
+ /** Preceding state in this stack */
+ yyGLRState* yypred;
+ /** Source position of the first token produced by my symbol */
+ size_t yyposn;
+ union {
+ /** First in a chain of alternative reductions producing the
+ * non-terminal corresponding to this state, threaded through
+ * yynext. */
+ yySemanticOption* yyfirstVal;
+ /** Semantic value for this state. */
+ YYSTYPE yysval;
+ } yysemantics;
+ /** Source location for this state. */
+ YYLTYPE yyloc;
+};
+
+struct yyGLRStateSet {
+ yyGLRState** yystates;
+ /** During nondeterministic operation, yylookaheadNeeds tracks which
+ * stacks have actually needed the current lookahead. During deterministic
+ * operation, yylookaheadNeeds[0] is not maintained since it would merely
+ * duplicate yychar != YYEMPTY. */
+ yybool* yylookaheadNeeds;
+ size_t yysize, yycapacity;
+};
+
+struct yySemanticOption {
+ /** Type tag: always false. */
+ yybool yyisState;
+ /** Rule number for this reduction */
+ yyRuleNum yyrule;
+ /** The last RHS state in the list of states to be reduced. */
+ yyGLRState* yystate;
+ /** The lookahead for this reduction. */
+ int yyrawchar;
+ YYSTYPE yyval;
+ YYLTYPE yyloc;
+ /** Next sibling in chain of options. To facilitate merging,
+ * options are chained in decreasing order by address. */
+ yySemanticOption* yynext;
+};
+
+/** Type of the items in the GLR stack. The yyisState field
+ * indicates which item of the union is valid. */
+union yyGLRStackItem {
+ yyGLRState yystate;
+ yySemanticOption yyoption;
+};
+
+struct yyGLRStack {
+ int yyerrState;
+ /* To compute the location of the error token. */
+ yyGLRStackItem yyerror_range[3];
+
+ YYJMP_BUF yyexception_buffer;
+ yyGLRStackItem* yyitems;
+ yyGLRStackItem* yynextFree;
+ size_t yyspaceLeft;
+ yyGLRState* yysplitPoint;
+ yyGLRState* yylastDeleted;
+ yyGLRStateSet yytops;
+};
+
+#if YYSTACKEXPANDABLE
+static void yyexpandGLRStack (yyGLRStack* yystackp);
+#endif
+
+static void yyFail (yyGLRStack* yystackp, const char* yymsg)
+ __attribute__ ((__noreturn__));
+static void
+yyFail (yyGLRStack* yystackp, const char* yymsg)
+{
+ if (yymsg != NULL)
+ yyerror (yymsg);
+ YYLONGJMP (yystackp->yyexception_buffer, 1);
+}
+
+static void yyMemoryExhausted (yyGLRStack* yystackp)
+ __attribute__ ((__noreturn__));
+static void
+yyMemoryExhausted (yyGLRStack* yystackp)
+{
+ YYLONGJMP (yystackp->yyexception_buffer, 2);
+}
+
+#if YYDEBUG || YYERROR_VERBOSE
+/** A printable representation of TOKEN. */
+static inline const char*
+yytokenName (yySymbol yytoken)
+{
+ if (yytoken == YYEMPTY)
+ return "";
+
+ return yytname[yytoken];
+}
+#endif
+
+/** Fill in YYVSP[YYLOW1 .. YYLOW0-1] from the chain of states starting
+ * at YYVSP[YYLOW0].yystate.yypred. Leaves YYVSP[YYLOW1].yystate.yypred
+ * containing the pointer to the next state in the chain. */
+static void yyfillin (yyGLRStackItem *, int, int) __attribute__ ((__unused__));
+static void
+yyfillin (yyGLRStackItem *yyvsp, int yylow0, int yylow1)
+{
+ yyGLRState* s;
+ int i;
+ s = yyvsp[yylow0].yystate.yypred;
+ for (i = yylow0-1; i >= yylow1; i -= 1)
+ {
+ YYASSERT (s->yyresolved);
+ yyvsp[i].yystate.yyresolved = yytrue;
+ yyvsp[i].yystate.yysemantics.yysval = s->yysemantics.yysval;
+ yyvsp[i].yystate.yyloc = s->yyloc;
+ s = yyvsp[i].yystate.yypred = s->yypred;
+ }
+}
+
+/* Do nothing if YYNORMAL or if *YYLOW <= YYLOW1. Otherwise, fill in
+ * YYVSP[YYLOW1 .. *YYLOW-1] as in yyfillin and set *YYLOW = YYLOW1.
+ * For convenience, always return YYLOW1. */
+static inline int yyfill (yyGLRStackItem *, int *, int, yybool)
+ __attribute__ ((__unused__));
+static inline int
+yyfill (yyGLRStackItem *yyvsp, int *yylow, int yylow1, yybool yynormal)
+{
+ if (!yynormal && yylow1 < *yylow)
+ {
+ yyfillin (yyvsp, *yylow, yylow1);
+ *yylow = yylow1;
+ }
+ return yylow1;
+}
+
+/** Perform user action for rule number YYN, with RHS length YYRHSLEN,
+ * and top stack item YYVSP. YYLVALP points to place to put semantic
+ * value ($$), and yylocp points to place for location information
+ * (@$). Returns yyok for normal return, yyaccept for YYACCEPT,
+ * yyerr for YYERROR, yyabort for YYABORT. */
+/*ARGSUSED*/ static YYRESULTTAG
+yyuserAction (yyRuleNum yyn, int yyrhslen, yyGLRStackItem* yyvsp,
+ YYSTYPE* yyvalp,
+ YYLTYPE* YYOPTIONAL_LOC (yylocp),
+ yyGLRStack* yystackp
+ )
+{
+ yybool yynormal __attribute__ ((__unused__)) =
+ (yystackp->yysplitPoint == NULL);
+ int yylow;
+# undef yyerrok
+# define yyerrok (yystackp->yyerrState = 0)
+# undef YYACCEPT
+# define YYACCEPT return yyaccept
+# undef YYABORT
+# define YYABORT return yyabort
+# undef YYERROR
+# define YYERROR return yyerrok, yyerr
+# undef YYRECOVERING
+# define YYRECOVERING() (yystackp->yyerrState != 0)
+# undef yyclearin
+# define yyclearin (yychar = YYEMPTY)
+# undef YYFILL
+# define YYFILL(N) yyfill (yyvsp, &yylow, N, yynormal)
+# undef YYBACKUP
+# define YYBACKUP(Token, Value) \
+ return yyerror (YY_("syntax error: cannot back up")), \
+ yyerrok, yyerr
+
+ yylow = 1;
+ if (yyrhslen == 0)
+ *yyvalp = yyval_default;
+ else
+ *yyvalp = yyvsp[YYFILL (1-yyrhslen)].yystate.yysemantics.yysval;
+ YYLLOC_DEFAULT ((*yylocp), (yyvsp - yyrhslen), yyrhslen);
+ yystackp->yyerror_range[1].yystate.yyloc = *yylocp;
+
+ switch (yyn)
+ {
+ case 2:
+#line 251 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(TopLev, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.TopLev));
+ L->ast = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.TopLev);
+ ;}
+ break;
+
+ case 3:
+#line 259 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.ClsDecl)) {
+ ((*yyvalp).TopLev) = ast_mkTopLevel(L_TOPLEVEL_CLASS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.TopLev), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ((*yyvalp).TopLev)->u.class = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.ClsDecl);
+ } else {
+ // Don't create a node for a forward class declaration.
+ ((*yyvalp).TopLev) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.TopLev);
+ }
+ ;}
+ break;
+
+ case 4:
+#line 269 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).TopLev) = ast_mkTopLevel(L_TOPLEVEL_FUN, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.TopLev), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->flags |= DECL_FN;
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->flags & DECL_PRIVATE) {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->flags |= SCOPE_SCRIPT;
+ } else {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->flags |= SCOPE_GLOBAL;
+ }
+ ((*yyvalp).TopLev)->u.fun = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl);
+ ;}
+ break;
+
+ case 5:
+#line 280 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).TopLev) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.TopLev); // nothing more to do
+ ;}
+ break;
+
+ case 6:
+#line 284 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ L_set_declBaseType((((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.VarDecl), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Type));
+ L_typedef_store((((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.VarDecl));
+ ((*yyvalp).TopLev) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yysemantics.yysval.TopLev); // nothing more to do
+ ;}
+ break;
+
+ case 7:
+#line 290 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ // Global variable declaration.
+ VarDecl *v;
+ ((*yyvalp).TopLev) = ast_mkTopLevel(L_TOPLEVEL_GLOBAL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.TopLev), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ for (v = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl); v; v = v->next) {
+ v->flags |= DECL_GLOBAL_VAR;
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl)->flags & DECL_PRIVATE) {
+ v->flags |= SCOPE_SCRIPT;
+ } else {
+ v->flags |= SCOPE_GLOBAL;
+ }
+ }
+ ((*yyvalp).TopLev)->u.global = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl);
+ ;}
+ break;
+
+ case 8:
+#line 305 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ // Top-level statement.
+ ((*yyvalp).TopLev) = ast_mkTopLevel(L_TOPLEVEL_STMT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.TopLev), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ((*yyvalp).TopLev)->u.stmt = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Stmt);
+ ;}
+ break;
+
+ case 9:
+#line 310 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).TopLev) = NULL; ;}
+ break;
+
+ case 10:
+#line 315 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /*
+ * This is a new class declaration.
+ * Alloc the VarDecl now and associate it with
+ * the class name so that it is available while
+ * parsing the class body.
+ */
+ Type *t = type_mkClass();
+ VarDecl *d = ast_mkVarDecl(t, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc));
+ ClsDecl *c = ast_mkClsDecl(d, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc));
+ t->u.class.clsdecl = c;
+ ASSERT(!L_typedef_lookup((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr)->str));
+ L_typedef_store(d);
+ ((*yyvalp).ClsDecl) = c;
+ ;}
+ break;
+
+ case 11:
+#line 330 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).ClsDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.ClsDecl);
+ /* silence unused warning */
+ (void)(((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.ClsDecl);
+ ;}
+ break;
+
+ case 12:
+#line 336 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /*
+ * This is a class declaration where the type name was
+ * previously declared. Use the ClsDecl from the
+ * prior decl.
+ */
+ ClsDecl *c = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Typename).t->u.class.clsdecl;
+ unless (c->decl->flags & DECL_FORWARD) {
+ L_err("redeclaration of %s", (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Typename).s);
+ }
+ ASSERT(isclasstype(c->decl->type));
+ c->decl->flags &= ~DECL_FORWARD;
+ ((*yyvalp).ClsDecl) = c;
+ ;}
+ break;
+
+ case 13:
+#line 350 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).ClsDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.ClsDecl);
+ /* silence unused warning */
+ (void)(((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.ClsDecl);
+ ;}
+ break;
+
+ case 14:
+#line 356 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /* This is a forward class declaration. */
+ Type *t = type_mkClass();
+ VarDecl *d = ast_mkVarDecl(t, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ClsDecl *c = ast_mkClsDecl(d, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ASSERT(!L_typedef_lookup((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr)->str));
+ t->u.class.clsdecl = c;
+ d->flags |= DECL_FORWARD;
+ L_typedef_store(d);
+ ((*yyvalp).ClsDecl) = NULL;
+ ;}
+ break;
+
+ case 15:
+#line 368 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /* Empty declaration of an already declared type. */
+ unless (isclasstype((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Typename).t)) {
+ L_err("%s not a class type", (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Typename).s);
+ }
+ ((*yyvalp).ClsDecl) = NULL;
+ ;}
+ break;
+
+ case 16:
+#line 379 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).ClsDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((0) - (2))].yystate.yysemantics.yysval.ClsDecl);
+ ((*yyvalp).ClsDecl)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc).end;
+ ((*yyvalp).ClsDecl)->decl->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc).end;
+ /* If constructor or destructor were omitted, make defaults. */
+ unless (((*yyvalp).ClsDecl)->constructors) {
+ ((*yyvalp).ClsDecl)->constructors = ast_mkConstructor(((*yyvalp).ClsDecl));
+ }
+ unless (((*yyvalp).ClsDecl)->destructors) {
+ ((*yyvalp).ClsDecl)->destructors = ast_mkDestructor(((*yyvalp).ClsDecl));
+ }
+ ;}
+ break;
+
+ case 17:
+#line 395 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ VarDecl *v;
+ ClsDecl *clsdecl = (((yyGLRStackItem const *)yyvsp)[YYFILL ((0) - (6))].yystate.yysemantics.yysval.ClsDecl);
+ REVERSE(VarDecl, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (6))].yystate.yysemantics.yysval.VarDecl));
+ for (v = (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (6))].yystate.yysemantics.yysval.VarDecl); v; v = v->next) {
+ v->clsdecl = clsdecl;
+ v->flags |= SCOPE_CLASS | DECL_CLASS_INST_VAR;
+ unless (v->flags & (DECL_PUBLIC | DECL_PRIVATE)) {
+ L_errf(v, "class instance variable %s not "
+ "declared public or private",
+ v->id->str);
+ v->flags |= DECL_PUBLIC;
+ }
+ }
+ APPEND_OR_SET(VarDecl, next, clsdecl->instvars, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (6))].yystate.yysemantics.yysval.VarDecl));
+ ;}
+ break;
+
+ case 19:
+#line 413 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ VarDecl *v;
+ ClsDecl *clsdecl = (((yyGLRStackItem const *)yyvsp)[YYFILL ((0) - (2))].yystate.yysemantics.yysval.ClsDecl);
+ REVERSE(VarDecl, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl));
+ for (v = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl); v; v = v->next) {
+ v->clsdecl = clsdecl;
+ v->flags |= SCOPE_CLASS | DECL_CLASS_VAR;
+ unless (v->flags & (DECL_PUBLIC | DECL_PRIVATE)) {
+ L_errf(v, "class variable %s not "
+ "declared public or private",
+ v->id->str);
+ v->flags |= DECL_PUBLIC;
+ }
+ }
+ APPEND_OR_SET(VarDecl, next, clsdecl->clsvars, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl));
+ ;}
+ break;
+
+ case 21:
+#line 431 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ L_set_declBaseType((((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.VarDecl), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Type));
+ L_typedef_store((((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.VarDecl));
+ ;}
+ break;
+
+ case 22:
+#line 436 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ClsDecl *clsdecl = (((yyGLRStackItem const *)yyvsp)[YYFILL ((0) - (2))].yystate.yysemantics.yysval.ClsDecl);
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->clsdecl = clsdecl;
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->flags |= DECL_CLASS_FN;
+ unless ((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->flags & DECL_PRIVATE) {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->flags |= SCOPE_GLOBAL | DECL_PUBLIC;
+ } else {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->flags |= SCOPE_CLASS;
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->tclprefix = cksprintf("_L_class_%s_",
+ clsdecl->decl->id->str);
+ }
+ APPEND_OR_SET(FnDecl, next, clsdecl->fns, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl));
+ ;}
+ break;
+
+ case 23:
+#line 450 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ClsDecl *clsdecl = (((yyGLRStackItem const *)yyvsp)[YYFILL ((0) - (3))].yystate.yysemantics.yysval.ClsDecl);
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl)->decl->type->base_type = clsdecl->decl->type;
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl)->decl->clsdecl = clsdecl;
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl)->decl->flags |= SCOPE_GLOBAL | DECL_CLASS_FN | DECL_PUBLIC |
+ DECL_CLASS_CONST;
+ APPEND_OR_SET(FnDecl, next, clsdecl->constructors, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl));
+ ;}
+ break;
+
+ case 24:
+#line 459 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ClsDecl *clsdecl = (((yyGLRStackItem const *)yyvsp)[YYFILL ((0) - (3))].yystate.yysemantics.yysval.ClsDecl);
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl)->decl->type->base_type = L_void;
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl)->decl->clsdecl = clsdecl;
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl)->decl->flags |= SCOPE_GLOBAL | DECL_CLASS_FN | DECL_PUBLIC |
+ DECL_CLASS_DESTR;
+ APPEND_OR_SET(FnDecl, next, clsdecl->destructors, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl));
+ ;}
+ break;
+
+ case 25:
+#line 468 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /*
+ * We don't store the things that make up class_code
+ * in order, so there's no place in which to
+ * interleave #pragmas. So don't create an AST node,
+ * just update L->options now; it gets used when other
+ * AST nodes are created.
+ */
+ L_compile_attributes(L->options, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr), L_attrs_pragma);
+ ;}
+ break;
+
+ case 29:
+#line 488 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->type->base_type = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Type);
+ ((*yyvalp).FnDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl);
+ ((*yyvalp).FnDecl)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc);
+ ;}
+ break;
+
+ case 30:
+#line 494 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl)->decl->type->base_type = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Type);
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl)->decl->flags |= (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.i);
+ ((*yyvalp).FnDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.FnDecl);
+ ((*yyvalp).FnDecl)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc);
+ ;}
+ break;
+
+ case 31:
+#line 504 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).FnDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl);
+ ((*yyvalp).FnDecl)->decl->id = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).FnDecl)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc);
+ ;}
+ break;
+
+ case 32:
+#line 510 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ VarDecl *new_param;
+ Expr *dollar1 = ast_mkId("$1", (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+
+ ((*yyvalp).FnDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl);
+ ((*yyvalp).FnDecl)->decl->id = ast_mkId((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc));
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.s));
+ ((*yyvalp).FnDecl)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc);
+ /* Prepend a new arg "$1" as the first formal. */
+ new_param = ast_mkVarDecl(L_string, dollar1, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ new_param->flags = SCOPE_LOCAL | DECL_LOCAL_VAR;
+ new_param->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.FnDecl)->decl->type->u.func.formals;
+ ((*yyvalp).FnDecl)->decl->type->u.func.formals = new_param;
+ ;}
+ break;
+
+ case 33:
+#line 528 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Type *type = type_mkFunc(NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (5))].yystate.yysemantics.yysval.VarDecl));
+ VarDecl *decl = ast_mkVarDecl(type, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yyloc));
+ decl->attrs = (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).FnDecl) = ast_mkFnDecl(decl, (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.Stmt)->u.block, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ;}
+ break;
+
+ case 34:
+#line 535 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Type *type = type_mkFunc(NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (5))].yystate.yysemantics.yysval.VarDecl));
+ VarDecl *decl = ast_mkVarDecl(type, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yyloc));
+ decl->attrs = (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).FnDecl) = ast_mkFnDecl(decl, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ;}
+ break;
+
+ case 35:
+#line 545 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_LABEL, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.label = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.s);
+ ((*yyvalp).Stmt)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Stmt);
+ ;}
+ break;
+
+ case 36:
+#line 551 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_LABEL, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.label = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.s);
+ ;}
+ break;
+
+ case 38:
+#line 557 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ L_compile_attributes(L->options, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Expr), L_attrs_pragma);
+ ((*yyvalp).Stmt) = NULL;
+ ;}
+ break;
+
+ case 39:
+#line 562 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ // Wrap the html in a puts(-nonewline) call.
+ Expr *fn = ast_mkId("puts", (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ Expr *arg = ast_mkConst(L_string, "-nonewline", (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ arg->next = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_EXPR, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.expr = ast_mkFnCall(fn, arg, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ;}
+ break;
+
+ case 40:
+#line 571 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ // Wrap expr in a puts(-nonewline) call.
+ Expr *fn = ast_mkId("puts", (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc));
+ Expr *arg = ast_mkConst(L_string, "-nonewline", (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc));
+ arg->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_EXPR, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.expr = ast_mkFnCall(fn, arg, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 42:
+#line 584 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQUALS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 43:
+#line 588 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *lit = ast_mkConst(L_int, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQUALS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), lit, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 44:
+#line 593 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc.beg = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc).beg;
+ ;}
+ break;
+
+ case 45:
+#line 599 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQUALS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ((*yyvalp).Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc.beg = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc).beg;
+ ;}
+ break;
+
+ case 46:
+#line 605 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *lit = ast_mkConst(L_int, (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQUALS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr), lit, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ((*yyvalp).Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc.beg = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc).beg;
+ ;}
+ break;
+
+ case 47:
+#line 615 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(Expr, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr));
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc.beg = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc).beg;
+ ;}
+ break;
+
+ case 48:
+#line 624 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(Expr, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr));
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc.beg = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc).beg;
+ ((*yyvalp).Expr)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc).end;
+ ;}
+ break;
+
+ case 49:
+#line 630 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Expr) = NULL; ;}
+ break;
+
+ case 52:
+#line 640 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_COND, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.cond = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Cond);
+ ;}
+ break;
+
+ case 53:
+#line 645 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_LOOP, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.loop = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Loop);
+ ;}
+ break;
+
+ case 54:
+#line 650 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_SWITCH, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.swich = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Switch);
+ ;}
+ break;
+
+ case 55:
+#line 655 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_FOREACH, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.foreach = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.ForEach);
+ ;}
+ break;
+
+ case 56:
+#line 660 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_EXPR, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.expr = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr);
+ ;}
+ break;
+
+ case 57:
+#line 665 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_BREAK, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 58:
+#line 669 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_CONTINUE, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 59:
+#line 673 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_RETURN, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 60:
+#line 677 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_RETURN, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.expr = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr);
+ ;}
+ break;
+
+ case 61:
+#line 682 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_GOTO, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.label = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.s);
+ ;}
+ break;
+
+ case 62:
+#line 687 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /*
+ * We don't want to make "catch" a keyword since it's a Tcl
+ * function name, so allow any ID here but check it.
+ */
+ unless (!strcmp((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (7))].yystate.yysemantics.yysval.s), "catch")) {
+ L_synerr2("syntax error -- expected 'catch'", (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (7))].yystate.yyloc).beg);
+ }
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_TRY, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (7))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((7) - (7))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.try = ast_mkTry((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (7))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (7))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((7) - (7))].yystate.yysemantics.yysval.Stmt));
+ ;}
+ break;
+
+ case 63:
+#line 699 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_TRY, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.try = ast_mkTry((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yysemantics.yysval.Stmt), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yysemantics.yysval.Stmt));
+ ;}
+ break;
+
+ case 64:
+#line 703 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Stmt) = NULL; ;}
+ break;
+
+ case 65:
+#line 708 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Cond) = ast_mkIfUnless((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (6))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (6))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (6))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (6))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (6))].yystate.yyloc));
+ ;}
+ break;
+
+ case 66:
+#line 713 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Cond) = ast_mkIfUnless((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.Stmt), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ;}
+ break;
+
+ case 67:
+#line 717 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Cond) = ast_mkIfUnless((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (6))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (6))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (6))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (6))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (6))].yystate.yyloc));
+ ;}
+ break;
+
+ case 68:
+#line 721 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Cond) = ast_mkIfUnless((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ;}
+ break;
+
+ case 69:
+#line 728 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Case *c, *def;
+
+ for (c = (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (7))].yystate.yysemantics.yysval.Case), def = NULL; c; c = c->next) {
+ if (c->expr) continue;
+ if (def) {
+ L_errf(c,
+ "multiple default cases in switch statement");
+ }
+ def = c;
+ }
+ ((*yyvalp).Switch) = ast_mkSwitch((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (7))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (7))].yystate.yysemantics.yysval.Case), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (7))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((7) - (7))].yystate.yyloc));
+ ;}
+ break;
+
+ case 70:
+#line 745 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Case)) {
+ APPEND(Case, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Case), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Case));
+ ((*yyvalp).Case) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Case);
+ } else {
+ ((*yyvalp).Case) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Case);
+ }
+ ;}
+ break;
+
+ case 71:
+#line 753 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Case) = NULL; ;}
+ break;
+
+ case 72:
+#line 758 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(Stmt, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.Stmt));
+ ((*yyvalp).Case) = ast_mkCase((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ;}
+ break;
+
+ case 73:
+#line 763 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /* The default case is distinguished by a NULL expr. */
+ REVERSE(Stmt, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Stmt));
+ ((*yyvalp).Case) = ast_mkCase(NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 74:
+#line 772 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Expr)->flags & L_EXPR_RE_G) {
+ L_errf((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Expr), "illegal regular expression modifier");
+ }
+ ;}
+ break;
+
+ case 76:
+#line 783 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Stmt);
+ ((*yyvalp).Stmt)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc);
+ ;}
+ break;
+
+ case 77:
+#line 788 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_COND, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.cond = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Cond);
+ ;}
+ break;
+
+ case 78:
+#line 792 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Stmt) = NULL; ;}
+ break;
+
+ case 79:
+#line 797 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Loop) = ast_mkLoop(L_LOOP_WHILE, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ;}
+ break;
+
+ case 80:
+#line 801 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Loop) = ast_mkLoop(L_LOOP_DO, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (7))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (7))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (7))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (7))].yystate.yyloc));
+ ;}
+ break;
+
+ case 81:
+#line 805 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Loop) = ast_mkLoop(L_LOOP_FOR, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (6))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (6))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (6))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (6))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (6))].yystate.yyloc));
+ ;}
+ break;
+
+ case 82:
+#line 809 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Loop) = ast_mkLoop(L_LOOP_FOR, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (7))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (7))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (7))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((7) - (7))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (7))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((7) - (7))].yystate.yyloc));
+ ;}
+ break;
+
+ case 83:
+#line 816 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).ForEach) = ast_mkForeach((((yyGLRStackItem const *)yyvsp)[YYFILL ((7) - (9))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (9))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (9))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((9) - (9))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (9))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((9) - (9))].yystate.yyloc));
+ unless (isid((((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (9))].yystate.yysemantics.yysval.Expr), "in")) {
+ L_synerr2("syntax error -- expected 'in' in foreach",
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (9))].yystate.yyloc).beg);
+ }
+ ;}
+ break;
+
+ case 84:
+#line 824 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).ForEach) = ast_mkForeach((((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (7))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (7))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((7) - (7))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (7))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((7) - (7))].yystate.yyloc));
+ unless (isid((((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (7))].yystate.yysemantics.yysval.Expr), "in")) {
+ L_synerr2("syntax error -- expected 'in' in foreach",
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (7))].yystate.yyloc).beg);
+ }
+ ;}
+ break;
+
+ case 85:
+#line 834 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Expr) = NULL; ;}
+ break;
+
+ case 88:
+#line 840 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Stmt) = NULL; ;}
+ break;
+
+ case 89:
+#line 845 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(Stmt, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Stmt));
+ ((*yyvalp).Stmt) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Stmt);
+ ;}
+ break;
+
+ case 90:
+#line 850 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Stmt)) {
+ REVERSE(Stmt, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Stmt));
+ APPEND(Stmt, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Stmt));
+ ((*yyvalp).Stmt) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Stmt);
+ } else {
+ // Empty stmt.
+ ((*yyvalp).Stmt) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Stmt);
+ }
+ ;}
+ break;
+
+ case 91:
+#line 864 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ VarDecl *v;
+ REVERSE(VarDecl, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.VarDecl));
+ for (v = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.VarDecl); v; v = v->next) {
+ v->flags |= SCOPE_LOCAL | DECL_LOCAL_VAR;
+ }
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.VarDecl);
+ /*
+ * Special case a parameter list of "void" -- a single
+ * formal of type void with no arg name. This really
+ * means there are no args.
+ */
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.VarDecl) && !(((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.VarDecl)->next && !(((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.VarDecl)->id && ((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.VarDecl)->type == L_void)) {
+ ((*yyvalp).VarDecl) = NULL;
+ }
+ ;}
+ break;
+
+ case 92:
+#line 880 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).VarDecl) = NULL; ;}
+ break;
+
+ case 94:
+#line 886 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.VarDecl)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.VarDecl);
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.VarDecl);
+ ((*yyvalp).VarDecl)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc);
+ ;}
+ break;
+
+ case 95:
+#line 895 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.VarDecl)) {
+ L_set_declBaseType((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.VarDecl), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Type));
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.VarDecl);
+ } else {
+ ((*yyvalp).VarDecl) = ast_mkVarDecl((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Type), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc));
+ if (isnameoftype((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Type))) ((*yyvalp).VarDecl)->flags |= DECL_REF;
+ }
+ ((*yyvalp).VarDecl)->flags |= (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.i);
+ ((*yyvalp).VarDecl)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc);
+ ;}
+ break;
+
+ case 96:
+#line 907 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Type *t = type_mkArray(NULL, L_poly);
+ ((*yyvalp).VarDecl) = ast_mkVarDecl(t, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).VarDecl)->flags |= (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.i) | DECL_REST_ARG;
+ ;}
+ break;
+
+ case 97:
+#line 915 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).i) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.i) | DECL_ARGUSED; ;}
+ break;
+
+ case 98:
+#line 916 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).i) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.i) | DECL_OPTIONAL; ;}
+ break;
+
+ case 99:
+#line 917 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).i) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.i) | DECL_NAME_EQUIV; ;}
+ break;
+
+ case 100:
+#line 918 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).i) = 0; ;}
+ break;
+
+ case 103:
+#line 925 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc);
+ ;}
+ break;
+
+ case 104:
+#line 931 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc).end;
+ ;}
+ break;
+
+ case 105:
+#line 937 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc).end;
+ ;}
+ break;
+
+ case 106:
+#line 943 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yysemantics.yysval.Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr);
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc).end;
+ ;}
+ break;
+
+ case 107:
+#line 960 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ char *s = cksprintf("-%s", (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.s));
+ ((*yyvalp).Expr) = ast_mkConst(L_string, s, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.s));
+ ;}
+ break;
+
+ case 108:
+#line 966 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ char *s = cksprintf("-default");
+ ((*yyvalp).Expr) = ast_mkConst(L_string, s, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 109:
+#line 974 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc);
+ ((*yyvalp).Expr)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc).end;
+ ;}
+ break;
+
+ case 110:
+#line 980 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ // This is a binop where an arg is a Type*.
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_CAST, (Expr *)(((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yysemantics.yysval.Type), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 111:
+#line 985 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_EXPAND, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 112:
+#line 989 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_BANG, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 113:
+#line 993 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_BITNOT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 114:
+#line 997 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_ADDROF, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 115:
+#line 1001 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_UMINUS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 116:
+#line 1005 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_UPLUS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 117:
+#line 1009 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_PLUSPLUS_PRE, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 118:
+#line 1013 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_MINUSMINUS_PRE, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 119:
+#line 1017 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_PLUSPLUS_POST, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 120:
+#line 1021 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_MINUSMINUS_POST, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 121:
+#line 1025 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQTWID, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 122:
+#line 1029 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_BANGTWID, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 123:
+#line 1033 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ if (strchr((((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.s), 'i')) (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr)->flags |= L_EXPR_RE_I;
+ if (strchr((((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.s), 'g')) (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr)->flags |= L_EXPR_RE_G;
+ ((*yyvalp).Expr) = ast_mkTrinOp(L_OP_EQTWID, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.s));
+ ;}
+ break;
+
+ case 124:
+#line 1040 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_STAR, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 125:
+#line 1044 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_SLASH, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 126:
+#line 1048 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_PERC, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 127:
+#line 1052 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_PLUS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 128:
+#line 1056 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_MINUS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 129:
+#line 1060 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_STR_EQ, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 130:
+#line 1064 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_STR_NE, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 131:
+#line 1068 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_STR_LT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 132:
+#line 1072 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_STR_LE, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 133:
+#line 1076 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_STR_GT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 134:
+#line 1080 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_STR_GE, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 135:
+#line 1084 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQUALEQUAL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 136:
+#line 1088 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQUALEQUAL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (6))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (6))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (6))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (6))].yystate.yyloc));
+ ;}
+ break;
+
+ case 137:
+#line 1092 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_NOTEQUAL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 138:
+#line 1096 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_GREATER, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 139:
+#line 1100 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_GREATEREQ, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 140:
+#line 1104 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_LESSTHAN, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 141:
+#line 1108 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_LESSTHANEQ, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 142:
+#line 1112 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_ANDAND, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 143:
+#line 1116 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_OROR, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 144:
+#line 1120 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_LSHIFT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 145:
+#line 1124 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_RSHIFT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 146:
+#line 1128 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_BITOR, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 147:
+#line 1132 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_BITAND, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 148:
+#line 1136 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_BITXOR, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 152:
+#line 1143 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkConst(L_int, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ;}
+ break;
+
+ case 153:
+#line 1147 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkConst(L_float, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ;}
+ break;
+
+ case 154:
+#line 1151 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(Expr, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr));
+ ((*yyvalp).Expr) = ast_mkFnCall((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 155:
+#line 1156 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkFnCall((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 156:
+#line 1160 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *id = ast_mkId("string", (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc));
+ REVERSE(Expr, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr));
+ ((*yyvalp).Expr) = ast_mkFnCall(id, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 157:
+#line 1166 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *id = ast_mkId("split", (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (7))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (7))].yystate.yyloc));
+ REVERSE(Expr, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (7))].yystate.yysemantics.yysval.Expr));
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (7))].yystate.yysemantics.yysval.Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((6) - (7))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr) = ast_mkFnCall(id, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (7))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (7))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((7) - (7))].yystate.yyloc));
+ ;}
+ break;
+
+ case 158:
+#line 1180 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *id = ast_mkId("split", (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc));
+ REVERSE(Expr, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.Expr));
+ ((*yyvalp).Expr) = ast_mkFnCall(id, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ;}
+ break;
+
+ case 159:
+#line 1187 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(Expr, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr));
+ ((*yyvalp).Expr) = ast_mkFnCall((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 160:
+#line 1192 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkFnCall((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 161:
+#line 1196 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQUALS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 162:
+#line 1200 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQPLUS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 163:
+#line 1204 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQMINUS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 164:
+#line 1208 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQSTAR, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 165:
+#line 1212 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQSLASH, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 166:
+#line 1216 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQPERC, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 167:
+#line 1220 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQBITAND, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 168:
+#line 1224 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQBITOR, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 169:
+#line 1228 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQBITXOR, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 170:
+#line 1232 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQLSHIFT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 171:
+#line 1236 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQRSHIFT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 172:
+#line 1240 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_EQDOT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 173:
+#line 1244 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_DEFINED, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 174:
+#line 1248 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_ARRAY_INDEX, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 175:
+#line 1252 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_HASH_INDEX, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 176:
+#line 1256 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_CONCAT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 177:
+#line 1260 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_DOT, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Expr)->str = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.s);
+ ;}
+ break;
+
+ case 178:
+#line 1265 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_POINTS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Expr)->str = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.s);
+ ;}
+ break;
+
+ case 179:
+#line 1270 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ // This is a binop where an arg is a Type*.
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_CLASS_INDEX, (Expr *)(((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Typename).t, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Expr)->str = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.s);
+ ;}
+ break;
+
+ case 180:
+#line 1276 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ // This is a binop where an arg is a Type*.
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_CLASS_INDEX, (Expr *)(((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Typename).t, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Expr)->str = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.s);
+ ;}
+ break;
+
+ case 181:
+#line 1282 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_COMMA, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 182:
+#line 1286 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkTrinOp(L_OP_ARRAY_SLICE, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (6))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (6))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (6))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (6))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (6))].yystate.yyloc));
+ ;}
+ break;
+
+ case 183:
+#line 1294 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc);
+ ((*yyvalp).Expr)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc).end;
+ L_scope_leave();
+ ;}
+ break;
+
+ case 184:
+#line 1301 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_LIST, NULL, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 185:
+#line 1305 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkTrinOp(L_OP_TERNARY_COND, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ;}
+ break;
+
+ case 186:
+#line 1309 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_FILE, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 187:
+#line 1313 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_FILE, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 188:
+#line 1319 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { L_lex_begReArg(0); ;}
+ break;
+
+ case 189:
+#line 1323 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { L_lex_begReArg(1); ;}
+ break;
+
+ case 190:
+#line 1328 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkId((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.s));
+ ;}
+ break;
+
+ case 192:
+#line 1337 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr);
+ ((*yyvalp).Expr)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc).end;
+ ;}
+ break;
+
+ case 193:
+#line 1346 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_BLOCK, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.block = ast_mkBlock(NULL, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ L_scope_leave();
+ ;}
+ break;
+
+ case 194:
+#line 1352 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(Stmt, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Stmt));
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_BLOCK, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.block = ast_mkBlock(NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ L_scope_leave();
+ ;}
+ break;
+
+ case 195:
+#line 1359 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ VarDecl *v;
+ REVERSE(VarDecl, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.VarDecl));
+ for (v = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.VarDecl); v; v = v->next) {
+ v->flags |= SCOPE_LOCAL | DECL_LOCAL_VAR;
+ }
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_BLOCK, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.block = ast_mkBlock((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.VarDecl), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ L_scope_leave();
+ ;}
+ break;
+
+ case 196:
+#line 1370 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ VarDecl *v;
+ REVERSE(VarDecl, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.VarDecl));
+ for (v = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.VarDecl); v; v = v->next) {
+ v->flags |= SCOPE_LOCAL | DECL_LOCAL_VAR;
+ }
+ REVERSE(Stmt, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.Stmt));
+ ((*yyvalp).Stmt) = ast_mkStmt(L_STMT_BLOCK, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ((*yyvalp).Stmt)->u.block = ast_mkBlock((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (5))].yystate.yysemantics.yysval.VarDecl), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.Stmt), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ L_scope_leave();
+ ;}
+ break;
+
+ case 197:
+#line 1384 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { L_scope_enter(); ;}
+ break;
+
+ case 199:
+#line 1390 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /*
+ * Each declaration is a list of declarators. Here we
+ * append the lists.
+ */
+ APPEND(VarDecl, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.VarDecl));
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl);
+ ;}
+ break;
+
+ case 201:
+#line 1403 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ VarDecl *v;
+ for (v = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.VarDecl); v; v = v->next) {
+ v->flags |= (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.i);
+ }
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.VarDecl);
+ ((*yyvalp).VarDecl)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc);
+ ;}
+ break;
+
+ case 202:
+#line 1414 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).i) = DECL_PRIVATE; ;}
+ break;
+
+ case 203:
+#line 1415 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).i) = DECL_PUBLIC; ;}
+ break;
+
+ case 204:
+#line 1416 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).i) = DECL_EXTERN; ;}
+ break;
+
+ case 205:
+#line 1421 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /* Don't REVERSE $2; it's done as part of declaration_list. */
+ VarDecl *v;
+ for (v = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl); v; v = v->next) {
+ L_set_declBaseType(v, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Type));
+ }
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl);
+ ;}
+ break;
+
+ case 207:
+#line 1434 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.VarDecl)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.VarDecl);
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.VarDecl);
+ ;}
+ break;
+
+ case 209:
+#line 1443 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.VarDecl)->next = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.VarDecl);
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.VarDecl);
+ ;}
+ break;
+
+ case 211:
+#line 1452 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.VarDecl)->initializer = ast_mkBinOp(L_OP_EQUALS, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.VarDecl)->id, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.VarDecl);
+ ((*yyvalp).VarDecl)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc).end;
+ ;}
+ break;
+
+ case 213:
+#line 1461 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).VarDecl) = NULL; ;}
+ break;
+
+ case 214:
+#line 1466 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).VarDecl) = ast_mkVarDecl((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Type), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 215:
+#line 1470 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *id = ast_mkId((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Typename).s, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc));
+ ((*yyvalp).VarDecl) = ast_mkVarDecl((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Type), id, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ if (isnameoftype((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Typename).t)) ((*yyvalp).VarDecl)->flags |= DECL_REF;
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Typename).s);
+ ;}
+ break;
+
+ case 216:
+#line 1477 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Type *t = type_mkNameOf((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Type));
+ ((*yyvalp).VarDecl) = ast_mkVarDecl(t, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).VarDecl)->flags |= DECL_REF;
+ ;}
+ break;
+
+ case 217:
+#line 1483 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Type *tf = type_mkFunc(NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.VarDecl));
+ Type *tn = type_mkNameOf(tf);
+ ((*yyvalp).VarDecl) = ast_mkVarDecl(tn, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (5))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (5))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((5) - (5))].yystate.yyloc));
+ ((*yyvalp).VarDecl)->flags |= DECL_REF;
+ ;}
+ break;
+
+ case 218:
+#line 1494 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Type) = NULL;
+ ;}
+ break;
+
+ case 219:
+#line 1498 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Type) = type_mkArray((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yysemantics.yysval.Type));
+ ;}
+ break;
+
+ case 220:
+#line 1502 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Type) = type_mkArray(NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Type));
+ ;}
+ break;
+
+ case 221:
+#line 1506 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Type) = type_mkHash((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yysemantics.yysval.Type), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yysemantics.yysval.Type));
+ ;}
+ break;
+
+ case 222:
+#line 1513 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Type)) {
+ L_set_baseType((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Type), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Type));
+ ((*yyvalp).Type) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Type);
+ } else {
+ ((*yyvalp).Type) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Type);
+ }
+ ;}
+ break;
+
+ case 223:
+#line 1522 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ if ((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Type)) {
+ L_set_baseType((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Type), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Type));
+ ((*yyvalp).Type) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.Type);
+ } else {
+ ((*yyvalp).Type) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Type);
+ }
+ ;}
+ break;
+
+ case 224:
+#line 1533 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Type) = L_string; ;}
+ break;
+
+ case 225:
+#line 1534 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Type) = L_int; ;}
+ break;
+
+ case 226:
+#line 1535 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Type) = L_float; ;}
+ break;
+
+ case 227:
+#line 1536 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Type) = L_poly; ;}
+ break;
+
+ case 228:
+#line 1537 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Type) = L_widget; ;}
+ break;
+
+ case 229:
+#line 1538 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Type) = L_void; ;}
+ break;
+
+ case 230:
+#line 1539 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).Type) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Typename).t; ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Typename).s); ;}
+ break;
+
+ case 231:
+#line 1544 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(VarDecl, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.VarDecl));
+ ((*yyvalp).Type) = L_struct_store((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (5))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (5))].yystate.yysemantics.yysval.VarDecl));
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (5))].yystate.yysemantics.yysval.s));
+ ;}
+ break;
+
+ case 232:
+#line 1550 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ REVERSE(VarDecl, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.VarDecl));
+ (void)L_struct_store(NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.VarDecl)); // to sanity check member types
+ ((*yyvalp).Type) = type_mkStruct(NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.VarDecl));
+ ;}
+ break;
+
+ case 233:
+#line 1556 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Type) = L_struct_lookup((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), FALSE);
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s));
+ ;}
+ break;
+
+ case 235:
+#line 1565 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ APPEND(VarDecl, next, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.VarDecl));
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl);
+ ((*yyvalp).VarDecl)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc);
+ ;}
+ break;
+
+ case 236:
+#line 1573 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ { ((*yyvalp).VarDecl)->node.loc.end = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc).end; ;}
+ break;
+
+ case 237:
+#line 1578 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ VarDecl *v;
+ for (v = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl); v; v = v->next) {
+ L_set_declBaseType(v, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Type));
+ }
+ ((*yyvalp).VarDecl) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.VarDecl);
+ ((*yyvalp).VarDecl)->node.loc = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc);
+ ;}
+ break;
+
+ case 239:
+#line 1591 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ APPEND(Expr, b, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr));
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr);
+ ;}
+ break;
+
+ case 241:
+#line 1600 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_LIST, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.Expr), NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ;}
+ break;
+
+ case 242:
+#line 1604 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *kv = ast_mkBinOp(L_OP_KV, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_LIST, kv, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 243:
+#line 1612 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ;}
+ break;
+
+ case 244:
+#line 1616 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *right = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_INTERP_STRING, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr), right, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 245:
+#line 1621 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *right = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_INTERP_STRING, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr), right, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 246:
+#line 1629 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *left = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc));
+ Expr *right = ast_mkUnOp(L_OP_CMDSUBST, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ right->str = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s);
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_INTERP_STRING, left, right, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 247:
+#line 1636 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *middle = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yyloc));
+ Expr *right = ast_mkUnOp(L_OP_CMDSUBST, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ right->str = (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.s);
+ ((*yyvalp).Expr) = ast_mkTrinOp(L_OP_INTERP_STRING, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.Expr), middle, right,
+ (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 248:
+#line 1647 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_CMDSUBST, NULL, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ((*yyvalp).Expr)->str = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.s);
+ ;}
+ break;
+
+ case 249:
+#line 1652 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkUnOp(L_OP_CMDSUBST, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ((*yyvalp).Expr)->str = (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s);
+ ;}
+ break;
+
+ case 250:
+#line 1660 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkRegexp((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ;}
+ break;
+
+ case 251:
+#line 1664 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *right = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_INTERP_RE, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr), right, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 252:
+#line 1672 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ /* Note: the scanner catches illegal modifiers. */
+ if (strchr((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), 'i')) (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr)->flags |= L_EXPR_RE_I;
+ if (strchr((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), 'g')) (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr)->flags |= L_EXPR_RE_G;
+ if (strchr((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), 'l')) (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr)->flags |= L_EXPR_RE_L;
+ if (strchr((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), 't')) (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr)->flags |= L_EXPR_RE_T;
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s));
+ ((*yyvalp).Expr) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr);
+ ;}
+ break;
+
+ case 253:
+#line 1685 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ;}
+ break;
+
+ case 254:
+#line 1689 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *right = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_INTERP_RE, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yysemantics.yysval.Expr), right, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (2))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yyloc));
+ ;}
+ break;
+
+ case 255:
+#line 1697 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *left = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_INTERP_STRING, left, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 256:
+#line 1702 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *middle = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkTrinOp(L_OP_INTERP_STRING, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yysemantics.yysval.Expr), middle, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 257:
+#line 1710 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *left = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkBinOp(L_OP_INTERP_STRING, left, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (3))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yyloc));
+ ;}
+ break;
+
+ case 258:
+#line 1715 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Expr *middle = ast_mkConst(L_string, (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yysemantics.yysval.s), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (4))].yystate.yyloc));
+ ((*yyvalp).Expr) = ast_mkTrinOp(L_OP_INTERP_STRING, (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yysemantics.yysval.Expr), middle, (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (4))].yystate.yysemantics.yysval.Expr), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (4))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((4) - (4))].yystate.yyloc));
+ ;}
+ break;
+
+ case 259:
+#line 1723 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkId(".", (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ ;}
+ break;
+
+ case 260:
+#line 1727 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).Expr) = ast_mkId(Tcl_GetString((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.obj)), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc), (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yyloc));
+ Tcl_DecrRefCount((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (1))].yystate.yysemantics.yysval.obj));
+ ;}
+ break;
+
+ case 261:
+#line 1735 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ ((*yyvalp).obj) = Tcl_NewObj();
+ Tcl_IncrRefCount(((*yyvalp).obj));
+ Tcl_AppendToObj(((*yyvalp).obj), ".", 1);
+ Tcl_AppendToObj(((*yyvalp).obj), (((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s), -1);
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((2) - (2))].yystate.yysemantics.yysval.s));
+ ;}
+ break;
+
+ case 262:
+#line 1743 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+ {
+ Tcl_AppendToObj((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.obj), ".", 1);
+ Tcl_AppendToObj((((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.obj), (((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.s), -1);
+ ((*yyvalp).obj) = (((yyGLRStackItem const *)yyvsp)[YYFILL ((1) - (3))].yystate.yysemantics.yysval.obj);
+ ckfree((((yyGLRStackItem const *)yyvsp)[YYFILL ((3) - (3))].yystate.yysemantics.yysval.s));
+ ;}
+ break;
+
+
+/* Line 930 of glr.c. */
+#line 4767 "Lgrammar.c"
+ default: break;
+ }
+
+ return yyok;
+# undef yyerrok
+# undef YYABORT
+# undef YYACCEPT
+# undef YYERROR
+# undef YYBACKUP
+# undef yyclearin
+# undef YYRECOVERING
+}
+
+
+/*ARGSUSED*/ static void
+yyuserMerge (int yyn, YYSTYPE* yy0, YYSTYPE* yy1)
+{
+ YYUSE (yy0);
+ YYUSE (yy1);
+
+ switch (yyn)
+ {
+
+ default: break;
+ }
+}
+
+ /* Bison grammar-table manipulation. */
+
+/*-----------------------------------------------.
+| Release the memory associated to this symbol. |
+`-----------------------------------------------*/
+
+/*ARGSUSED*/
+static void
+yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep, YYLTYPE *yylocationp)
+{
+ YYUSE (yyvaluep);
+ YYUSE (yylocationp);
+
+ if (!yymsg)
+ yymsg = "Deleting";
+ YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
+
+ switch (yytype)
+ {
+
+ default:
+ break;
+ }
+}
+
+/** Number of symbols composing the right hand side of rule #RULE. */
+static inline int
+yyrhsLength (yyRuleNum yyrule)
+{
+ return yyr2[yyrule];
+}
+
+static void
+yydestroyGLRState (char const *yymsg, yyGLRState *yys)
+{
+ if (yys->yyresolved)
+ yydestruct (yymsg, yystos[yys->yylrState],
+ &yys->yysemantics.yysval, &yys->yyloc);
+ else
+ {
+#if YYDEBUG
+ if (yydebug)
+ {
+ if (yys->yysemantics.yyfirstVal)
+ YYFPRINTF (stderr, "%s unresolved ", yymsg);
+ else
+ YYFPRINTF (stderr, "%s incomplete ", yymsg);
+ yy_symbol_print (stderr, yystos[yys->yylrState],
+ NULL, &yys->yyloc);
+ YYFPRINTF (stderr, "\n");
+ }
+#endif
+
+ if (yys->yysemantics.yyfirstVal)
+ {
+ yySemanticOption *yyoption = yys->yysemantics.yyfirstVal;
+ yyGLRState *yyrh;
+ int yyn;
+ for (yyrh = yyoption->yystate, yyn = yyrhsLength (yyoption->yyrule);
+ yyn > 0;
+ yyrh = yyrh->yypred, yyn -= 1)
+ yydestroyGLRState (yymsg, yyrh);
+ }
+ }
+}
+
+/** Left-hand-side symbol for rule #RULE. */
+static inline yySymbol
+yylhsNonterm (yyRuleNum yyrule)
+{
+ return yyr1[yyrule];
+}
+
+#define yyis_pact_ninf(yystate) \
+ ((yystate) == YYPACT_NINF)
+
+/** True iff LR state STATE has only a default reduction (regardless
+ * of token). */
+static inline yybool
+yyisDefaultedState (yyStateNum yystate)
+{
+ return yyis_pact_ninf (yypact[yystate]);
+}
+
+/** The default reduction for STATE, assuming it has one. */
+static inline yyRuleNum
+yydefaultAction (yyStateNum yystate)
+{
+ return yydefact[yystate];
+}
+
+#define yyis_table_ninf(yytable_value) \
+ YYID (0)
+
+/** Set *YYACTION to the action to take in YYSTATE on seeing YYTOKEN.
+ * Result R means
+ * R < 0: Reduce on rule -R.
+ * R = 0: Error.
+ * R > 0: Shift to state R.
+ * Set *CONFLICTS to a pointer into yyconfl to 0-terminated list of
+ * conflicting reductions.
+ */
+static inline void
+yygetLRActions (yyStateNum yystate, int yytoken,
+ int* yyaction, const short int** yyconflicts)
+{
+ int yyindex = yypact[yystate] + yytoken;
+ if (yyindex < 0 || YYLAST < yyindex || yycheck[yyindex] != yytoken)
+ {
+ *yyaction = -yydefact[yystate];
+ *yyconflicts = yyconfl;
+ }
+ else if (! yyis_table_ninf (yytable[yyindex]))
+ {
+ *yyaction = yytable[yyindex];
+ *yyconflicts = yyconfl + yyconflp[yyindex];
+ }
+ else
+ {
+ *yyaction = 0;
+ *yyconflicts = yyconfl + yyconflp[yyindex];
+ }
+}
+
+static inline yyStateNum
+yyLRgotoState (yyStateNum yystate, yySymbol yylhs)
+{
+ int yyr;
+ yyr = yypgoto[yylhs - YYNTOKENS] + yystate;
+ if (0 <= yyr && yyr <= YYLAST && yycheck[yyr] == yystate)
+ return yytable[yyr];
+ else
+ return yydefgoto[yylhs - YYNTOKENS];
+}
+
+static inline yybool
+yyisShiftAction (int yyaction)
+{
+ return 0 < yyaction;
+}
+
+static inline yybool
+yyisErrorAction (int yyaction)
+{
+ return yyaction == 0;
+}
+
+ /* GLRStates */
+
+/** Return a fresh GLRStackItem. Callers should call
+ * YY_RESERVE_GLRSTACK afterwards to make sure there is sufficient
+ * headroom. */
+
+static inline yyGLRStackItem*
+yynewGLRStackItem (yyGLRStack* yystackp, yybool yyisState)
+{
+ yyGLRStackItem* yynewItem = yystackp->yynextFree;
+ yystackp->yyspaceLeft -= 1;
+ yystackp->yynextFree += 1;
+ yynewItem->yystate.yyisState = yyisState;
+ return yynewItem;
+}
+
+/** Add a new semantic action that will execute the action for rule
+ * RULENUM on the semantic values in RHS to the list of
+ * alternative actions for STATE. Assumes that RHS comes from
+ * stack #K of *STACKP. */
+static void
+yyaddDeferredAction (yyGLRStack* yystackp, size_t yyk, yyGLRState* yystate,
+ yyGLRState* rhs, yyRuleNum yyrule)
+{
+ yySemanticOption* yynewOption =
+ &yynewGLRStackItem (yystackp, yyfalse)->yyoption;
+ yynewOption->yystate = rhs;
+ yynewOption->yyrule = yyrule;
+ if (yystackp->yytops.yylookaheadNeeds[yyk])
+ {
+ yynewOption->yyrawchar = yychar;
+ yynewOption->yyval = yylval;
+ yynewOption->yyloc = yylloc;
+ }
+ else
+ yynewOption->yyrawchar = YYEMPTY;
+ yynewOption->yynext = yystate->yysemantics.yyfirstVal;
+ yystate->yysemantics.yyfirstVal = yynewOption;
+
+ YY_RESERVE_GLRSTACK (yystackp);
+}
+
+ /* GLRStacks */
+
+/** Initialize SET to a singleton set containing an empty stack. */
+static yybool
+yyinitStateSet (yyGLRStateSet* yyset)
+{
+ yyset->yysize = 1;
+ yyset->yycapacity = 16;
+ yyset->yystates = (yyGLRState**) YYMALLOC (16 * sizeof yyset->yystates[0]);
+ if (! yyset->yystates)
+ return yyfalse;
+ yyset->yystates[0] = NULL;
+ yyset->yylookaheadNeeds =
+ (yybool*) YYMALLOC (16 * sizeof yyset->yylookaheadNeeds[0]);
+ if (! yyset->yylookaheadNeeds)
+ {
+ YYFREE (yyset->yystates);
+ return yyfalse;
+ }
+ return yytrue;
+}
+
+static void yyfreeStateSet (yyGLRStateSet* yyset)
+{
+ YYFREE (yyset->yystates);
+ YYFREE (yyset->yylookaheadNeeds);
+}
+
+/** Initialize STACK to a single empty stack, with total maximum
+ * capacity for all stacks of SIZE. */
+static yybool
+yyinitGLRStack (yyGLRStack* yystackp, size_t yysize)
+{
+ yystackp->yyerrState = 0;
+ yynerrs = 0;
+ yystackp->yyspaceLeft = yysize;
+ yystackp->yyitems =
+ (yyGLRStackItem*) YYMALLOC (yysize * sizeof yystackp->yynextFree[0]);
+ if (!yystackp->yyitems)
+ return yyfalse;
+ yystackp->yynextFree = yystackp->yyitems;
+ yystackp->yysplitPoint = NULL;
+ yystackp->yylastDeleted = NULL;
+ return yyinitStateSet (&yystackp->yytops);
+}
+
+
+#if YYSTACKEXPANDABLE
+# define YYRELOC(YYFROMITEMS,YYTOITEMS,YYX,YYTYPE) \
+ &((YYTOITEMS) - ((YYFROMITEMS) - (yyGLRStackItem*) (YYX)))->YYTYPE
+
+/** If STACK is expandable, extend it. WARNING: Pointers into the
+ stack from outside should be considered invalid after this call.
+ We always expand when there are 1 or fewer items left AFTER an
+ allocation, so that we can avoid having external pointers exist
+ across an allocation. */
+static void
+yyexpandGLRStack (yyGLRStack* yystackp)
+{
+ yyGLRStackItem* yynewItems;
+ yyGLRStackItem* yyp0, *yyp1;
+ size_t yysize, yynewSize;
+ size_t yyn;
+ yysize = yystackp->yynextFree - yystackp->yyitems;
+ if (YYMAXDEPTH - YYHEADROOM < yysize)
+ yyMemoryExhausted (yystackp);
+ yynewSize = 2*yysize;
+ if (YYMAXDEPTH < yynewSize)
+ yynewSize = YYMAXDEPTH;
+ yynewItems = (yyGLRStackItem*) YYMALLOC (yynewSize * sizeof yynewItems[0]);
+ if (! yynewItems)
+ yyMemoryExhausted (yystackp);
+ for (yyp0 = yystackp->yyitems, yyp1 = yynewItems, yyn = yysize;
+ 0 < yyn;
+ yyn -= 1, yyp0 += 1, yyp1 += 1)
+ {
+ *yyp1 = *yyp0;
+ if (*(yybool *) yyp0)
+ {
+ yyGLRState* yys0 = &yyp0->yystate;
+ yyGLRState* yys1 = &yyp1->yystate;
+ if (yys0->yypred != NULL)
+ yys1->yypred =
+ YYRELOC (yyp0, yyp1, yys0->yypred, yystate);
+ if (! yys0->yyresolved && yys0->yysemantics.yyfirstVal != NULL)
+ yys1->yysemantics.yyfirstVal =
+ YYRELOC(yyp0, yyp1, yys0->yysemantics.yyfirstVal, yyoption);
+ }
+ else
+ {
+ yySemanticOption* yyv0 = &yyp0->yyoption;
+ yySemanticOption* yyv1 = &yyp1->yyoption;
+ if (yyv0->yystate != NULL)
+ yyv1->yystate = YYRELOC (yyp0, yyp1, yyv0->yystate, yystate);
+ if (yyv0->yynext != NULL)
+ yyv1->yynext = YYRELOC (yyp0, yyp1, yyv0->yynext, yyoption);
+ }
+ }
+ if (yystackp->yysplitPoint != NULL)
+ yystackp->yysplitPoint = YYRELOC (yystackp->yyitems, yynewItems,
+ yystackp->yysplitPoint, yystate);
+
+ for (yyn = 0; yyn < yystackp->yytops.yysize; yyn += 1)
+ if (yystackp->yytops.yystates[yyn] != NULL)
+ yystackp->yytops.yystates[yyn] =
+ YYRELOC (yystackp->yyitems, yynewItems,
+ yystackp->yytops.yystates[yyn], yystate);
+ YYFREE (yystackp->yyitems);
+ yystackp->yyitems = yynewItems;
+ yystackp->yynextFree = yynewItems + yysize;
+ yystackp->yyspaceLeft = yynewSize - yysize;
+}
+#endif
+
+static void
+yyfreeGLRStack (yyGLRStack* yystackp)
+{
+ YYFREE (yystackp->yyitems);
+ yyfreeStateSet (&yystackp->yytops);
+}
+
+/** Assuming that S is a GLRState somewhere on STACK, update the
+ * splitpoint of STACK, if needed, so that it is at least as deep as
+ * S. */
+static inline void
+yyupdateSplit (yyGLRStack* yystackp, yyGLRState* yys)
+{
+ if (yystackp->yysplitPoint != NULL && yystackp->yysplitPoint > yys)
+ yystackp->yysplitPoint = yys;
+}
+
+/** Invalidate stack #K in STACK. */
+static inline void
+yymarkStackDeleted (yyGLRStack* yystackp, size_t yyk)
+{
+ if (yystackp->yytops.yystates[yyk] != NULL)
+ yystackp->yylastDeleted = yystackp->yytops.yystates[yyk];
+ yystackp->yytops.yystates[yyk] = NULL;
+}
+
+/** Undelete the last stack that was marked as deleted. Can only be
+ done once after a deletion, and only when all other stacks have
+ been deleted. */
+static void
+yyundeleteLastStack (yyGLRStack* yystackp)
+{
+ if (yystackp->yylastDeleted == NULL || yystackp->yytops.yysize != 0)
+ return;
+ yystackp->yytops.yystates[0] = yystackp->yylastDeleted;
+ yystackp->yytops.yysize = 1;
+ YYDPRINTF ((stderr, "Restoring last deleted stack as stack #0.\n"));
+ yystackp->yylastDeleted = NULL;
+}
+
+static inline void
+yyremoveDeletes (yyGLRStack* yystackp)
+{
+ size_t yyi, yyj;
+ yyi = yyj = 0;
+ while (yyj < yystackp->yytops.yysize)
+ {
+ if (yystackp->yytops.yystates[yyi] == NULL)
+ {
+ if (yyi == yyj)
+ {
+ YYDPRINTF ((stderr, "Removing dead stacks.\n"));
+ }
+ yystackp->yytops.yysize -= 1;
+ }
+ else
+ {
+ yystackp->yytops.yystates[yyj] = yystackp->yytops.yystates[yyi];
+ /* In the current implementation, it's unnecessary to copy
+ yystackp->yytops.yylookaheadNeeds[yyi] since, after
+ yyremoveDeletes returns, the parser immediately either enters
+ deterministic operation or shifts a token. However, it doesn't
+ hurt, and the code might evolve to need it. */
+ yystackp->yytops.yylookaheadNeeds[yyj] =
+ yystackp->yytops.yylookaheadNeeds[yyi];
+ if (yyj != yyi)
+ {
+ YYDPRINTF ((stderr, "Rename stack %lu -> %lu.\n",
+ (unsigned long int) yyi, (unsigned long int) yyj));
+ }
+ yyj += 1;
+ }
+ yyi += 1;
+ }
+}
+
+/** Shift to a new state on stack #K of STACK, corresponding to LR state
+ * LRSTATE, at input position POSN, with (resolved) semantic value SVAL. */
+static inline void
+yyglrShift (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
+ size_t yyposn,
+ YYSTYPE* yyvalp, YYLTYPE* yylocp)
+{
+ yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
+
+ yynewState->yylrState = yylrState;
+ yynewState->yyposn = yyposn;
+ yynewState->yyresolved = yytrue;
+ yynewState->yypred = yystackp->yytops.yystates[yyk];
+ yynewState->yysemantics.yysval = *yyvalp;
+ yynewState->yyloc = *yylocp;
+ yystackp->yytops.yystates[yyk] = yynewState;
+
+ YY_RESERVE_GLRSTACK (yystackp);
+}
+
+/** Shift stack #K of YYSTACK, to a new state corresponding to LR
+ * state YYLRSTATE, at input position YYPOSN, with the (unresolved)
+ * semantic value of YYRHS under the action for YYRULE. */
+static inline void
+yyglrShiftDefer (yyGLRStack* yystackp, size_t yyk, yyStateNum yylrState,
+ size_t yyposn, yyGLRState* rhs, yyRuleNum yyrule)
+{
+ yyGLRState* yynewState = &yynewGLRStackItem (yystackp, yytrue)->yystate;
+
+ yynewState->yylrState = yylrState;
+ yynewState->yyposn = yyposn;
+ yynewState->yyresolved = yyfalse;
+ yynewState->yypred = yystackp->yytops.yystates[yyk];
+ yynewState->yysemantics.yyfirstVal = NULL;
+ yystackp->yytops.yystates[yyk] = yynewState;
+
+ /* Invokes YY_RESERVE_GLRSTACK. */
+ yyaddDeferredAction (yystackp, yyk, yynewState, rhs, yyrule);
+}
+
+/** Pop the symbols consumed by reduction #RULE from the top of stack
+ * #K of STACK, and perform the appropriate semantic action on their
+ * semantic values. Assumes that all ambiguities in semantic values
+ * have been previously resolved. Set *VALP to the resulting value,
+ * and *LOCP to the computed location (if any). Return value is as
+ * for userAction. */
+static inline YYRESULTTAG
+yydoAction (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
+ YYSTYPE* yyvalp, YYLTYPE* yylocp)
+{
+ int yynrhs = yyrhsLength (yyrule);
+
+ if (yystackp->yysplitPoint == NULL)
+ {
+ /* Standard special case: single stack. */
+ yyGLRStackItem* rhs = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
+ YYASSERT (yyk == 0);
+ yystackp->yynextFree -= yynrhs;
+ yystackp->yyspaceLeft += yynrhs;
+ yystackp->yytops.yystates[0] = & yystackp->yynextFree[-1].yystate;
+ return yyuserAction (yyrule, yynrhs, rhs,
+ yyvalp, yylocp, yystackp);
+ }
+ else
+ {
+ /* At present, doAction is never called in nondeterministic
+ * mode, so this branch is never taken. It is here in
+ * anticipation of a future feature that will allow immediate
+ * evaluation of selected actions in nondeterministic mode. */
+ int yyi;
+ yyGLRState* yys;
+ yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
+ yys = yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred
+ = yystackp->yytops.yystates[yyk];
+ if (yynrhs == 0)
+ /* Set default location. */
+ yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yys->yyloc;
+ for (yyi = 0; yyi < yynrhs; yyi += 1)
+ {
+ yys = yys->yypred;
+ YYASSERT (yys);
+ }
+ yyupdateSplit (yystackp, yys);
+ yystackp->yytops.yystates[yyk] = yys;
+ return yyuserAction (yyrule, yynrhs, yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
+ yyvalp, yylocp, yystackp);
+ }
+}
+
+#if !YYDEBUG
+# define YY_REDUCE_PRINT(Args)
+#else
+# define YY_REDUCE_PRINT(Args) \
+do { \
+ if (yydebug) \
+ yy_reduce_print Args; \
+} while (YYID (0))
+
+/*----------------------------------------------------------.
+| Report that the RULE is going to be reduced on stack #K. |
+`----------------------------------------------------------*/
+
+/*ARGSUSED*/ static inline void
+yy_reduce_print (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
+ YYSTYPE* yyvalp, YYLTYPE* yylocp)
+{
+ int yynrhs = yyrhsLength (yyrule);
+ yybool yynormal __attribute__ ((__unused__)) =
+ (yystackp->yysplitPoint == NULL);
+ yyGLRStackItem* yyvsp = (yyGLRStackItem*) yystackp->yytops.yystates[yyk];
+ int yylow = 1;
+ int yyi;
+ YYUSE (yyvalp);
+ YYUSE (yylocp);
+ YYFPRINTF (stderr, "Reducing stack %lu by rule %d (line %lu):\n",
+ (unsigned long int) yyk, yyrule - 1,
+ (unsigned long int) yyrline[yyrule]);
+ /* The symbols being reduced. */
+ for (yyi = 0; yyi < yynrhs; yyi++)
+ {
+ fprintf (stderr, " $%d = ", yyi + 1);
+ yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi],
+ &(((yyGLRStackItem const *)yyvsp)[YYFILL ((yyi + 1) - (yynrhs))].yystate.yysemantics.yysval)
+ , &(((yyGLRStackItem const *)yyvsp)[YYFILL ((yyi + 1) - (yynrhs))].yystate.yyloc) );
+ fprintf (stderr, "\n");
+ }
+}
+#endif
+
+/** Pop items off stack #K of STACK according to grammar rule RULE,
+ * and push back on the resulting nonterminal symbol. Perform the
+ * semantic action associated with RULE and store its value with the
+ * newly pushed state, if FORCEEVAL or if STACK is currently
+ * unambiguous. Otherwise, store the deferred semantic action with
+ * the new state. If the new state would have an identical input
+ * position, LR state, and predecessor to an existing state on the stack,
+ * it is identified with that existing state, eliminating stack #K from
+ * the STACK. In this case, the (necessarily deferred) semantic value is
+ * added to the options for the existing state's semantic value.
+ */
+static inline YYRESULTTAG
+yyglrReduce (yyGLRStack* yystackp, size_t yyk, yyRuleNum yyrule,
+ yybool yyforceEval)
+{
+ size_t yyposn = yystackp->yytops.yystates[yyk]->yyposn;
+
+ if (yyforceEval || yystackp->yysplitPoint == NULL)
+ {
+ YYSTYPE yysval;
+ YYLTYPE yyloc;
+
+ YY_REDUCE_PRINT ((yystackp, yyk, yyrule, &yysval, &yyloc));
+ YYCHK (yydoAction (yystackp, yyk, yyrule, &yysval,
+ &yyloc));
+ YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyrule], &yysval, &yyloc);
+ yyglrShift (yystackp, yyk,
+ yyLRgotoState (yystackp->yytops.yystates[yyk]->yylrState,
+ yylhsNonterm (yyrule)),
+ yyposn, &yysval, &yyloc);
+ }
+ else
+ {
+ size_t yyi;
+ int yyn;
+ yyGLRState* yys, *yys0 = yystackp->yytops.yystates[yyk];
+ yyStateNum yynewLRState;
+
+ for (yys = yystackp->yytops.yystates[yyk], yyn = yyrhsLength (yyrule);
+ 0 < yyn; yyn -= 1)
+ {
+ yys = yys->yypred;
+ YYASSERT (yys);
+ }
+ yyupdateSplit (yystackp, yys);
+ yynewLRState = yyLRgotoState (yys->yylrState, yylhsNonterm (yyrule));
+ YYDPRINTF ((stderr,
+ "Reduced stack %lu by rule #%d; action deferred. Now in state %d.\n",
+ (unsigned long int) yyk, yyrule - 1, yynewLRState));
+ for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
+ if (yyi != yyk && yystackp->yytops.yystates[yyi] != NULL)
+ {
+ yyGLRState* yyp, *yysplit = yystackp->yysplitPoint;
+ yyp = yystackp->yytops.yystates[yyi];
+ while (yyp != yys && yyp != yysplit && yyp->yyposn >= yyposn)
+ {
+ if (yyp->yylrState == yynewLRState && yyp->yypred == yys)
+ {
+ yyaddDeferredAction (yystackp, yyk, yyp, yys0, yyrule);
+ yymarkStackDeleted (yystackp, yyk);
+ YYDPRINTF ((stderr, "Merging stack %lu into stack %lu.\n",
+ (unsigned long int) yyk,
+ (unsigned long int) yyi));
+ return yyok;
+ }
+ yyp = yyp->yypred;
+ }
+ }
+ yystackp->yytops.yystates[yyk] = yys;
+ yyglrShiftDefer (yystackp, yyk, yynewLRState, yyposn, yys0, yyrule);
+ }
+ return yyok;
+}
+
+static size_t
+yysplitStack (yyGLRStack* yystackp, size_t yyk)
+{
+ if (yystackp->yysplitPoint == NULL)
+ {
+ YYASSERT (yyk == 0);
+ yystackp->yysplitPoint = yystackp->yytops.yystates[yyk];
+ }
+ if (yystackp->yytops.yysize >= yystackp->yytops.yycapacity)
+ {
+ yyGLRState** yynewStates;
+ yybool* yynewLookaheadNeeds;
+
+ yynewStates = NULL;
+
+ if (yystackp->yytops.yycapacity
+ > (YYSIZEMAX / (2 * sizeof yynewStates[0])))
+ yyMemoryExhausted (yystackp);
+ yystackp->yytops.yycapacity *= 2;
+
+ yynewStates =
+ (yyGLRState**) YYREALLOC (yystackp->yytops.yystates,
+ (yystackp->yytops.yycapacity
+ * sizeof yynewStates[0]));
+ if (yynewStates == NULL)
+ yyMemoryExhausted (yystackp);
+ yystackp->yytops.yystates = yynewStates;
+
+ yynewLookaheadNeeds =
+ (yybool*) YYREALLOC (yystackp->yytops.yylookaheadNeeds,
+ (yystackp->yytops.yycapacity
+ * sizeof yynewLookaheadNeeds[0]));
+ if (yynewLookaheadNeeds == NULL)
+ yyMemoryExhausted (yystackp);
+ yystackp->yytops.yylookaheadNeeds = yynewLookaheadNeeds;
+ }
+ yystackp->yytops.yystates[yystackp->yytops.yysize]
+ = yystackp->yytops.yystates[yyk];
+ yystackp->yytops.yylookaheadNeeds[yystackp->yytops.yysize]
+ = yystackp->yytops.yylookaheadNeeds[yyk];
+ yystackp->yytops.yysize += 1;
+ return yystackp->yytops.yysize-1;
+}
+
+/** True iff Y0 and Y1 represent identical options at the top level.
+ * That is, they represent the same rule applied to RHS symbols
+ * that produce the same terminal symbols. */
+static yybool
+yyidenticalOptions (yySemanticOption* yyy0, yySemanticOption* yyy1)
+{
+ if (yyy0->yyrule == yyy1->yyrule)
+ {
+ yyGLRState *yys0, *yys1;
+ int yyn;
+ for (yys0 = yyy0->yystate, yys1 = yyy1->yystate,
+ yyn = yyrhsLength (yyy0->yyrule);
+ yyn > 0;
+ yys0 = yys0->yypred, yys1 = yys1->yypred, yyn -= 1)
+ if (yys0->yyposn != yys1->yyposn)
+ return yyfalse;
+ return yytrue;
+ }
+ else
+ return yyfalse;
+}
+
+/** Assuming identicalOptions (Y0,Y1), destructively merge the
+ * alternative semantic values for the RHS-symbols of Y1 and Y0. */
+static void
+yymergeOptionSets (yySemanticOption* yyy0, yySemanticOption* yyy1)
+{
+ yyGLRState *yys0, *yys1;
+ int yyn;
+ for (yys0 = yyy0->yystate, yys1 = yyy1->yystate,
+ yyn = yyrhsLength (yyy0->yyrule);
+ yyn > 0;
+ yys0 = yys0->yypred, yys1 = yys1->yypred, yyn -= 1)
+ {
+ if (yys0 == yys1)
+ break;
+ else if (yys0->yyresolved)
+ {
+ yys1->yyresolved = yytrue;
+ yys1->yysemantics.yysval = yys0->yysemantics.yysval;
+ }
+ else if (yys1->yyresolved)
+ {
+ yys0->yyresolved = yytrue;
+ yys0->yysemantics.yysval = yys1->yysemantics.yysval;
+ }
+ else
+ {
+ yySemanticOption** yyz0p;
+ yySemanticOption* yyz1;
+ yyz0p = &yys0->yysemantics.yyfirstVal;
+ yyz1 = yys1->yysemantics.yyfirstVal;
+ while (YYID (yytrue))
+ {
+ if (yyz1 == *yyz0p || yyz1 == NULL)
+ break;
+ else if (*yyz0p == NULL)
+ {
+ *yyz0p = yyz1;
+ break;
+ }
+ else if (*yyz0p < yyz1)
+ {
+ yySemanticOption* yyz = *yyz0p;
+ *yyz0p = yyz1;
+ yyz1 = yyz1->yynext;
+ (*yyz0p)->yynext = yyz;
+ }
+ yyz0p = &(*yyz0p)->yynext;
+ }
+ yys1->yysemantics.yyfirstVal = yys0->yysemantics.yyfirstVal;
+ }
+ }
+}
+
+/** Y0 and Y1 represent two possible actions to take in a given
+ * parsing state; return 0 if no combination is possible,
+ * 1 if user-mergeable, 2 if Y0 is preferred, 3 if Y1 is preferred. */
+static int
+yypreference (yySemanticOption* y0, yySemanticOption* y1)
+{
+ yyRuleNum r0 = y0->yyrule, r1 = y1->yyrule;
+ int p0 = yydprec[r0], p1 = yydprec[r1];
+
+ if (p0 == p1)
+ {
+ if (yymerger[r0] == 0 || yymerger[r0] != yymerger[r1])
+ return 0;
+ else
+ return 1;
+ }
+ if (p0 == 0 || p1 == 0)
+ return 0;
+ if (p0 < p1)
+ return 3;
+ if (p1 < p0)
+ return 2;
+ return 0;
+}
+
+static YYRESULTTAG yyresolveValue (yyGLRState* yys,
+ yyGLRStack* yystackp);
+
+
+/** Resolve the previous N states starting at and including state S. If result
+ * != yyok, some states may have been left unresolved possibly with empty
+ * semantic option chains. Regardless of whether result = yyok, each state
+ * has been left with consistent data so that yydestroyGLRState can be invoked
+ * if necessary. */
+static YYRESULTTAG
+yyresolveStates (yyGLRState* yys, int yyn,
+ yyGLRStack* yystackp)
+{
+ if (0 < yyn)
+ {
+ YYASSERT (yys->yypred);
+ YYCHK (yyresolveStates (yys->yypred, yyn-1, yystackp));
+ if (! yys->yyresolved)
+ YYCHK (yyresolveValue (yys, yystackp));
+ }
+ return yyok;
+}
+
+/** Resolve the states for the RHS of OPT, perform its user action, and return
+ * the semantic value and location. Regardless of whether result = yyok, all
+ * RHS states have been destroyed (assuming the user action destroys all RHS
+ * semantic values if invoked). */
+static YYRESULTTAG
+yyresolveAction (yySemanticOption* yyopt, yyGLRStack* yystackp,
+ YYSTYPE* yyvalp, YYLTYPE* yylocp)
+{
+ yyGLRStackItem yyrhsVals[YYMAXRHS + YYMAXLEFT + 1];
+ int yynrhs;
+ int yychar_current;
+ YYSTYPE yylval_current;
+ YYLTYPE yylloc_current;
+ YYRESULTTAG yyflag;
+
+ yynrhs = yyrhsLength (yyopt->yyrule);
+ yyflag = yyresolveStates (yyopt->yystate, yynrhs, yystackp);
+ if (yyflag != yyok)
+ {
+ yyGLRState *yys;
+ for (yys = yyopt->yystate; yynrhs > 0; yys = yys->yypred, yynrhs -= 1)
+ yydestroyGLRState ("Cleanup: popping", yys);
+ return yyflag;
+ }
+
+ yyrhsVals[YYMAXRHS + YYMAXLEFT].yystate.yypred = yyopt->yystate;
+ if (yynrhs == 0)
+ /* Set default location. */
+ yyrhsVals[YYMAXRHS + YYMAXLEFT - 1].yystate.yyloc = yyopt->yystate->yyloc;
+ yychar_current = yychar;
+ yylval_current = yylval;
+ yylloc_current = yylloc;
+ yychar = yyopt->yyrawchar;
+ yylval = yyopt->yyval;
+ yylloc = yyopt->yyloc;
+ yyflag = yyuserAction (yyopt->yyrule, yynrhs,
+ yyrhsVals + YYMAXRHS + YYMAXLEFT - 1,
+ yyvalp, yylocp, yystackp);
+ yychar = yychar_current;
+ yylval = yylval_current;
+ yylloc = yylloc_current;
+ return yyflag;
+}
+
+#if YYDEBUG
+static void
+yyreportTree (yySemanticOption* yyx, int yyindent)
+{
+ int yynrhs = yyrhsLength (yyx->yyrule);
+ int yyi;
+ yyGLRState* yys;
+ yyGLRState* yystates[1 + YYMAXRHS];
+ yyGLRState yyleftmost_state;
+
+ for (yyi = yynrhs, yys = yyx->yystate; 0 < yyi; yyi -= 1, yys = yys->yypred)
+ yystates[yyi] = yys;
+ if (yys == NULL)
+ {
+ yyleftmost_state.yyposn = 0;
+ yystates[0] = &yyleftmost_state;
+ }
+ else
+ yystates[0] = yys;
+
+ if (yyx->yystate->yyposn < yys->yyposn + 1)
+ YYFPRINTF (stderr, "%*s%s -> <Rule %d, empty>\n",
+ yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
+ yyx->yyrule - 1);
+ else
+ YYFPRINTF (stderr, "%*s%s -> <Rule %d, tokens %lu .. %lu>\n",
+ yyindent, "", yytokenName (yylhsNonterm (yyx->yyrule)),
+ yyx->yyrule - 1, (unsigned long int) (yys->yyposn + 1),
+ (unsigned long int) yyx->yystate->yyposn);
+ for (yyi = 1; yyi <= yynrhs; yyi += 1)
+ {
+ if (yystates[yyi]->yyresolved)
+ {
+ if (yystates[yyi-1]->yyposn+1 > yystates[yyi]->yyposn)
+ YYFPRINTF (stderr, "%*s%s <empty>\n", yyindent+2, "",
+ yytokenName (yyrhs[yyprhs[yyx->yyrule]+yyi-1]));
+ else
+ YYFPRINTF (stderr, "%*s%s <tokens %lu .. %lu>\n", yyindent+2, "",
+ yytokenName (yyrhs[yyprhs[yyx->yyrule]+yyi-1]),
+ (unsigned long int) (yystates[yyi - 1]->yyposn + 1),
+ (unsigned long int) yystates[yyi]->yyposn);
+ }
+ else
+ yyreportTree (yystates[yyi]->yysemantics.yyfirstVal, yyindent+2);
+ }
+}
+#endif
+
+/*ARGSUSED*/ static YYRESULTTAG
+yyreportAmbiguity (yySemanticOption* yyx0,
+ yySemanticOption* yyx1)
+{
+ YYUSE (yyx0);
+ YYUSE (yyx1);
+
+#if YYDEBUG
+ YYFPRINTF (stderr, "Ambiguity detected.\n");
+ YYFPRINTF (stderr, "Option 1,\n");
+ yyreportTree (yyx0, 2);
+ YYFPRINTF (stderr, "\nOption 2,\n");
+ yyreportTree (yyx1, 2);
+ YYFPRINTF (stderr, "\n");
+#endif
+
+ yyerror (YY_("syntax is ambiguous"));
+ return yyabort;
+}
+
+/** Starting at and including state S1, resolve the location for each of the
+ * previous N1 states that is unresolved. The first semantic option of a state
+ * is always chosen. */
+static void
+yyresolveLocations (yyGLRState* yys1, int yyn1,
+ yyGLRStack *yystackp)
+{
+ if (0 < yyn1)
+ {
+ yyresolveLocations (yys1->yypred, yyn1 - 1, yystackp);
+ if (!yys1->yyresolved)
+ {
+ yySemanticOption *yyoption;
+ yyGLRStackItem yyrhsloc[1 + YYMAXRHS];
+ int yynrhs;
+ int yychar_current;
+ YYSTYPE yylval_current;
+ YYLTYPE yylloc_current;
+ yyoption = yys1->yysemantics.yyfirstVal;
+ YYASSERT (yyoption != NULL);
+ yynrhs = yyrhsLength (yyoption->yyrule);
+ if (yynrhs > 0)
+ {
+ yyGLRState *yys;
+ int yyn;
+ yyresolveLocations (yyoption->yystate, yynrhs,
+ yystackp);
+ for (yys = yyoption->yystate, yyn = yynrhs;
+ yyn > 0;
+ yys = yys->yypred, yyn -= 1)
+ yyrhsloc[yyn].yystate.yyloc = yys->yyloc;
+ }
+ else
+ {
+ /* Both yyresolveAction and yyresolveLocations traverse the GSS
+ in reverse rightmost order. It is only necessary to invoke
+ yyresolveLocations on a subforest for which yyresolveAction
+ would have been invoked next had an ambiguity not been
+ detected. Thus the location of the previous state (but not
+ necessarily the previous state itself) is guaranteed to be
+ resolved already. */
+ yyGLRState *yyprevious = yyoption->yystate;
+ yyrhsloc[0].yystate.yyloc = yyprevious->yyloc;
+ }
+ yychar_current = yychar;
+ yylval_current = yylval;
+ yylloc_current = yylloc;
+ yychar = yyoption->yyrawchar;
+ yylval = yyoption->yyval;
+ yylloc = yyoption->yyloc;
+ YYLLOC_DEFAULT ((yys1->yyloc), yyrhsloc, yynrhs);
+ yychar = yychar_current;
+ yylval = yylval_current;
+ yylloc = yylloc_current;
+ }
+ }
+}
+
+/** Resolve the ambiguity represented in state S, perform the indicated
+ * actions, and set the semantic value of S. If result != yyok, the chain of
+ * semantic options in S has been cleared instead or it has been left
+ * unmodified except that redundant options may have been removed. Regardless
+ * of whether result = yyok, S has been left with consistent data so that
+ * yydestroyGLRState can be invoked if necessary. */
+static YYRESULTTAG
+yyresolveValue (yyGLRState* yys, yyGLRStack* yystackp)
+{
+ yySemanticOption* yyoptionList = yys->yysemantics.yyfirstVal;
+ yySemanticOption* yybest;
+ yySemanticOption** yypp;
+ yybool yymerge;
+ YYSTYPE yysval;
+ YYRESULTTAG yyflag;
+ YYLTYPE *yylocp = &yys->yyloc;
+
+ yybest = yyoptionList;
+ yymerge = yyfalse;
+ for (yypp = &yyoptionList->yynext; *yypp != NULL; )
+ {
+ yySemanticOption* yyp = *yypp;
+
+ if (yyidenticalOptions (yybest, yyp))
+ {
+ yymergeOptionSets (yybest, yyp);
+ *yypp = yyp->yynext;
+ }
+ else
+ {
+ switch (yypreference (yybest, yyp))
+ {
+ case 0:
+ yyresolveLocations (yys, 1, yystackp);
+ return yyreportAmbiguity (yybest, yyp);
+ break;
+ case 1:
+ yymerge = yytrue;
+ break;
+ case 2:
+ break;
+ case 3:
+ yybest = yyp;
+ yymerge = yyfalse;
+ break;
+ default:
+ /* This cannot happen so it is not worth a YYASSERT (yyfalse),
+ but some compilers complain if the default case is
+ omitted. */
+ break;
+ }
+ yypp = &yyp->yynext;
+ }
+ }
+
+ if (yymerge)
+ {
+ yySemanticOption* yyp;
+ int yyprec = yydprec[yybest->yyrule];
+ yyflag = yyresolveAction (yybest, yystackp, &yysval,
+ yylocp);
+ if (yyflag == yyok)
+ for (yyp = yybest->yynext; yyp != NULL; yyp = yyp->yynext)
+ {
+ if (yyprec == yydprec[yyp->yyrule])
+ {
+ YYSTYPE yysval_other;
+ YYLTYPE yydummy;
+ yyflag = yyresolveAction (yyp, yystackp, &yysval_other,
+ &yydummy);
+ if (yyflag != yyok)
+ {
+ yydestruct ("Cleanup: discarding incompletely merged value for",
+ yystos[yys->yylrState],
+ &yysval, yylocp);
+ break;
+ }
+ yyuserMerge (yymerger[yyp->yyrule], &yysval, &yysval_other);
+ }
+ }
+ }
+ else
+ yyflag = yyresolveAction (yybest, yystackp, &yysval, yylocp);
+
+ if (yyflag == yyok)
+ {
+ yys->yyresolved = yytrue;
+ yys->yysemantics.yysval = yysval;
+ }
+ else
+ yys->yysemantics.yyfirstVal = NULL;
+ return yyflag;
+}
+
+static YYRESULTTAG
+yyresolveStack (yyGLRStack* yystackp)
+{
+ if (yystackp->yysplitPoint != NULL)
+ {
+ yyGLRState* yys;
+ int yyn;
+
+ for (yyn = 0, yys = yystackp->yytops.yystates[0];
+ yys != yystackp->yysplitPoint;
+ yys = yys->yypred, yyn += 1)
+ continue;
+ YYCHK (yyresolveStates (yystackp->yytops.yystates[0], yyn, yystackp
+ ));
+ }
+ return yyok;
+}
+
+static void
+yycompressStack (yyGLRStack* yystackp)
+{
+ yyGLRState* yyp, *yyq, *yyr;
+
+ if (yystackp->yytops.yysize != 1 || yystackp->yysplitPoint == NULL)
+ return;
+
+ for (yyp = yystackp->yytops.yystates[0], yyq = yyp->yypred, yyr = NULL;
+ yyp != yystackp->yysplitPoint;
+ yyr = yyp, yyp = yyq, yyq = yyp->yypred)
+ yyp->yypred = yyr;
+
+ yystackp->yyspaceLeft += yystackp->yynextFree - yystackp->yyitems;
+ yystackp->yynextFree = ((yyGLRStackItem*) yystackp->yysplitPoint) + 1;
+ yystackp->yyspaceLeft -= yystackp->yynextFree - yystackp->yyitems;
+ yystackp->yysplitPoint = NULL;
+ yystackp->yylastDeleted = NULL;
+
+ while (yyr != NULL)
+ {
+ yystackp->yynextFree->yystate = *yyr;
+ yyr = yyr->yypred;
+ yystackp->yynextFree->yystate.yypred = &yystackp->yynextFree[-1].yystate;
+ yystackp->yytops.yystates[0] = &yystackp->yynextFree->yystate;
+ yystackp->yynextFree += 1;
+ yystackp->yyspaceLeft -= 1;
+ }
+}
+
+static YYRESULTTAG
+yyprocessOneStack (yyGLRStack* yystackp, size_t yyk,
+ size_t yyposn)
+{
+ int yyaction;
+ const short int* yyconflicts;
+ yyRuleNum yyrule;
+
+ while (yystackp->yytops.yystates[yyk] != NULL)
+ {
+ yyStateNum yystate = yystackp->yytops.yystates[yyk]->yylrState;
+ YYDPRINTF ((stderr, "Stack %lu Entering state %d\n",
+ (unsigned long int) yyk, yystate));
+
+ YYASSERT (yystate != YYFINAL);
+
+ if (yyisDefaultedState (yystate))
+ {
+ yyrule = yydefaultAction (yystate);
+ if (yyrule == 0)
+ {
+ YYDPRINTF ((stderr, "Stack %lu dies.\n",
+ (unsigned long int) yyk));
+ yymarkStackDeleted (yystackp, yyk);
+ return yyok;
+ }
+ YYCHK (yyglrReduce (yystackp, yyk, yyrule, yyfalse));
+ }
+ else
+ {
+ yySymbol yytoken;
+ yystackp->yytops.yylookaheadNeeds[yyk] = yytrue;
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+ else
+ yytoken = YYTRANSLATE (yychar);
+ yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts);
+
+ while (*yyconflicts != 0)
+ {
+ size_t yynewStack = yysplitStack (yystackp, yyk);
+ YYDPRINTF ((stderr, "Splitting off stack %lu from %lu.\n",
+ (unsigned long int) yynewStack,
+ (unsigned long int) yyk));
+ YYCHK (yyglrReduce (yystackp, yynewStack,
+ *yyconflicts, yyfalse));
+ YYCHK (yyprocessOneStack (yystackp, yynewStack,
+ yyposn));
+ yyconflicts += 1;
+ }
+
+ if (yyisShiftAction (yyaction))
+ break;
+ else if (yyisErrorAction (yyaction))
+ {
+ YYDPRINTF ((stderr, "Stack %lu dies.\n",
+ (unsigned long int) yyk));
+ yymarkStackDeleted (yystackp, yyk);
+ break;
+ }
+ else
+ YYCHK (yyglrReduce (yystackp, yyk, -yyaction,
+ yyfalse));
+ }
+ }
+ return yyok;
+}
+
+/*ARGSUSED*/ static void
+yyreportSyntaxError (yyGLRStack* yystackp)
+{
+ if (yystackp->yyerrState == 0)
+ {
+#if YYERROR_VERBOSE
+ int yyn;
+ yyn = yypact[yystackp->yytops.yystates[0]->yylrState];
+ if (YYPACT_NINF < yyn && yyn <= YYLAST)
+ {
+ yySymbol yytoken = YYTRANSLATE (yychar);
+ size_t yysize0 = yytnamerr (NULL, yytokenName (yytoken));
+ size_t yysize = yysize0;
+ size_t yysize1;
+ yybool yysize_overflow = yyfalse;
+ char* yymsg = NULL;
+ enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
+ char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
+ int yyx;
+ char *yyfmt;
+ char const *yyf;
+ static char const yyunexpected[] = "syntax error, unexpected %s";
+ static char const yyexpecting[] = ", expecting %s";
+ static char const yyor[] = " or %s";
+ char yyformat[sizeof yyunexpected
+ + sizeof yyexpecting - 1
+ + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2)
+ * (sizeof yyor - 1))];
+ char const *yyprefix = yyexpecting;
+
+ /* Start YYX at -YYN if negative to avoid negative indexes in
+ YYCHECK. */
+ int yyxbegin = yyn < 0 ? -yyn : 0;
+
+ /* Stay within bounds of both yycheck and yytname. */
+ int yychecklim = YYLAST - yyn + 1;
+ int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
+ int yycount = 1;
+
+ yyarg[0] = yytokenName (yytoken);
+ yyfmt = yystpcpy (yyformat, yyunexpected);
+
+ for (yyx = yyxbegin; yyx < yyxend; ++yyx)
+ if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR)
+ {
+ if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
+ {
+ yycount = 1;
+ yysize = yysize0;
+ yyformat[sizeof yyunexpected - 1] = '\0';
+ break;
+ }
+ yyarg[yycount++] = yytokenName (yyx);
+ yysize1 = yysize + yytnamerr (NULL, yytokenName (yyx));
+ yysize_overflow |= yysize1 < yysize;
+ yysize = yysize1;
+ yyfmt = yystpcpy (yyfmt, yyprefix);
+ yyprefix = yyor;
+ }
+
+ yyf = YY_(yyformat);
+ yysize1 = yysize + strlen (yyf);
+ yysize_overflow |= yysize1 < yysize;
+ yysize = yysize1;
+
+ if (!yysize_overflow)
+ yymsg = (char *) YYMALLOC (yysize);
+
+ if (yymsg)
+ {
+ char *yyp = yymsg;
+ int yyi = 0;
+ while ((*yyp = *yyf))
+ {
+ if (*yyp == '%' && yyf[1] == 's' && yyi < yycount)
+ {
+ yyp += yytnamerr (yyp, yyarg[yyi++]);
+ yyf += 2;
+ }
+ else
+ {
+ yyp++;
+ yyf++;
+ }
+ }
+ yyerror (yymsg);
+ YYFREE (yymsg);
+ }
+ else
+ {
+ yyerror (YY_("syntax error"));
+ yyMemoryExhausted (yystackp);
+ }
+ }
+ else
+#endif /* YYERROR_VERBOSE */
+ yyerror (YY_("syntax error"));
+ yynerrs += 1;
+ }
+}
+
+/* Recover from a syntax error on *YYSTACKP, assuming that *YYSTACKP->YYTOKENP,
+ yylval, and yylloc are the syntactic category, semantic value, and location
+ of the look-ahead. */
+/*ARGSUSED*/ static void
+yyrecoverSyntaxError (yyGLRStack* yystackp)
+{
+ size_t yyk;
+ int yyj;
+
+ if (yystackp->yyerrState == 3)
+ /* We just shifted the error token and (perhaps) took some
+ reductions. Skip tokens until we can proceed. */
+ while (YYID (yytrue))
+ {
+ yySymbol yytoken;
+ if (yychar == YYEOF)
+ yyFail (yystackp, NULL);
+ if (yychar != YYEMPTY)
+ {
+ /* We throw away the lookahead, but the error range
+ of the shifted error token must take it into account. */
+ yyGLRState *yys = yystackp->yytops.yystates[0];
+ yyGLRStackItem yyerror_range[3];
+ yyerror_range[1].yystate.yyloc = yys->yyloc;
+ yyerror_range[2].yystate.yyloc = yylloc;
+ YYLLOC_DEFAULT ((yys->yyloc), yyerror_range, 2);
+ yytoken = YYTRANSLATE (yychar);
+ yydestruct ("Error: discarding",
+ yytoken, &yylval, &yylloc);
+ }
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ yyj = yypact[yystackp->yytops.yystates[0]->yylrState];
+ if (yyis_pact_ninf (yyj))
+ return;
+ yyj += yytoken;
+ if (yyj < 0 || YYLAST < yyj || yycheck[yyj] != yytoken)
+ {
+ if (yydefact[yystackp->yytops.yystates[0]->yylrState] != 0)
+ return;
+ }
+ else if (yytable[yyj] != 0 && ! yyis_table_ninf (yytable[yyj]))
+ return;
+ }
+
+ /* Reduce to one stack. */
+ for (yyk = 0; yyk < yystackp->yytops.yysize; yyk += 1)
+ if (yystackp->yytops.yystates[yyk] != NULL)
+ break;
+ if (yyk >= yystackp->yytops.yysize)
+ yyFail (yystackp, NULL);
+ for (yyk += 1; yyk < yystackp->yytops.yysize; yyk += 1)
+ yymarkStackDeleted (yystackp, yyk);
+ yyremoveDeletes (yystackp);
+ yycompressStack (yystackp);
+
+ /* Now pop stack until we find a state that shifts the error token. */
+ yystackp->yyerrState = 3;
+ while (yystackp->yytops.yystates[0] != NULL)
+ {
+ yyGLRState *yys = yystackp->yytops.yystates[0];
+ yyj = yypact[yys->yylrState];
+ if (! yyis_pact_ninf (yyj))
+ {
+ yyj += YYTERROR;
+ if (0 <= yyj && yyj <= YYLAST && yycheck[yyj] == YYTERROR
+ && yyisShiftAction (yytable[yyj]))
+ {
+ /* Shift the error token having adjusted its location. */
+ YYLTYPE yyerrloc;
+ yystackp->yyerror_range[2].yystate.yyloc = yylloc;
+ YYLLOC_DEFAULT (yyerrloc, (yystackp->yyerror_range), 2);
+ YY_SYMBOL_PRINT ("Shifting", yystos[yytable[yyj]],
+ &yylval, &yyerrloc);
+ yyglrShift (yystackp, 0, yytable[yyj],
+ yys->yyposn, &yylval, &yyerrloc);
+ yys = yystackp->yytops.yystates[0];
+ break;
+ }
+ }
+ yystackp->yyerror_range[1].yystate.yyloc = yys->yyloc;
+ yydestroyGLRState ("Error: popping", yys);
+ yystackp->yytops.yystates[0] = yys->yypred;
+ yystackp->yynextFree -= 1;
+ yystackp->yyspaceLeft += 1;
+ }
+ if (yystackp->yytops.yystates[0] == NULL)
+ yyFail (yystackp, NULL);
+}
+
+#define YYCHK1(YYE) \
+ do { \
+ switch (YYE) { \
+ case yyok: \
+ break; \
+ case yyabort: \
+ goto yyabortlab; \
+ case yyaccept: \
+ goto yyacceptlab; \
+ case yyerr: \
+ goto yyuser_error; \
+ default: \
+ goto yybuglab; \
+ } \
+ } while (YYID (0))
+
+
+/*----------.
+| yyparse. |
+`----------*/
+
+int
+yyparse (void)
+{
+ int yyresult;
+ yyGLRStack yystack;
+ yyGLRStack* const yystackp = &yystack;
+ size_t yyposn;
+
+ YYDPRINTF ((stderr, "Starting parse\n"));
+
+ yychar = YYEMPTY;
+ yylval = yyval_default;
+
+#if defined YYLTYPE_IS_TRIVIAL && YYLTYPE_IS_TRIVIAL
+ yylloc.first_line = yylloc.last_line = 1;
+ yylloc.first_column = yylloc.last_column = 0;
+#endif
+
+
+ if (! yyinitGLRStack (yystackp, YYINITDEPTH))
+ goto yyexhaustedlab;
+ switch (YYSETJMP (yystack.yyexception_buffer))
+ {
+ case 0: break;
+ case 1: goto yyabortlab;
+ case 2: goto yyexhaustedlab;
+ default: goto yybuglab;
+ }
+ yyglrShift (&yystack, 0, 0, 0, &yylval, &yylloc);
+ yyposn = 0;
+
+ while (YYID (yytrue))
+ {
+ /* For efficiency, we have two loops, the first of which is
+ specialized to deterministic operation (single stack, no
+ potential ambiguity). */
+ /* Standard mode */
+ while (YYID (yytrue))
+ {
+ yyRuleNum yyrule;
+ int yyaction;
+ const short int* yyconflicts;
+
+ yyStateNum yystate = yystack.yytops.yystates[0]->yylrState;
+ YYDPRINTF ((stderr, "Entering state %d\n", yystate));
+ if (yystate == YYFINAL)
+ goto yyacceptlab;
+ if (yyisDefaultedState (yystate))
+ {
+ yyrule = yydefaultAction (yystate);
+ if (yyrule == 0)
+ {
+ yystack.yyerror_range[1].yystate.yyloc = yylloc;
+ yyreportSyntaxError (&yystack);
+ goto yyuser_error;
+ }
+ YYCHK1 (yyglrReduce (&yystack, 0, yyrule, yytrue));
+ }
+ else
+ {
+ yySymbol yytoken;
+ if (yychar == YYEMPTY)
+ {
+ YYDPRINTF ((stderr, "Reading a token: "));
+ yychar = YYLEX;
+ yytoken = YYTRANSLATE (yychar);
+ YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
+ }
+ else
+ yytoken = YYTRANSLATE (yychar);
+ yygetLRActions (yystate, yytoken, &yyaction, &yyconflicts);
+ if (*yyconflicts != 0)
+ break;
+ if (yyisShiftAction (yyaction))
+ {
+ YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
+ if (yychar != YYEOF)
+ yychar = YYEMPTY;
+ yyposn += 1;
+ yyglrShift (&yystack, 0, yyaction, yyposn, &yylval, &yylloc);
+ if (0 < yystack.yyerrState)
+ yystack.yyerrState -= 1;
+ }
+ else if (yyisErrorAction (yyaction))
+ {
+ yystack.yyerror_range[1].yystate.yyloc = yylloc;
+ yyreportSyntaxError (&yystack);
+ goto yyuser_error;
+ }
+ else
+ YYCHK1 (yyglrReduce (&yystack, 0, -yyaction, yytrue));
+ }
+ }
+
+ while (YYID (yytrue))
+ {
+ yySymbol yytoken_to_shift;
+ size_t yys;
+
+ for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
+ yystackp->yytops.yylookaheadNeeds[yys] = yychar != YYEMPTY;
+
+ /* yyprocessOneStack returns one of three things:
+
+ - An error flag. If the caller is yyprocessOneStack, it
+ immediately returns as well. When the caller is finally
+ yyparse, it jumps to an error label via YYCHK1.
+
+ - yyok, but yyprocessOneStack has invoked yymarkStackDeleted
+ (&yystack, yys), which sets the top state of yys to NULL. Thus,
+ yyparse's following invocation of yyremoveDeletes will remove
+ the stack.
+
+ - yyok, when ready to shift a token.
+
+ Except in the first case, yyparse will invoke yyremoveDeletes and
+ then shift the next token onto all remaining stacks. This
+ synchronization of the shift (that is, after all preceding
+ reductions on all stacks) helps prevent double destructor calls
+ on yylval in the event of memory exhaustion. */
+
+ for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
+ YYCHK1 (yyprocessOneStack (&yystack, yys, yyposn));
+ yyremoveDeletes (&yystack);
+ if (yystack.yytops.yysize == 0)
+ {
+ yyundeleteLastStack (&yystack);
+ if (yystack.yytops.yysize == 0)
+ yyFail (&yystack, YY_("syntax error"));
+ YYCHK1 (yyresolveStack (&yystack));
+ YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
+ yystack.yyerror_range[1].yystate.yyloc = yylloc;
+ yyreportSyntaxError (&yystack);
+ goto yyuser_error;
+ }
+
+ /* If any yyglrShift call fails, it will fail after shifting. Thus,
+ a copy of yylval will already be on stack 0 in the event of a
+ failure in the following loop. Thus, yychar is set to YYEMPTY
+ before the loop to make sure the user destructor for yylval isn't
+ called twice. */
+ yytoken_to_shift = YYTRANSLATE (yychar);
+ yychar = YYEMPTY;
+ yyposn += 1;
+ for (yys = 0; yys < yystack.yytops.yysize; yys += 1)
+ {
+ int yyaction;
+ const short int* yyconflicts;
+ yyStateNum yystate = yystack.yytops.yystates[yys]->yylrState;
+ yygetLRActions (yystate, yytoken_to_shift, &yyaction,
+ &yyconflicts);
+ /* Note that yyconflicts were handled by yyprocessOneStack. */
+ YYDPRINTF ((stderr, "On stack %lu, ", (unsigned long int) yys));
+ YY_SYMBOL_PRINT ("shifting", yytoken_to_shift, &yylval, &yylloc);
+ yyglrShift (&yystack, yys, yyaction, yyposn,
+ &yylval, &yylloc);
+ YYDPRINTF ((stderr, "Stack %lu now in state #%d\n",
+ (unsigned long int) yys,
+ yystack.yytops.yystates[yys]->yylrState));
+ }
+
+ if (yystack.yytops.yysize == 1)
+ {
+ YYCHK1 (yyresolveStack (&yystack));
+ YYDPRINTF ((stderr, "Returning to deterministic operation.\n"));
+ yycompressStack (&yystack);
+ break;
+ }
+ }
+ continue;
+ yyuser_error:
+ yyrecoverSyntaxError (&yystack);
+ yyposn = yystack.yytops.yystates[0]->yyposn;
+ }
+
+ yyacceptlab:
+ yyresult = 0;
+ goto yyreturn;
+
+ yybuglab:
+ YYASSERT (yyfalse);
+ goto yyabortlab;
+
+ yyabortlab:
+ yyresult = 1;
+ goto yyreturn;
+
+ yyexhaustedlab:
+ yyerror (YY_("memory exhausted"));
+ yyresult = 2;
+ goto yyreturn;
+
+ yyreturn:
+ if (yychar != YYEOF && yychar != YYEMPTY)
+ yydestruct ("Cleanup: discarding lookahead",
+ YYTRANSLATE (yychar),
+ &yylval, &yylloc);
+
+ /* If the stack is well-formed, pop the stack until it is empty,
+ destroying its entries as we go. But free the stack regardless
+ of whether it is well-formed. */
+ if (yystack.yyitems)
+ {
+ yyGLRState** yystates = yystack.yytops.yystates;
+ if (yystates)
+ {
+ size_t yysize = yystack.yytops.yysize;
+ size_t yyk;
+ for (yyk = 0; yyk < yysize; yyk += 1)
+ if (yystates[yyk])
+ {
+ while (yystates[yyk])
+ {
+ yyGLRState *yys = yystates[yyk];
+ yystack.yyerror_range[1].yystate.yyloc = yys->yyloc;
+ yydestroyGLRState ("Cleanup: popping", yys);
+ yystates[yyk] = yys->yypred;
+ yystack.yynextFree -= 1;
+ yystack.yyspaceLeft += 1;
+ }
+ break;
+ }
+ }
+ yyfreeGLRStack (&yystack);
+ }
+
+ /* Make sure YYID is used. */
+ return YYID (yyresult);
+}
+
+/* DEBUGGING ONLY */
+#ifdef YYDEBUG
+static void yypstack (yyGLRStack* yystackp, size_t yyk)
+ __attribute__ ((__unused__));
+static void yypdumpstack (yyGLRStack* yystackp) __attribute__ ((__unused__));
+
+static void
+yy_yypstack (yyGLRState* yys)
+{
+ if (yys->yypred)
+ {
+ yy_yypstack (yys->yypred);
+ fprintf (stderr, " -> ");
+ }
+ fprintf (stderr, "%d@%lu", yys->yylrState, (unsigned long int) yys->yyposn);
+}
+
+static void
+yypstates (yyGLRState* yyst)
+{
+ if (yyst == NULL)
+ fprintf (stderr, "<null>");
+ else
+ yy_yypstack (yyst);
+ fprintf (stderr, "\n");
+}
+
+static void
+yypstack (yyGLRStack* yystackp, size_t yyk)
+{
+ yypstates (yystackp->yytops.yystates[yyk]);
+}
+
+#define YYINDEX(YYX) \
+ ((YYX) == NULL ? -1 : (yyGLRStackItem*) (YYX) - yystackp->yyitems)
+
+
+static void
+yypdumpstack (yyGLRStack* yystackp)
+{
+ yyGLRStackItem* yyp;
+ size_t yyi;
+ for (yyp = yystackp->yyitems; yyp < yystackp->yynextFree; yyp += 1)
+ {
+ fprintf (stderr, "%3lu. ", (unsigned long int) (yyp - yystackp->yyitems));
+ if (*(yybool *) yyp)
+ {
+ fprintf (stderr, "Res: %d, LR State: %d, posn: %lu, pred: %ld",
+ yyp->yystate.yyresolved, yyp->yystate.yylrState,
+ (unsigned long int) yyp->yystate.yyposn,
+ (long int) YYINDEX (yyp->yystate.yypred));
+ if (! yyp->yystate.yyresolved)
+ fprintf (stderr, ", firstVal: %ld",
+ (long int) YYINDEX (yyp->yystate.yysemantics.yyfirstVal));
+ }
+ else
+ {
+ fprintf (stderr, "Option. rule: %d, state: %ld, next: %ld",
+ yyp->yyoption.yyrule - 1,
+ (long int) YYINDEX (yyp->yyoption.yystate),
+ (long int) YYINDEX (yyp->yyoption.yynext));
+ }
+ fprintf (stderr, "\n");
+ }
+ fprintf (stderr, "Tops:");
+ for (yyi = 0; yyi < yystackp->yytops.yysize; yyi += 1)
+ fprintf (stderr, "%lu: %ld; ", (unsigned long int) yyi,
+ (long int) YYINDEX (yystackp->yytops.yystates[yyi]));
+ fprintf (stderr, "\n");
+}
+#endif
+
+
+#line 1750 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+
+
diff --git a/generic/Lgrammar.h b/generic/Lgrammar.h
new file mode 100644
index 0000000..4135082
--- /dev/null
+++ b/generic/Lgrammar.h
@@ -0,0 +1,233 @@
+/* A Bison parser, made by GNU Bison 2.3. */
+
+/* Skeleton interface for Bison GLR parsers in C
+
+ Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+/* As a special exception, you may create a larger work that contains
+ part or all of the Bison parser skeleton and distribute that work
+ under terms of your choice, so long as that work isn't itself a
+ parser generator using the skeleton or a modified version thereof
+ as a parser skeleton. Alternatively, if you modify or redistribute
+ the parser skeleton itself, you may (at your option) remove this
+ special exception, which will cause the skeleton and the resulting
+ Bison output files to be licensed under the GNU General Public
+ License without this special exception.
+
+ This special exception was added by the Free Software Foundation in
+ version 2.2 of Bison. */
+
+/* Tokens. */
+#ifndef YYTOKENTYPE
+# define YYTOKENTYPE
+ /* Put the tokens into the symbol table, so that GDB and other debuggers
+ know about them. */
+ enum yytokentype {
+ END = 0,
+ T_ANDAND = 258,
+ T_ARROW = 259,
+ T_ATTRIBUTE = 260,
+ T_BANG = 261,
+ T_BANGTWID = 262,
+ T_BITAND = 263,
+ T_BITOR = 264,
+ T_BITNOT = 265,
+ T_BITXOR = 266,
+ T_BREAK = 267,
+ T_CLASS = 268,
+ T_COLON = 269,
+ T_COMMA = 270,
+ T_CONSTRUCTOR = 271,
+ T_CONTINUE = 272,
+ T_DEFINED = 273,
+ T_DESTRUCTOR = 274,
+ T_DO = 275,
+ T_DOT = 276,
+ T_DOTDOT = 277,
+ T_ELLIPSIS = 278,
+ T_ELSE = 279,
+ T_EQ = 280,
+ T_EQBITAND = 281,
+ T_EQBITOR = 282,
+ T_EQBITXOR = 283,
+ T_EQDOT = 284,
+ T_EQLSHIFT = 285,
+ T_EQMINUS = 286,
+ T_EQPERC = 287,
+ T_EQPLUS = 288,
+ T_EQRSHIFT = 289,
+ T_EQSTAR = 290,
+ T_EQSLASH = 291,
+ T_EQTWID = 292,
+ T_EQUALS = 293,
+ T_EQUALEQUAL = 294,
+ T_EXPAND = 295,
+ T_EXTERN = 296,
+ T_FLOAT = 297,
+ T_FLOAT_LITERAL = 298,
+ T_FOR = 299,
+ T_FOREACH = 300,
+ T_GOTO = 301,
+ T_GE = 302,
+ T_GREATER = 303,
+ T_GREATEREQ = 304,
+ T_GT = 305,
+ T_HTML = 306,
+ T_ID = 307,
+ T_IF = 308,
+ T_INSTANCE = 309,
+ T_INT = 310,
+ T_INT_LITERAL = 311,
+ T_LHTML_EXPR_START = 312,
+ T_LHTML_EXPR_END = 313,
+ T_LBRACE = 314,
+ T_LBRACKET = 315,
+ T_LE = 316,
+ T_LEFT_INTERPOL = 317,
+ T_LEFT_INTERPOL_RE = 318,
+ T_LESSTHAN = 319,
+ T_LESSTHANEQ = 320,
+ T_LPAREN = 321,
+ T_LSHIFT = 322,
+ T_LT = 323,
+ T_MINUS = 324,
+ T_MINUSMINUS = 325,
+ T_NE = 326,
+ T_NOTEQUAL = 327,
+ T_OROR = 328,
+ T_PATTERN = 329,
+ T_PERC = 330,
+ T_PLUS = 331,
+ T_PLUSPLUS = 332,
+ T_POINTS = 333,
+ T_POLY = 334,
+ T_PRIVATE = 335,
+ T_PUBLIC = 336,
+ T_QUESTION = 337,
+ T_RBRACE = 338,
+ T_RBRACKET = 339,
+ T_RE = 340,
+ T_RE_MODIFIER = 341,
+ T_RETURN = 342,
+ T_RIGHT_INTERPOL = 343,
+ T_RIGHT_INTERPOL_RE = 344,
+ T_RPAREN = 345,
+ T_RSHIFT = 346,
+ T_TRY = 347,
+ T_SEMI = 348,
+ T_SLASH = 349,
+ T_SPLIT = 350,
+ T_STAR = 351,
+ T_START_BACKTICK = 352,
+ T_STR_BACKTICK = 353,
+ T_STR_LITERAL = 354,
+ T_STRCAT = 355,
+ T_STRING = 356,
+ T_STRUCT = 357,
+ T_SUBST = 358,
+ T_TYPE = 359,
+ T_TYPEDEF = 360,
+ T_UNLESS = 361,
+ T_ARGUSED = 362,
+ T_OPTIONAL = 363,
+ T_MUSTBETYPE = 364,
+ T_VOID = 365,
+ T_WIDGET = 366,
+ T_WHILE = 367,
+ T_PRAGMA = 368,
+ T_SWITCH = 369,
+ T_CASE = 370,
+ T_DEFAULT = 371,
+ LOWEST = 372,
+ ADDRESS = 373,
+ UMINUS = 374,
+ UPLUS = 375,
+ PREFIX_INCDEC = 376,
+ HIGHEST = 377
+ };
+#endif
+
+
+/* Copy the first part of user declarations. */
+#line 1 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+
+/*
+ * Copyright (c) 2006-2008 BitMover, Inc.
+ */
+#include <stdio.h>
+#include "Lcompile.h"
+
+/* L_lex is generated by flex. */
+extern int L_lex (void);
+
+#define YYERROR_VERBOSE
+#define L_error L_synerr
+
+
+#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
+typedef union YYSTYPE
+#line 53 "/Users/rob/bk/dev-L-lhtml-fix/src/gui/tcltk/tcl/generic/Lgrammar.y"
+{
+ long i;
+ char *s;
+ Tcl_Obj *obj;
+ Type *Type;
+ Expr *Expr;
+ Block *Block;
+ ForEach *ForEach;
+ Switch *Switch;
+ Case *Case;
+ FnDecl *FnDecl;
+ Cond *Cond;
+ Loop *Loop;
+ Stmt *Stmt;
+ TopLev *TopLev;
+ VarDecl *VarDecl;
+ ClsDecl *ClsDecl;
+ struct {
+ Type *t;
+ char *s;
+ } Typename;
+}
+/* Line 2616 of glr.c. */
+#line 209 "Lgrammar.h"
+ YYSTYPE;
+# define YYSTYPE_IS_DECLARED 1
+# define YYSTYPE_IS_TRIVIAL 1
+#endif
+
+#if ! defined YYLTYPE && ! defined YYLTYPE_IS_DECLARED
+typedef struct YYLTYPE
+{
+
+ int first_line;
+ int first_column;
+ int last_line;
+ int last_column;
+
+} YYLTYPE;
+# define YYLTYPE_IS_DECLARED 1
+# define YYLTYPE_IS_TRIVIAL 1
+#endif
+
+
+extern YYSTYPE L_lval;
+
+extern YYLTYPE L_lloc;
+
+
diff --git a/generic/Lgrammar.y b/generic/Lgrammar.y
new file mode 100644
index 0000000..2b6ee8f
--- /dev/null
+++ b/generic/Lgrammar.y
@@ -0,0 +1,1750 @@
+%{
+/*
+ * Copyright (c) 2006-2008 BitMover, Inc.
+ */
+#include <stdio.h>
+#include "Lcompile.h"
+
+/* L_lex is generated by flex. */
+extern int L_lex (void);
+
+#define YYERROR_VERBOSE
+#define L_error L_synerr
+%}
+
+/*
+ * We need a GLR parser because of a shift/reduce conflict introduced
+ * by hash-element types. This production is the culprit:
+ *
+ * array_or_hash_type: "{" scalar_type_specifier "}"
+ *
+ * This introduced a shift/reduce conflict on "{" due to "{" being in
+ * the FOLLOW set of scalar_type_specifier because "{" can follow
+ * type_specifier in function_decl. For example, after you
+ * have seen
+ *
+ * struct s
+ *
+ * and "{" is the next token, the parser can't tell whether to shift
+ * and proceed to parse a struct_specifier that declares a struct:
+ *
+ * struct s { int x,y; }
+ *
+ * or whether to reduce and proceed in to a array_or_hash_type:
+ *
+ * struct s { int } f() {}
+ *
+ * To make this grammar LALR(1) seemed difficult. The grammar seems
+ * to want to be LALR(3) perhaps(?). The best we could do was to extend
+ * the language by pushing the array_or_hash_type syntax down into
+ * scalar_type_specifier and struct_specifier. This would allow
+ * inputs that should be syntax errors, so extra checking would have
+ * been needed to detect these cases.
+ *
+ * The GLR parser has no problem with this type of conflict and keeps
+ * the grammar nice.
+ *
+ * Note that the %expect 1 below is for this conflict. Although the
+ * GLR parser handles it, it is still reported as a conflict.
+ */
+%glr-parser
+%expect 1
+
+%union {
+ long i;
+ char *s;
+ Tcl_Obj *obj;
+ Type *Type;
+ Expr *Expr;
+ Block *Block;
+ ForEach *ForEach;
+ Switch *Switch;
+ Case *Case;
+ FnDecl *FnDecl;
+ Cond *Cond;
+ Loop *Loop;
+ Stmt *Stmt;
+ TopLev *TopLev;
+ VarDecl *VarDecl;
+ ClsDecl *ClsDecl;
+ struct {
+ Type *t;
+ char *s;
+ } Typename;
+}
+
+%token T_ANDAND "&&"
+%token T_ARROW "=>"
+%token T_ATTRIBUTE "_attribute"
+%token T_BANG "!"
+%token T_BANGTWID "!~"
+%token T_BITAND "&"
+%token T_BITOR "|"
+%token T_BITNOT "~"
+%token T_BITXOR "^"
+%token T_BREAK "break"
+%token T_CLASS "class"
+%token T_COLON ":"
+%token T_COMMA ","
+%token T_CONSTRUCTOR "constructor"
+%token T_CONTINUE "continue"
+%token T_DEFINED "defined"
+%token T_DESTRUCTOR "destructor"
+%token T_DO "do"
+%token T_DOT "."
+%token T_DOTDOT ".."
+%token T_ELLIPSIS "..."
+%token T_ELSE "else"
+%token T_EQ "eq"
+%token T_EQBITAND "&="
+%token T_EQBITOR "|="
+%token T_EQBITXOR "^="
+%token T_EQDOT ".="
+%token T_EQLSHIFT "<<="
+%token T_EQMINUS "-="
+%token T_EQPERC "%="
+%token T_EQPLUS "+="
+%token T_EQRSHIFT ">>="
+%token T_EQSTAR "*="
+%token T_EQSLASH "/="
+%token T_EQTWID "=~"
+%token T_EQUALS "="
+%token T_EQUALEQUAL "=="
+%token T_EXPAND "(expand)"
+%token T_EXTERN "extern"
+%token T_FLOAT "float"
+%token <s> T_FLOAT_LITERAL "float constant"
+%token T_FOR "for"
+%token T_FOREACH "foreach"
+%token T_GOTO "goto"
+%token T_GE "ge"
+%token T_GREATER ">"
+%token T_GREATEREQ ">="
+%token T_GT "gt"
+%token <s> T_HTML
+%token <s> T_ID "id"
+%token T_IF "if"
+%token T_INSTANCE "instance"
+%token T_INT "int"
+%token <s> T_INT_LITERAL "integer constant"
+%token <s> T_LHTML_EXPR_START "<?="
+%token <s> T_LHTML_EXPR_END "?>"
+%token T_LBRACE "{"
+%token T_LBRACKET "["
+%token T_LE "le"
+%token <s> T_LEFT_INTERPOL "${"
+%token <s> T_LEFT_INTERPOL_RE "${ (in re)"
+%token T_LESSTHAN "<"
+%token T_LESSTHANEQ "<="
+%token T_LPAREN "("
+%token T_LSHIFT "<<"
+%token T_LT "lt"
+%token T_MINUS "-"
+%token T_MINUSMINUS "--"
+%token T_NE "ne"
+%token T_NOTEQUAL "!="
+%token T_OROR "||"
+%token <s> T_PATTERN "pattern function"
+%token T_PERC "%"
+%token T_PLUS "+"
+%token T_PLUSPLUS "++"
+%token T_POINTS "->"
+%token T_POLY "poly"
+%token T_PRIVATE "private"
+%token T_PUBLIC "public"
+%token T_QUESTION "?"
+%token T_RBRACE "}"
+%token T_RBRACKET "]"
+%token <s> T_RE "regular expression"
+%token <s> T_RE_MODIFIER "regexp modifier"
+%token T_RETURN "return"
+%token T_RIGHT_INTERPOL "} (end of interpolation)"
+%token T_RIGHT_INTERPOL_RE "} (end of interpolation in re)"
+%token T_RPAREN ")"
+%token T_RSHIFT ">>"
+%token T_TRY "try"
+%token T_SEMI ";"
+%token T_SLASH "/"
+%token T_SPLIT "split"
+%token T_STAR "*"
+%token <s> T_START_BACKTICK "backtick"
+%token <s> T_STR_BACKTICK "`"
+%token <s> T_STR_LITERAL "string constant"
+%token T_STRCAT " . "
+%token T_STRING "string"
+%token T_STRUCT "struct"
+%token <s> T_SUBST "=~ s/a/b/"
+%token <Typename> T_TYPE "type name"
+%token T_TYPEDEF "typedef"
+%token T_UNLESS "unless"
+%token T_ARGUSED "_argused"
+%token T_OPTIONAL "_optional"
+%token T_MUSTBETYPE "_mustbetype"
+%token T_VOID "void"
+%token T_WIDGET "widget"
+%token T_WHILE "while"
+%token T_PRAGMA "#pragma"
+%token T_SWITCH "switch"
+%token T_CASE "case"
+%token T_DEFAULT "default"
+%token END 0 "end of file"
+
+/*
+ * This follows the C operator-precedence rules, from lowest to
+ * highest precedence.
+ */
+%left LOWEST
+// The following %nonassoc lines are defined to resolve a conflict with
+// labeled statements (see the stmt nonterm).
+%nonassoc T_IF T_UNLESS T_RETURN T_ID T_STR_LITERAL T_LEFT_INTERPOL
+%nonassoc T_STR_BACKTICK T_INT_LITERAL T_FLOAT_LITERAL T_TYPE T_WHILE
+%nonassoc T_FOR T_DO T_DEFINED T_STRING T_FOREACH T_BREAK T_CONTINUE
+%nonassoc T_SPLIT T_GOTO T_WIDGET T_PRAGMA T_SWITCH T_START_BACKTICK T_TRY
+%nonassoc T_HTML T_LHTML_EXPR_START
+%left T_COMMA
+%nonassoc T_ELSE T_SEMI
+%right T_EQUALS T_EQPLUS T_EQMINUS T_EQSTAR T_EQSLASH T_EQPERC
+ T_EQBITAND T_EQBITOR T_EQBITXOR T_EQLSHIFT T_EQRSHIFT T_EQDOT
+%right T_QUESTION
+%left T_OROR
+%left T_ANDAND
+%left T_BITOR
+%left T_BITXOR
+%left T_BITAND
+%left T_EQ T_NE T_EQUALEQUAL T_NOTEQUAL T_EQTWID T_BANGTWID
+%left T_GT T_GE T_LT T_LE T_GREATER T_GREATEREQ T_LESSTHAN T_LESSTHANEQ
+%left T_LSHIFT T_RSHIFT
+%left T_PLUS T_MINUS T_STRCAT
+%left T_STAR T_SLASH T_PERC
+%right PREFIX_INCDEC UPLUS UMINUS T_BANG T_BITNOT ADDRESS
+%left T_LBRACKET T_LBRACE T_RBRACE T_DOT T_POINTS T_PLUSPLUS T_MINUSMINUS
+%left HIGHEST
+
+%type <TopLev> toplevel_code
+%type <ClsDecl> class_decl class_decl_tail
+%type <FnDecl> function_decl fundecl_tail fundecl_tail1
+%type <Stmt> stmt single_stmt compound_stmt stmt_list opt_stmt_list
+%type <Stmt> unlabeled_stmt optional_else
+%type <Cond> selection_stmt
+%type <Loop> iteration_stmt
+%type <ForEach> foreach_stmt
+%type <Switch> switch_stmt
+%type <Case> switch_cases switch_case
+%type <Expr> expr expression_stmt argument_expr_list pragma_expr_list
+%type <Expr> id id_list string_literal cmdsubst_literal dotted_id
+%type <Expr> regexp_literal regexp_literal_mod subst_literal interpolated_expr
+%type <Expr> interpolated_expr_re list list_element case_expr option_arg
+%type <Expr> here_doc_backtick opt_attribute pragma
+%type <VarDecl> parameter_list parameter_decl_list parameter_decl
+%type <VarDecl> declaration_list declaration declaration2
+%type <VarDecl> init_declarator_list declarator_list init_declarator
+%type <VarDecl> declarator opt_declarator struct_decl_list struct_decl
+%type <VarDecl> struct_declarator_list
+%type <Type> array_or_hash_type type_specifier scalar_type_specifier
+%type <Type> struct_specifier
+%type <obj> dotted_id_1
+%type <i> decl_qualifier parameter_attrs
+
+%%
+
+start: toplevel_code
+ {
+ REVERSE(TopLev, next, $1);
+ L->ast = $1;
+ }
+ ;
+
+toplevel_code:
+ toplevel_code class_decl
+ {
+ if ($2) {
+ $$ = ast_mkTopLevel(L_TOPLEVEL_CLASS, $1, @2, @2);
+ $$->u.class = $2;
+ } else {
+ // Don't create a node for a forward class declaration.
+ $$ = $1;
+ }
+ }
+ | toplevel_code function_decl
+ {
+ $$ = ast_mkTopLevel(L_TOPLEVEL_FUN, $1, @2, @2);
+ $2->decl->flags |= DECL_FN;
+ if ($2->decl->flags & DECL_PRIVATE) {
+ $2->decl->flags |= SCOPE_SCRIPT;
+ } else {
+ $2->decl->flags |= SCOPE_GLOBAL;
+ }
+ $$->u.fun = $2;
+ }
+ | toplevel_code struct_specifier ";"
+ {
+ $$ = $1; // nothing more to do
+ }
+ | toplevel_code T_TYPEDEF type_specifier declarator ";"
+ {
+ L_set_declBaseType($4, $3);
+ L_typedef_store($4);
+ $$ = $1; // nothing more to do
+ }
+ | toplevel_code declaration
+ {
+ // Global variable declaration.
+ VarDecl *v;
+ $$ = ast_mkTopLevel(L_TOPLEVEL_GLOBAL, $1, @2, @2);
+ for (v = $2; v; v = v->next) {
+ v->flags |= DECL_GLOBAL_VAR;
+ if ($2->flags & DECL_PRIVATE) {
+ v->flags |= SCOPE_SCRIPT;
+ } else {
+ v->flags |= SCOPE_GLOBAL;
+ }
+ }
+ $$->u.global = $2;
+ }
+ | toplevel_code stmt
+ {
+ // Top-level statement.
+ $$ = ast_mkTopLevel(L_TOPLEVEL_STMT, $1, @2, @2);
+ $$->u.stmt = $2;
+ }
+ | /* epsilon */ { $$ = NULL; }
+ ;
+
+class_decl:
+ T_CLASS id "{"
+ {
+ /*
+ * This is a new class declaration.
+ * Alloc the VarDecl now and associate it with
+ * the class name so that it is available while
+ * parsing the class body.
+ */
+ Type *t = type_mkClass();
+ VarDecl *d = ast_mkVarDecl(t, $2, @1, @1);
+ ClsDecl *c = ast_mkClsDecl(d, @1, @1);
+ t->u.class.clsdecl = c;
+ ASSERT(!L_typedef_lookup($2->str));
+ L_typedef_store(d);
+ $<ClsDecl>$ = c;
+ } class_decl_tail
+ {
+ $$ = $5;
+ /* silence unused warning */
+ (void)$<ClsDecl>4;
+ }
+ | T_CLASS T_TYPE "{"
+ {
+ /*
+ * This is a class declaration where the type name was
+ * previously declared. Use the ClsDecl from the
+ * prior decl.
+ */
+ ClsDecl *c = $2.t->u.class.clsdecl;
+ unless (c->decl->flags & DECL_FORWARD) {
+ L_err("redeclaration of %s", $2.s);
+ }
+ ASSERT(isclasstype(c->decl->type));
+ c->decl->flags &= ~DECL_FORWARD;
+ $<ClsDecl>$ = c;
+ } class_decl_tail
+ {
+ $$ = $5;
+ /* silence unused warning */
+ (void)$<ClsDecl>4;
+ }
+ | T_CLASS id ";"
+ {
+ /* This is a forward class declaration. */
+ Type *t = type_mkClass();
+ VarDecl *d = ast_mkVarDecl(t, $2, @1, @3);
+ ClsDecl *c = ast_mkClsDecl(d, @1, @3);
+ ASSERT(!L_typedef_lookup($2->str));
+ t->u.class.clsdecl = c;
+ d->flags |= DECL_FORWARD;
+ L_typedef_store(d);
+ $<ClsDecl>$ = NULL;
+ }
+ | T_CLASS T_TYPE ";"
+ {
+ /* Empty declaration of an already declared type. */
+ unless (isclasstype($2.t)) {
+ L_err("%s not a class type", $2.s);
+ }
+ $<ClsDecl>$ = NULL;
+ }
+ ;
+
+class_decl_tail:
+ class_code "}"
+ {
+ $$ = $<ClsDecl>0;
+ $$->node.loc.end = @2.end;
+ $$->decl->node.loc.end = @2.end;
+ /* If constructor or destructor were omitted, make defaults. */
+ unless ($$->constructors) {
+ $$->constructors = ast_mkConstructor($$);
+ }
+ unless ($$->destructors) {
+ $$->destructors = ast_mkDestructor($$);
+ }
+ }
+ ;
+
+class_code:
+ class_code T_INSTANCE "{" declaration_list "}" opt_semi
+ {
+ VarDecl *v;
+ ClsDecl *clsdecl = $<ClsDecl>0;
+ REVERSE(VarDecl, next, $4);
+ for (v = $4; v; v = v->next) {
+ v->clsdecl = clsdecl;
+ v->flags |= SCOPE_CLASS | DECL_CLASS_INST_VAR;
+ unless (v->flags & (DECL_PUBLIC | DECL_PRIVATE)) {
+ L_errf(v, "class instance variable %s not "
+ "declared public or private",
+ v->id->str);
+ v->flags |= DECL_PUBLIC;
+ }
+ }
+ APPEND_OR_SET(VarDecl, next, clsdecl->instvars, $4);
+ }
+ | class_code T_INSTANCE "{" "}" opt_semi
+ | class_code declaration
+ {
+ VarDecl *v;
+ ClsDecl *clsdecl = $<ClsDecl>0;
+ REVERSE(VarDecl, next, $2);
+ for (v = $2; v; v = v->next) {
+ v->clsdecl = clsdecl;
+ v->flags |= SCOPE_CLASS | DECL_CLASS_VAR;
+ unless (v->flags & (DECL_PUBLIC | DECL_PRIVATE)) {
+ L_errf(v, "class variable %s not "
+ "declared public or private",
+ v->id->str);
+ v->flags |= DECL_PUBLIC;
+ }
+ }
+ APPEND_OR_SET(VarDecl, next, clsdecl->clsvars, $2);
+ }
+ | class_code struct_specifier ";"
+ | class_code T_TYPEDEF type_specifier declarator ";"
+ {
+ L_set_declBaseType($4, $3);
+ L_typedef_store($4);
+ }
+ | class_code function_decl
+ {
+ ClsDecl *clsdecl = $<ClsDecl>0;
+ $2->decl->clsdecl = clsdecl;
+ $2->decl->flags |= DECL_CLASS_FN;
+ unless ($2->decl->flags & DECL_PRIVATE) {
+ $2->decl->flags |= SCOPE_GLOBAL | DECL_PUBLIC;
+ } else {
+ $2->decl->flags |= SCOPE_CLASS;
+ $2->decl->tclprefix = cksprintf("_L_class_%s_",
+ clsdecl->decl->id->str);
+ }
+ APPEND_OR_SET(FnDecl, next, clsdecl->fns, $2);
+ }
+ | class_code T_CONSTRUCTOR fundecl_tail
+ {
+ ClsDecl *clsdecl = $<ClsDecl>0;
+ $3->decl->type->base_type = clsdecl->decl->type;
+ $3->decl->clsdecl = clsdecl;
+ $3->decl->flags |= SCOPE_GLOBAL | DECL_CLASS_FN | DECL_PUBLIC |
+ DECL_CLASS_CONST;
+ APPEND_OR_SET(FnDecl, next, clsdecl->constructors, $3);
+ }
+ | class_code T_DESTRUCTOR fundecl_tail
+ {
+ ClsDecl *clsdecl = $<ClsDecl>0;
+ $3->decl->type->base_type = L_void;
+ $3->decl->clsdecl = clsdecl;
+ $3->decl->flags |= SCOPE_GLOBAL | DECL_CLASS_FN | DECL_PUBLIC |
+ DECL_CLASS_DESTR;
+ APPEND_OR_SET(FnDecl, next, clsdecl->destructors, $3);
+ }
+ | class_code pragma
+ {
+ /*
+ * We don't store the things that make up class_code
+ * in order, so there's no place in which to
+ * interleave #pragmas. So don't create an AST node,
+ * just update L->options now; it gets used when other
+ * AST nodes are created.
+ */
+ L_compile_attributes(L->options, $2, L_attrs_pragma);
+ }
+ | /* epsilon */
+ ;
+
+opt_semi:
+ ";"
+ | /* epsilon */
+ ;
+
+function_decl:
+ type_specifier fundecl_tail
+ {
+ $2->decl->type->base_type = $1;
+ $$ = $2;
+ $$->node.loc = @1;
+ }
+ | decl_qualifier type_specifier fundecl_tail
+ {
+ $3->decl->type->base_type = $2;
+ $3->decl->flags |= $1;
+ $$ = $3;
+ $$->node.loc = @1;
+ }
+ ;
+
+fundecl_tail:
+ id fundecl_tail1
+ {
+ $$ = $2;
+ $$->decl->id = $1;
+ $$->node.loc = @1;
+ }
+ | T_PATTERN fundecl_tail1
+ {
+ VarDecl *new_param;
+ Expr *dollar1 = ast_mkId("$1", @2, @2);
+
+ $$ = $2;
+ $$->decl->id = ast_mkId($1, @1, @1);
+ ckfree($1);
+ $$->node.loc = @1;
+ /* Prepend a new arg "$1" as the first formal. */
+ new_param = ast_mkVarDecl(L_string, dollar1, @1, @2);
+ new_param->flags = SCOPE_LOCAL | DECL_LOCAL_VAR;
+ new_param->next = $2->decl->type->u.func.formals;
+ $$->decl->type->u.func.formals = new_param;
+ }
+ ;
+
+fundecl_tail1:
+ "(" parameter_list ")" opt_attribute compound_stmt
+ {
+ Type *type = type_mkFunc(NULL, $2);
+ VarDecl *decl = ast_mkVarDecl(type, NULL, @1, @3);
+ decl->attrs = $4;
+ $$ = ast_mkFnDecl(decl, $5->u.block, @1, @5);
+ }
+ | "(" parameter_list ")" opt_attribute ";"
+ {
+ Type *type = type_mkFunc(NULL, $2);
+ VarDecl *decl = ast_mkVarDecl(type, NULL, @1, @3);
+ decl->attrs = $4;
+ $$ = ast_mkFnDecl(decl, NULL, @1, @5);
+ }
+ ;
+
+stmt:
+ T_ID ":" stmt
+ {
+ $$ = ast_mkStmt(L_STMT_LABEL, NULL, @1, @3);
+ $$->u.label = $1;
+ $$->next = $3;
+ }
+ | T_ID ":" %prec LOWEST
+ {
+ $$ = ast_mkStmt(L_STMT_LABEL, NULL, @1, @2);
+ $$->u.label = $1;
+ }
+ | unlabeled_stmt
+ | pragma
+ {
+ L_compile_attributes(L->options, $1, L_attrs_pragma);
+ $$ = NULL;
+ }
+ | T_HTML
+ {
+ // Wrap the html in a puts(-nonewline) call.
+ Expr *fn = ast_mkId("puts", @1, @1);
+ Expr *arg = ast_mkConst(L_string, "-nonewline", @1, @1);
+ arg->next = ast_mkConst(L_string, $1, @1, @1);
+ $$ = ast_mkStmt(L_STMT_EXPR, NULL, @1, @1);
+ $$->u.expr = ast_mkFnCall(fn, arg, @1, @1);
+ }
+ | T_LHTML_EXPR_START expr T_LHTML_EXPR_END
+ {
+ // Wrap expr in a puts(-nonewline) call.
+ Expr *fn = ast_mkId("puts", @2, @2);
+ Expr *arg = ast_mkConst(L_string, "-nonewline", @2, @2);
+ arg->next = $2;
+ $$ = ast_mkStmt(L_STMT_EXPR, NULL, @1, @3);
+ $$->u.expr = ast_mkFnCall(fn, arg, @1, @3);
+ }
+ ;
+
+pragma_expr_list:
+ id
+ | id "=" id
+ {
+ $$ = ast_mkBinOp(L_OP_EQUALS, $1, $3, @1, @3);
+ }
+ | id "=" T_INT_LITERAL
+ {
+ Expr *lit = ast_mkConst(L_int, $3, @3, @3);
+ $$ = ast_mkBinOp(L_OP_EQUALS, $1, lit, @1, @3);
+ }
+ | pragma_expr_list "," id
+ {
+ $3->next = $1;
+ $$ = $3;
+ $$->node.loc.beg = @1.beg;
+ }
+ | pragma_expr_list "," id "=" id
+ {
+ $$ = ast_mkBinOp(L_OP_EQUALS, $3, $5, @3, @5);
+ $$->next = $1;
+ $$->node.loc.beg = @1.beg;
+ }
+ | pragma_expr_list "," id "=" T_INT_LITERAL
+ {
+ Expr *lit = ast_mkConst(L_int, $5, @5, @5);
+ $$ = ast_mkBinOp(L_OP_EQUALS, $3, lit, @3, @5);
+ $$->next = $1;
+ $$->node.loc.beg = @1.beg;
+ }
+ ;
+
+pragma:
+ T_PRAGMA pragma_expr_list
+ {
+ REVERSE(Expr, next, $2);
+ $$ = $2;
+ $$->node.loc.beg = @1.beg;
+ }
+ ;
+
+opt_attribute:
+ T_ATTRIBUTE "(" argument_expr_list ")"
+ {
+ REVERSE(Expr, next, $3);
+ $$ = $3;
+ $$->node.loc.beg = @1.beg;
+ $$->node.loc.end = @4.end;
+ }
+ | { $$ = NULL; }
+ ;
+
+unlabeled_stmt:
+ single_stmt
+ | compound_stmt
+ ;
+
+single_stmt:
+ selection_stmt
+ {
+ $$ = ast_mkStmt(L_STMT_COND, NULL, @1, @1);
+ $$->u.cond = $1;
+ }
+ | iteration_stmt
+ {
+ $$ = ast_mkStmt(L_STMT_LOOP, NULL, @1, @1);
+ $$->u.loop = $1;
+ }
+ | switch_stmt
+ {
+ $$ = ast_mkStmt(L_STMT_SWITCH, NULL, @1, @1);
+ $$->u.swich = $1;
+ }
+ | foreach_stmt
+ {
+ $$ = ast_mkStmt(L_STMT_FOREACH, NULL, @1, @1);
+ $$->u.foreach = $1;
+ }
+ | expr ";"
+ {
+ $$ = ast_mkStmt(L_STMT_EXPR, NULL, @1, @1);
+ $$->u.expr = $1;
+ }
+ | T_BREAK ";"
+ {
+ $$ = ast_mkStmt(L_STMT_BREAK, NULL, @1, @1);
+ }
+ | T_CONTINUE ";"
+ {
+ $$ = ast_mkStmt(L_STMT_CONTINUE, NULL, @1, @1);
+ }
+ | T_RETURN ";"
+ {
+ $$ = ast_mkStmt(L_STMT_RETURN, NULL, @1, @1);
+ }
+ | T_RETURN expr ";"
+ {
+ $$ = ast_mkStmt(L_STMT_RETURN, NULL, @1, @2);
+ $$->u.expr = $2;
+ }
+ | T_GOTO T_ID ";"
+ {
+ $$ = ast_mkStmt(L_STMT_GOTO, NULL, @1, @3);
+ $$->u.label = $2;
+ }
+ | "try" compound_stmt T_ID "(" expr ")" compound_stmt
+ {
+ /*
+ * We don't want to make "catch" a keyword since it's a Tcl
+ * function name, so allow any ID here but check it.
+ */
+ unless (!strcmp($3, "catch")) {
+ L_synerr2("syntax error -- expected 'catch'", @3.beg);
+ }
+ $$ = ast_mkStmt(L_STMT_TRY, NULL, @1, @7);
+ $$->u.try = ast_mkTry($2, $5, $7);
+ }
+ | "try" compound_stmt T_ID compound_stmt
+ {
+ $$ = ast_mkStmt(L_STMT_TRY, NULL, @1, @4);
+ $$->u.try = ast_mkTry($2, NULL, $4);
+ }
+ | ";" { $$ = NULL; }
+ ;
+
+selection_stmt:
+ T_IF "(" expr ")" compound_stmt optional_else
+ {
+ $$ = ast_mkIfUnless($3, $5, $6, @1, @6);
+ }
+ /* If you have no curly braces, you get no else. */
+ | T_IF "(" expr ")" single_stmt
+ {
+ $$ = ast_mkIfUnless($3, $5, NULL, @1, @5);
+ }
+ | T_UNLESS "(" expr ")" compound_stmt optional_else
+ {
+ $$ = ast_mkIfUnless($3, $6, $5, @1, @6);
+ }
+ | T_UNLESS "(" expr ")" single_stmt
+ {
+ $$ = ast_mkIfUnless($3, NULL, $5, @1, @5);
+ }
+ ;
+
+switch_stmt:
+ T_SWITCH "(" expr ")" "{" switch_cases "}"
+ {
+ Case *c, *def;
+
+ for (c = $6, def = NULL; c; c = c->next) {
+ if (c->expr) continue;
+ if (def) {
+ L_errf(c,
+ "multiple default cases in switch statement");
+ }
+ def = c;
+ }
+ $$ = ast_mkSwitch($3, $6, @1, @7);
+ }
+ ;
+
+switch_cases:
+ switch_cases switch_case
+ {
+ if ($1) {
+ APPEND(Case, next, $1, $2);
+ $$ = $1;
+ } else {
+ $$ = $2;
+ }
+ }
+ | /* epsilon */ { $$ = NULL; }
+ ;
+
+switch_case:
+ "case" re_start_case case_expr ":" opt_stmt_list
+ {
+ REVERSE(Stmt, next, $5);
+ $$ = ast_mkCase($3, $5, @1, @5);
+ }
+ | "default" ":" opt_stmt_list
+ {
+ /* The default case is distinguished by a NULL expr. */
+ REVERSE(Stmt, next, $3);
+ $$ = ast_mkCase(NULL, $3, @1, @2);
+ }
+ ;
+
+case_expr:
+ regexp_literal_mod
+ {
+ if ($1->flags & L_EXPR_RE_G) {
+ L_errf($1, "illegal regular expression modifier");
+ }
+ }
+ | expr
+ ;
+
+optional_else:
+ /* Else clause must either have curly braces or be another if/unless. */
+ T_ELSE compound_stmt
+ {
+ $$ = $2;
+ $$->node.loc = @1;
+ }
+ | T_ELSE selection_stmt
+ {
+ $$ = ast_mkStmt(L_STMT_COND, NULL, @1, @2);
+ $$->u.cond = $2;
+ }
+ | /* epsilon */ { $$ = NULL; }
+ ;
+
+iteration_stmt:
+ T_WHILE "(" expr ")" stmt
+ {
+ $$ = ast_mkLoop(L_LOOP_WHILE, NULL, $3, NULL, $5, @1, @5);
+ }
+ | T_DO stmt T_WHILE "(" expr ")" ";"
+ {
+ $$ = ast_mkLoop(L_LOOP_DO, NULL, $5, NULL, $2, @1, @6);
+ }
+ | T_FOR "(" expression_stmt expression_stmt ")" stmt
+ {
+ $$ = ast_mkLoop(L_LOOP_FOR, $3, $4, NULL, $6, @1, @6);
+ }
+ | T_FOR "(" expression_stmt expression_stmt expr ")" stmt
+ {
+ $$ = ast_mkLoop(L_LOOP_FOR, $3, $4, $5, $7, @1, @7);
+ }
+ ;
+
+foreach_stmt:
+ T_FOREACH "(" id "=>" id id expr ")" stmt
+ {
+ $$ = ast_mkForeach($7, $3, $5, $9, @1, @9);
+ unless (isid($6, "in")) {
+ L_synerr2("syntax error -- expected 'in' in foreach",
+ @6.beg);
+ }
+ }
+ | T_FOREACH "(" id_list id expr ")" stmt
+ {
+ $$ = ast_mkForeach($5, $3, NULL, $7, @1, @7);
+ unless (isid($4, "in")) {
+ L_synerr2("syntax error -- expected 'in' in foreach",
+ @4.beg);
+ }
+ }
+ ;
+
+expression_stmt:
+ ";" { $$ = NULL; }
+ | expr ";"
+ ;
+
+opt_stmt_list:
+ stmt_list
+ | { $$ = NULL; }
+ ;
+
+stmt_list:
+ stmt
+ {
+ REVERSE(Stmt, next, $1);
+ $$ = $1;
+ }
+ | stmt_list stmt
+ {
+ if ($2) {
+ REVERSE(Stmt, next, $2);
+ APPEND(Stmt, next, $2, $1);
+ $$ = $2;
+ } else {
+ // Empty stmt.
+ $$ = $1;
+ }
+ }
+ ;
+
+parameter_list:
+ parameter_decl_list
+ {
+ VarDecl *v;
+ REVERSE(VarDecl, next, $1);
+ for (v = $1; v; v = v->next) {
+ v->flags |= SCOPE_LOCAL | DECL_LOCAL_VAR;
+ }
+ $$ = $1;
+ /*
+ * Special case a parameter list of "void" -- a single
+ * formal of type void with no arg name. This really
+ * means there are no args.
+ */
+ if ($1 && !$1->next && !$1->id && ($1->type == L_void)) {
+ $$ = NULL;
+ }
+ }
+ | /* epsilon */ { $$ = NULL; }
+ ;
+
+parameter_decl_list:
+ parameter_decl
+ | parameter_decl_list "," parameter_decl
+ {
+ $3->next = $1;
+ $$ = $3;
+ $$->node.loc = @1;
+ }
+ ;
+
+parameter_decl:
+ parameter_attrs type_specifier opt_declarator
+ {
+ if ($3) {
+ L_set_declBaseType($3, $2);
+ $$ = $3;
+ } else {
+ $$ = ast_mkVarDecl($2, NULL, @2, @2);
+ if (isnameoftype($2)) $$->flags |= DECL_REF;
+ }
+ $$->flags |= $1;
+ $$->node.loc = @1;
+ }
+ | parameter_attrs T_ELLIPSIS id
+ {
+ Type *t = type_mkArray(NULL, L_poly);
+ $$ = ast_mkVarDecl(t, $3, @1, @3);
+ $$->flags |= $1 | DECL_REST_ARG;
+ }
+ ;
+
+parameter_attrs:
+ parameter_attrs T_ARGUSED { $$ = $1 | DECL_ARGUSED; }
+ | parameter_attrs T_OPTIONAL { $$ = $1 | DECL_OPTIONAL; }
+ | parameter_attrs T_MUSTBETYPE { $$ = $1 | DECL_NAME_EQUIV; }
+ | /* epsilon */ { $$ = 0; }
+ ;
+
+argument_expr_list:
+ expr %prec T_COMMA
+ | option_arg
+ | option_arg expr %prec T_COMMA
+ {
+ $2->next = $1;
+ $$ = $2;
+ $$->node.loc = @1;
+ }
+ | argument_expr_list "," expr
+ {
+ $3->next = $1;
+ $$ = $3;
+ $$->node.loc.end = @3.end;
+ }
+ | argument_expr_list "," option_arg
+ {
+ $3->next = $1;
+ $$ = $3;
+ $$->node.loc.end = @3.end;
+ }
+ | argument_expr_list "," option_arg expr %prec T_COMMA
+ {
+ $4->next = $3;
+ $3->next = $1;
+ $$ = $4;
+ $$->node.loc.end = @4.end;
+ }
+ ;
+
+/*
+ * option_arg is an actual parameter "arg:" that becomes "-arg".
+ * Allow both "T_ID:" and "default:" to overcome a nasty grammar
+ * conflict with statement labels that otherwise results. The scanner
+ * returns T_DEFAULT T_COLON when it sees "default:" but returns T_ID
+ * T_COLON for the other cases even if they include a reserved word.
+ */
+option_arg:
+ T_ID ":"
+ {
+ char *s = cksprintf("-%s", $1);
+ $$ = ast_mkConst(L_string, s, @1, @2);
+ ckfree($1);
+ }
+ | "default" ":"
+ {
+ char *s = cksprintf("-default");
+ $$ = ast_mkConst(L_string, s, @1, @2);
+ }
+ ;
+
+expr:
+ "(" expr ")"
+ {
+ $$ = $2;
+ $$->node.loc = @1;
+ $$->node.loc.end = @3.end;
+ }
+ | "(" type_specifier ")" expr %prec PREFIX_INCDEC
+ {
+ // This is a binop where an arg is a Type*.
+ $$ = ast_mkBinOp(L_OP_CAST, (Expr *)$2, $4, @1, @4);
+ }
+ | "(" T_EXPAND ")" expr %prec PREFIX_INCDEC
+ {
+ $$ = ast_mkUnOp(L_OP_EXPAND, $4, @1, @4);
+ }
+ | T_BANG expr
+ {
+ $$ = ast_mkUnOp(L_OP_BANG, $2, @1, @2);
+ }
+ | T_BITNOT expr
+ {
+ $$ = ast_mkUnOp(L_OP_BITNOT, $2, @1, @2);
+ }
+ | T_BITAND expr %prec ADDRESS
+ {
+ $$ = ast_mkUnOp(L_OP_ADDROF, $2, @1, @2);
+ }
+ | T_MINUS expr %prec UMINUS
+ {
+ $$ = ast_mkUnOp(L_OP_UMINUS, $2, @1, @2);
+ }
+ | T_PLUS expr %prec UPLUS
+ {
+ $$ = ast_mkUnOp(L_OP_UPLUS, $2, @1, @2);
+ }
+ | T_PLUSPLUS expr %prec PREFIX_INCDEC
+ {
+ $$ = ast_mkUnOp(L_OP_PLUSPLUS_PRE, $2, @1, @2);
+ }
+ | T_MINUSMINUS expr %prec PREFIX_INCDEC
+ {
+ $$ = ast_mkUnOp(L_OP_MINUSMINUS_PRE, $2, @1, @2);
+ }
+ | expr T_PLUSPLUS
+ {
+ $$ = ast_mkUnOp(L_OP_PLUSPLUS_POST, $1, @1, @2);
+ }
+ | expr T_MINUSMINUS
+ {
+ $$ = ast_mkUnOp(L_OP_MINUSMINUS_POST, $1, @1, @2);
+ }
+ | expr T_EQTWID regexp_literal_mod
+ {
+ $$ = ast_mkBinOp(L_OP_EQTWID, $1, $3, @1, @3);
+ }
+ | expr T_BANGTWID regexp_literal_mod
+ {
+ $$ = ast_mkBinOp(L_OP_BANGTWID, $1, $3, @1, @3);
+ }
+ | expr T_EQTWID regexp_literal subst_literal T_RE_MODIFIER
+ {
+ if (strchr($5, 'i')) $3->flags |= L_EXPR_RE_I;
+ if (strchr($5, 'g')) $3->flags |= L_EXPR_RE_G;
+ $$ = ast_mkTrinOp(L_OP_EQTWID, $1, $3, $4, @1, @5);
+ ckfree($5);
+ }
+ | expr T_STAR expr
+ {
+ $$ = ast_mkBinOp(L_OP_STAR, $1, $3, @1, @3);
+ }
+ | expr T_SLASH expr
+ {
+ $$ = ast_mkBinOp(L_OP_SLASH, $1, $3, @1, @3);
+ }
+ | expr T_PERC expr
+ {
+ $$ = ast_mkBinOp(L_OP_PERC, $1, $3, @1, @3);
+ }
+ | expr T_PLUS expr
+ {
+ $$ = ast_mkBinOp(L_OP_PLUS, $1, $3, @1, @3);
+ }
+ | expr T_MINUS expr
+ {
+ $$ = ast_mkBinOp(L_OP_MINUS, $1, $3, @1, @3);
+ }
+ | expr T_EQ expr
+ {
+ $$ = ast_mkBinOp(L_OP_STR_EQ, $1, $3, @1, @3);
+ }
+ | expr T_NE expr
+ {
+ $$ = ast_mkBinOp(L_OP_STR_NE, $1, $3, @1, @3);
+ }
+ | expr T_LT expr
+ {
+ $$ = ast_mkBinOp(L_OP_STR_LT, $1, $3, @1, @3);
+ }
+ | expr T_LE expr
+ {
+ $$ = ast_mkBinOp(L_OP_STR_LE, $1, $3, @1, @3);
+ }
+ | expr T_GT expr
+ {
+ $$ = ast_mkBinOp(L_OP_STR_GT, $1, $3, @1, @3);
+ }
+ | expr T_GE expr
+ {
+ $$ = ast_mkBinOp(L_OP_STR_GE, $1, $3, @1, @3);
+ }
+ | expr T_EQUALEQUAL expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQUALEQUAL, $1, $3, @1, @3);
+ }
+ | T_EQ "(" expr "," expr ")"
+ {
+ $$ = ast_mkBinOp(L_OP_EQUALEQUAL, $3, $5, @1, @6);
+ }
+ | expr T_NOTEQUAL expr
+ {
+ $$ = ast_mkBinOp(L_OP_NOTEQUAL, $1, $3, @1, @3);
+ }
+ | expr T_GREATER expr
+ {
+ $$ = ast_mkBinOp(L_OP_GREATER, $1, $3, @1, @3);
+ }
+ | expr T_GREATEREQ expr
+ {
+ $$ = ast_mkBinOp(L_OP_GREATEREQ, $1, $3, @1, @3);
+ }
+ | expr T_LESSTHAN expr
+ {
+ $$ = ast_mkBinOp(L_OP_LESSTHAN, $1, $3, @1, @3);
+ }
+ | expr T_LESSTHANEQ expr
+ {
+ $$ = ast_mkBinOp(L_OP_LESSTHANEQ, $1, $3, @1, @3);
+ }
+ | expr T_ANDAND expr
+ {
+ $$ = ast_mkBinOp(L_OP_ANDAND, $1, $3, @1, @3);
+ }
+ | expr T_OROR expr
+ {
+ $$ = ast_mkBinOp(L_OP_OROR, $1, $3, @1, @3);
+ }
+ | expr T_LSHIFT expr
+ {
+ $$ = ast_mkBinOp(L_OP_LSHIFT, $1, $3, @1, @3);
+ }
+ | expr T_RSHIFT expr
+ {
+ $$ = ast_mkBinOp(L_OP_RSHIFT, $1, $3, @1, @3);
+ }
+ | expr T_BITOR expr
+ {
+ $$ = ast_mkBinOp(L_OP_BITOR, $1, $3, @1, @3);
+ }
+ | expr T_BITAND expr
+ {
+ $$ = ast_mkBinOp(L_OP_BITAND, $1, $3, @1, @3);
+ }
+ | expr T_BITXOR expr
+ {
+ $$ = ast_mkBinOp(L_OP_BITXOR, $1, $3, @1, @3);
+ }
+ | id
+ | string_literal
+ | cmdsubst_literal
+ | T_INT_LITERAL
+ {
+ $$ = ast_mkConst(L_int, $1, @1, @1);
+ }
+ | T_FLOAT_LITERAL
+ {
+ $$ = ast_mkConst(L_float, $1, @1, @1);
+ }
+ | id "(" argument_expr_list ")"
+ {
+ REVERSE(Expr, next, $3);
+ $$ = ast_mkFnCall($1, $3, @1, @4);
+ }
+ | id "(" ")"
+ {
+ $$ = ast_mkFnCall($1, NULL, @1, @3);
+ }
+ | T_STRING "(" argument_expr_list ")"
+ {
+ Expr *id = ast_mkId("string", @1, @1);
+ REVERSE(Expr, next, $3);
+ $$ = ast_mkFnCall(id, $3, @1, @4);
+ }
+ | T_SPLIT "(" re_start_split regexp_literal_mod "," argument_expr_list ")"
+ {
+ Expr *id = ast_mkId("split", @1, @1);
+ REVERSE(Expr, next, $6);
+ $4->next = $6;
+ $$ = ast_mkFnCall(id, $4, @1, @7);
+ }
+ /*
+ * Even though there is no regexp arg in this form, the
+ * re_start_split is necessary to be able to scan either a
+ * regexp or a non-regexp first argument. The scanner makes
+ * that decision based on the first one or two characters and
+ * then returns appropriate tokens.
+ */
+ | T_SPLIT "(" re_start_split argument_expr_list ")"
+ {
+ Expr *id = ast_mkId("split", @1, @1);
+ REVERSE(Expr, next, $4);
+ $$ = ast_mkFnCall(id, $4, @1, @5);
+ }
+ /* this is to allow calling Tk widget functions */
+ | dotted_id "(" argument_expr_list ")"
+ {
+ REVERSE(Expr, next, $3);
+ $$ = ast_mkFnCall($1, $3, @1, @4);
+ }
+ | dotted_id "(" ")"
+ {
+ $$ = ast_mkFnCall($1, NULL, @1, @3);
+ }
+ | expr T_EQUALS expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQUALS, $1, $3, @1, @3);
+ }
+ | expr T_EQPLUS expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQPLUS, $1, $3, @1, @3);
+ }
+ | expr T_EQMINUS expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQMINUS, $1, $3, @1, @3);
+ }
+ | expr T_EQSTAR expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQSTAR, $1, $3, @1, @3);
+ }
+ | expr T_EQSLASH expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQSLASH, $1, $3, @1, @3);
+ }
+ | expr T_EQPERC expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQPERC, $1, $3, @1, @3);
+ }
+ | expr T_EQBITAND expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQBITAND, $1, $3, @1, @3);
+ }
+ | expr T_EQBITOR expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQBITOR, $1, $3, @1, @3);
+ }
+ | expr T_EQBITXOR expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQBITXOR, $1, $3, @1, @3);
+ }
+ | expr T_EQLSHIFT expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQLSHIFT, $1, $3, @1, @3);
+ }
+ | expr T_EQRSHIFT expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQRSHIFT, $1, $3, @1, @3);
+ }
+ | expr T_EQDOT expr
+ {
+ $$ = ast_mkBinOp(L_OP_EQDOT, $1, $3, @1, @3);
+ }
+ | T_DEFINED "(" expr ")"
+ {
+ $$ = ast_mkUnOp(L_OP_DEFINED, $3, @1, @4);
+ }
+ | expr "[" expr "]"
+ {
+ $$ = ast_mkBinOp(L_OP_ARRAY_INDEX, $1, $3, @1, @4);
+ }
+ | expr "{" expr "}"
+ {
+ $$ = ast_mkBinOp(L_OP_HASH_INDEX, $1, $3, @1, @4);
+ }
+ | expr T_STRCAT expr
+ {
+ $$ = ast_mkBinOp(L_OP_CONCAT, $1, $3, @1, @3);
+ }
+ | expr "." T_ID
+ {
+ $$ = ast_mkBinOp(L_OP_DOT, $1, NULL, @1, @3);
+ $$->str = $3;
+ }
+ | expr "->" T_ID
+ {
+ $$ = ast_mkBinOp(L_OP_POINTS, $1, NULL, @1, @3);
+ $$->str = $3;
+ }
+ | T_TYPE "." T_ID
+ {
+ // This is a binop where an arg is a Type*.
+ $$ = ast_mkBinOp(L_OP_CLASS_INDEX, (Expr *)$1.t, NULL, @1, @3);
+ $$->str = $3;
+ }
+ | T_TYPE "->" T_ID
+ {
+ // This is a binop where an arg is a Type*.
+ $$ = ast_mkBinOp(L_OP_CLASS_INDEX, (Expr *)$1.t, NULL, @1, @3);
+ $$->str = $3;
+ }
+ | expr "," expr
+ {
+ $$ = ast_mkBinOp(L_OP_COMMA, $1, $3, @1, @3);
+ }
+ | expr "[" expr T_DOTDOT expr "]"
+ {
+ $$ = ast_mkTrinOp(L_OP_ARRAY_SLICE, $1, $3, $5, @1, @3);
+ }
+ /*
+ * We don't really need to open a scope here, but it doesn't hurt, and
+ * it avoids a shift/reduce conflict with a compound_stmt production.
+ */
+ | "{" enter_scope list "}"
+ {
+ $$ = $3;
+ $$->node.loc = @1;
+ $$->node.loc.end = @4.end;
+ L_scope_leave();
+ }
+ | "{" "}"
+ {
+ $$ = ast_mkBinOp(L_OP_LIST, NULL, NULL, @1, @2);
+ }
+ | expr "?" expr ":" expr %prec T_QUESTION
+ {
+ $$ = ast_mkTrinOp(L_OP_TERNARY_COND, $1, $3, $5, @1, @5);
+ }
+ | "<" expr ">"
+ {
+ $$ = ast_mkUnOp(L_OP_FILE, $2, @1, @3);
+ }
+ | "<" ">"
+ {
+ $$ = ast_mkUnOp(L_OP_FILE, NULL, @1, @2);
+ }
+ ;
+
+re_start_split:
+ { L_lex_begReArg(0); }
+ ;
+
+re_start_case:
+ { L_lex_begReArg(1); }
+ ;
+
+id:
+ T_ID
+ {
+ $$ = ast_mkId($1, @1, @1);
+ ckfree($1);
+ }
+ ;
+
+id_list:
+ id
+ | id "," id_list
+ {
+ $$ = $1;
+ $$->next = $3;
+ $$->node.loc.end = @3.end;
+ }
+ ;
+
+compound_stmt:
+ "{" enter_scope "}"
+ {
+ $$ = ast_mkStmt(L_STMT_BLOCK, NULL, @1, @3);
+ $$->u.block = ast_mkBlock(NULL, NULL, @1, @3);
+ L_scope_leave();
+ }
+ | "{" enter_scope stmt_list "}"
+ {
+ REVERSE(Stmt, next, $3);
+ $$ = ast_mkStmt(L_STMT_BLOCK, NULL, @1, @4);
+ $$->u.block = ast_mkBlock(NULL, $3, @1, @4);
+ L_scope_leave();
+ }
+ | "{" enter_scope declaration_list "}"
+ {
+ VarDecl *v;
+ REVERSE(VarDecl, next, $3);
+ for (v = $3; v; v = v->next) {
+ v->flags |= SCOPE_LOCAL | DECL_LOCAL_VAR;
+ }
+ $$ = ast_mkStmt(L_STMT_BLOCK, NULL, @1, @4);
+ $$->u.block = ast_mkBlock($3, NULL, @1, @4);
+ L_scope_leave();
+ }
+ | "{" enter_scope declaration_list stmt_list "}"
+ {
+ VarDecl *v;
+ REVERSE(VarDecl, next, $3);
+ for (v = $3; v; v = v->next) {
+ v->flags |= SCOPE_LOCAL | DECL_LOCAL_VAR;
+ }
+ REVERSE(Stmt, next, $4);
+ $$ = ast_mkStmt(L_STMT_BLOCK, NULL, @1, @5);
+ $$->u.block = ast_mkBlock($3, $4, @1, @5);
+ L_scope_leave();
+ }
+ ;
+
+enter_scope:
+ /* epsilon */ %prec HIGHEST { L_scope_enter(); }
+ ;
+
+declaration_list:
+ declaration
+ | declaration_list declaration
+ {
+ /*
+ * Each declaration is a list of declarators. Here we
+ * append the lists.
+ */
+ APPEND(VarDecl, next, $2, $1);
+ $$ = $2;
+ }
+ ;
+
+declaration:
+ declaration2 ";"
+ | decl_qualifier declaration2 ";"
+ {
+ VarDecl *v;
+ for (v = $2; v; v = v->next) {
+ v->flags |= $1;
+ }
+ $$ = $2;
+ $$->node.loc = @1;
+ }
+ ;
+
+decl_qualifier:
+ T_PRIVATE { $$ = DECL_PRIVATE; }
+ | T_PUBLIC { $$ = DECL_PUBLIC; }
+ | T_EXTERN { $$ = DECL_EXTERN; }
+ ;
+
+declaration2:
+ type_specifier init_declarator_list
+ {
+ /* Don't REVERSE $2; it's done as part of declaration_list. */
+ VarDecl *v;
+ for (v = $2; v; v = v->next) {
+ L_set_declBaseType(v, $1);
+ }
+ $$ = $2;
+ }
+ ;
+
+init_declarator_list:
+ init_declarator
+ | init_declarator_list "," init_declarator
+ {
+ $3->next = $1;
+ $$ = $3;
+ }
+ ;
+
+declarator_list:
+ declarator
+ | declarator_list "," declarator
+ {
+ $3->next = $1;
+ $$ = $3;
+ }
+ ;
+
+init_declarator:
+ declarator
+ | declarator T_EQUALS expr
+ {
+ $1->initializer = ast_mkBinOp(L_OP_EQUALS, $1->id, $3, @3, @3);
+ $$ = $1;
+ $$->node.loc.end = @3.end;
+ }
+ ;
+
+opt_declarator:
+ declarator
+ | { $$ = NULL; }
+ ;
+
+declarator:
+ id array_or_hash_type
+ {
+ $$ = ast_mkVarDecl($2, $1, @1, @2);
+ }
+ | T_TYPE array_or_hash_type
+ {
+ Expr *id = ast_mkId($1.s, @1, @1);
+ $$ = ast_mkVarDecl($2, id, @1, @2);
+ if (isnameoftype($1.t)) $$->flags |= DECL_REF;
+ ckfree($1.s);
+ }
+ | T_BITAND id array_or_hash_type
+ {
+ Type *t = type_mkNameOf($3);
+ $$ = ast_mkVarDecl(t, $2, @1, @3);
+ $$->flags |= DECL_REF;
+ }
+ | T_BITAND id "(" parameter_list ")"
+ {
+ Type *tf = type_mkFunc(NULL, $4);
+ Type *tn = type_mkNameOf(tf);
+ $$ = ast_mkVarDecl(tn, $2, @1, @5);
+ $$->flags |= DECL_REF;
+ }
+ ;
+
+/* Right recursion OK here since depth is typically low. */
+array_or_hash_type:
+ /* epsilon */
+ {
+ $$ = NULL;
+ }
+ | "[" expr "]" array_or_hash_type
+ {
+ $$ = type_mkArray($2, $4);
+ }
+ | "[" "]" array_or_hash_type
+ {
+ $$ = type_mkArray(NULL, $3);
+ }
+ | "{" scalar_type_specifier "}" array_or_hash_type
+ {
+ $$ = type_mkHash($2, $4);
+ }
+ ;
+
+type_specifier:
+ scalar_type_specifier array_or_hash_type
+ {
+ if ($2) {
+ L_set_baseType($2, $1);
+ $$ = $2;
+ } else {
+ $$ = $1;
+ }
+ }
+ | struct_specifier array_or_hash_type
+ {
+ if ($2) {
+ L_set_baseType($2, $1);
+ $$ = $2;
+ } else {
+ $$ = $1;
+ }
+ }
+ ;
+
+scalar_type_specifier:
+ T_STRING { $$ = L_string; }
+ | T_INT { $$ = L_int; }
+ | T_FLOAT { $$ = L_float; }
+ | T_POLY { $$ = L_poly; }
+ | T_WIDGET { $$ = L_widget; }
+ | T_VOID { $$ = L_void; }
+ | T_TYPE { $$ = $1.t; ckfree($1.s); }
+ ;
+
+struct_specifier:
+ T_STRUCT T_ID "{" struct_decl_list "}"
+ {
+ REVERSE(VarDecl, next, $4);
+ $$ = L_struct_store($2, $4);
+ ckfree($2);
+ }
+ | T_STRUCT "{" struct_decl_list "}"
+ {
+ REVERSE(VarDecl, next, $3);
+ (void)L_struct_store(NULL, $3); // to sanity check member types
+ $$ = type_mkStruct(NULL, $3);
+ }
+ | T_STRUCT T_ID
+ {
+ $$ = L_struct_lookup($2, FALSE);
+ ckfree($2);
+ }
+ ;
+
+struct_decl_list:
+ struct_decl
+ | struct_decl_list struct_decl
+ {
+ APPEND(VarDecl, next, $2, $1);
+ $$ = $2;
+ $$->node.loc = @1;
+ }
+ ;
+
+struct_decl:
+ struct_declarator_list ";" { $$->node.loc.end = @2.end; }
+ ;
+
+struct_declarator_list:
+ type_specifier declarator_list
+ {
+ VarDecl *v;
+ for (v = $2; v; v = v->next) {
+ L_set_declBaseType(v, $1);
+ }
+ $$ = $2;
+ $$->node.loc = @1;
+ }
+ ;
+
+list:
+ list_element
+ | list "," list_element
+ {
+ APPEND(Expr, b, $1, $3);
+ $$ = $1;
+ }
+ | list ","
+ ;
+
+list_element:
+ expr %prec HIGHEST
+ {
+ $$ = ast_mkBinOp(L_OP_LIST, $1, NULL, @1, @1);
+ }
+ | expr "=>" expr %prec HIGHEST
+ {
+ Expr *kv = ast_mkBinOp(L_OP_KV, $1, $3, @1, @3);
+ $$ = ast_mkBinOp(L_OP_LIST, kv, NULL, @1, @3);
+ }
+ ;
+
+string_literal:
+ T_STR_LITERAL
+ {
+ $$ = ast_mkConst(L_string, $1, @1, @1);
+ }
+ | interpolated_expr T_STR_LITERAL
+ {
+ Expr *right = ast_mkConst(L_string, $2, @2, @2);
+ $$ = ast_mkBinOp(L_OP_INTERP_STRING, $1, right, @1, @2);
+ }
+ | here_doc_backtick T_STR_LITERAL
+ {
+ Expr *right = ast_mkConst(L_string, $2, @2, @2);
+ $$ = ast_mkBinOp(L_OP_INTERP_STRING, $1, right, @1, @2);
+ }
+ ;
+
+here_doc_backtick:
+ T_START_BACKTICK T_STR_BACKTICK
+ {
+ Expr *left = ast_mkConst(L_string, $1, @1, @1);
+ Expr *right = ast_mkUnOp(L_OP_CMDSUBST, NULL, @2, @2);
+ right->str = $2;
+ $$ = ast_mkBinOp(L_OP_INTERP_STRING, left, right, @1, @2);
+ }
+ | here_doc_backtick T_START_BACKTICK T_STR_BACKTICK
+ {
+ Expr *middle = ast_mkConst(L_string, $2, @2, @2);
+ Expr *right = ast_mkUnOp(L_OP_CMDSUBST, NULL, @3, @3);
+ right->str = $3;
+ $$ = ast_mkTrinOp(L_OP_INTERP_STRING, $1, middle, right,
+ @1, @3);
+ }
+ ;
+
+cmdsubst_literal:
+ T_STR_BACKTICK
+ {
+ $$ = ast_mkUnOp(L_OP_CMDSUBST, NULL, @1, @1);
+ $$->str = $1;
+ }
+ | interpolated_expr T_STR_BACKTICK
+ {
+ $$ = ast_mkUnOp(L_OP_CMDSUBST, $1, @1, @2);
+ $$->str = $2;
+ }
+ ;
+
+regexp_literal:
+ T_RE
+ {
+ $$ = ast_mkRegexp($1, @1, @1);
+ }
+ | interpolated_expr_re T_RE
+ {
+ Expr *right = ast_mkConst(L_string, $2, @2, @2);
+ $$ = ast_mkBinOp(L_OP_INTERP_RE, $1, right, @1, @2);
+ }
+ ;
+
+regexp_literal_mod:
+ regexp_literal T_RE_MODIFIER
+ {
+ /* Note: the scanner catches illegal modifiers. */
+ if (strchr($2, 'i')) $1->flags |= L_EXPR_RE_I;
+ if (strchr($2, 'g')) $1->flags |= L_EXPR_RE_G;
+ if (strchr($2, 'l')) $1->flags |= L_EXPR_RE_L;
+ if (strchr($2, 't')) $1->flags |= L_EXPR_RE_T;
+ ckfree($2);
+ $$ = $1;
+ }
+ ;
+
+subst_literal:
+ T_SUBST
+ {
+ $$ = ast_mkConst(L_string, $1, @1, @1);
+ }
+ | interpolated_expr_re T_SUBST
+ {
+ Expr *right = ast_mkConst(L_string, $2, @2, @2);
+ $$ = ast_mkBinOp(L_OP_INTERP_RE, $1, right, @1, @2);
+ }
+ ;
+
+interpolated_expr:
+ T_LEFT_INTERPOL expr T_RIGHT_INTERPOL
+ {
+ Expr *left = ast_mkConst(L_string, $1, @1, @1);
+ $$ = ast_mkBinOp(L_OP_INTERP_STRING, left, $2, @1, @3);
+ }
+ | interpolated_expr T_LEFT_INTERPOL expr T_RIGHT_INTERPOL
+ {
+ Expr *middle = ast_mkConst(L_string, $2, @2, @2);
+ $$ = ast_mkTrinOp(L_OP_INTERP_STRING, $1, middle, $3, @1, @4);
+ }
+ ;
+
+interpolated_expr_re:
+ T_LEFT_INTERPOL_RE expr T_RIGHT_INTERPOL_RE
+ {
+ Expr *left = ast_mkConst(L_string, $1, @1, @1);
+ $$ = ast_mkBinOp(L_OP_INTERP_STRING, left, $2, @1, @3);
+ }
+ | interpolated_expr_re T_LEFT_INTERPOL_RE expr T_RIGHT_INTERPOL_RE
+ {
+ Expr *middle = ast_mkConst(L_string, $2, @2, @2);
+ $$ = ast_mkTrinOp(L_OP_INTERP_STRING, $1, middle, $3, @1, @4);
+ }
+ ;
+
+dotted_id:
+ "."
+ {
+ $$ = ast_mkId(".", @1, @1);
+ }
+ | dotted_id_1
+ {
+ $$ = ast_mkId(Tcl_GetString($1), @1, @1);
+ Tcl_DecrRefCount($1);
+ }
+ ;
+
+dotted_id_1:
+ "." T_ID
+ {
+ $$ = Tcl_NewObj();
+ Tcl_IncrRefCount($$);
+ Tcl_AppendToObj($$, ".", 1);
+ Tcl_AppendToObj($$, $2, -1);
+ ckfree($2);
+ }
+ | dotted_id_1 "." T_ID
+ {
+ Tcl_AppendToObj($1, ".", 1);
+ Tcl_AppendToObj($1, $3, -1);
+ $$ = $1;
+ ckfree($3);
+ }
+ ;
+%%
diff --git a/generic/Lscanner-pregen.c b/generic/Lscanner-pregen.c
new file mode 100644
index 0000000..2af2ada
--- /dev/null
+++ b/generic/Lscanner-pregen.c
@@ -0,0 +1,4739 @@
+
+#line 3 "<stdout>"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define yy_create_buffer L__create_buffer
+#define yy_delete_buffer L__delete_buffer
+#define yy_flex_debug L__flex_debug
+#define yy_init_buffer L__init_buffer
+#define yy_flush_buffer L__flush_buffer
+#define yy_load_buffer_state L__load_buffer_state
+#define yy_switch_to_buffer L__switch_to_buffer
+#define yyin L_in
+#define yyleng L_leng
+#define yylex L_lex
+#define yylineno L_lineno
+#define yyout L_out
+#define yyrestart L_restart
+#define yytext L_text
+#define yywrap L_wrap
+#define yyalloc L_alloc
+#define yyrealloc L_realloc
+#define yyfree L_free
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 39
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! C99 */
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE L_restart(L_in )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k.
+ * Moreover, YY_BUF_SIZE is 2*YY_READ_BUF_SIZE in the general case.
+ * Ditto for the __ia64__ case accordingly.
+ */
+#define YY_BUF_SIZE 32768
+#else
+#define YY_BUF_SIZE 16384
+#endif /* __ia64__ */
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+extern yy_size_t L_leng;
+
+extern FILE *L_in, *L_out;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+ #define YY_LINENO_REWIND_TO(ptr)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up L_text. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up L_text again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ yy_size_t yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via L_restart()), so that the user can continue scanning by
+ * just pointing L_in at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when L_text is formed. */
+static char yy_hold_char;
+static yy_size_t yy_n_chars; /* number of characters read into yy_ch_buf */
+yy_size_t L_leng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow L_wrap()'s to do buffer switches
+ * instead of setting up a fresh L_in. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void L_restart (FILE *input_file );
+void L__switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE L__create_buffer (FILE *file,int size );
+void L__delete_buffer (YY_BUFFER_STATE b );
+void L__flush_buffer (YY_BUFFER_STATE b );
+void L_push_buffer_state (YY_BUFFER_STATE new_buffer );
+void L_pop_buffer_state (void );
+
+static void L_ensure_buffer_stack (void );
+static void L__load_buffer_state (void );
+static void L__init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER L__flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE L__scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE L__scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE L__scan_bytes (yyconst char *bytes,yy_size_t len );
+
+void *L_alloc (yy_size_t );
+void *L_realloc (void *,yy_size_t );
+void L_free (void * );
+
+#define yy_new_buffer L__create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ L_ensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ L__create_buffer(L_in,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ L_ensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ L__create_buffer(L_in,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define L_wrap() 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *L_in = (FILE *) 0, *L_out = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int L_lineno;
+
+int L_lineno = 1;
+
+extern char *L_text;
+#define yytext_ptr L_text
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up L_text.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ L_leng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 206
+#define YY_END_OF_BUFFER 207
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_acclist[819] =
+ { 0,
+ 138, 138, 142, 142, 207, 205, 206, 117, 205, 206,
+ 118, 206, 118, 205, 206, 118, 205, 206, 7, 205,
+ 206, 119, 205, 206, 205, 206, 12, 205, 206, 28,
+ 205, 206, 120, 205, 206, 1, 205, 206, 2, 205,
+ 206, 10, 205, 206, 8, 205, 206, 6, 205, 206,
+ 9, 205, 206, 36, 205, 206, 11, 205, 206, 103,
+ 205, 206, 103, 205, 206, 92, 205, 206, 35, 205,
+ 206, 89, 205, 206, 34, 205, 206, 87, 205, 206,
+ 93, 205, 206, 99, 205, 206, 4, 205, 206, 5,
+ 205, 206, 30, 205, 206, 99, 205, 206, 121, 205,
+
+ 206, 99, 205, 206, 99, 205, 206, 99, 205, 206,
+ 99, 205, 206, 99, 205, 206, 99, 205, 206, 99,
+ 205, 206, 99, 205, 206, 99, 205, 206, 99, 205,
+ 206, 99, 205, 206, 99, 205, 206, 99, 205, 206,
+ 99, 205, 206, 99, 205, 206, 99, 205, 206, 99,
+ 205, 206, 99, 205, 206, 99, 205, 206, 99, 205,
+ 206, 3, 205, 206, 29, 205, 206, 146, 205, 206,
+ 31, 205, 206, 205, 206, 200, 206, 199, 206, 202,
+ 206, 201, 202, 206, 141, 206, 138, 141, 206, 138,
+ 206, 139, 141, 206, 141, 206, 145, 206, 142, 145,
+
+ 206, 142, 206, 143, 145, 206, 145, 206, 198, 206,
+ 196, 206, 198, 206, 198, 206, 191, 206, 192, 206,
+ 159, 206, 158, 206, 162, 206, 157, 206, 206, 168,
+ 206, 166, 206, 170, 206, 206, 175, 206, 176, 206,
+ 174, 206, 206, 178, 206, 148, 206, 117, 148, 206,
+ 118, 148, 206, 118, 148, 206, 7, 148, 206, 119,
+ 148, 206, 148, 206, 12, 148, 206, 28, 148, 206,
+ 120, 148, 206, 1, 148, 206, 2, 148, 206, 10,
+ 148, 206, 8, 148, 206, 6, 148, 206, 9, 148,
+ 206, 36, 148, 206, 11, 148, 206, 103, 148, 206,
+
+ 103, 148, 206, 92, 148, 206, 35, 148, 206, 89,
+ 148, 206, 34, 148, 206, 87, 148, 206, 93, 148,
+ 206, 99, 148, 206, 4, 148, 206, 5, 148, 206,
+ 30, 148, 206, 99, 148, 206, 121, 148, 206, 99,
+ 148, 206, 99, 148, 206, 99, 148, 206, 99, 148,
+ 206, 99, 148, 206, 99, 148, 206, 99, 148, 206,
+ 99, 148, 206, 99, 148, 206, 99, 148, 206, 99,
+ 148, 206, 99, 148, 206, 99, 148, 206, 99, 148,
+ 206, 99, 148, 206, 99, 148, 206, 99, 148, 206,
+ 99, 148, 206, 99, 148, 206, 99, 148, 206, 3,
+
+ 148, 206, 29, 148, 206, 147, 148, 206, 31, 148,
+ 206, 148, 206, 190, 206, 190, 206, 190, 206, 187,
+ 190, 206, 189, 190, 206, 190, 206, 181, 206, 180,
+ 181, 206, 181, 206, 203, 206, 204, 206, 136, 206,
+ 136, 206, 136, 206, 137, 206, 117, 86, 102, 17,
+ 26, 18, 15, 24, 13, 25, 14, 91, 38, 106,
+ 23, 122, 16, 103, 99, 32, 90, 85, 78, 88,
+ 33, 94, 99, 100, 99, 20, 99, 100, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 54, 99, 99,
+ 79, 99, 99, 99, 99, 84, 99, 99, 83, 99,
+
+ 50, 99, 99, 82, 99, 81, 99, 80, 99, 99,
+ 97, 99, 99, 99, 99, 99, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 19, 27, 114, 114,
+ 201, 138, 140, 142, 144, 197, 194, 195, 191, 193,
+ 159, 161, 160, 156, 150, 156, 149, 156, 151, 156,
+ 156, 168, 169, 167, 165, 164, 167, 163, 167, 175,
+ 177, 173, 172, 171, 173, 186, 185, 183, 182, 184,
+ 189, 188, 180, 179, 135, 115, 115, 37, 124, 39,
+ 116, 116, 104, 105, 21, 22, 101, 99, 99, 99,
+ 99, 95, 99, 99, 99, 99, 99, 99, 99, 99,
+
+ 99, 99, 99, 55, 99, 99, 99, 46, 99, 96,
+ 99, 99, 99, 99, 99, 99, 99, 99, 77, 99,
+ 99, 99, 99, 99, 99, 98, 99, 114, 152, 135,
+ 115, 123, 116, 125, 99, 99, 99, 99, 99, 75,
+ 99, 99, 99, 99, 99, 99, 99, 51, 99, 99,
+ 99, 99, 99, 73, 99, 99, 48, 99, 99, 99,
+ 99, 99, 99, 99, 99, 99, 99, 43, 99, 99,
+ 99, 153, 131, 131, 128, 131, 130, 126, 130, 99,
+ 99, 99, 99, 60, 99, 40, 99, 99, 99, 99,
+ 99, 99, 99, 99, 47, 99, 99, 99, 99, 99,
+
+ 99, 49, 99, 99, 99, 99, 99, 99, 53, 99,
+ 99, 154, 131, 131, 128, 131, 99, 99, 99, 99,
+ 99, 99, 99, 99, 99, 67, 99, 41, 99, 99,
+ 99, 99, 64, 99, 42, 99, 44, 99, 56, 99,
+ 74, 99, 99, 52, 99, 45, 99, 109, 114, 114,
+ 155, 133, 132, 127, 129, 99, 99, 99, 99, 99,
+ 99, 76, 99, 58, 99, 99, 59, 99, 99, 63,
+ 99, 57, 99, 109, 114, 68, 99, 99, 99, 99,
+ 99, 61, 99, 99, 62, 99, 112, 107, 109, 114,
+ 113, 134, 99, 99, 71, 99, 99, 99, 69, 99,
+
+ 99, 99, 66, 99, 114, 114, 114, 70, 99, 72,
+ 99, 65, 99, 110, 111, 108, 109, 114
+ } ;
+
+static yyconst flex_int16_t yy_accept[584] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 2, 3, 4,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 6, 8, 11, 13, 16,
+ 19, 22, 25, 27, 30, 33, 36, 39, 42, 45,
+ 48, 51, 54, 57, 60, 63, 66, 69, 72, 75,
+ 78, 81, 84, 87, 90, 93, 96, 99, 102, 105,
+ 108, 111, 114, 117, 120, 123, 126, 129, 132, 135,
+ 138, 141, 144, 147, 150, 153, 156, 159, 162, 165,
+ 168, 171, 174, 176, 178, 180, 182, 185, 187, 190,
+
+ 192, 195, 197, 199, 202, 204, 207, 209, 211, 213,
+ 215, 217, 219, 221, 223, 225, 227, 229, 230, 232,
+ 234, 236, 237, 239, 241, 243, 244, 246, 248, 251,
+ 254, 257, 260, 263, 265, 268, 271, 274, 277, 280,
+ 283, 286, 289, 292, 295, 298, 301, 304, 307, 310,
+ 313, 316, 319, 322, 325, 328, 331, 334, 337, 340,
+ 343, 346, 349, 352, 355, 358, 361, 364, 367, 370,
+ 373, 376, 379, 382, 385, 388, 391, 394, 397, 400,
+ 403, 406, 409, 412, 414, 416, 418, 420, 423, 426,
+ 428, 430, 433, 435, 437, 439, 441, 443, 445, 447,
+
+ 448, 448, 448, 448, 449, 449, 450, 451, 452, 453,
+ 454, 455, 456, 457, 458, 459, 460, 461, 462, 463,
+ 463, 464, 464, 465, 465, 465, 466, 467, 468, 468,
+ 468, 469, 470, 470, 471, 472, 473, 474, 475, 476,
+ 477, 478, 479, 480, 481, 482, 483, 484, 485, 486,
+ 487, 488, 490, 491, 493, 494, 495, 496, 498, 499,
+ 501, 503, 504, 506, 508, 510, 511, 513, 514, 515,
+ 516, 517, 518, 519, 520, 521, 522, 523, 524, 525,
+ 526, 527, 528, 529, 529, 530, 531, 531, 531, 531,
+ 532, 533, 534, 535, 536, 537, 538, 539, 540, 541,
+
+ 542, 542, 543, 544, 545, 547, 549, 551, 552, 553,
+ 553, 554, 555, 556, 558, 560, 561, 562, 563, 564,
+ 566, 567, 568, 569, 570, 571, 572, 572, 573, 573,
+ 573, 574, 574, 575, 575, 575, 576, 576, 576, 577,
+ 578, 579, 579, 580, 580, 581, 581, 582, 583, 584,
+ 585, 586, 586, 586, 586, 587, 588, 589, 590, 591,
+ 592, 594, 595, 596, 597, 598, 599, 600, 601, 602,
+ 603, 604, 606, 607, 608, 610, 612, 613, 614, 615,
+ 616, 617, 618, 619, 621, 622, 623, 624, 625, 626,
+ 628, 629, 629, 629, 629, 630, 631, 631, 632, 633,
+
+ 634, 634, 634, 634, 634, 635, 636, 637, 638, 639,
+ 640, 642, 643, 644, 645, 646, 647, 648, 650, 651,
+ 652, 653, 654, 656, 657, 659, 660, 661, 662, 663,
+ 664, 665, 666, 667, 668, 670, 671, 672, 672, 672,
+ 672, 673, 673, 674, 674, 675, 675, 677, 678, 679,
+ 680, 681, 682, 683, 684, 686, 688, 689, 690, 691,
+ 692, 693, 694, 695, 697, 698, 699, 700, 701, 702,
+ 704, 705, 706, 707, 708, 709, 711, 712, 712, 712,
+ 712, 713, 713, 714, 714, 714, 715, 715, 717, 718,
+ 719, 720, 721, 722, 723, 724, 725, 726, 728, 730,
+
+ 731, 732, 733, 735, 737, 739, 741, 743, 744, 746,
+ 748, 748, 748, 748, 750, 751, 751, 752, 752, 753,
+ 753, 754, 755, 756, 756, 757, 758, 759, 760, 761,
+ 762, 764, 766, 767, 769, 770, 772, 774, 774, 774,
+ 776, 776, 776, 778, 779, 780, 781, 782, 784, 785,
+ 787, 788, 788, 791, 792, 793, 794, 795, 797, 798,
+ 799, 799, 799, 799, 799, 801, 802, 803, 805, 805,
+ 806, 806, 807, 807, 808, 808, 810, 812, 814, 815,
+ 816, 819, 819
+ } ;
+
+static yyconst flex_int32_t yy_ec[256] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
+ 1, 4, 5, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 6, 7, 8, 9, 10, 11, 12, 13,
+ 14, 15, 16, 17, 18, 19, 20, 21, 22, 22,
+ 22, 22, 22, 22, 22, 23, 23, 24, 25, 26,
+ 27, 28, 29, 1, 30, 30, 30, 30, 30, 30,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 31, 31, 31, 31, 31, 31, 31, 31, 31, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
+
+ 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
+ 62, 47, 63, 64, 65, 66, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int32_t yy_meta[67] =
+ { 0,
+ 1, 2, 3, 1, 4, 1, 5, 1, 6, 1,
+ 1, 7, 4, 8, 9, 1, 1, 1, 1, 1,
+ 10, 10, 10, 11, 12, 1, 1, 1, 1, 13,
+ 14, 1, 15, 1, 1, 16, 17, 13, 13, 13,
+ 13, 13, 13, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
+ 14, 14, 1, 1, 1, 1
+ } ;
+
+static yyconst flex_int16_t yy_base[637] =
+ { 0,
+ 0, 1883, 1885, 1881, 23, 24, 72, 80, 84, 88,
+ 85, 92, 93, 94, 1866, 1865, 102, 103, 95, 111,
+ 110, 112, 149, 1870, 207, 243, 0, 304, 1874, 1871,
+ 1844, 91, 0, 0, 1867, 2002, 215, 219, 2002, 223,
+ 192, 2002, 110, 1839, 113, 2002, 2002, 2002, 1836, 121,
+ 2002, 209, 227, 236, 210, 238, 1836, 2002, 52, 305,
+ 114, 1831, 211, 2002, 2002, 1831, 215, 2002, 217, 254,
+ 287, 343, 344, 289, 345, 1833, 348, 346, 352, 351,
+ 355, 288, 358, 354, 219, 349, 376, 356, 2002, 250,
+ 2002, 2002, 378, 2002, 2002, 2002, 271, 2002, 316, 321,
+
+ 2002, 0, 2002, 387, 423, 2002, 0, 2002, 2002, 411,
+ 0, 0, 1836, 0, 2002, 433, 1790, 386, 0, 2002,
+ 443, 417, 0, 2002, 1773, 414, 2002, 2002, 451, 2002,
+ 458, 203, 2002, 443, 1792, 385, 2002, 2002, 2002, 1754,
+ 239, 2002, 440, 457, 442, 464, 469, 1753, 2002, 445,
+ 491, 454, 1747, 350, 2002, 2002, 1747, 451, 2002, 449,
+ 471, 475, 478, 474, 390, 480, 1749, 488, 487, 491,
+ 481, 490, 510, 514, 485, 517, 497, 527, 526, 2002,
+ 519, 2002, 2002, 550, 2002, 1709, 551, 2002, 1769, 427,
+ 2002, 1768, 555, 2002, 2002, 2002, 1738, 1715, 2002, 574,
+
+ 587, 324, 505, 2002, 561, 564, 2002, 2002, 2002, 2002,
+ 2002, 2002, 2002, 2002, 2002, 1744, 579, 2002, 2002, 556,
+ 2002, 586, 591, 548, 0, 580, 1735, 2002, 592, 1735,
+ 2002, 2002, 617, 2002, 1733, 2002, 581, 1735, 105, 2002,
+ 1734, 1733, 574, 567, 591, 597, 599, 60, 602, 600,
+ 603, 1732, 604, 1731, 608, 606, 609, 1728, 611, 1724,
+ 1722, 615, 1721, 1720, 1719, 612, 1718, 621, 610, 298,
+ 618, 625, 623, 630, 619, 624, 631, 633, 638, 642,
+ 639, 2002, 2002, 647, 2002, 682, 683, 686, 687, 649,
+ 694, 2002, 698, 2002, 2002, 2002, 2002, 0, 2002, 0,
+
+ 702, 2002, 2002, 2002, 2002, 2002, 2002, 0, 0, 708,
+ 2002, 2002, 2002, 2002, 2002, 0, 2002, 2002, 2002, 2002,
+ 2002, 2002, 2002, 2002, 2002, 1739, 699, 2002, 705, 1735,
+ 1733, 711, 2002, 712, 1731, 1706, 1686, 713, 2002, 714,
+ 720, 724, 2002, 0, 2002, 728, 2002, 735, 724, 0,
+ 2002, 774, 839, 0, 2002, 2002, 697, 704, 711, 715,
+ 1707, 719, 723, 819, 821, 724, 822, 726, 725, 727,
+ 728, 729, 824, 823, 1706, 1705, 825, 360, 832, 826,
+ 827, 828, 831, 1704, 731, 829, 841, 834, 846, 1703,
+ 2002, 857, 858, 861, 0, 2002, 1675, 2002, 2002, 2002,
+
+ 0, 909, 1694, 975, 2002, 833, 830, 843, 848, 844,
+ 1673, 845, 1018, 1019, 1020, 1021, 1022, 1670, 1023, 1024,
+ 1025, 869, 1648, 1026, 1640, 1028, 1027, 1029, 1030, 1032,
+ 1031, 1036, 1039, 1033, 1636, 1043, 1044, 1056, 1085, 1088,
+ 0, 1596, 0, 0, 1617, 0, 0, 2002, 2002, 0,
+ 1038, 1046, 1057, 1045, 1604, 1602, 1071, 1074, 1075, 1076,
+ 1077, 1078, 1079, 1591, 1080, 1082, 1083, 1088, 1085, 1568,
+ 1087, 1084, 1089, 1097, 1086, 1561, 1090, 1112, 900, 1140,
+ 0, 1574, 0, 1563, 1571, 1557, 1556, 0, 1113, 1099,
+ 1120, 1098, 1092, 1105, 1122, 1124, 1127, 1539, 1535, 1128,
+
+ 1129, 1130, 1534, 1533, 1261, 1260, 1252, 532, 1243, 1225,
+ 1153, 751, 1175, 2002, 755, 1154, 2002, 1162, 2002, 1154,
+ 2002, 2002, 2002, 1046, 1147, 1137, 1136, 1144, 1151, 1157,
+ 740, 735, 1150, 688, 1162, 482, 473, 1184, 1198, 2002,
+ 1203, 1206, 425, 1178, 1152, 1187, 1186, 353, 1188, 292,
+ 1239, 1245, 2002, 1213, 2002, 1189, 629, 240, 1193, 1198,
+ 1252, 901, 1234, 1227, 1200, 1209, 1214, 122, 1261, 1267,
+ 1255, 1258, 1268, 1274, 893, 115, 52, 47, 1220, 1277,
+ 2002, 2002, 1286, 1303, 1320, 1337, 1354, 1371, 1388, 1405,
+ 1422, 1439, 1456, 1473, 1490, 1507, 1515, 1522, 1538, 1555,
+
+ 1572, 1589, 1606, 1623, 1640, 1657, 1674, 1691, 1707, 1723,
+ 1737, 1752, 1766, 1782, 1799, 262, 552, 1816, 1833, 1517,
+ 1838, 1848, 1524, 1855, 1859, 1869, 1873, 1880, 1896, 1573,
+ 1907, 1923, 1934, 1950, 1967, 1984
+ } ;
+
+static yyconst flex_int16_t yy_def[637] =
+ { 0,
+ 582, 1, 583, 583, 584, 584, 585, 585, 586, 586,
+ 587, 587, 587, 587, 588, 588, 589, 589, 590, 590,
+ 591, 591, 582, 23, 592, 592, 593, 593, 594, 594,
+ 595, 595, 596, 596, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 597, 582, 582, 582, 598, 582, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 582, 582,
+ 582, 582, 599, 582, 582, 582, 582, 582, 582, 582,
+
+ 582, 600, 582, 582, 582, 582, 601, 582, 582, 582,
+ 602, 603, 582, 604, 582, 582, 582, 605, 606, 582,
+ 582, 607, 608, 582, 582, 609, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 597, 582, 582, 582, 598, 582, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 582,
+ 582, 582, 582, 599, 582, 582, 582, 582, 610, 611,
+ 582, 612, 613, 582, 582, 582, 582, 582, 582, 582,
+
+ 582, 614, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 615,
+ 582, 582, 582, 582, 616, 597, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 597, 582, 598, 582,
+ 598, 582, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 582, 582, 599, 582, 599, 599, 599, 599, 582,
+ 582, 582, 582, 582, 582, 582, 582, 603, 582, 604,
+
+ 582, 582, 582, 582, 582, 582, 582, 617, 606, 582,
+ 582, 582, 582, 582, 582, 608, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 610, 611, 582, 611, 582,
+ 612, 613, 582, 613, 582, 582, 582, 614, 582, 614,
+ 582, 582, 582, 618, 582, 615, 582, 615, 582, 616,
+ 582, 582, 582, 619, 582, 582, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 582, 599, 599, 599, 620, 582, 582, 582, 582, 582,
+
+ 621, 582, 622, 582, 582, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 599, 599, 599,
+ 623, 582, 624, 625, 626, 627, 628, 582, 582, 404,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 599, 629, 599,
+ 630, 582, 624, 631, 632, 626, 633, 628, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+
+ 598, 598, 598, 598, 598, 598, 598, 598, 598, 598,
+ 599, 629, 629, 582, 629, 599, 582, 582, 582, 631,
+ 582, 582, 582, 633, 598, 598, 598, 598, 598, 598,
+ 598, 598, 598, 598, 598, 598, 598, 599, 629, 582,
+ 599, 582, 598, 598, 598, 598, 598, 598, 598, 598,
+ 599, 629, 582, 599, 582, 598, 598, 598, 598, 598,
+ 599, 634, 635, 636, 598, 598, 598, 598, 634, 634,
+ 635, 635, 636, 636, 629, 598, 598, 598, 599, 599,
+ 582, 0, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582
+ } ;
+
+static yyconst flex_int16_t yy_nxt[2069] =
+ { 0,
+ 36, 37, 38, 39, 40, 41, 42, 36, 43, 44,
+ 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
+ 55, 56, 56, 57, 58, 59, 60, 61, 62, 63,
+ 63, 64, 36, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 76, 76, 78, 76,
+ 79, 80, 81, 76, 82, 83, 84, 85, 86, 87,
+ 88, 76, 89, 90, 91, 92, 97, 97, 97, 97,
+ 242, 97, 97, 99, 100, 242, 99, 227, 228, 97,
+ 97, 99, 100, 242, 99, 104, 105, 109, 104, 104,
+ 105, 101, 104, 110, 109, 109, 109, 120, 198, 101,
+
+ 110, 110, 110, 106, 115, 115, 121, 106, 116, 116,
+ 117, 117, 124, 120, 124, 363, 197, 111, 125, 356,
+ 125, 102, 121, 208, 111, 111, 111, 122, 242, 102,
+ 206, 206, 206, 107, 118, 118, 211, 107, 242, 209,
+ 234, 235, 126, 122, 126, 242, 127, 212, 127, 128,
+ 129, 38, 130, 131, 132, 133, 128, 134, 135, 136,
+ 137, 138, 139, 140, 141, 142, 143, 144, 145, 146,
+ 147, 147, 148, 149, 150, 151, 152, 153, 154, 154,
+ 155, 128, 156, 157, 158, 159, 160, 161, 162, 163,
+ 164, 165, 166, 167, 168, 167, 167, 169, 167, 170,
+
+ 171, 172, 167, 173, 174, 175, 176, 177, 178, 179,
+ 167, 180, 181, 182, 183, 186, 200, 201, 204, 201,
+ 201, 201, 202, 201, 201, 201, 213, 201, 222, 204,
+ 223, 223, 223, 203, 238, 214, 215, 203, 242, 187,
+ 242, 203, 242, 188, 189, 216, 239, 217, 217, 217,
+ 219, 186, 243, 218, 211, 220, 222, 205, 223, 223,
+ 223, 224, 221, 242, 244, 212, 245, 246, 205, 277,
+ 225, 350, 190, 190, 350, 187, 282, 242, 190, 188,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+ 190, 190, 190, 190, 190, 190, 190, 190, 190, 190,
+
+ 190, 190, 190, 190, 190, 192, 229, 229, 247, 229,
+ 242, 242, 242, 283, 290, 242, 290, 291, 291, 290,
+ 291, 242, 291, 291, 248, 291, 339, 290, 340, 271,
+ 230, 231, 232, 193, 193, 249, 379, 256, 250, 193,
+ 257, 193, 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 193, 193, 193, 193,
+ 193, 193, 193, 193, 193, 193, 242, 242, 242, 242,
+ 233, 242, 242, 238, 242, 242, 242, 242, 242, 242,
+ 285, 242, 286, 242, 251, 239, 258, 263, 293, 293,
+ 261, 293, 253, 265, 252, 208, 259, 254, 262, 242,
+
+ 278, 260, 264, 266, 255, 267, 268, 281, 275, 269,
+ 272, 209, 270, 242, 273, 276, 319, 274, 426, 313,
+ 279, 280, 320, 287, 293, 293, 288, 293, 314, 328,
+ 289, 295, 295, 295, 301, 301, 305, 301, 256, 302,
+ 306, 257, 307, 308, 310, 310, 320, 310, 242, 315,
+ 320, 330, 200, 201, 311, 201, 219, 213, 202, 201,
+ 201, 220, 201, 206, 206, 206, 214, 215, 221, 203,
+ 227, 228, 242, 296, 242, 216, 203, 217, 217, 217,
+ 234, 235, 222, 218, 223, 223, 223, 222, 243, 223,
+ 223, 223, 229, 229, 242, 229, 242, 242, 242, 246,
+
+ 244, 242, 245, 242, 242, 242, 341, 341, 242, 341,
+ 242, 242, 248, 242, 242, 224, 230, 231, 232, 251,
+ 242, 258, 253, 249, 225, 247, 250, 254, 263, 252,
+ 261, 259, 265, 242, 255, 267, 260, 242, 262, 275,
+ 242, 268, 266, 264, 269, 282, 276, 270, 278, 242,
+ 242, 271, 285, 322, 286, 242, 233, 333, 347, 323,
+ 348, 395, 342, 342, 395, 342, 272, 277, 349, 349,
+ 273, 279, 280, 274, 537, 200, 201, 281, 201, 335,
+ 343, 202, 283, 324, 206, 206, 206, 325, 201, 201,
+ 242, 201, 203, 229, 229, 287, 229, 242, 288, 217,
+
+ 217, 217, 289, 238, 238, 203, 217, 217, 217, 222,
+ 344, 223, 223, 223, 242, 239, 239, 230, 353, 353,
+ 242, 353, 242, 242, 359, 242, 242, 242, 357, 242,
+ 358, 242, 242, 242, 242, 242, 343, 361, 242, 364,
+ 362, 242, 242, 360, 242, 366, 242, 242, 242, 285,
+ 365, 286, 242, 242, 242, 378, 242, 371, 367, 368,
+ 369, 242, 242, 372, 370, 242, 344, 373, 376, 377,
+ 374, 375, 354, 381, 380, 383, 385, 382, 387, 386,
+ 384, 566, 389, 388, 391, 285, 286, 286, 285, 285,
+ 286, 286, 290, 390, 290, 291, 291, 290, 291, 293,
+
+ 293, 328, 293, 301, 301, 290, 301, 328, 302, 310,
+ 310, 242, 310, 333, 333, 339, 398, 340, 340, 311,
+ 242, 341, 341, 330, 341, 342, 342, 242, 342, 330,
+ 347, 393, 348, 392, 242, 335, 335, 400, 242, 348,
+ 406, 394, 242, 343, 349, 349, 242, 242, 242, 242,
+ 242, 242, 242, 514, 242, 515, 410, 540, 242, 515,
+ 407, 415, 419, 242, 411, 421, 408, 418, 420, 416,
+ 422, 409, 433, 344, 401, 401, 401, 401, 401, 401,
+ 401, 401, 401, 401, 401, 402, 401, 401, 401, 401,
+ 401, 403, 401, 401, 401, 401, 401, 401, 401, 401,
+
+ 401, 401, 401, 404, 404, 401, 401, 401, 401, 404,
+ 401, 404, 404, 404, 404, 404, 404, 404, 404, 404,
+ 404, 404, 404, 404, 404, 404, 404, 404, 404, 404,
+ 404, 404, 404, 404, 404, 404, 401, 401, 401, 401,
+ 353, 353, 242, 353, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 242, 343, 285,
+ 285, 286, 286, 285, 242, 286, 242, 242, 242, 242,
+ 434, 242, 429, 430, 412, 423, 413, 414, 417, 424,
+ 427, 435, 436, 428, 452, 431, 425, 432, 344, 437,
+ 451, 455, 242, 454, 354, 581, 438, 515, 440, 453,
+
+ 456, 513, 514, 285, 515, 570, 465, 284, 439, 444,
+ 444, 444, 444, 444, 444, 444, 444, 444, 444, 444,
+ 444, 444, 444, 444, 444, 444, 444, 444, 444, 444,
+ 444, 444, 444, 444, 444, 444, 444, 444, 445, 445,
+ 444, 444, 444, 444, 445, 444, 445, 445, 445, 445,
+ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445,
+ 445, 445, 445, 445, 445, 445, 445, 445, 445, 445,
+ 445, 444, 444, 444, 444, 448, 448, 449, 448, 448,
+ 448, 448, 448, 448, 448, 448, 448, 448, 448, 448,
+ 448, 448, 448, 448, 448, 450, 450, 450, 448, 448,
+
+ 448, 448, 448, 448, 450, 450, 448, 448, 448, 448,
+ 450, 448, 450, 450, 450, 450, 450, 450, 450, 450,
+ 450, 450, 450, 450, 450, 450, 450, 450, 450, 450,
+ 450, 450, 450, 450, 450, 450, 450, 448, 448, 448,
+ 448, 242, 242, 242, 242, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 242, 242, 242, 523, 285, 242,
+ 286, 242, 242, 466, 458, 467, 242, 242, 242, 242,
+ 472, 460, 468, 462, 457, 473, 461, 459, 463, 474,
+ 242, 464, 471, 469, 476, 477, 470, 285, 475, 286,
+ 285, 490, 286, 489, 242, 491, 492, 242, 242, 242,
+
+ 242, 242, 242, 242, 478, 242, 242, 242, 242, 242,
+ 242, 242, 242, 242, 285, 242, 286, 496, 498, 500,
+ 242, 242, 242, 495, 494, 493, 479, 503, 242, 499,
+ 505, 480, 501, 507, 497, 504, 242, 526, 508, 502,
+ 506, 509, 285, 242, 286, 242, 510, 242, 528, 529,
+ 242, 242, 242, 242, 525, 285, 285, 286, 286, 242,
+ 242, 527, 530, 518, 532, 519, 533, 242, 535, 511,
+ 242, 536, 534, 242, 242, 242, 513, 514, 531, 515,
+ 242, 546, 542, 542, 542, 242, 285, 543, 286, 516,
+ 547, 541, 545, 538, 544, 539, 539, 539, 548, 552,
+
+ 553, 242, 515, 550, 554, 285, 549, 286, 555, 242,
+ 242, 242, 242, 557, 554, 285, 242, 286, 539, 539,
+ 539, 242, 285, 242, 286, 551, 542, 542, 542, 514,
+ 565, 574, 242, 575, 556, 558, 285, 242, 572, 560,
+ 561, 285, 559, 286, 567, 562, 552, 514, 242, 515,
+ 577, 564, 568, 561, 285, 576, 286, 285, 562, 572,
+ 391, 284, 572, 285, 563, 570, 242, 579, 578, 391,
+ 514, 570, 574, 579, 575, 242, 540, 563, 574, 285,
+ 575, 286, 580, 242, 242, 580, 94, 94, 94, 94,
+ 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
+
+ 94, 94, 94, 96, 96, 96, 96, 96, 96, 96,
+ 96, 96, 96, 96, 96, 96, 96, 96, 96, 96,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 103, 103, 103,
+ 103, 103, 103, 103, 103, 103, 103, 103, 103, 103,
+ 103, 103, 103, 103, 108, 108, 108, 108, 108, 108,
+ 108, 108, 108, 108, 108, 108, 108, 108, 108, 108,
+ 108, 112, 112, 112, 112, 112, 112, 112, 112, 112,
+ 112, 112, 112, 112, 112, 112, 112, 112, 114, 114,
+ 114, 114, 114, 114, 114, 114, 114, 114, 114, 114,
+
+ 114, 114, 114, 114, 114, 119, 119, 119, 119, 119,
+ 119, 119, 119, 119, 119, 119, 119, 119, 119, 119,
+ 119, 119, 123, 123, 123, 123, 123, 123, 123, 123,
+ 123, 123, 123, 123, 123, 123, 123, 123, 123, 185,
+ 185, 185, 185, 185, 185, 185, 185, 185, 185, 185,
+ 185, 185, 185, 185, 185, 185, 191, 191, 191, 191,
+ 191, 191, 191, 191, 191, 191, 191, 191, 191, 191,
+ 191, 191, 191, 194, 194, 194, 194, 194, 194, 194,
+ 194, 194, 194, 194, 194, 194, 194, 194, 194, 194,
+ 196, 196, 196, 196, 196, 196, 196, 196, 196, 196,
+
+ 196, 196, 196, 196, 196, 196, 196, 199, 199, 199,
+ 199, 199, 199, 199, 199, 199, 199, 199, 199, 199,
+ 199, 199, 199, 199, 237, 237, 441, 237, 237, 441,
+ 237, 241, 241, 481, 241, 241, 481, 241, 284, 284,
+ 284, 284, 284, 284, 284, 284, 284, 284, 284, 284,
+ 284, 284, 284, 284, 284, 292, 242, 242, 242, 292,
+ 292, 292, 242, 292, 292, 292, 292, 523, 485, 292,
+ 292, 292, 294, 522, 519, 518, 294, 294, 294, 294,
+ 294, 294, 517, 294, 242, 517, 294, 294, 294, 297,
+ 297, 242, 297, 297, 297, 297, 297, 297, 297, 297,
+
+ 297, 297, 297, 297, 297, 297, 298, 298, 298, 298,
+ 298, 298, 298, 298, 242, 298, 298, 298, 298, 298,
+ 298, 298, 298, 300, 300, 242, 300, 242, 485, 300,
+ 300, 300, 300, 300, 300, 300, 300, 482, 300, 300,
+ 304, 304, 304, 304, 304, 304, 304, 304, 304, 304,
+ 304, 304, 304, 304, 304, 304, 304, 309, 309, 242,
+ 309, 309, 309, 242, 309, 309, 309, 309, 309, 309,
+ 309, 242, 309, 309, 312, 312, 312, 312, 312, 312,
+ 312, 312, 312, 312, 312, 312, 312, 312, 312, 312,
+ 312, 316, 316, 242, 316, 316, 242, 316, 316, 316,
+
+ 316, 316, 316, 316, 316, 446, 316, 318, 318, 318,
+ 318, 318, 318, 318, 318, 318, 318, 318, 318, 318,
+ 318, 318, 318, 318, 327, 442, 242, 242, 242, 242,
+ 242, 397, 396, 333, 331, 327, 327, 328, 327, 329,
+ 326, 242, 242, 242, 242, 242, 329, 242, 329, 329,
+ 329, 242, 329, 332, 242, 242, 241, 242, 237, 355,
+ 352, 351, 345, 337, 332, 332, 336, 332, 334, 331,
+ 326, 321, 242, 240, 236, 334, 226, 334, 334, 334,
+ 210, 334, 338, 338, 338, 338, 338, 338, 338, 338,
+ 338, 338, 338, 338, 338, 338, 338, 338, 338, 346,
+
+ 346, 346, 346, 346, 346, 346, 346, 346, 346, 346,
+ 346, 346, 346, 346, 346, 346, 399, 399, 207, 399,
+ 399, 399, 399, 399, 399, 399, 399, 399, 399, 399,
+ 399, 399, 399, 405, 405, 317, 405, 405, 405, 405,
+ 405, 405, 405, 405, 405, 405, 405, 405, 405, 405,
+ 443, 443, 303, 443, 447, 299, 242, 240, 236, 226,
+ 447, 447, 210, 447, 483, 207, 582, 483, 483, 197,
+ 483, 484, 484, 195, 484, 486, 195, 184, 486, 113,
+ 113, 486, 486, 95, 486, 487, 487, 95, 487, 488,
+ 93, 582, 488, 488, 582, 488, 512, 512, 512, 512,
+
+ 512, 512, 512, 512, 512, 512, 512, 512, 512, 512,
+ 512, 512, 512, 520, 582, 582, 520, 582, 582, 520,
+ 520, 582, 520, 521, 521, 521, 521, 521, 521, 521,
+ 521, 521, 521, 521, 521, 521, 521, 521, 521, 521,
+ 524, 582, 582, 524, 582, 582, 524, 524, 582, 524,
+ 569, 569, 569, 569, 569, 569, 569, 569, 569, 569,
+ 569, 569, 569, 569, 569, 569, 569, 571, 571, 571,
+ 571, 571, 571, 571, 571, 571, 571, 571, 571, 571,
+ 571, 571, 571, 571, 573, 573, 573, 573, 573, 573,
+ 573, 573, 573, 573, 573, 573, 573, 573, 573, 573,
+
+ 573, 35, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582
+ } ;
+
+static yyconst flex_int16_t yy_chk[2069] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 5, 6, 5, 6,
+ 578, 5, 6, 7, 7, 577, 7, 59, 59, 5,
+ 6, 8, 8, 248, 8, 9, 9, 11, 9, 10,
+ 10, 7, 10, 11, 12, 13, 14, 19, 32, 8,
+
+ 12, 13, 14, 9, 17, 18, 19, 10, 17, 18,
+ 17, 18, 21, 20, 22, 248, 32, 11, 21, 239,
+ 22, 7, 20, 45, 12, 13, 14, 19, 239, 8,
+ 43, 43, 43, 9, 17, 18, 50, 10, 576, 45,
+ 61, 61, 21, 20, 22, 568, 21, 50, 22, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 25, 37, 37, 41, 37,
+ 38, 38, 37, 38, 40, 40, 52, 40, 55, 132,
+ 55, 55, 55, 37, 63, 52, 52, 38, 67, 25,
+ 69, 40, 85, 25, 26, 53, 63, 53, 53, 53,
+ 54, 26, 67, 53, 141, 54, 56, 41, 56, 56,
+ 56, 55, 54, 558, 67, 141, 67, 69, 132, 85,
+ 55, 616, 26, 26, 616, 26, 90, 70, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+ 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
+
+ 26, 26, 26, 26, 26, 28, 60, 60, 70, 60,
+ 71, 82, 74, 90, 97, 550, 97, 99, 99, 97,
+ 99, 270, 100, 100, 71, 100, 202, 97, 202, 82,
+ 60, 60, 60, 28, 28, 71, 270, 74, 71, 28,
+ 74, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
+ 28, 28, 28, 28, 28, 28, 72, 73, 75, 78,
+ 60, 77, 86, 154, 80, 79, 548, 84, 81, 88,
+ 93, 83, 93, 378, 72, 154, 75, 78, 104, 104,
+ 77, 104, 73, 79, 72, 136, 75, 73, 77, 87,
+
+ 86, 75, 78, 79, 73, 80, 81, 88, 84, 81,
+ 83, 136, 81, 165, 83, 84, 126, 83, 378, 122,
+ 87, 87, 126, 93, 105, 105, 93, 105, 122, 190,
+ 93, 110, 110, 110, 116, 116, 118, 116, 165, 116,
+ 118, 165, 118, 118, 121, 121, 126, 121, 543, 122,
+ 126, 190, 129, 129, 121, 129, 145, 143, 129, 131,
+ 131, 145, 131, 134, 134, 134, 143, 143, 145, 129,
+ 150, 150, 160, 110, 158, 144, 131, 144, 144, 144,
+ 152, 152, 146, 144, 146, 146, 146, 147, 158, 147,
+ 147, 147, 151, 151, 161, 151, 537, 164, 162, 160,
+
+ 158, 163, 158, 166, 171, 536, 203, 203, 175, 203,
+ 169, 168, 162, 172, 170, 146, 151, 151, 151, 163,
+ 177, 166, 164, 162, 146, 161, 162, 164, 169, 163,
+ 168, 166, 170, 173, 164, 171, 166, 174, 168, 175,
+ 176, 172, 170, 169, 172, 181, 175, 172, 177, 179,
+ 178, 173, 184, 187, 184, 508, 151, 193, 220, 187,
+ 220, 617, 205, 205, 617, 205, 174, 176, 224, 224,
+ 174, 178, 178, 174, 508, 200, 200, 179, 200, 193,
+ 205, 200, 181, 187, 206, 206, 206, 187, 201, 201,
+ 244, 201, 200, 229, 229, 184, 229, 243, 184, 217,
+
+ 217, 217, 184, 226, 237, 201, 222, 222, 222, 223,
+ 205, 223, 223, 223, 245, 226, 237, 229, 233, 233,
+ 246, 233, 247, 250, 244, 249, 251, 253, 243, 256,
+ 243, 255, 257, 269, 259, 266, 233, 246, 262, 249,
+ 247, 271, 275, 245, 268, 251, 273, 276, 272, 284,
+ 250, 284, 557, 274, 277, 269, 278, 256, 251, 253,
+ 255, 279, 281, 257, 255, 280, 233, 259, 266, 268,
+ 262, 262, 233, 272, 271, 274, 276, 273, 278, 277,
+ 275, 557, 280, 279, 286, 287, 286, 287, 288, 289,
+ 288, 289, 290, 281, 290, 291, 291, 290, 291, 293,
+
+ 293, 327, 293, 301, 301, 290, 301, 329, 301, 310,
+ 310, 534, 310, 332, 334, 338, 340, 338, 340, 310,
+ 357, 341, 341, 327, 341, 342, 342, 358, 342, 329,
+ 346, 288, 346, 287, 359, 332, 334, 348, 360, 348,
+ 357, 289, 362, 342, 349, 349, 363, 366, 369, 368,
+ 370, 371, 372, 512, 385, 512, 362, 515, 532, 515,
+ 358, 366, 369, 531, 363, 371, 359, 368, 370, 366,
+ 372, 360, 385, 342, 352, 352, 352, 352, 352, 352,
+ 352, 352, 352, 352, 352, 352, 352, 352, 352, 352,
+ 352, 352, 352, 352, 352, 352, 352, 352, 352, 352,
+
+ 352, 352, 352, 352, 352, 352, 352, 352, 352, 352,
+ 352, 352, 352, 352, 352, 352, 352, 352, 352, 352,
+ 352, 352, 352, 352, 352, 352, 352, 352, 352, 352,
+ 352, 352, 352, 352, 352, 352, 352, 352, 352, 352,
+ 353, 353, 364, 353, 365, 367, 374, 373, 377, 380,
+ 381, 382, 386, 407, 383, 379, 406, 388, 353, 392,
+ 393, 392, 393, 394, 387, 394, 408, 410, 412, 389,
+ 386, 409, 381, 382, 364, 373, 365, 365, 367, 374,
+ 379, 387, 388, 380, 407, 382, 377, 383, 353, 389,
+ 406, 410, 422, 409, 353, 575, 392, 575, 394, 408,
+
+ 412, 479, 479, 562, 479, 562, 422, 562, 393, 402,
+ 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,
+ 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,
+ 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,
+ 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,
+ 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,
+ 402, 402, 402, 402, 402, 402, 402, 402, 402, 402,
+ 402, 402, 402, 402, 402, 404, 404, 404, 404, 404,
+ 404, 404, 404, 404, 404, 404, 404, 404, 404, 404,
+ 404, 404, 404, 404, 404, 404, 404, 404, 404, 404,
+
+ 404, 404, 404, 404, 404, 404, 404, 404, 404, 404,
+ 404, 404, 404, 404, 404, 404, 404, 404, 404, 404,
+ 404, 404, 404, 404, 404, 404, 404, 404, 404, 404,
+ 404, 404, 404, 404, 404, 404, 404, 404, 404, 404,
+ 404, 413, 414, 415, 416, 417, 419, 420, 421, 424,
+ 427, 426, 428, 429, 431, 430, 434, 524, 438, 432,
+ 438, 451, 433, 424, 414, 426, 436, 437, 454, 452,
+ 431, 416, 427, 419, 413, 432, 417, 415, 420, 433,
+ 453, 421, 430, 428, 436, 437, 429, 439, 434, 439,
+ 440, 452, 440, 451, 457, 453, 454, 458, 459, 460,
+
+ 461, 462, 463, 465, 438, 466, 467, 472, 469, 475,
+ 471, 468, 473, 477, 478, 493, 478, 460, 462, 465,
+ 474, 492, 490, 459, 458, 457, 439, 468, 494, 463,
+ 471, 440, 466, 473, 461, 469, 489, 490, 474, 467,
+ 472, 475, 480, 491, 480, 495, 477, 496, 492, 493,
+ 497, 500, 501, 502, 489, 511, 516, 511, 516, 527,
+ 526, 491, 494, 518, 496, 520, 497, 528, 501, 478,
+ 525, 502, 500, 533, 529, 545, 513, 513, 495, 513,
+ 530, 528, 518, 518, 518, 535, 538, 525, 538, 480,
+ 529, 516, 527, 511, 526, 513, 513, 513, 530, 539,
+
+ 539, 544, 539, 535, 541, 541, 533, 541, 542, 547,
+ 546, 549, 556, 545, 554, 554, 559, 554, 539, 539,
+ 539, 560, 579, 565, 579, 538, 542, 542, 542, 564,
+ 556, 564, 566, 564, 544, 546, 563, 567, 563, 549,
+ 551, 551, 547, 551, 559, 551, 552, 552, 510, 552,
+ 566, 552, 560, 561, 561, 565, 561, 571, 561, 571,
+ 572, 563, 572, 569, 551, 569, 509, 569, 567, 570,
+ 573, 570, 573, 570, 573, 507, 574, 561, 574, 580,
+ 574, 580, 571, 506, 505, 572, 583, 583, 583, 583,
+ 583, 583, 583, 583, 583, 583, 583, 583, 583, 583,
+
+ 583, 583, 583, 584, 584, 584, 584, 584, 584, 584,
+ 584, 584, 584, 584, 584, 584, 584, 584, 584, 584,
+ 585, 585, 585, 585, 585, 585, 585, 585, 585, 585,
+ 585, 585, 585, 585, 585, 585, 585, 586, 586, 586,
+ 586, 586, 586, 586, 586, 586, 586, 586, 586, 586,
+ 586, 586, 586, 586, 587, 587, 587, 587, 587, 587,
+ 587, 587, 587, 587, 587, 587, 587, 587, 587, 587,
+ 587, 588, 588, 588, 588, 588, 588, 588, 588, 588,
+ 588, 588, 588, 588, 588, 588, 588, 588, 589, 589,
+ 589, 589, 589, 589, 589, 589, 589, 589, 589, 589,
+
+ 589, 589, 589, 589, 589, 590, 590, 590, 590, 590,
+ 590, 590, 590, 590, 590, 590, 590, 590, 590, 590,
+ 590, 590, 591, 591, 591, 591, 591, 591, 591, 591,
+ 591, 591, 591, 591, 591, 591, 591, 591, 591, 592,
+ 592, 592, 592, 592, 592, 592, 592, 592, 592, 592,
+ 592, 592, 592, 592, 592, 592, 593, 593, 593, 593,
+ 593, 593, 593, 593, 593, 593, 593, 593, 593, 593,
+ 593, 593, 593, 594, 594, 594, 594, 594, 594, 594,
+ 594, 594, 594, 594, 594, 594, 594, 594, 594, 594,
+ 595, 595, 595, 595, 595, 595, 595, 595, 595, 595,
+
+ 595, 595, 595, 595, 595, 595, 595, 596, 596, 596,
+ 596, 596, 596, 596, 596, 596, 596, 596, 596, 596,
+ 596, 596, 596, 596, 597, 597, 620, 597, 597, 620,
+ 597, 598, 598, 623, 598, 598, 623, 598, 599, 599,
+ 599, 599, 599, 599, 599, 599, 599, 599, 599, 599,
+ 599, 599, 599, 599, 599, 600, 504, 503, 499, 600,
+ 600, 600, 498, 600, 600, 600, 600, 487, 486, 600,
+ 600, 600, 601, 485, 484, 482, 601, 601, 601, 601,
+ 601, 601, 630, 601, 476, 630, 601, 601, 601, 602,
+ 602, 470, 602, 602, 602, 602, 602, 602, 602, 602,
+
+ 602, 602, 602, 602, 602, 602, 603, 603, 603, 603,
+ 603, 603, 603, 603, 464, 603, 603, 603, 603, 603,
+ 603, 603, 603, 604, 604, 456, 604, 455, 445, 604,
+ 604, 604, 604, 604, 604, 604, 604, 442, 604, 604,
+ 605, 605, 605, 605, 605, 605, 605, 605, 605, 605,
+ 605, 605, 605, 605, 605, 605, 605, 606, 606, 435,
+ 606, 606, 606, 425, 606, 606, 606, 606, 606, 606,
+ 606, 423, 606, 606, 607, 607, 607, 607, 607, 607,
+ 607, 607, 607, 607, 607, 607, 607, 607, 607, 607,
+ 607, 608, 608, 418, 608, 608, 411, 608, 608, 608,
+
+ 608, 608, 608, 608, 608, 403, 608, 609, 609, 609,
+ 609, 609, 609, 609, 609, 609, 609, 609, 609, 609,
+ 609, 609, 609, 609, 610, 397, 390, 384, 376, 375,
+ 361, 337, 336, 335, 331, 610, 610, 330, 610, 611,
+ 326, 267, 265, 264, 263, 261, 611, 260, 611, 611,
+ 611, 258, 611, 612, 254, 252, 242, 241, 238, 235,
+ 230, 227, 216, 198, 612, 612, 197, 612, 613, 192,
+ 189, 186, 167, 157, 153, 613, 148, 613, 613, 613,
+ 140, 613, 614, 614, 614, 614, 614, 614, 614, 614,
+ 614, 614, 614, 614, 614, 614, 614, 614, 614, 615,
+
+ 615, 615, 615, 615, 615, 615, 615, 615, 615, 615,
+ 615, 615, 615, 615, 615, 615, 618, 618, 135, 618,
+ 618, 618, 618, 618, 618, 618, 618, 618, 618, 618,
+ 618, 618, 618, 619, 619, 125, 619, 619, 619, 619,
+ 619, 619, 619, 619, 619, 619, 619, 619, 619, 619,
+ 621, 621, 117, 621, 622, 113, 76, 66, 62, 57,
+ 622, 622, 49, 622, 624, 44, 35, 624, 624, 31,
+ 624, 625, 625, 30, 625, 626, 29, 24, 626, 16,
+ 15, 626, 626, 4, 626, 627, 627, 3, 627, 628,
+ 2, 0, 628, 628, 0, 628, 629, 629, 629, 629,
+
+ 629, 629, 629, 629, 629, 629, 629, 629, 629, 629,
+ 629, 629, 629, 631, 0, 0, 631, 0, 0, 631,
+ 631, 0, 631, 632, 632, 632, 632, 632, 632, 632,
+ 632, 632, 632, 632, 632, 632, 632, 632, 632, 632,
+ 633, 0, 0, 633, 0, 0, 633, 633, 0, 633,
+ 634, 634, 634, 634, 634, 634, 634, 634, 634, 634,
+ 634, 634, 634, 634, 634, 634, 634, 635, 635, 635,
+ 635, 635, 635, 635, 635, 635, 635, 635, 635, 635,
+ 635, 635, 635, 635, 636, 636, 636, 636, 636, 636,
+ 636, 636, 636, 636, 636, 636, 636, 636, 636, 636,
+
+ 636, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582, 582, 582,
+ 582, 582, 582, 582, 582, 582, 582, 582
+ } ;
+
+extern int L__flex_debug;
+int L__flex_debug = 0;
+
+static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;
+static char *yy_full_match;
+static int yy_lp;
+#define REJECT \
+{ \
+*yy_cp = (yy_hold_char); /* undo effects of setting up L_text */ \
+yy_cp = (yy_full_match); /* restore poss. backed-over text */ \
+++(yy_lp); \
+goto find_rule; \
+}
+
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *L_text;
+#line 1 "../generic/Lscanner.l"
+#define YY_NO_INPUT 1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+#line 24 "../generic/Lscanner.l"
+/*
+ * Copyright (c) 2006-2008 BitMover, Inc.
+ */
+#include <string.h>
+#define _PWD_H // Some solaris9 conflict, we don't need pwd.h
+#include "tclInt.h"
+#include "Lcompile.h"
+#include "Lgrammar.h"
+#include "tommath.h"
+
+private void extract_re_delims(char c);
+private int include_pop();
+private int include_push(Tcl_Channel chan, char *name);
+private Tcl_Channel include_search(char *file, char **path, int cwdOnly);
+private Tcl_Channel include_try(Tcl_Obj *fileObj, int *found);
+private void inject(char *s);
+private void interpol_lbrace();
+private void interpol_pop();
+private int interpol_push();
+private int interpol_rbrace();
+private void put_back(char c);
+private void tally_newlines(char *s, int len, int tally);
+
+// Max nesting depth of string interpolations.
+#define INTERPOL_STACK_SZ 10
+
+// Stack for tracking include() statements.
+#define INCLUDE_STACK_SZ 10
+typedef struct {
+ char *name;
+ char *dir;
+ int line;
+ YY_BUFFER_STATE buf;
+} Include;
+
+private char re_start_delim; // delimiters for m|regexp| form
+private char re_end_delim;
+private Tcl_Obj *str; // string collection buffer
+private int str_beg; // source offset of string
+private char *here_delim = NULL;
+private char *here_pfx = NULL;
+private int include_top;
+private Include include_stk[INCLUDE_STACK_SZ+1];
+private Tcl_HashTable *include_table = NULL;
+private int interpol_top = -1;
+private int interpol_stk[INTERPOL_STACK_SZ+1];
+private int in_lhtml = 0; // Lhtml mode
+
+#define STRBUF_START(beg) \
+ do { \
+ str = Tcl_NewObj(); \
+ Tcl_IncrRefCount(str); \
+ str_beg = (beg); \
+ } while (0)
+
+
+#define STRBUF_STRING() Tcl_GetString(str)
+
+#define STRBUF_STARTED() (str != NULL)
+
+#define STRBUF_ADD(s, len) Tcl_AppendToObj(str, s, len)
+
+#define STRBUF_STOP(e) \
+ do { \
+ Tcl_DecrRefCount(str); \
+ str = NULL; \
+ L_lloc.beg = str_beg; \
+ L_lloc.end = (e); \
+ } while (0)
+
+/*
+ * Keep track of the current offset in the input string.
+ * YY_USER_ACTION is run before each action. Note that some actions
+ * further modify L_lloc.
+ */
+
+#define YY_USER_ACTION yy_user_action();
+
+private void
+yy_user_action()
+{
+ L->prev_token_off = L->token_off;
+ L->token_off += L->prev_token_len;
+ L->prev_token_len = L_leng;
+
+ L_lloc.beg = L->token_off;
+ L_lloc.end = L->token_off + L_leng;
+
+ tally_newlines(L_text, L_leng, 1);
+ L_lloc.line = L->line;
+
+ L_lloc.file = L->file;
+
+ /*
+ * Build up in L->script the text that the scanner scans.
+ * The compiler later passes this on to tcl as the script
+ * source. This allows include() stmts to be handled properly.
+ */
+ Tcl_AppendToObj(L->script, L_text, L_leng);
+ L->script_len += L_leng;
+}
+
+/*
+ * Un-do the effects of the YY_USER_ACTION on the token offset
+ * tracking. This is useful in include() processing where the
+ * characters in the '#include "file"' must be ignored.
+ */
+private void
+undo_yy_user_action()
+{
+ L->prev_token_len = L->token_off - L->prev_token_off;
+ L->token_off = L->prev_token_off;
+
+ L_lloc.beg = L->prev_token_off;
+ L_lloc.end = L->prev_token_off + L->prev_token_len;
+
+ tally_newlines(L_text, L_leng, -1);
+ L_lloc.line = L->line;
+
+ L->script_len -= L_leng;
+ Tcl_SetObjLength(L->script, L->script_len);
+}
+
+/*
+ * Inject the given string into the L script text, but do not give it
+ * to the scanner. This is useful for inserting #line directives (for
+ * #include's) which need to remain in the script so Tcl can see them
+ * but which aren't parsed.
+ */
+private void
+inject(char *s)
+{
+ int len = strlen(s);
+
+ L->prev_token_len += len;
+
+ Tcl_AppendToObj(L->script, s, len);
+ L->script_len += len;
+}
+
+/*
+ * Count the newlines in a string and add the number to L->line. Pass
+ * in tally == 1 to count them and tally == -1 to undo it.
+ */
+private void
+tally_newlines(char *s, int len, int tally)
+{
+ char *end, *p;
+
+ for (p = s, end = p + len; p < end; p++) {
+ if (*p == '\n') {
+ L->line += tally;
+ } else if ((*p == '\r') && ((p+1) < end) && (*(p+1) != '\n')) {
+ /* Mac line endings. */
+ L->line += tally;
+ }
+ }
+}
+
+private Tcl_Channel
+include_try(Tcl_Obj *fileObj, int *found)
+{
+ int new;
+ Tcl_Channel chan;
+ char *file = Tcl_GetString(fileObj);
+ char *path;
+ Tcl_Obj *pathObj;
+
+ /*
+ * See if the normalized path has been included before. If the path
+ * isn't absolute, consider it to be relative to where L->file is.
+ */
+ if (Tcl_FSGetPathType(fileObj) == TCL_PATH_ABSOLUTE) {
+ if ((pathObj = Tcl_FSGetNormalizedPath(NULL, fileObj)) == NULL){
+ L_err("unable to normalize include file %s", file);
+ return (NULL);
+ }
+ } else {
+ pathObj = Tcl_ObjPrintf("%s/%s", L->dir, file);
+ }
+ Tcl_IncrRefCount(pathObj);
+
+ path = Tcl_GetString(pathObj);
+ Tcl_CreateHashEntry(include_table, path, &new);
+ if (new) {
+ chan = Tcl_FSOpenFileChannel(L->interp, pathObj, "r", 0666);
+ *found = (chan != NULL);
+ return (chan);
+ } else {
+ *found = 1; // already included
+ return (NULL);
+ }
+ Tcl_DecrRefCount(pathObj);
+}
+
+/*
+ * Search for an include file. If the path is absolute, use it.
+ * Else, for #include <file> (cwdOnly == 0) try
+ * $BIN/include (where BIN is where the running tclsh lives)
+ * /usr/local/include/L
+ * /usr/include/L
+ * For #include "file" (cwdOnly == 1) look only in the directory
+ * where the script doing the #include resides.
+ */
+private Tcl_Channel
+include_search(char *file, char **path, int cwdOnly)
+{
+ int found, len;
+ Tcl_Channel chan;
+ Tcl_Obj *binObj = NULL;
+ Tcl_Obj *fileObj;
+
+ unless (include_table) {
+ include_table = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
+ Tcl_InitHashTable(include_table, TCL_STRING_KEYS);
+ }
+
+ fileObj = Tcl_NewStringObj(file, -1);
+ Tcl_IncrRefCount(fileObj);
+ if ((Tcl_FSGetPathType(fileObj) == TCL_PATH_ABSOLUTE) || cwdOnly) {
+ chan = include_try(fileObj, &found);
+ } else {
+ /* Try $BIN/include */
+ binObj = TclGetObjNameOfExecutable();
+ Tcl_GetStringFromObj(binObj, &len);
+ if (len > 0) {
+ Tcl_DecrRefCount(fileObj);
+ /* TclPathPart bumps the ref count. */
+ fileObj = TclPathPart(L->interp, binObj,
+ TCL_PATH_DIRNAME);
+ Tcl_AppendPrintfToObj(fileObj, "/include/%s", file);
+ chan = include_try(fileObj, &found);
+ if (found) goto done;
+ }
+ /* Try /usr/local/include/L */
+ Tcl_DecrRefCount(fileObj);
+ fileObj = Tcl_ObjPrintf("/usr/local/include/L/%s", file);
+ Tcl_IncrRefCount(fileObj);
+ chan = include_try(fileObj, &found);
+ if (found) goto done;
+ /* Try /usr/include/L */
+ Tcl_DecrRefCount(fileObj);
+ fileObj = Tcl_ObjPrintf("/usr/include/L/%s", file);
+ Tcl_IncrRefCount(fileObj);
+ chan = include_try(fileObj, &found);
+ }
+ done:
+ unless (found) {
+ L_err("cannot find include file %s", file);
+ }
+ if (path) *path = ckstrdup(Tcl_GetString(fileObj));
+ Tcl_DecrRefCount(fileObj);
+ return (chan);
+}
+
+private int
+include_push(Tcl_Channel chan, char *name)
+{
+ YY_BUFFER_STATE buf;
+ Tcl_Obj *objPtr;
+ char *dec = NULL, *script;
+ int len, ret;
+
+ /* Read the file into memory. */
+ objPtr = Tcl_NewObj();
+ Tcl_IncrRefCount(objPtr);
+ if (Tcl_ReadChars(chan, objPtr, -1, 0) < 0) {
+ Tcl_Close(L->interp, chan);
+ L_err("error reading include file %s", name);
+ return (0);
+ }
+ Tcl_Close(L->interp, chan);
+
+ /* If it is encrypted, decrypt it. */
+ script = Tcl_GetStringFromObj(objPtr, &len);
+
+ /* Create a new flex buffer with the file contents. */
+ if (include_top >= INCLUDE_STACK_SZ) {
+ L_err("include file nesting too deep -- aborting");
+ while (include_pop()) ;
+ ret = 0;
+ } else {
+ ++include_top;
+ include_stk[include_top].name = L->file;
+ include_stk[include_top].dir = L->dir;
+ include_stk[include_top].line = L->line;
+ include_stk[include_top].buf = YY_CURRENT_BUFFER;
+ buf = L__scan_bytes(script,len);
+ L->file = name;
+ L->dir = L_dirname(L->file);
+ L->line = 1;
+ inject("#line 1\n");
+ ret = 1;
+ }
+ Tcl_DecrRefCount(objPtr);
+ if (dec) ckfree(dec);
+ return (ret);
+}
+
+private int
+include_pop()
+{
+ char *s;
+
+ if (include_top >= 0) {
+ L->file = include_stk[include_top].name;
+ L->dir = include_stk[include_top].dir;
+ L->line = include_stk[include_top].line;
+ L__delete_buffer(YY_CURRENT_BUFFER);
+ L__switch_to_buffer(include_stk[include_top].buf);
+ --include_top;
+ s = cksprintf("#line %d\n", L->line);
+ inject(s);
+ ckfree(s);
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+/*
+ * Given a decimal, hex, or octal integer constant of arbitrary
+ * precision, return a canonical string representation. This is done
+ * by converting it to a bignum and then taking its string rep.
+ */
+private char *
+canonical_num(char *num)
+{
+ char *ret;
+ Tcl_Obj *obj;
+ mp_int big;
+
+ obj = Tcl_NewStringObj(num, -1);
+ Tcl_IncrRefCount(obj);
+ Tcl_TakeBignumFromObj(NULL, obj, &big);
+ Tcl_SetBignumObj(obj, &big);
+ ret = ckstrdup(Tcl_GetString(obj));
+ Tcl_DecrRefCount(obj);
+ return (ret);
+}
+
+/*
+ * Work around a Windows problem where our getopt type conficts
+ * with the system's.
+ */
+#undef getopt
+#undef optarg
+#undef optind
+
+#line 1605 "<stdout>"
+
+#define INITIAL 0
+#define re_delim 1
+#define re_modifier 2
+#define re_arg_split 3
+#define re_arg_case 4
+#define glob_re 5
+#define subst_re 6
+#define comment 7
+#define str_double 8
+#define str_single 9
+#define str_backtick 10
+#define interpol 11
+#define here_doc_interp 12
+#define here_doc_nointerp 13
+#define eat_through_eol 14
+#define lhtml 15
+#define lhtml_expr_start 16
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int L_lex_destroy (void );
+
+int L_get_debug (void );
+
+void L_set_debug (int debug_flag );
+
+YY_EXTRA_TYPE L_get_extra (void );
+
+void L_set_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *L_get_in (void );
+
+void L_set_in (FILE * in_str );
+
+FILE *L_get_out (void );
+
+void L_set_out (FILE * out_str );
+
+yy_size_t L_get_leng (void );
+
+char *L_get_text (void );
+
+int L_get_lineno (void );
+
+void L_set_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int L_wrap (void );
+#else
+extern int L_wrap (void );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+ static int yy_start_stack_ptr = 0;
+ static int yy_start_stack_depth = 0;
+ static int *yy_start_stack = NULL;
+
+ static void yy_push_state (int new_state );
+
+ static void yy_pop_state (void );
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#ifdef __ia64__
+/* On IA-64, the buffer size is 16k, not 8k */
+#define YY_READ_BUF_SIZE 16384
+#else
+#define YY_READ_BUF_SIZE 8192
+#endif /* __ia64__ */
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( L_text, L_leng, 1, L_out )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ size_t n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( L_in )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( L_in ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, L_in))==0 && ferror(L_in)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(L_in); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int L_lex (void);
+
+#define YY_DECL int L_lex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after L_text and L_leng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ if ( L_leng > 0 ) \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = \
+ (L_text[L_leng - 1] == '\n'); \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ /* Create the reject buffer large enough to save one state per allowed character. */
+ if ( ! (yy_state_buf) )
+ (yy_state_buf) = (yy_state_type *)L_alloc(YY_STATE_BUF_SIZE );
+ if ( ! (yy_state_buf) )
+ YY_FATAL_ERROR( "out of dynamic memory in L_lex()" );
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! L_in )
+ L_in = stdin;
+
+ if ( ! L_out )
+ L_out = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ L_ensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ L__create_buffer(L_in,YY_BUF_SIZE );
+ }
+
+ L__load_buffer_state( );
+ }
+
+ {
+#line 374 "../generic/Lscanner.l"
+
+#line 1854 "<stdout>"
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of L_text. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+
+ (yy_state_ptr) = (yy_state_buf);
+ *(yy_state_ptr)++ = yy_current_state;
+
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)] ;
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 583 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ *(yy_state_ptr)++ = yy_current_state;
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 2002 );
+
+yy_find_action:
+ yy_current_state = *--(yy_state_ptr);
+ (yy_lp) = yy_accept[yy_current_state];
+find_rule: /* we branch to this label when backing up */
+ for ( ; ; ) /* until we find what rule we matched */
+ {
+ if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] )
+ {
+ yy_act = yy_acclist[(yy_lp)];
+ {
+ (yy_full_match) = yy_cp;
+ break;
+ }
+ }
+ --yy_cp;
+ yy_current_state = *--(yy_state_ptr);
+ (yy_lp) = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+
+case 1:
+YY_RULE_SETUP
+#line 376 "../generic/Lscanner.l"
+return T_LPAREN;
+ YY_BREAK
+case 2:
+YY_RULE_SETUP
+#line 377 "../generic/Lscanner.l"
+return T_RPAREN;
+ YY_BREAK
+case 3:
+YY_RULE_SETUP
+#line 378 "../generic/Lscanner.l"
+interpol_lbrace(); return T_LBRACE;
+ YY_BREAK
+case 4:
+YY_RULE_SETUP
+#line 379 "../generic/Lscanner.l"
+return T_LBRACKET;
+ YY_BREAK
+case 5:
+YY_RULE_SETUP
+#line 380 "../generic/Lscanner.l"
+return T_RBRACKET;
+ YY_BREAK
+case 6:
+YY_RULE_SETUP
+#line 381 "../generic/Lscanner.l"
+return T_COMMA;
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 382 "../generic/Lscanner.l"
+return T_BANG;
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 383 "../generic/Lscanner.l"
+return T_PLUS;
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 384 "../generic/Lscanner.l"
+return T_MINUS;
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 385 "../generic/Lscanner.l"
+return T_STAR;
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 386 "../generic/Lscanner.l"
+return T_SLASH;
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 387 "../generic/Lscanner.l"
+return T_PERC;
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 388 "../generic/Lscanner.l"
+return T_EQPLUS;
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 389 "../generic/Lscanner.l"
+return T_EQMINUS;
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 390 "../generic/Lscanner.l"
+return T_EQSTAR;
+ YY_BREAK
+case 16:
+YY_RULE_SETUP
+#line 391 "../generic/Lscanner.l"
+return T_EQSLASH;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 392 "../generic/Lscanner.l"
+return T_EQPERC;
+ YY_BREAK
+case 18:
+YY_RULE_SETUP
+#line 393 "../generic/Lscanner.l"
+return T_EQBITAND;
+ YY_BREAK
+case 19:
+YY_RULE_SETUP
+#line 394 "../generic/Lscanner.l"
+return T_EQBITOR;
+ YY_BREAK
+case 20:
+YY_RULE_SETUP
+#line 395 "../generic/Lscanner.l"
+return T_EQBITXOR;
+ YY_BREAK
+case 21:
+YY_RULE_SETUP
+#line 396 "../generic/Lscanner.l"
+return T_EQLSHIFT;
+ YY_BREAK
+case 22:
+YY_RULE_SETUP
+#line 397 "../generic/Lscanner.l"
+return T_EQRSHIFT;
+ YY_BREAK
+case 23:
+YY_RULE_SETUP
+#line 398 "../generic/Lscanner.l"
+return T_EQDOT;
+ YY_BREAK
+case 24:
+YY_RULE_SETUP
+#line 399 "../generic/Lscanner.l"
+return T_PLUSPLUS;
+ YY_BREAK
+case 25:
+YY_RULE_SETUP
+#line 400 "../generic/Lscanner.l"
+return T_MINUSMINUS;
+ YY_BREAK
+case 26:
+YY_RULE_SETUP
+#line 401 "../generic/Lscanner.l"
+return T_ANDAND;
+ YY_BREAK
+case 27:
+YY_RULE_SETUP
+#line 402 "../generic/Lscanner.l"
+return T_OROR;
+ YY_BREAK
+case 28:
+YY_RULE_SETUP
+#line 403 "../generic/Lscanner.l"
+return T_BITAND;
+ YY_BREAK
+case 29:
+YY_RULE_SETUP
+#line 404 "../generic/Lscanner.l"
+return T_BITOR;
+ YY_BREAK
+case 30:
+YY_RULE_SETUP
+#line 405 "../generic/Lscanner.l"
+return T_BITXOR;
+ YY_BREAK
+case 31:
+YY_RULE_SETUP
+#line 406 "../generic/Lscanner.l"
+return T_BITNOT;
+ YY_BREAK
+case 32:
+YY_RULE_SETUP
+#line 407 "../generic/Lscanner.l"
+return T_LSHIFT;
+ YY_BREAK
+case 33:
+YY_RULE_SETUP
+#line 408 "../generic/Lscanner.l"
+return T_RSHIFT;
+ YY_BREAK
+case 34:
+YY_RULE_SETUP
+#line 409 "../generic/Lscanner.l"
+return T_EQUALS;
+ YY_BREAK
+case 35:
+YY_RULE_SETUP
+#line 410 "../generic/Lscanner.l"
+return T_SEMI;
+ YY_BREAK
+case 36:
+YY_RULE_SETUP
+#line 411 "../generic/Lscanner.l"
+return T_DOT;
+ YY_BREAK
+case 37:
+/* rule 37 can match eol */
+YY_RULE_SETUP
+#line 412 "../generic/Lscanner.l"
+return T_STRCAT;
+ YY_BREAK
+case 38:
+YY_RULE_SETUP
+#line 413 "../generic/Lscanner.l"
+return T_DOTDOT;
+ YY_BREAK
+case 39:
+YY_RULE_SETUP
+#line 414 "../generic/Lscanner.l"
+return T_ELLIPSIS;
+ YY_BREAK
+case 40:
+YY_RULE_SETUP
+#line 415 "../generic/Lscanner.l"
+return T_CLASS;
+ YY_BREAK
+case 41:
+YY_RULE_SETUP
+#line 416 "../generic/Lscanner.l"
+return T_EXTERN;
+ YY_BREAK
+case 42:
+YY_RULE_SETUP
+#line 417 "../generic/Lscanner.l"
+return T_RETURN;
+ YY_BREAK
+case 43:
+YY_RULE_SETUP
+#line 418 "../generic/Lscanner.l"
+return T_VOID;
+ YY_BREAK
+case 44:
+YY_RULE_SETUP
+#line 419 "../generic/Lscanner.l"
+return T_STRING;
+ YY_BREAK
+case 45:
+YY_RULE_SETUP
+#line 420 "../generic/Lscanner.l"
+return T_WIDGET;
+ YY_BREAK
+case 46:
+YY_RULE_SETUP
+#line 421 "../generic/Lscanner.l"
+return T_INT;
+ YY_BREAK
+case 47:
+YY_RULE_SETUP
+#line 422 "../generic/Lscanner.l"
+return T_FLOAT;
+ YY_BREAK
+case 48:
+YY_RULE_SETUP
+#line 423 "../generic/Lscanner.l"
+return T_POLY;
+ YY_BREAK
+case 49:
+YY_RULE_SETUP
+#line 424 "../generic/Lscanner.l"
+return T_SPLIT;
+ YY_BREAK
+case 50:
+YY_RULE_SETUP
+#line 425 "../generic/Lscanner.l"
+return T_IF;
+ YY_BREAK
+case 51:
+YY_RULE_SETUP
+#line 426 "../generic/Lscanner.l"
+return T_ELSE;
+ YY_BREAK
+case 52:
+YY_RULE_SETUP
+#line 427 "../generic/Lscanner.l"
+return T_UNLESS;
+ YY_BREAK
+case 53:
+YY_RULE_SETUP
+#line 428 "../generic/Lscanner.l"
+return T_WHILE;
+ YY_BREAK
+case 54:
+YY_RULE_SETUP
+#line 429 "../generic/Lscanner.l"
+return T_DO;
+ YY_BREAK
+case 55:
+YY_RULE_SETUP
+#line 430 "../generic/Lscanner.l"
+return T_FOR;
+ YY_BREAK
+case 56:
+YY_RULE_SETUP
+#line 431 "../generic/Lscanner.l"
+return T_STRUCT;
+ YY_BREAK
+case 57:
+YY_RULE_SETUP
+#line 432 "../generic/Lscanner.l"
+return T_TYPEDEF;
+ YY_BREAK
+case 58:
+YY_RULE_SETUP
+#line 433 "../generic/Lscanner.l"
+return T_DEFINED;
+ YY_BREAK
+case 59:
+YY_RULE_SETUP
+#line 434 "../generic/Lscanner.l"
+return T_FOREACH;
+ YY_BREAK
+case 60:
+YY_RULE_SETUP
+#line 435 "../generic/Lscanner.l"
+return T_BREAK;
+ YY_BREAK
+case 61:
+YY_RULE_SETUP
+#line 436 "../generic/Lscanner.l"
+return T_CONTINUE;
+ YY_BREAK
+case 62:
+YY_RULE_SETUP
+#line 437 "../generic/Lscanner.l"
+return T_INSTANCE;
+ YY_BREAK
+case 63:
+YY_RULE_SETUP
+#line 438 "../generic/Lscanner.l"
+return T_PRIVATE;
+ YY_BREAK
+case 64:
+YY_RULE_SETUP
+#line 439 "../generic/Lscanner.l"
+return T_PUBLIC;
+ YY_BREAK
+case 65:
+YY_RULE_SETUP
+#line 440 "../generic/Lscanner.l"
+return T_CONSTRUCTOR;
+ YY_BREAK
+case 66:
+YY_RULE_SETUP
+#line 441 "../generic/Lscanner.l"
+return T_DESTRUCTOR;
+ YY_BREAK
+case 67:
+YY_RULE_SETUP
+#line 442 "../generic/Lscanner.l"
+return T_EXPAND;
+ YY_BREAK
+case 68:
+YY_RULE_SETUP
+#line 443 "../generic/Lscanner.l"
+return T_ARGUSED;
+ YY_BREAK
+case 69:
+YY_RULE_SETUP
+#line 444 "../generic/Lscanner.l"
+return T_ATTRIBUTE;
+ YY_BREAK
+case 70:
+YY_RULE_SETUP
+#line 445 "../generic/Lscanner.l"
+return T_ATTRIBUTE;
+ YY_BREAK
+case 71:
+YY_RULE_SETUP
+#line 446 "../generic/Lscanner.l"
+return T_OPTIONAL;
+ YY_BREAK
+case 72:
+YY_RULE_SETUP
+#line 447 "../generic/Lscanner.l"
+return T_MUSTBETYPE;
+ YY_BREAK
+case 73:
+YY_RULE_SETUP
+#line 448 "../generic/Lscanner.l"
+return T_GOTO;
+ YY_BREAK
+case 74:
+YY_RULE_SETUP
+#line 449 "../generic/Lscanner.l"
+return T_SWITCH;
+ YY_BREAK
+case 75:
+YY_RULE_SETUP
+#line 450 "../generic/Lscanner.l"
+return T_CASE;
+ YY_BREAK
+case 76:
+YY_RULE_SETUP
+#line 451 "../generic/Lscanner.l"
+return T_DEFAULT;
+ YY_BREAK
+case 77:
+YY_RULE_SETUP
+#line 452 "../generic/Lscanner.l"
+return T_TRY;
+ YY_BREAK
+case 78:
+YY_RULE_SETUP
+#line 453 "../generic/Lscanner.l"
+return T_ARROW;
+ YY_BREAK
+case 79:
+YY_RULE_SETUP
+#line 454 "../generic/Lscanner.l"
+return T_EQ;
+ YY_BREAK
+case 80:
+YY_RULE_SETUP
+#line 455 "../generic/Lscanner.l"
+return T_NE;
+ YY_BREAK
+case 81:
+YY_RULE_SETUP
+#line 456 "../generic/Lscanner.l"
+return T_LT;
+ YY_BREAK
+case 82:
+YY_RULE_SETUP
+#line 457 "../generic/Lscanner.l"
+return T_LE;
+ YY_BREAK
+case 83:
+YY_RULE_SETUP
+#line 458 "../generic/Lscanner.l"
+return T_GT;
+ YY_BREAK
+case 84:
+YY_RULE_SETUP
+#line 459 "../generic/Lscanner.l"
+return T_GE;
+ YY_BREAK
+case 85:
+YY_RULE_SETUP
+#line 460 "../generic/Lscanner.l"
+return T_EQUALEQUAL;
+ YY_BREAK
+case 86:
+YY_RULE_SETUP
+#line 461 "../generic/Lscanner.l"
+return T_NOTEQUAL;
+ YY_BREAK
+case 87:
+YY_RULE_SETUP
+#line 462 "../generic/Lscanner.l"
+return T_GREATER;
+ YY_BREAK
+case 88:
+YY_RULE_SETUP
+#line 463 "../generic/Lscanner.l"
+return T_GREATEREQ;
+ YY_BREAK
+case 89:
+YY_RULE_SETUP
+#line 464 "../generic/Lscanner.l"
+return T_LESSTHAN;
+ YY_BREAK
+case 90:
+YY_RULE_SETUP
+#line 465 "../generic/Lscanner.l"
+return T_LESSTHANEQ;
+ YY_BREAK
+case 91:
+YY_RULE_SETUP
+#line 466 "../generic/Lscanner.l"
+return T_POINTS;
+ YY_BREAK
+case 92:
+YY_RULE_SETUP
+#line 467 "../generic/Lscanner.l"
+return T_COLON;
+ YY_BREAK
+case 93:
+YY_RULE_SETUP
+#line 468 "../generic/Lscanner.l"
+return T_QUESTION;
+ YY_BREAK
+case 94:
+YY_RULE_SETUP
+#line 469 "../generic/Lscanner.l"
+{
+ /*
+ * ?> marks the end of a script or expr
+ * inside of an lhtml document but is a
+ * syntax error otherwise.
+ */
+ unless (in_lhtml) {
+ undo_yy_user_action();
+ REJECT;
+ }
+ yy_pop_state();
+ STRBUF_START(L_lloc.end);
+ if (YYSTATE == lhtml_expr_start) {
+ yy_pop_state(); // pop back to lhtml
+ ASSERT(YYSTATE == lhtml);
+ return T_LHTML_EXPR_END;
+ }
+ }
+ YY_BREAK
+case 95:
+YY_RULE_SETUP
+#line 487 "../generic/Lscanner.l"
+{
+ L_err("'and','or','xor','not' are "
+ "unimplemented reserved words");
+ return T_ANDAND;
+ }
+ YY_BREAK
+case 96:
+YY_RULE_SETUP
+#line 492 "../generic/Lscanner.l"
+{
+ L_err("'and','or','xor','not' are "
+ "unimplemented reserved words");
+ return T_BANG;
+ }
+ YY_BREAK
+case 97:
+YY_RULE_SETUP
+#line 497 "../generic/Lscanner.l"
+{
+ L_err("'and','or','xor','not' are "
+ "unimplemented reserved words");
+ return T_OROR;
+ }
+ YY_BREAK
+case 98:
+YY_RULE_SETUP
+#line 502 "../generic/Lscanner.l"
+{
+ L_err("'and','or','xor','not' are "
+ "unimplemented reserved words");
+ return T_BITXOR;
+ }
+ YY_BREAK
+case 99:
+YY_RULE_SETUP
+#line 507 "../generic/Lscanner.l"
+{
+ Type *t = L_typedef_lookup(L_text);
+ if (t) {
+ L_lval.Typename.s = ckstrdup(L_text);
+ L_lval.Typename.t = t;
+ return T_TYPE;
+ } else {
+ L_lval.s = ckstrdup(L_text);
+ return T_ID;
+ }
+ }
+ YY_BREAK
+case 100:
+YY_RULE_SETUP
+#line 518 "../generic/Lscanner.l"
+{
+ /*
+ * Push back the : and return a T_ID
+ * unless it's "default". The grammar relies
+ * on this to avoid a nasty conflict.
+ */
+ put_back(':');
+ if (!strncmp(L_text, "default", 7)) {
+ return T_DEFAULT;
+ }
+ L_lval.s = ckstrdup(L_text);
+ L_lval.s[L_leng-1] = 0;
+ return T_ID;
+ }
+ YY_BREAK
+case 101:
+YY_RULE_SETUP
+#line 532 "../generic/Lscanner.l"
+{
+ L_lval.s = ckstrdup(L_text);
+ return T_PATTERN;
+ }
+ YY_BREAK
+case 102:
+YY_RULE_SETUP
+#line 536 "../generic/Lscanner.l"
+{
+ /* Regular expression submatches */
+ L_lval.s = ckstrdup(L_text);
+ return T_ID;
+ }
+ YY_BREAK
+case 103:
+YY_RULE_SETUP
+#line 541 "../generic/Lscanner.l"
+{
+ /*
+ * Skip any leading 0's which would
+ * make it look like octal to Tcl.
+ */
+ size_t z = strspn(L_text, "0");
+ if (z == L_leng) z = 0; // number is all 0's
+ L_lval.s = canonical_num(L_text+z);
+ return T_INT_LITERAL;
+ }
+ YY_BREAK
+case 104:
+YY_RULE_SETUP
+#line 551 "../generic/Lscanner.l"
+{
+ /*
+ * Create a leading 0 so it looks like
+ * octal to Tcl.
+ */
+ L_text[1] = '0';
+ L_lval.s = canonical_num(L_text+1);
+ return T_INT_LITERAL;
+ }
+ YY_BREAK
+case 105:
+YY_RULE_SETUP
+#line 560 "../generic/Lscanner.l"
+{
+ L_lval.s = canonical_num(L_text);
+ return T_INT_LITERAL;
+ }
+ YY_BREAK
+case 106:
+YY_RULE_SETUP
+#line 564 "../generic/Lscanner.l"
+{
+ L_lval.s = ckstrdup(L_text);
+ return T_FLOAT_LITERAL;
+ }
+ YY_BREAK
+case 107:
+/* rule 107 can match eol */
+YY_RULE_SETUP
+#line 568 "../generic/Lscanner.l"
+{
+ int line = strtoul(L_text+5, NULL, 10);
+
+ if (line <= 0) {
+ --L->line; // since \n already scanned
+ L_err("malformed #line");
+ ++L->line;
+ } else {
+ L->line = line;
+ }
+ }
+ YY_BREAK
+case 108:
+/* rule 108 can match eol */
+YY_RULE_SETUP
+#line 579 "../generic/Lscanner.l"
+{
+ int line = strtoul(L_text+5, NULL, 10);
+ char *beg = strchr(L_text, '"') + 1;
+ char *end = strrchr(L_text, '"');
+ char *name = ckstrndup(beg, end-beg);
+
+ if (line <= 0) {
+ --L->line; // since \n already scanned
+ L_err("malformed #line");
+ ++L->line;
+ } else {
+ L->file = name;
+ L->line = line;
+ }
+ }
+ YY_BREAK
+case 109:
+/* rule 109 can match eol */
+YY_RULE_SETUP
+#line 594 "../generic/Lscanner.l"
+{
+ --L->line; // since \n already scanned
+ L_err("malformed #line");
+ ++L->line;
+ }
+ YY_BREAK
+case 110:
+YY_RULE_SETUP
+#line 599 "../generic/Lscanner.l"
+{
+ char *beg = strchr(L_text, '"') + 1;
+ char *end = strrchr(L_text, '"');
+ char *name = ckstrndup(beg, end-beg);
+ Tcl_Channel chan;
+
+ chan = include_search(name, NULL, 1);
+
+ undo_yy_user_action();
+ if (chan && !include_push(chan, name)) {
+ /* Bail if includes nest too deeply. */
+ yyterminate();
+ }
+ }
+ YY_BREAK
+case 111:
+YY_RULE_SETUP
+#line 613 "../generic/Lscanner.l"
+{
+ char *beg = strchr(L_text, '<') + 1;
+ char *end = strrchr(L_text, '>');
+ char *name = ckstrndup(beg, end-beg);
+ char *path = NULL;
+ Tcl_Channel chan;
+
+ chan = include_search(name, &path, 0);
+ ckfree(name);
+
+ undo_yy_user_action();
+ if (chan && !include_push(chan, path)) {
+ /* Bail if includes nest too deeply. */
+ yyterminate();
+ }
+ }
+ YY_BREAK
+case 112:
+YY_RULE_SETUP
+#line 629 "../generic/Lscanner.l"
+{
+ L_err("malformed #include");
+ yy_push_state(eat_through_eol);
+ }
+ YY_BREAK
+case 113:
+YY_RULE_SETUP
+#line 633 "../generic/Lscanner.l"
+return T_PRAGMA;
+ YY_BREAK
+case 114:
+/* rule 114 can match eol */
+YY_RULE_SETUP
+#line 634 "../generic/Lscanner.l"
+{
+ /*
+ * Rather than using a start condition
+ * to separate out all the ^# patterns
+ * that don't end in \n, this is
+ * simpler. If it's not a comment,
+ * REJECT it so that flex then takes
+ * the second best rule (those above).
+ */
+ if (!strncmp(L_text, "#pragma ", 8) ||
+ !strncmp(L_text, "#pragma\t", 8)) {
+ undo_yy_user_action();
+ REJECT;
+ } else if (!strncmp(L_text, "#include", 8)) {
+ undo_yy_user_action();
+ REJECT;
+ } else unless (L->line == 2) {
+ --L->line; // since \n already scanned
+ L_err("# comment valid only on line 1");
+ ++L->line;
+ }
+ }
+ YY_BREAK
+case 115:
+/* rule 115 can match eol */
+YY_RULE_SETUP
+#line 656 "../generic/Lscanner.l"
+{
+ --L->line; // since \n already scanned
+ unless (L->line == 1) {
+ L_err("# comment valid only on line 1");
+ } else {
+ L_err("# comment must start at "
+ "first column");
+ }
+ ++L->line;
+ }
+ YY_BREAK
+case 116:
+/* rule 116 can match eol */
+YY_RULE_SETUP
+#line 666 "../generic/Lscanner.l"
+
+ YY_BREAK
+case 117:
+YY_RULE_SETUP
+#line 667 "../generic/Lscanner.l"
+
+ YY_BREAK
+case 118:
+/* rule 118 can match eol */
+YY_RULE_SETUP
+#line 668 "../generic/Lscanner.l"
+
+ YY_BREAK
+case 119:
+YY_RULE_SETUP
+#line 669 "../generic/Lscanner.l"
+yy_push_state(str_double); STRBUF_START(L->token_off);
+ YY_BREAK
+case 120:
+YY_RULE_SETUP
+#line 670 "../generic/Lscanner.l"
+yy_push_state(str_single); STRBUF_START(L->token_off);
+ YY_BREAK
+case 121:
+YY_RULE_SETUP
+#line 671 "../generic/Lscanner.l"
+yy_push_state(str_backtick); STRBUF_START(L->token_off);
+ YY_BREAK
+case 122:
+YY_RULE_SETUP
+#line 672 "../generic/Lscanner.l"
+yy_push_state(comment);
+ YY_BREAK
+case 123:
+/* rule 123 can match eol */
+YY_RULE_SETUP
+#line 673 "../generic/Lscanner.l"
+{
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 2); // next token starts at the "m"
+ extract_re_delims(L_text[L_leng-1]);
+ L_lloc.end = L_lloc.beg + 2; // this token spans the "=~"
+ return ((L_text[0] == '=') ? T_EQTWID : T_BANGTWID);
+ }
+ YY_BREAK
+/* if / is used to delimit the regexp, the m can be omitted */
+case 124:
+/* rule 124 can match eol */
+YY_RULE_SETUP
+#line 682 "../generic/Lscanner.l"
+{
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the "/"
+ extract_re_delims('/');
+ L_lloc.end = L_lloc.beg + 2; // this token spans the "=~"
+ return ((L_text[0] == '=') ? T_EQTWID : T_BANGTWID);
+ }
+ YY_BREAK
+/* a substitution pattern */
+case 125:
+/* rule 125 can match eol */
+YY_RULE_SETUP
+#line 691 "../generic/Lscanner.l"
+{
+ yy_push_state(re_modifier);
+ yy_push_state(subst_re);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 2); // next token starts at the "s"
+ extract_re_delims(L_text[L_leng-1]);
+ L_lloc.end = L_lloc.beg + 2; // this token spans the "=~"
+ return T_EQTWID;
+ }
+ YY_BREAK
+/* here document (interpolated), valid only on rhs of an assignment */
+case 126:
+/* rule 126 can match eol */
+YY_RULE_SETUP
+#line 701 "../generic/Lscanner.l"
+{
+ char *p, *q;
+
+ if (here_delim) {
+ L_err("nested here documents illegal");
+ }
+ p = strchr(L_text, '<') + 2; // the < is guaranteed to exist
+ for (q = p; (q > L_text) && (*q != '\n'); --q) ;
+ if ((q > L_text) && (*q == '\n')) {
+ // \n then <<; the in-between whitespace is the here_pfx
+ here_pfx = ckstrndup(q+1, p-q-3);
+ } else {
+ // non-indented here document
+ here_pfx = ckstrdup("");
+ }
+ here_delim = ckstrndup(p, L_leng - (p-L_text) - 1);
+ STRBUF_START(L->token_off);
+ L_lloc.end = L_lloc.beg + 1;
+ yy_push_state(here_doc_interp);
+ return T_EQUALS;
+ }
+ YY_BREAK
+/* here document (uninterpolated), valid only on rhs of an assignment */
+case 127:
+/* rule 127 can match eol */
+YY_RULE_SETUP
+#line 723 "../generic/Lscanner.l"
+{
+ char *p, *q;
+
+ if (here_delim) {
+ L_err("nested here documents illegal");
+ }
+ p = strchr(L_text, '<') + 2; // the < is guaranteed to exist
+ for (q = p; (q > L_text) && (*q != '\n'); --q) ;
+ if ((q > L_text) && (*q == '\n')) {
+ // \n then <<; the in-between whitespace is the here_pfx
+ here_pfx = ckstrndup(q+1, p-q-3);
+ } else {
+ // non-indented here document
+ here_pfx = ckstrdup("");
+ }
+ here_delim = ckstrndup(p+1, L_leng - (p-L_text) - 3);
+ STRBUF_START(L->token_off);
+ L_lloc.end = L_lloc.beg + 1;
+ yy_push_state(here_doc_nointerp);
+ return T_EQUALS;
+ }
+ YY_BREAK
+/* illegal here documents (bad stuff before or after the delim) */
+case 128:
+/* rule 128 can match eol */
+#line 746 "../generic/Lscanner.l"
+case 129:
+/* rule 129 can match eol */
+YY_RULE_SETUP
+#line 746 "../generic/Lscanner.l"
+{
+ L_synerr("<<- unsupported, use =\\n\\t<<END to strip one "
+ "leading tab");
+ }
+ YY_BREAK
+case 130:
+/* rule 130 can match eol */
+YY_RULE_SETUP
+#line 750 "../generic/Lscanner.l"
+{
+ L_synerr("illegal characters after here-document delimeter");
+ }
+ YY_BREAK
+case 131:
+/* rule 131 can match eol */
+YY_RULE_SETUP
+#line 753 "../generic/Lscanner.l"
+{
+ L_synerr("illegal characters before here-document delimeter");
+ }
+ YY_BREAK
+case 132:
+/* rule 132 can match eol */
+YY_RULE_SETUP
+#line 756 "../generic/Lscanner.l"
+{
+ L_synerr("illegal characters after here-document delimeter");
+ }
+ YY_BREAK
+case 133:
+/* rule 133 can match eol */
+YY_RULE_SETUP
+#line 759 "../generic/Lscanner.l"
+{
+ L_synerr("illegal characters before here-document delimeter");
+ }
+ YY_BREAK
+
+
+/*
+ * The compiler prepends a #line directive to Lhtml source.
+ * This communicates the correct line number to the Tcl
+ * code that prints run-time error messages.
+ */
+case 134:
+/* rule 134 can match eol */
+YY_RULE_SETUP
+#line 770 "../generic/Lscanner.l"
+{
+ int line = strtoul(L_text+5, NULL, 10);
+
+ if (line <= 0) {
+ --L->line; // since \n already scanned
+ L_err("malformed #line");
+ ++L->line;
+ } else {
+ L->line = line;
+ }
+ }
+ YY_BREAK
+case 135:
+YY_RULE_SETUP
+#line 781 "../generic/Lscanner.l"
+{
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ if (L_leng == 2) {
+ yy_push_state(INITIAL);
+ } else {
+ yy_push_state(lhtml_expr_start);
+ }
+ return T_HTML;
+ }
+ YY_BREAK
+case 136:
+/* rule 136 can match eol */
+YY_RULE_SETUP
+#line 791 "../generic/Lscanner.l"
+STRBUF_ADD(L_text, L_leng);
+ YY_BREAK
+case YY_STATE_EOF(lhtml):
+#line 792 "../generic/Lscanner.l"
+{
+ unless (STRBUF_STARTED()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_HTML;
+ }
+ YY_BREAK
+
+
+/*
+ * This start condition is here only so the rule for ?> can
+ * know whether we previously scanned <? or <?=.
+ */
+case 137:
+/* rule 137 can match eol */
+YY_RULE_SETUP
+#line 805 "../generic/Lscanner.l"
+{
+ unput(L_text[0]);
+ undo_yy_user_action();
+ yy_push_state(INITIAL);
+ return T_LHTML_EXPR_START;
+ }
+ YY_BREAK
+
+
+/*
+ * A regexp in the context of the first arg to split(). If
+ * it's not an RE, pop the start-condition stack and push it
+ * back, so we can continue as normal.
+ */
+case 138:
+/* rule 138 can match eol */
+YY_RULE_SETUP
+#line 819 "../generic/Lscanner.l"
+
+ YY_BREAK
+/* / starts an RE */
+case 139:
+YY_RULE_SETUP
+#line 821 "../generic/Lscanner.l"
+{
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the "/"
+ extract_re_delims('/');
+ }
+ YY_BREAK
+/*
+ * m<punctuation> starts an RE, except for "m)" so that
+ * "split(m)" works.
+ */
+case 140:
+YY_RULE_SETUP
+#line 831 "../generic/Lscanner.l"
+{
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the delim
+ extract_re_delims(L_text[L_leng-1]);
+ }
+ YY_BREAK
+/* nothing else starts an RE */
+case 141:
+YY_RULE_SETUP
+#line 838 "../generic/Lscanner.l"
+{
+ unput(L_text[0]);
+ undo_yy_user_action();
+ yy_pop_state();
+ }
+ YY_BREAK
+
+
+/*
+ * A regexp in the context of a case statement. If it's not
+ * an RE, pop the start-condition stack and push it back, so
+ * we can continue as normal.
+ */
+case 142:
+/* rule 142 can match eol */
+YY_RULE_SETUP
+#line 851 "../generic/Lscanner.l"
+
+ YY_BREAK
+/* / starts an RE */
+case 143:
+YY_RULE_SETUP
+#line 853 "../generic/Lscanner.l"
+{
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the "/"
+ extract_re_delims('/');
+ }
+ YY_BREAK
+/*
+ * m<punctuation> starts an RE except for "m:" which we scan
+ * as the variable m (so that "case m:" works) or "m(" which
+ * is the start of a call to the function m (so that "case m():"
+ * or "case m(arg):" etc work).
+ */
+case 144:
+YY_RULE_SETUP
+#line 865 "../generic/Lscanner.l"
+{
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the delim
+ extract_re_delims(L_text[L_leng-1]);
+ }
+ YY_BREAK
+/* nothing else starts an RE */
+case 145:
+YY_RULE_SETUP
+#line 872 "../generic/Lscanner.l"
+{
+ unput(L_text[0]);
+ undo_yy_user_action();
+ yy_pop_state();
+ }
+ YY_BREAK
+
+
+case 146:
+YY_RULE_SETUP
+#line 880 "../generic/Lscanner.l"
+return T_RBRACE;
+ YY_BREAK
+
+
+case 147:
+YY_RULE_SETUP
+#line 884 "../generic/Lscanner.l"
+{
+ if (interpol_rbrace()) {
+ STRBUF_START(L_lloc.end);
+ interpol_pop();
+ if ((YYSTATE == glob_re) ||
+ (YYSTATE == subst_re)) {
+ return T_RIGHT_INTERPOL_RE;
+ } else {
+ return T_RIGHT_INTERPOL;
+ }
+ } else {
+ return T_RBRACE;
+ }
+ }
+ YY_BREAK
+case 148:
+YY_RULE_SETUP
+#line 898 "../generic/Lscanner.l"
+{
+ L_synerr("illegal character");
+ }
+ YY_BREAK
+
+
+case 149:
+YY_RULE_SETUP
+#line 904 "../generic/Lscanner.l"
+STRBUF_ADD("\r", 1);
+ YY_BREAK
+case 150:
+YY_RULE_SETUP
+#line 905 "../generic/Lscanner.l"
+STRBUF_ADD("\n", 1);
+ YY_BREAK
+case 151:
+YY_RULE_SETUP
+#line 906 "../generic/Lscanner.l"
+STRBUF_ADD("\t", 1);
+ YY_BREAK
+case 152:
+#line 908 "../generic/Lscanner.l"
+case 153:
+#line 909 "../generic/Lscanner.l"
+case 154:
+#line 910 "../generic/Lscanner.l"
+case 155:
+YY_RULE_SETUP
+#line 910 "../generic/Lscanner.l"
+{
+ char buf[TCL_UTF_MAX];
+ int ch;
+ TclParseHex(L_text+2, 4, &ch);
+ STRBUF_ADD(buf, Tcl_UniCharToUtf(ch, buf));
+ }
+ YY_BREAK
+case 156:
+/* rule 156 can match eol */
+YY_RULE_SETUP
+#line 916 "../generic/Lscanner.l"
+STRBUF_ADD(L_text+1, 1);
+ YY_BREAK
+case 157:
+YY_RULE_SETUP
+#line 917 "../generic/Lscanner.l"
+STRBUF_ADD("$", 1);
+ YY_BREAK
+case 158:
+/* rule 158 can match eol */
+YY_RULE_SETUP
+#line 918 "../generic/Lscanner.l"
+{
+ L_err("missing string terminator \"");
+ STRBUF_ADD("\n", 1);
+ }
+ YY_BREAK
+case 159:
+YY_RULE_SETUP
+#line 922 "../generic/Lscanner.l"
+STRBUF_ADD(L_text, L_leng);
+ YY_BREAK
+case 160:
+YY_RULE_SETUP
+#line 923 "../generic/Lscanner.l"
+{
+ if (interpol_push()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_LEFT_INTERPOL;
+ }
+ YY_BREAK
+case 161:
+/* rule 161 can match eol */
+YY_RULE_SETUP
+#line 929 "../generic/Lscanner.l"
+
+ YY_BREAK
+case 162:
+YY_RULE_SETUP
+#line 930 "../generic/Lscanner.l"
+{
+ yy_pop_state();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ return T_STR_LITERAL;
+ }
+ YY_BREAK
+
+
+case 163:
+YY_RULE_SETUP
+#line 939 "../generic/Lscanner.l"
+STRBUF_ADD("\\", 1);
+ YY_BREAK
+case 164:
+YY_RULE_SETUP
+#line 940 "../generic/Lscanner.l"
+STRBUF_ADD("'", 1);
+ YY_BREAK
+case 165:
+/* rule 165 can match eol */
+YY_RULE_SETUP
+#line 941 "../generic/Lscanner.l"
+STRBUF_ADD("\n", 1);
+ YY_BREAK
+case 166:
+/* rule 166 can match eol */
+YY_RULE_SETUP
+#line 942 "../generic/Lscanner.l"
+{
+ L_err("missing string terminator \'");
+ STRBUF_ADD("\n", 1);
+ }
+ YY_BREAK
+case 167:
+#line 947 "../generic/Lscanner.l"
+case 168:
+YY_RULE_SETUP
+#line 947 "../generic/Lscanner.l"
+STRBUF_ADD(L_text, L_leng);
+ YY_BREAK
+case 169:
+/* rule 169 can match eol */
+YY_RULE_SETUP
+#line 948 "../generic/Lscanner.l"
+
+ YY_BREAK
+case 170:
+YY_RULE_SETUP
+#line 949 "../generic/Lscanner.l"
+{
+ yy_pop_state();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ return T_STR_LITERAL;
+ }
+ YY_BREAK
+
+
+case 171:
+YY_RULE_SETUP
+#line 958 "../generic/Lscanner.l"
+STRBUF_ADD(L_text+1, 1);
+ YY_BREAK
+case 172:
+/* rule 172 can match eol */
+YY_RULE_SETUP
+#line 959 "../generic/Lscanner.l"
+/* ignore \<newline> */
+ YY_BREAK
+case 173:
+#line 961 "../generic/Lscanner.l"
+case 174:
+#line 962 "../generic/Lscanner.l"
+case 175:
+YY_RULE_SETUP
+#line 962 "../generic/Lscanner.l"
+STRBUF_ADD(L_text, L_leng);
+ YY_BREAK
+case 176:
+/* rule 176 can match eol */
+YY_RULE_SETUP
+#line 963 "../generic/Lscanner.l"
+{
+ L_err("missing string terminator `");
+ STRBUF_ADD("\n", 1);
+ }
+ YY_BREAK
+case 177:
+YY_RULE_SETUP
+#line 967 "../generic/Lscanner.l"
+{
+ if (interpol_push()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_LEFT_INTERPOL;
+ }
+ YY_BREAK
+case 178:
+YY_RULE_SETUP
+#line 973 "../generic/Lscanner.l"
+{
+ yy_pop_state();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ if (YYSTATE == here_doc_interp) {
+ STRBUF_START(L_lloc.end);
+ }
+ return T_STR_BACKTICK;
+ }
+ YY_BREAK
+
+
+case 179:
+*yy_cp = (yy_hold_char); /* undo effects of setting up L_text */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up L_text again */
+YY_RULE_SETUP
+#line 985 "../generic/Lscanner.l"
+{
+ int len;
+ char *p = L_text;
+
+ /*
+ * Look for whitespace-prefixed here_delim.
+ * Any amount of white space is allowed.
+ */
+ while (isspace(*p)) ++p;
+ len = L_leng - (p - L_text);
+ if (p[len-1] == ';') --len;
+ if ((len == strlen(here_delim)) &&
+ !strncmp(p, here_delim, len)) {
+ yy_pop_state();
+ unput(';'); // for the parser
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ ckfree(here_delim);
+ ckfree(here_pfx);
+ here_delim = NULL;
+ here_pfx = NULL;
+ return T_STR_LITERAL;
+ }
+ /*
+ * It's a data line. It must begin with
+ * here_pfx or else it's an error.
+ */
+ p = strstr(L_text, here_pfx);
+ if (p == L_text) {
+ p += strlen(here_pfx);
+ } else {
+ L_err("bad here-document prefix");
+ p = L_text;
+ }
+ STRBUF_ADD(p, L_leng - (p - L_text));
+ }
+ YY_BREAK
+case 180:
+YY_RULE_SETUP
+#line 1021 "../generic/Lscanner.l"
+{
+ char *p = strstr(L_text, here_pfx);
+ if (p == L_text) {
+ p += strlen(here_pfx);
+ STRBUF_ADD(p, L_leng - (p - L_text));
+ } else {
+ L_err("bad here-document prefix");
+ p = L_text;
+ }
+ }
+ YY_BREAK
+case 181:
+/* rule 181 can match eol */
+YY_RULE_SETUP
+#line 1031 "../generic/Lscanner.l"
+STRBUF_ADD(L_text, 1);
+ YY_BREAK
+
+
+case 182:
+YY_RULE_SETUP
+#line 1035 "../generic/Lscanner.l"
+STRBUF_ADD("\\", 1);
+ YY_BREAK
+case 183:
+YY_RULE_SETUP
+#line 1036 "../generic/Lscanner.l"
+STRBUF_ADD("$", 1);
+ YY_BREAK
+case 184:
+YY_RULE_SETUP
+#line 1037 "../generic/Lscanner.l"
+STRBUF_ADD("`", 1);
+ YY_BREAK
+case 185:
+/* rule 185 can match eol */
+YY_RULE_SETUP
+#line 1038 "../generic/Lscanner.l"
+// ignore \<newline>
+ YY_BREAK
+case 186:
+YY_RULE_SETUP
+#line 1039 "../generic/Lscanner.l"
+{
+ if (interpol_push()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_LEFT_INTERPOL;
+ }
+ YY_BREAK
+case 187:
+YY_RULE_SETUP
+#line 1045 "../generic/Lscanner.l"
+{
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ yy_push_state(str_backtick);
+ STRBUF_START(L->token_off);
+ return T_START_BACKTICK;
+ }
+ YY_BREAK
+case 188:
+*yy_cp = (yy_hold_char); /* undo effects of setting up L_text */
+(yy_c_buf_p) = yy_cp -= 1;
+YY_DO_BEFORE_ACTION; /* set up L_text again */
+YY_RULE_SETUP
+#line 1052 "../generic/Lscanner.l"
+{
+ int len;
+ char *p = L_text;
+
+ /*
+ * Look for whitespace-prefixed here_delim.
+ * Any amount of white space is allowed.
+ */
+ while (isspace(*p)) ++p;
+ len = L_leng - (p - L_text);
+ if (p[len-1] == ';') --len;
+ if ((len == strlen(here_delim)) &&
+ !strncmp(p, here_delim, len)) {
+ yy_pop_state();
+ unput(';'); // for the parser
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ ckfree(here_delim);
+ ckfree(here_pfx);
+ here_delim = NULL;
+ here_pfx = NULL;
+ return T_STR_LITERAL;
+ }
+ /*
+ * It's a data line. It must begin with
+ * here_pfx or else it's an error.
+ */
+ p = strstr(L_text, here_pfx);
+ if (p == L_text) {
+ p += strlen(here_pfx);
+ } else {
+ L_err("bad here-document prefix");
+ p = L_text;
+ }
+ STRBUF_ADD(p, L_leng - (p - L_text));
+ }
+ YY_BREAK
+case 189:
+YY_RULE_SETUP
+#line 1088 "../generic/Lscanner.l"
+{
+ char *p = strstr(L_text, here_pfx);
+ if (p == L_text) {
+ p += strlen(here_pfx);
+ STRBUF_ADD(p, L_leng - (p - L_text));
+ } else {
+ L_err("bad here-document prefix");
+ p = L_text;
+ }
+ }
+ YY_BREAK
+case 190:
+/* rule 190 can match eol */
+YY_RULE_SETUP
+#line 1098 "../generic/Lscanner.l"
+STRBUF_ADD(L_text, 1);
+ YY_BREAK
+
+
+case 191:
+/* rule 191 can match eol */
+YY_RULE_SETUP
+#line 1102 "../generic/Lscanner.l"
+
+ YY_BREAK
+case 192:
+YY_RULE_SETUP
+#line 1103 "../generic/Lscanner.l"
+
+ YY_BREAK
+case 193:
+YY_RULE_SETUP
+#line 1104 "../generic/Lscanner.l"
+yy_pop_state();
+ YY_BREAK
+
+
+case 194:
+YY_RULE_SETUP
+#line 1108 "../generic/Lscanner.l"
+{
+ if (interpol_push()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_LEFT_INTERPOL_RE;
+ }
+ YY_BREAK
+case 195:
+YY_RULE_SETUP
+#line 1114 "../generic/Lscanner.l"
+{
+ if ((L_text[1] == re_end_delim) ||
+ (L_text[1] == re_start_delim)) {
+ STRBUF_ADD(L_text+1, 1);
+ } else {
+ STRBUF_ADD(L_text, L_leng);
+ }
+ }
+ YY_BREAK
+case 196:
+/* rule 196 can match eol */
+YY_RULE_SETUP
+#line 1122 "../generic/Lscanner.l"
+{
+ --L->line; // since \n already scanned
+ L_err("run-away regular expression");
+ ++L->line;
+ STRBUF_ADD(L_text, L_leng);
+ yy_pop_state();
+ if (YYSTATE == re_modifier) yy_pop_state();
+ return T_RE;
+ }
+ YY_BREAK
+case 197:
+YY_RULE_SETUP
+#line 1131 "../generic/Lscanner.l"
+{
+ // Convert $3 to \3 (regexp capture reference).
+ STRBUF_ADD("\\", 1);
+ STRBUF_ADD(L_text+1, L_leng-1);
+ }
+ YY_BREAK
+case 198:
+YY_RULE_SETUP
+#line 1136 "../generic/Lscanner.l"
+{
+ if (*L_text == re_end_delim) {
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ if (YYSTATE == subst_re) {
+ yy_pop_state();
+ return T_SUBST;
+ } else {
+ yy_pop_state();
+ if (YYSTATE == subst_re) {
+ STRBUF_START(L_lloc.end);
+ if (re_start_delim !=
+ re_end_delim) {
+ yy_push_state(
+ re_delim);
+ }
+ }
+ return T_RE;
+ }
+ } else if (*L_text == re_start_delim) {
+ L_err("regexp delimiter must be quoted "
+ "inside the regexp");
+ STRBUF_ADD(L_text+1, 1);
+ } else {
+ STRBUF_ADD(L_text, L_leng);
+ }
+ }
+ YY_BREAK
+
+
+case 199:
+/* rule 199 can match eol */
+YY_RULE_SETUP
+#line 1167 "../generic/Lscanner.l"
+{
+ --L->line; // since \n already scanned
+ L_err("run-away regular expression");
+ ++L->line;
+ STRBUF_ADD(L_text, L_leng);
+ yy_pop_state();
+ }
+ YY_BREAK
+case 200:
+YY_RULE_SETUP
+#line 1174 "../generic/Lscanner.l"
+{
+ extract_re_delims(*L_text);
+ yy_pop_state();
+ }
+ YY_BREAK
+
+
+case 201:
+YY_RULE_SETUP
+#line 1181 "../generic/Lscanner.l"
+{
+ L_lval.s = ckstrdup(L_text);
+ yy_pop_state();
+ return T_RE_MODIFIER;
+ }
+ YY_BREAK
+case 202:
+/* rule 202 can match eol */
+YY_RULE_SETUP
+#line 1186 "../generic/Lscanner.l"
+{
+ unput(L_text[0]);
+ undo_yy_user_action();
+ yy_pop_state();
+ L_lval.s = ckstrdup("");
+ return T_RE_MODIFIER;
+ }
+ YY_BREAK
+
+
+case 203:
+YY_RULE_SETUP
+#line 1196 "../generic/Lscanner.l"
+
+ YY_BREAK
+case 204:
+/* rule 204 can match eol */
+YY_RULE_SETUP
+#line 1197 "../generic/Lscanner.l"
+yy_pop_state();
+ YY_BREAK
+
+case 205:
+YY_RULE_SETUP
+#line 1200 "../generic/Lscanner.l"
+{
+ /* This rule matches a char if no other does. */
+ L_synerr("illegal character");
+ yyterminate();
+ }
+ YY_BREAK
+case YY_STATE_EOF(INITIAL):
+case YY_STATE_EOF(re_delim):
+case YY_STATE_EOF(re_modifier):
+case YY_STATE_EOF(re_arg_split):
+case YY_STATE_EOF(re_arg_case):
+case YY_STATE_EOF(glob_re):
+case YY_STATE_EOF(subst_re):
+case YY_STATE_EOF(comment):
+case YY_STATE_EOF(str_double):
+case YY_STATE_EOF(str_single):
+case YY_STATE_EOF(str_backtick):
+case YY_STATE_EOF(interpol):
+case YY_STATE_EOF(here_doc_interp):
+case YY_STATE_EOF(here_doc_nointerp):
+case YY_STATE_EOF(eat_through_eol):
+case YY_STATE_EOF(lhtml_expr_start):
+#line 1205 "../generic/Lscanner.l"
+{
+ if (in_lhtml) {
+ yy_user_action(); // for line #s
+ L_synerr("premature EOF");
+ }
+ unless (include_pop()) yyterminate();
+ }
+ YY_BREAK
+case 206:
+YY_RULE_SETUP
+#line 1212 "../generic/Lscanner.l"
+ECHO;
+ YY_BREAK
+#line 3605 "<stdout>"
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed L_in at a new source and called
+ * L_lex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = L_in;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( L_wrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * L_text, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+ } /* end of user's declarations */
+} /* end of L_lex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ yy_size_t num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ L_restart(L_in );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) L_realloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+ yy_current_state += YY_AT_BOL();
+
+ (yy_state_ptr) = (yy_state_buf);
+ *(yy_state_ptr)++ = yy_current_state;
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 583 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ *(yy_state_ptr)++ = yy_current_state;
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+
+ register YY_CHAR yy_c = 1;
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 583 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ yy_is_jam = (yy_current_state == 582);
+ if ( ! yy_is_jam )
+ *(yy_state_ptr)++ = yy_current_state;
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp )
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up L_text */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register yy_size_t number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ yy_size_t offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ L_restart(L_in );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( L_wrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve L_text */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = (c == '\n');
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void L_restart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ L_ensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ L__create_buffer(L_in,YY_BUF_SIZE );
+ }
+
+ L__init_buffer(YY_CURRENT_BUFFER,input_file );
+ L__load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void L__switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * L_pop_buffer_state();
+ * L_push_buffer_state(new_buffer);
+ */
+ L_ensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ L__load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (L_wrap()) processing, but the only time this flag
+ * is looked at is after L_wrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void L__load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ L_in = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE L__create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) L_alloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in L__create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) L_alloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in L__create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ L__init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with L__create_buffer()
+ *
+ */
+ void L__delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ L_free((void *) b->yy_ch_buf );
+
+ L_free((void *) b );
+}
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a L_restart() or at EOF.
+ */
+ static void L__init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ L__flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then L__init_buffer was _probably_
+ * called from L_restart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void L__flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ L__load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void L_push_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ L_ensure_buffer_stack();
+
+ /* This block is copied from L__switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from L__switch_to_buffer. */
+ L__load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void L_pop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ L__delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ L__load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void L_ensure_buffer_stack (void)
+{
+ yy_size_t num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)L_alloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in L_ensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)L_realloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in L_ensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE L__scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) L_alloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in L__scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ L__switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to L_lex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * L__scan_bytes() instead.
+ */
+YY_BUFFER_STATE L__scan_string (yyconst char * yystr )
+{
+
+ return L__scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to L_lex() will
+ * scan from a @e copy of @a bytes.
+ * @param yybytes the byte buffer to scan
+ * @param _yybytes_len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE L__scan_bytes (yyconst char * yybytes, yy_size_t _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ yy_size_t i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) L_alloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in L__scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = L__scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in L__scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+ static void yy_push_state (int new_state )
+{
+ if ( (yy_start_stack_ptr) >= (yy_start_stack_depth) )
+ {
+ yy_size_t new_size;
+
+ (yy_start_stack_depth) += YY_START_STACK_INCR;
+ new_size = (yy_start_stack_depth) * sizeof( int );
+
+ if ( ! (yy_start_stack) )
+ (yy_start_stack) = (int *) L_alloc(new_size );
+
+ else
+ (yy_start_stack) = (int *) L_realloc((void *) (yy_start_stack),new_size );
+
+ if ( ! (yy_start_stack) )
+ YY_FATAL_ERROR( "out of memory expanding start-condition stack" );
+ }
+
+ (yy_start_stack)[(yy_start_stack_ptr)++] = YY_START;
+
+ BEGIN(new_state);
+}
+
+ static void yy_pop_state (void)
+{
+ if ( --(yy_start_stack_ptr) < 0 )
+ YY_FATAL_ERROR( "start-condition stack underflow" );
+
+ BEGIN((yy_start_stack)[(yy_start_stack_ptr)]);
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up L_text. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ L_text[L_leng] = (yy_hold_char); \
+ (yy_c_buf_p) = L_text + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ L_leng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int L_get_lineno (void)
+{
+
+ return L_lineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *L_get_in (void)
+{
+ return L_in;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *L_get_out (void)
+{
+ return L_out;
+}
+
+/** Get the length of the current token.
+ *
+ */
+yy_size_t L_get_leng (void)
+{
+ return L_leng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *L_get_text (void)
+{
+ return L_text;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void L_set_lineno (int line_number )
+{
+
+ L_lineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see L__switch_to_buffer
+ */
+void L_set_in (FILE * in_str )
+{
+ L_in = in_str ;
+}
+
+void L_set_out (FILE * out_str )
+{
+ L_out = out_str ;
+}
+
+int L_get_debug (void)
+{
+ return L__flex_debug;
+}
+
+void L_set_debug (int bdebug )
+{
+ L__flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from L_lex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+ (yy_start_stack_ptr) = 0;
+ (yy_start_stack_depth) = 0;
+ (yy_start_stack) = NULL;
+
+ (yy_state_buf) = 0;
+ (yy_state_ptr) = 0;
+ (yy_full_match) = 0;
+ (yy_lp) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ L_in = stdin;
+ L_out = stdout;
+#else
+ L_in = (FILE *) 0;
+ L_out = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * L_lex_init()
+ */
+ return 0;
+}
+
+/* L_lex_destroy is for both reentrant and non-reentrant scanners. */
+int L_lex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ L__delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ L_pop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ L_free((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ /* Destroy the start condition stack. */
+ L_free((yy_start_stack) );
+ (yy_start_stack) = NULL;
+
+ L_free ( (yy_state_buf) );
+ (yy_state_buf) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * L_lex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *L_alloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *L_realloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void L_free (void * ptr )
+{
+ free( (char *) ptr ); /* see L_realloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 1211 "../generic/Lscanner.l"
+
+
+void
+L_lex_start()
+{
+ include_top = -1;
+ if (in_lhtml) {
+ STRBUF_START(0);
+ BEGIN(lhtml);
+ } else {
+ BEGIN(INITIAL);
+ }
+}
+
+void
+L_lex_begReArg(int kind)
+{
+ switch (kind) {
+ case 0:
+ yy_push_state(re_arg_split);
+ break;
+ case 1:
+ yy_push_state(re_arg_case);
+ break;
+ default:
+ break;
+ }
+}
+
+private void
+extract_re_delims(char c)
+{
+ re_start_delim = c;
+ if (c == '{') {
+ re_end_delim = '}';
+ } else {
+ re_end_delim = c;
+ }
+}
+
+void
+L_lex_begLhtml()
+{
+ in_lhtml = 1;
+}
+
+void
+L_lex_endLhtml()
+{
+ in_lhtml = 0;
+}
+
+/*
+ * These functions are declared down here because they reference
+ * things that flex has not yet declared in the prelogue (like
+ * unput() or yyterminate() etc).
+ */
+
+/*
+ * Unput a single character. This function is declared down here
+ * because it calls flex's unput() which is not declared before
+ * the prelogue code earlier.
+ */
+private void
+put_back(char c)
+{
+ unput(c);
+ --L_lloc.end;
+ --L->prev_token_len;
+ tally_newlines(&c, 1, -1);
+ --L->script_len;
+ Tcl_SetObjLength(L->script, L->script_len);
+}
+
+/*
+ * API for scanning string interpolations:
+ * interpol_push() - call when starting an interpolation; returns 1
+ * on interpolation stack overflow
+ * interpol_pop() - call when finishing an interpolation
+ * interpol_lbrace() - call when "{" seen
+ * interpol_rbrace() - call when "}" seen; returns non-0 if this brace
+ * ends the current interpolation
+ */
+
+private int
+interpol_push()
+{
+ if (interpol_top >= INTERPOL_STACK_SZ) {
+ L_err("string interpolation nesting too deep -- aborting");
+ interpol_top = -1;
+ return (1);
+ }
+ interpol_stk[++interpol_top] = 0;
+ yy_push_state(interpol);
+ return (0);
+}
+
+private void
+interpol_pop()
+{
+ ASSERT((interpol_top >= 0) && (interpol_top <= INTERPOL_STACK_SZ));
+ --interpol_top;
+ yy_pop_state();
+}
+
+private void
+interpol_lbrace()
+{
+ if (interpol_top >= 0) {
+ ASSERT(interpol_top <= INTERPOL_STACK_SZ);
+ ++interpol_stk[interpol_top];
+ }
+}
+
+private int
+interpol_rbrace()
+{
+ if (interpol_top >= 0) {
+ ASSERT(interpol_top <= INTERPOL_STACK_SZ);
+ return (interpol_stk[interpol_top]-- == 0);
+ } else {
+ return (0);
+ }
+}
+
diff --git a/generic/Lscanner.l b/generic/Lscanner.l
new file mode 100644
index 0000000..126b019
--- /dev/null
+++ b/generic/Lscanner.l
@@ -0,0 +1,1334 @@
+%option noyywrap
+%option noyy_top_state
+%option stack
+%option noinput
+%x re_delim
+%x re_modifier
+%x re_arg_split
+%x re_arg_case
+%x glob_re
+%x subst_re
+%x comment
+%x str_double
+%x str_single
+%x str_backtick
+%x interpol
+%x here_doc_interp
+%x here_doc_nointerp
+%x eat_through_eol
+%x lhtml
+%x lhtml_expr_start
+ID ([a-zA-Z_]|::)([0-9a-zA-Z_]|::)*
+HEX [a-fA-F0-9]
+%{
+/*
+ * Copyright (c) 2006-2008 BitMover, Inc.
+ */
+#include <string.h>
+#define _PWD_H // Some solaris9 conflict, we don't need pwd.h
+#include "tclInt.h"
+#include "Lcompile.h"
+#include "Lgrammar.h"
+#include "tommath.h"
+
+private void extract_re_delims(char c);
+private int include_pop();
+private int include_push(Tcl_Channel chan, char *name);
+private Tcl_Channel include_search(char *file, char **path, int cwdOnly);
+private Tcl_Channel include_try(Tcl_Obj *fileObj, int *found);
+private void inject(char *s);
+private void interpol_lbrace();
+private void interpol_pop();
+private int interpol_push();
+private int interpol_rbrace();
+private void put_back(char c);
+private void tally_newlines(char *s, int len, int tally);
+
+// Max nesting depth of string interpolations.
+#define INTERPOL_STACK_SZ 10
+
+// Stack for tracking include() statements.
+#define INCLUDE_STACK_SZ 10
+typedef struct {
+ char *name;
+ char *dir;
+ int line;
+ YY_BUFFER_STATE buf;
+} Include;
+
+private char re_start_delim; // delimiters for m|regexp| form
+private char re_end_delim;
+private Tcl_Obj *str; // string collection buffer
+private int str_beg; // source offset of string
+private char *here_delim = NULL;
+private char *here_pfx = NULL;
+private int include_top;
+private Include include_stk[INCLUDE_STACK_SZ+1];
+private Tcl_HashTable *include_table = NULL;
+private int interpol_top = -1;
+private int interpol_stk[INTERPOL_STACK_SZ+1];
+private int in_lhtml = 0; // Lhtml mode
+
+#define STRBUF_START(beg) \
+ do { \
+ str = Tcl_NewObj(); \
+ Tcl_IncrRefCount(str); \
+ str_beg = (beg); \
+ } while (0)
+
+
+#define STRBUF_STRING() Tcl_GetString(str)
+
+#define STRBUF_STARTED() (str != NULL)
+
+#define STRBUF_ADD(s, len) Tcl_AppendToObj(str, s, len)
+
+#define STRBUF_STOP(e) \
+ do { \
+ Tcl_DecrRefCount(str); \
+ str = NULL; \
+ L_lloc.beg = str_beg; \
+ L_lloc.end = (e); \
+ } while (0)
+
+/*
+ * Keep track of the current offset in the input string.
+ * YY_USER_ACTION is run before each action. Note that some actions
+ * further modify L_lloc.
+ */
+
+#define YY_USER_ACTION yy_user_action();
+
+private void
+yy_user_action()
+{
+ L->prev_token_off = L->token_off;
+ L->token_off += L->prev_token_len;
+ L->prev_token_len = yyleng;
+
+ L_lloc.beg = L->token_off;
+ L_lloc.end = L->token_off + yyleng;
+
+ tally_newlines(yytext, yyleng, 1);
+ L_lloc.line = L->line;
+
+ L_lloc.file = L->file;
+
+ /*
+ * Build up in L->script the text that the scanner scans.
+ * The compiler later passes this on to tcl as the script
+ * source. This allows include() stmts to be handled properly.
+ */
+ Tcl_AppendToObj(L->script, yytext, yyleng);
+ L->script_len += yyleng;
+}
+
+/*
+ * Un-do the effects of the YY_USER_ACTION on the token offset
+ * tracking. This is useful in include() processing where the
+ * characters in the '#include "file"' must be ignored.
+ */
+private void
+undo_yy_user_action()
+{
+ L->prev_token_len = L->token_off - L->prev_token_off;
+ L->token_off = L->prev_token_off;
+
+ L_lloc.beg = L->prev_token_off;
+ L_lloc.end = L->prev_token_off + L->prev_token_len;
+
+ tally_newlines(yytext, yyleng, -1);
+ L_lloc.line = L->line;
+
+ L->script_len -= yyleng;
+ Tcl_SetObjLength(L->script, L->script_len);
+}
+
+/*
+ * Inject the given string into the L script text, but do not give it
+ * to the scanner. This is useful for inserting #line directives (for
+ * #include's) which need to remain in the script so Tcl can see them
+ * but which aren't parsed.
+ */
+private void
+inject(char *s)
+{
+ int len = strlen(s);
+
+ L->prev_token_len += len;
+
+ Tcl_AppendToObj(L->script, s, len);
+ L->script_len += len;
+}
+
+/*
+ * Count the newlines in a string and add the number to L->line. Pass
+ * in tally == 1 to count them and tally == -1 to undo it.
+ */
+private void
+tally_newlines(char *s, int len, int tally)
+{
+ char *end, *p;
+
+ for (p = s, end = p + len; p < end; p++) {
+ if (*p == '\n') {
+ L->line += tally;
+ } else if ((*p == '\r') && ((p+1) < end) && (*(p+1) != '\n')) {
+ /* Mac line endings. */
+ L->line += tally;
+ }
+ }
+}
+
+private Tcl_Channel
+include_try(Tcl_Obj *fileObj, int *found)
+{
+ int new;
+ Tcl_Channel chan;
+ char *file = Tcl_GetString(fileObj);
+ char *path;
+ Tcl_Obj *pathObj;
+
+ /*
+ * See if the normalized path has been included before. If the path
+ * isn't absolute, consider it to be relative to where L->file is.
+ */
+ if (Tcl_FSGetPathType(fileObj) == TCL_PATH_ABSOLUTE) {
+ if ((pathObj = Tcl_FSGetNormalizedPath(NULL, fileObj)) == NULL){
+ L_err("unable to normalize include file %s", file);
+ return (NULL);
+ }
+ } else {
+ pathObj = Tcl_ObjPrintf("%s/%s", L->dir, file);
+ }
+ Tcl_IncrRefCount(pathObj);
+
+ path = Tcl_GetString(pathObj);
+ Tcl_CreateHashEntry(include_table, path, &new);
+ if (new) {
+ chan = Tcl_FSOpenFileChannel(L->interp, pathObj, "r", 0666);
+ *found = (chan != NULL);
+ return (chan);
+ } else {
+ *found = 1; // already included
+ return (NULL);
+ }
+ Tcl_DecrRefCount(pathObj);
+}
+
+/*
+ * Search for an include file. If the path is absolute, use it.
+ * Else, for #include <file> (cwdOnly == 0) try
+ * $BIN/include (where BIN is where the running tclsh lives)
+ * /usr/local/include/L
+ * /usr/include/L
+ * For #include "file" (cwdOnly == 1) look only in the directory
+ * where the script doing the #include resides.
+ */
+private Tcl_Channel
+include_search(char *file, char **path, int cwdOnly)
+{
+ int found, len;
+ Tcl_Channel chan;
+ Tcl_Obj *binObj = NULL;
+ Tcl_Obj *fileObj;
+
+ unless (include_table) {
+ include_table = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
+ Tcl_InitHashTable(include_table, TCL_STRING_KEYS);
+ }
+
+ fileObj = Tcl_NewStringObj(file, -1);
+ Tcl_IncrRefCount(fileObj);
+ if ((Tcl_FSGetPathType(fileObj) == TCL_PATH_ABSOLUTE) || cwdOnly) {
+ chan = include_try(fileObj, &found);
+ } else {
+ /* Try $BIN/include */
+ binObj = TclGetObjNameOfExecutable();
+ Tcl_GetStringFromObj(binObj, &len);
+ if (len > 0) {
+ Tcl_DecrRefCount(fileObj);
+ /* TclPathPart bumps the ref count. */
+ fileObj = TclPathPart(L->interp, binObj,
+ TCL_PATH_DIRNAME);
+ Tcl_AppendPrintfToObj(fileObj, "/include/%s", file);
+ chan = include_try(fileObj, &found);
+ if (found) goto done;
+ }
+ /* Try /usr/local/include/L */
+ Tcl_DecrRefCount(fileObj);
+ fileObj = Tcl_ObjPrintf("/usr/local/include/L/%s", file);
+ Tcl_IncrRefCount(fileObj);
+ chan = include_try(fileObj, &found);
+ if (found) goto done;
+ /* Try /usr/include/L */
+ Tcl_DecrRefCount(fileObj);
+ fileObj = Tcl_ObjPrintf("/usr/include/L/%s", file);
+ Tcl_IncrRefCount(fileObj);
+ chan = include_try(fileObj, &found);
+ }
+ done:
+ unless (found) {
+ L_err("cannot find include file %s", file);
+ }
+ if (path) *path = ckstrdup(Tcl_GetString(fileObj));
+ Tcl_DecrRefCount(fileObj);
+ return (chan);
+}
+
+private int
+include_push(Tcl_Channel chan, char *name)
+{
+ YY_BUFFER_STATE buf;
+ Tcl_Obj *objPtr;
+ char *dec = NULL, *script;
+ int len, ret;
+
+ /* Read the file into memory. */
+ objPtr = Tcl_NewObj();
+ Tcl_IncrRefCount(objPtr);
+ if (Tcl_ReadChars(chan, objPtr, -1, 0) < 0) {
+ Tcl_Close(L->interp, chan);
+ L_err("error reading include file %s", name);
+ return (0);
+ }
+ Tcl_Close(L->interp, chan);
+
+ /* If it is encrypted, decrypt it. */
+ script = Tcl_GetStringFromObj(objPtr, &len);
+
+ /* Create a new flex buffer with the file contents. */
+ if (include_top >= INCLUDE_STACK_SZ) {
+ L_err("include file nesting too deep -- aborting");
+ while (include_pop()) ;
+ ret = 0;
+ } else {
+ ++include_top;
+ include_stk[include_top].name = L->file;
+ include_stk[include_top].dir = L->dir;
+ include_stk[include_top].line = L->line;
+ include_stk[include_top].buf = YY_CURRENT_BUFFER;
+ buf = yy_scan_bytes(script, len);
+ L->file = name;
+ L->dir = L_dirname(L->file);
+ L->line = 1;
+ inject("#line 1\n");
+ ret = 1;
+ }
+ Tcl_DecrRefCount(objPtr);
+ if (dec) ckfree(dec);
+ return (ret);
+}
+
+private int
+include_pop()
+{
+ char *s;
+
+ if (include_top >= 0) {
+ L->file = include_stk[include_top].name;
+ L->dir = include_stk[include_top].dir;
+ L->line = include_stk[include_top].line;
+ yy_delete_buffer(YY_CURRENT_BUFFER);
+ yy_switch_to_buffer(include_stk[include_top].buf);
+ --include_top;
+ s = cksprintf("#line %d\n", L->line);
+ inject(s);
+ ckfree(s);
+ return (1);
+ } else {
+ return (0);
+ }
+}
+
+/*
+ * Given a decimal, hex, or octal integer constant of arbitrary
+ * precision, return a canonical string representation. This is done
+ * by converting it to a bignum and then taking its string rep.
+ */
+private char *
+canonical_num(char *num)
+{
+ char *ret;
+ Tcl_Obj *obj;
+ mp_int big;
+
+ obj = Tcl_NewStringObj(num, -1);
+ Tcl_IncrRefCount(obj);
+ Tcl_TakeBignumFromObj(NULL, obj, &big);
+ Tcl_SetBignumObj(obj, &big);
+ ret = ckstrdup(Tcl_GetString(obj));
+ Tcl_DecrRefCount(obj);
+ return (ret);
+}
+
+/*
+ * Work around a Windows problem where our getopt type conficts
+ * with the system's.
+ */
+#undef getopt
+#undef optarg
+#undef optind
+
+%}
+%%
+<INITIAL,interpol>{
+ "(" return T_LPAREN;
+ ")" return T_RPAREN;
+ "{" interpol_lbrace(); return T_LBRACE;
+ "[" return T_LBRACKET;
+ "]" return T_RBRACKET;
+ "," return T_COMMA;
+ "!" return T_BANG;
+ "+" return T_PLUS;
+ "-" return T_MINUS;
+ "*" return T_STAR;
+ "/" return T_SLASH;
+ "%" return T_PERC;
+ "+=" return T_EQPLUS;
+ "-=" return T_EQMINUS;
+ "*=" return T_EQSTAR;
+ "/=" return T_EQSLASH;
+ "%=" return T_EQPERC;
+ "&=" return T_EQBITAND;
+ "|=" return T_EQBITOR;
+ "^=" return T_EQBITXOR;
+ "<<=" return T_EQLSHIFT;
+ ">>=" return T_EQRSHIFT;
+ ".=" return T_EQDOT;
+ "++" return T_PLUSPLUS;
+ "--" return T_MINUSMINUS;
+ "&&" return T_ANDAND;
+ "||" return T_OROR;
+ "&" return T_BITAND;
+ "|" return T_BITOR;
+ "^" return T_BITXOR;
+ "~" return T_BITNOT;
+ "<<" return T_LSHIFT;
+ ">>" return T_RSHIFT;
+ "=" return T_EQUALS;
+ ";" return T_SEMI;
+ "." return T_DOT;
+ [ \t\n\r]+"."[ \t\n\r]+ return T_STRCAT;
+ ".." return T_DOTDOT;
+ "..." return T_ELLIPSIS;
+ "class" return T_CLASS;
+ "extern" return T_EXTERN;
+ "return" return T_RETURN;
+ "void" return T_VOID;
+ "string" return T_STRING;
+ "widget" return T_WIDGET;
+ "int" return T_INT;
+ "float" return T_FLOAT;
+ "poly" return T_POLY;
+ "split" return T_SPLIT;
+ "if" return T_IF;
+ "else" return T_ELSE;
+ "unless" return T_UNLESS;
+ "while" return T_WHILE;
+ "do" return T_DO;
+ "for" return T_FOR;
+ "struct" return T_STRUCT;
+ "typedef" return T_TYPEDEF;
+ "defined" return T_DEFINED;
+ "foreach" return T_FOREACH;
+ "break" return T_BREAK;
+ "continue" return T_CONTINUE;
+ "instance" return T_INSTANCE;
+ "private" return T_PRIVATE;
+ "public" return T_PUBLIC;
+ "constructor" return T_CONSTRUCTOR;
+ "destructor" return T_DESTRUCTOR;
+ "expand" return T_EXPAND;
+ "_argused" return T_ARGUSED;
+ "_attribute" return T_ATTRIBUTE;
+ "_attributes" return T_ATTRIBUTE;
+ "_optional" return T_OPTIONAL;
+ "_mustbetype" return T_MUSTBETYPE;
+ "goto" return T_GOTO;
+ "switch" return T_SWITCH;
+ "case" return T_CASE;
+ "default" return T_DEFAULT;
+ "try" return T_TRY;
+ "=>" return T_ARROW;
+ "eq" return T_EQ;
+ "ne" return T_NE;
+ "lt" return T_LT;
+ "le" return T_LE;
+ "gt" return T_GT;
+ "ge" return T_GE;
+ "==" return T_EQUALEQUAL;
+ "!=" return T_NOTEQUAL;
+ ">" return T_GREATER;
+ ">=" return T_GREATEREQ;
+ "<" return T_LESSTHAN;
+ "<=" return T_LESSTHANEQ;
+ "->" return T_POINTS;
+ ":" return T_COLON;
+ "?" return T_QUESTION;
+ "?>" {
+ /*
+ * ?> marks the end of a script or expr
+ * inside of an lhtml document but is a
+ * syntax error otherwise.
+ */
+ unless (in_lhtml) {
+ undo_yy_user_action();
+ REJECT;
+ }
+ yy_pop_state();
+ STRBUF_START(L_lloc.end);
+ if (YYSTATE == lhtml_expr_start) {
+ yy_pop_state(); // pop back to lhtml
+ ASSERT(YYSTATE == lhtml);
+ return T_LHTML_EXPR_END;
+ }
+ }
+ "and" {
+ L_err("'and','or','xor','not' are "
+ "unimplemented reserved words");
+ return T_ANDAND;
+ }
+ "not" {
+ L_err("'and','or','xor','not' are "
+ "unimplemented reserved words");
+ return T_BANG;
+ }
+ "or" {
+ L_err("'and','or','xor','not' are "
+ "unimplemented reserved words");
+ return T_OROR;
+ }
+ "xor" {
+ L_err("'and','or','xor','not' are "
+ "unimplemented reserved words");
+ return T_BITXOR;
+ }
+ {ID} {
+ Type *t = L_typedef_lookup(yytext);
+ if (t) {
+ L_lval.Typename.s = ckstrdup(yytext);
+ L_lval.Typename.t = t;
+ return T_TYPE;
+ } else {
+ L_lval.s = ckstrdup(yytext);
+ return T_ID;
+ }
+ }
+ {ID}: {
+ /*
+ * Push back the : and return a T_ID
+ * unless it's "default". The grammar relies
+ * on this to avoid a nasty conflict.
+ */
+ put_back(':');
+ if (!strncmp(yytext, "default", 7)) {
+ return T_DEFAULT;
+ }
+ L_lval.s = ckstrdup(yytext);
+ L_lval.s[yyleng-1] = 0;
+ return T_ID;
+ }
+ ([A-Z]|::)([0-9a-zA-Z]|::)*_\* {
+ L_lval.s = ckstrdup(yytext);
+ return T_PATTERN;
+ }
+ $[0-9]+ {
+ /* Regular expression submatches */
+ L_lval.s = ckstrdup(yytext);
+ return T_ID;
+ }
+ [0-9]+ {
+ /*
+ * Skip any leading 0's which would
+ * make it look like octal to Tcl.
+ */
+ size_t z = strspn(yytext, "0");
+ if (z == yyleng) z = 0; // number is all 0's
+ L_lval.s = canonical_num(yytext+z);
+ return T_INT_LITERAL;
+ }
+ 0o[0-7]+ {
+ /*
+ * Create a leading 0 so it looks like
+ * octal to Tcl.
+ */
+ yytext[1] = '0';
+ L_lval.s = canonical_num(yytext+1);
+ return T_INT_LITERAL;
+ }
+ 0x[0-9a-fA-F]+ {
+ L_lval.s = canonical_num(yytext);
+ return T_INT_LITERAL;
+ }
+ [0-9]*\.[0-9]+ {
+ L_lval.s = ckstrdup(yytext);
+ return T_FLOAT_LITERAL;
+ }
+ ^#line[ \t]+[0-9]+\n {
+ int line = strtoul(yytext+5, NULL, 10);
+
+ if (line <= 0) {
+ --L->line; // since \n already scanned
+ L_err("malformed #line");
+ ++L->line;
+ } else {
+ L->line = line;
+ }
+ }
+ ^#line[ \t]+[0-9]+[ \t]+\"[^\"\n]*\"\n {
+ int line = strtoul(yytext+5, NULL, 10);
+ char *beg = strchr(yytext, '"') + 1;
+ char *end = strrchr(yytext, '"');
+ char *name = ckstrndup(beg, end-beg);
+
+ if (line <= 0) {
+ --L->line; // since \n already scanned
+ L_err("malformed #line");
+ ++L->line;
+ } else {
+ L->file = name;
+ L->line = line;
+ }
+ }
+ ^#line.*\n {
+ --L->line; // since \n already scanned
+ L_err("malformed #line");
+ ++L->line;
+ }
+ ^#include[ \t]*\"[^\"\n]+\" {
+ char *beg = strchr(yytext, '"') + 1;
+ char *end = strrchr(yytext, '"');
+ char *name = ckstrndup(beg, end-beg);
+ Tcl_Channel chan;
+
+ chan = include_search(name, NULL, 1);
+
+ undo_yy_user_action();
+ if (chan && !include_push(chan, name)) {
+ /* Bail if includes nest too deeply. */
+ yyterminate();
+ }
+ }
+ ^#include[ \t]*<[^>\n]+> {
+ char *beg = strchr(yytext, '<') + 1;
+ char *end = strrchr(yytext, '>');
+ char *name = ckstrndup(beg, end-beg);
+ char *path = NULL;
+ Tcl_Channel chan;
+
+ chan = include_search(name, &path, 0);
+ ckfree(name);
+
+ undo_yy_user_action();
+ if (chan && !include_push(chan, path)) {
+ /* Bail if includes nest too deeply. */
+ yyterminate();
+ }
+ }
+ ^#include {
+ L_err("malformed #include");
+ yy_push_state(eat_through_eol);
+ }
+ ^#pragma[ \t]+ return T_PRAGMA;
+ ^#.*("\r"|"\n"|"\r\n") {
+ /*
+ * Rather than using a start condition
+ * to separate out all the ^# patterns
+ * that don't end in \n, this is
+ * simpler. If it's not a comment,
+ * REJECT it so that flex then takes
+ * the second best rule (those above).
+ */
+ if (!strncmp(yytext, "#pragma ", 8) ||
+ !strncmp(yytext, "#pragma\t", 8)) {
+ undo_yy_user_action();
+ REJECT;
+ } else if (!strncmp(yytext, "#include", 8)) {
+ undo_yy_user_action();
+ REJECT;
+ } else unless (L->line == 2) {
+ --L->line; // since \n already scanned
+ L_err("# comment valid only on line 1");
+ ++L->line;
+ }
+ }
+ [ \t]+#.*("\r"|"\n"|"\r\n") {
+ --L->line; // since \n already scanned
+ unless (L->line == 1) {
+ L_err("# comment valid only on line 1");
+ } else {
+ L_err("# comment must start at "
+ "first column");
+ }
+ ++L->line;
+ }
+ "//".*("\r"|"\n"|"\r\n")
+ [ \t]+
+ \n|\r|\f
+ \" yy_push_state(str_double); STRBUF_START(L->token_off);
+ \' yy_push_state(str_single); STRBUF_START(L->token_off);
+ \` yy_push_state(str_backtick); STRBUF_START(L->token_off);
+ "/*" yy_push_state(comment);
+ [!=]~[ \t\r\n]*"m". {
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 2); // next token starts at the "m"
+ extract_re_delims(yytext[yyleng-1]);
+ L_lloc.end = L_lloc.beg + 2; // this token spans the "=~"
+ return ((yytext[0] == '=') ? T_EQTWID : T_BANGTWID);
+ }
+ /* if / is used to delimit the regexp, the m can be omitted */
+ [!=]~[ \t\r\n]*"/" {
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the "/"
+ extract_re_delims('/');
+ L_lloc.end = L_lloc.beg + 2; // this token spans the "=~"
+ return ((yytext[0] == '=') ? T_EQTWID : T_BANGTWID);
+ }
+ /* a substitution pattern */
+ "=~"[ \t\r\n]*"s". {
+ yy_push_state(re_modifier);
+ yy_push_state(subst_re);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 2); // next token starts at the "s"
+ extract_re_delims(yytext[yyleng-1]);
+ L_lloc.end = L_lloc.beg + 2; // this token spans the "=~"
+ return T_EQTWID;
+ }
+ /* here document (interpolated), valid only on rhs of an assignment */
+ =[ \t\r\n]*<<[a-zA-Z_][a-zA-Z_0-9]*\n {
+ char *p, *q;
+
+ if (here_delim) {
+ L_err("nested here documents illegal");
+ }
+ p = strchr(yytext, '<') + 2; // the < is guaranteed to exist
+ for (q = p; (q > yytext) && (*q != '\n'); --q) ;
+ if ((q > yytext) && (*q == '\n')) {
+ // \n then <<; the in-between whitespace is the here_pfx
+ here_pfx = ckstrndup(q+1, p-q-3);
+ } else {
+ // non-indented here document
+ here_pfx = ckstrdup("");
+ }
+ here_delim = ckstrndup(p, yyleng - (p-yytext) - 1);
+ STRBUF_START(L->token_off);
+ L_lloc.end = L_lloc.beg + 1;
+ yy_push_state(here_doc_interp);
+ return T_EQUALS;
+ }
+ /* here document (uninterpolated), valid only on rhs of an assignment */
+ =[ \t\r\n]*<<\'[a-zA-Z_][a-zA-Z_0-9]*\'\n {
+ char *p, *q;
+
+ if (here_delim) {
+ L_err("nested here documents illegal");
+ }
+ p = strchr(yytext, '<') + 2; // the < is guaranteed to exist
+ for (q = p; (q > yytext) && (*q != '\n'); --q) ;
+ if ((q > yytext) && (*q == '\n')) {
+ // \n then <<; the in-between whitespace is the here_pfx
+ here_pfx = ckstrndup(q+1, p-q-3);
+ } else {
+ // non-indented here document
+ here_pfx = ckstrdup("");
+ }
+ here_delim = ckstrndup(p+1, yyleng - (p-yytext) - 3);
+ STRBUF_START(L->token_off);
+ L_lloc.end = L_lloc.beg + 1;
+ yy_push_state(here_doc_nointerp);
+ return T_EQUALS;
+ }
+ /* illegal here documents (bad stuff before or after the delim) */
+ =[ \t\r\n]*<<-[a-zA-Z_][a-zA-Z_0-9]* |
+ =[ \t\r\n]*<<-\'[a-zA-Z_][a-zA-Z_0-9]*\' {
+ L_synerr("<<- unsupported, use =\\n\\t<<END to strip one "
+ "leading tab");
+ }
+ =[ \t\r\n]*<<[a-zA-Z_][a-zA-Z_0-9]*[^\n] {
+ L_synerr("illegal characters after here-document delimeter");
+ }
+ =[ \t\r\n]*<<[^a-zA-Z_][a-zA-Z_][a-zA-Z_0-9]* {
+ L_synerr("illegal characters before here-document delimeter");
+ }
+ =[ \t\r\n]*<<\'[a-zA-Z_][a-zA-Z_0-9]*\'[^\n] {
+ L_synerr("illegal characters after here-document delimeter");
+ }
+ =[ \t\r\n]*<<\'[^a-zA-Z_][a-zA-Z_][a-zA-Z_0-9]*\' {
+ L_synerr("illegal characters before here-document delimeter");
+ }
+}
+
+<lhtml>{
+ /*
+ * The compiler prepends a #line directive to Lhtml source.
+ * This communicates the correct line number to the Tcl
+ * code that prints run-time error messages.
+ */
+ ^#line[ \t]+[0-9]+\n {
+ int line = strtoul(yytext+5, NULL, 10);
+
+ if (line <= 0) {
+ --L->line; // since \n already scanned
+ L_err("malformed #line");
+ ++L->line;
+ } else {
+ L->line = line;
+ }
+ }
+ "<?"=? {
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ if (yyleng == 2) {
+ yy_push_state(INITIAL);
+ } else {
+ yy_push_state(lhtml_expr_start);
+ }
+ return T_HTML;
+ }
+ .|\n STRBUF_ADD(yytext, yyleng);
+ <<EOF>> {
+ unless (STRBUF_STARTED()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_HTML;
+ }
+}
+
+<lhtml_expr_start>{
+ /*
+ * This start condition is here only so the rule for ?> can
+ * know whether we previously scanned <? or <?=.
+ */
+ .|\n {
+ unput(yytext[0]);
+ undo_yy_user_action();
+ yy_push_state(INITIAL);
+ return T_LHTML_EXPR_START;
+ }
+}
+
+<re_arg_split>{
+ /*
+ * A regexp in the context of the first arg to split(). If
+ * it's not an RE, pop the start-condition stack and push it
+ * back, so we can continue as normal.
+ */
+ [ \t\r\n]*
+ /* / starts an RE */
+ "/" {
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the "/"
+ extract_re_delims('/');
+ }
+ /*
+ * m<punctuation> starts an RE, except for "m)" so that
+ * "split(m)" works.
+ */
+ "m"[^a-zA-Z() \t\r\n] {
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the delim
+ extract_re_delims(yytext[yyleng-1]);
+ }
+ /* nothing else starts an RE */
+ . {
+ unput(yytext[0]);
+ undo_yy_user_action();
+ yy_pop_state();
+ }
+}
+
+<re_arg_case>{
+ /*
+ * A regexp in the context of a case statement. If it's not
+ * an RE, pop the start-condition stack and push it back, so
+ * we can continue as normal.
+ */
+ [ \t\r\n]*
+ /* / starts an RE */
+ "/" {
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the "/"
+ extract_re_delims('/');
+ }
+ /*
+ * m<punctuation> starts an RE except for "m:" which we scan
+ * as the variable m (so that "case m:" works) or "m(" which
+ * is the start of a call to the function m (so that "case m():"
+ * or "case m(arg):" etc work).
+ */
+ m[^a-zA-Z:( \t\r\n] {
+ yy_push_state(re_modifier);
+ yy_push_state(glob_re);
+ STRBUF_START(L_lloc.end - 1); // next token starts at the delim
+ extract_re_delims(yytext[yyleng-1]);
+ }
+ /* nothing else starts an RE */
+ . {
+ unput(yytext[0]);
+ undo_yy_user_action();
+ yy_pop_state();
+ }
+}
+
+<INITIAL>{
+ "}" return T_RBRACE;
+}
+
+<interpol>{
+ "}" {
+ if (interpol_rbrace()) {
+ STRBUF_START(L_lloc.end);
+ interpol_pop();
+ if ((YYSTATE == glob_re) ||
+ (YYSTATE == subst_re)) {
+ return T_RIGHT_INTERPOL_RE;
+ } else {
+ return T_RIGHT_INTERPOL;
+ }
+ } else {
+ return T_RBRACE;
+ }
+ }
+ . {
+ L_synerr("illegal character");
+ }
+}
+
+<str_double>{
+ \\r STRBUF_ADD("\r", 1);
+ \\n STRBUF_ADD("\n", 1);
+ \\t STRBUF_ADD("\t", 1);
+ \\u{HEX} |
+ \\u{HEX}{HEX} |
+ \\u{HEX}{HEX}{HEX} |
+ \\u{HEX}{HEX}{HEX}{HEX} {
+ char buf[TCL_UTF_MAX];
+ int ch;
+ TclParseHex(yytext+2, 4, &ch);
+ STRBUF_ADD(buf, Tcl_UniCharToUtf(ch, buf));
+ }
+ \\(.|\n) STRBUF_ADD(yytext+1, 1);
+ "$" STRBUF_ADD("$", 1);
+ \n {
+ L_err("missing string terminator \"");
+ STRBUF_ADD("\n", 1);
+ }
+ [^\\\"$\n]+ STRBUF_ADD(yytext, yyleng);
+ "${" {
+ if (interpol_push()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_LEFT_INTERPOL;
+ }
+ \"[ \t\r\n]*\"
+ \" {
+ yy_pop_state();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ return T_STR_LITERAL;
+ }
+}
+
+<str_single>{
+ \\\\ STRBUF_ADD("\\", 1);
+ \\\' STRBUF_ADD("'", 1);
+ \\\n STRBUF_ADD("\n", 1);
+ \n {
+ L_err("missing string terminator \'");
+ STRBUF_ADD("\n", 1);
+ }
+ \\. |
+ [^\\\'\n]+ STRBUF_ADD(yytext, yyleng);
+ \'[ \t\r\n]*\'
+ \' {
+ yy_pop_state();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ return T_STR_LITERAL;
+ }
+}
+
+<str_backtick>{
+ \\("$"|`|\\) STRBUF_ADD(yytext+1, 1);
+ \\\n /* ignore \<newline> */
+ \\. |
+ "$" |
+ [^\\`$\n]+ STRBUF_ADD(yytext, yyleng);
+ \n {
+ L_err("missing string terminator `");
+ STRBUF_ADD("\n", 1);
+ }
+ "${" {
+ if (interpol_push()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_LEFT_INTERPOL;
+ }
+ ` {
+ yy_pop_state();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ if (YYSTATE == here_doc_interp) {
+ STRBUF_START(L_lloc.end);
+ }
+ return T_STR_BACKTICK;
+ }
+}
+
+<here_doc_nointerp>{
+ ^[ \t]*[a-zA-Z_][a-zA-Z_0-9]*;?$ {
+ int len;
+ char *p = yytext;
+
+ /*
+ * Look for whitespace-prefixed here_delim.
+ * Any amount of white space is allowed.
+ */
+ while (isspace(*p)) ++p;
+ len = yyleng - (p - yytext);
+ if (p[len-1] == ';') --len;
+ if ((len == strlen(here_delim)) &&
+ !strncmp(p, here_delim, len)) {
+ yy_pop_state();
+ unput(';'); // for the parser
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ ckfree(here_delim);
+ ckfree(here_pfx);
+ here_delim = NULL;
+ here_pfx = NULL;
+ return T_STR_LITERAL;
+ }
+ /*
+ * It's a data line. It must begin with
+ * here_pfx or else it's an error.
+ */
+ p = strstr(yytext, here_pfx);
+ if (p == yytext) {
+ p += strlen(here_pfx);
+ } else {
+ L_err("bad here-document prefix");
+ p = yytext;
+ }
+ STRBUF_ADD(p, yyleng - (p - yytext));
+ }
+ ^[ \t]+ {
+ char *p = strstr(yytext, here_pfx);
+ if (p == yytext) {
+ p += strlen(here_pfx);
+ STRBUF_ADD(p, yyleng - (p - yytext));
+ } else {
+ L_err("bad here-document prefix");
+ p = yytext;
+ }
+ }
+ .|\n STRBUF_ADD(yytext, 1);
+}
+
+<here_doc_interp>{
+ \\\\ STRBUF_ADD("\\", 1);
+ \\\$ STRBUF_ADD("$", 1);
+ \\` STRBUF_ADD("`", 1);
+ \\\n // ignore \<newline>
+ "${" {
+ if (interpol_push()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_LEFT_INTERPOL;
+ }
+ ` {
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ yy_push_state(str_backtick);
+ STRBUF_START(L->token_off);
+ return T_START_BACKTICK;
+ }
+ ^[ \t]*[a-zA-Z_][a-zA-Z_0-9]*;?$ {
+ int len;
+ char *p = yytext;
+
+ /*
+ * Look for whitespace-prefixed here_delim.
+ * Any amount of white space is allowed.
+ */
+ while (isspace(*p)) ++p;
+ len = yyleng - (p - yytext);
+ if (p[len-1] == ';') --len;
+ if ((len == strlen(here_delim)) &&
+ !strncmp(p, here_delim, len)) {
+ yy_pop_state();
+ unput(';'); // for the parser
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ ckfree(here_delim);
+ ckfree(here_pfx);
+ here_delim = NULL;
+ here_pfx = NULL;
+ return T_STR_LITERAL;
+ }
+ /*
+ * It's a data line. It must begin with
+ * here_pfx or else it's an error.
+ */
+ p = strstr(yytext, here_pfx);
+ if (p == yytext) {
+ p += strlen(here_pfx);
+ } else {
+ L_err("bad here-document prefix");
+ p = yytext;
+ }
+ STRBUF_ADD(p, yyleng - (p - yytext));
+ }
+ ^[ \t]+ {
+ char *p = strstr(yytext, here_pfx);
+ if (p == yytext) {
+ p += strlen(here_pfx);
+ STRBUF_ADD(p, yyleng - (p - yytext));
+ } else {
+ L_err("bad here-document prefix");
+ p = yytext;
+ }
+ }
+ .|\n STRBUF_ADD(yytext, 1);
+}
+
+<comment>{
+ [^*]+
+ "*"
+ "*/" yy_pop_state();
+}
+
+<glob_re,subst_re>{
+ "${" {
+ if (interpol_push()) yyterminate();
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.beg);
+ return T_LEFT_INTERPOL_RE;
+ }
+ \\. {
+ if ((yytext[1] == re_end_delim) ||
+ (yytext[1] == re_start_delim)) {
+ STRBUF_ADD(yytext+1, 1);
+ } else {
+ STRBUF_ADD(yytext, yyleng);
+ }
+ }
+ \n {
+ --L->line; // since \n already scanned
+ L_err("run-away regular expression");
+ ++L->line;
+ STRBUF_ADD(yytext, yyleng);
+ yy_pop_state();
+ if (YYSTATE == re_modifier) yy_pop_state();
+ return T_RE;
+ }
+ "$"[0-9] {
+ // Convert $3 to \3 (regexp capture reference).
+ STRBUF_ADD("\\", 1);
+ STRBUF_ADD(yytext+1, yyleng-1);
+ }
+ . {
+ if (*yytext == re_end_delim) {
+ L_lval.s = ckstrdup(STRBUF_STRING());
+ STRBUF_STOP(L_lloc.end);
+ if (YYSTATE == subst_re) {
+ yy_pop_state();
+ return T_SUBST;
+ } else {
+ yy_pop_state();
+ if (YYSTATE == subst_re) {
+ STRBUF_START(L_lloc.end);
+ if (re_start_delim !=
+ re_end_delim) {
+ yy_push_state(
+ re_delim);
+ }
+ }
+ return T_RE;
+ }
+ } else if (*yytext == re_start_delim) {
+ L_err("regexp delimiter must be quoted "
+ "inside the regexp");
+ STRBUF_ADD(yytext+1, 1);
+ } else {
+ STRBUF_ADD(yytext, yyleng);
+ }
+ }
+
+}
+
+<re_delim>{
+ \n {
+ --L->line; // since \n already scanned
+ L_err("run-away regular expression");
+ ++L->line;
+ STRBUF_ADD(yytext, yyleng);
+ yy_pop_state();
+ }
+ . {
+ extract_re_delims(*yytext);
+ yy_pop_state();
+ }
+}
+
+<re_modifier>{
+ [iglt]+ {
+ L_lval.s = ckstrdup(yytext);
+ yy_pop_state();
+ return T_RE_MODIFIER;
+ }
+ .|\n {
+ unput(yytext[0]);
+ undo_yy_user_action();
+ yy_pop_state();
+ L_lval.s = ckstrdup("");
+ return T_RE_MODIFIER;
+ }
+}
+
+<eat_through_eol>{
+ .
+ \n yy_pop_state();
+}
+
+ . {
+ /* This rule matches a char if no other does. */
+ L_synerr("illegal character");
+ yyterminate();
+ }
+ <<EOF>> {
+ if (in_lhtml) {
+ yy_user_action(); // for line #s
+ L_synerr("premature EOF");
+ }
+ unless (include_pop()) yyterminate();
+ }
+%%
+void
+L_lex_start()
+{
+ include_top = -1;
+ if (in_lhtml) {
+ STRBUF_START(0);
+ BEGIN(lhtml);
+ } else {
+ BEGIN(INITIAL);
+ }
+}
+
+void
+L_lex_begReArg(int kind)
+{
+ switch (kind) {
+ case 0:
+ yy_push_state(re_arg_split);
+ break;
+ case 1:
+ yy_push_state(re_arg_case);
+ break;
+ default:
+ break;
+ }
+}
+
+private void
+extract_re_delims(char c)
+{
+ re_start_delim = c;
+ if (c == '{') {
+ re_end_delim = '}';
+ } else {
+ re_end_delim = c;
+ }
+}
+
+void
+L_lex_begLhtml()
+{
+ in_lhtml = 1;
+}
+
+void
+L_lex_endLhtml()
+{
+ in_lhtml = 0;
+}
+
+/*
+ * These functions are declared down here because they reference
+ * things that flex has not yet declared in the prelogue (like
+ * unput() or yyterminate() etc).
+ */
+
+/*
+ * Unput a single character. This function is declared down here
+ * because it calls flex's unput() which is not declared before
+ * the prelogue code earlier.
+ */
+private void
+put_back(char c)
+{
+ unput(c);
+ --L_lloc.end;
+ --L->prev_token_len;
+ tally_newlines(&c, 1, -1);
+ --L->script_len;
+ Tcl_SetObjLength(L->script, L->script_len);
+}
+
+/*
+ * API for scanning string interpolations:
+ * interpol_push() - call when starting an interpolation; returns 1
+ * on interpolation stack overflow
+ * interpol_pop() - call when finishing an interpolation
+ * interpol_lbrace() - call when "{" seen
+ * interpol_rbrace() - call when "}" seen; returns non-0 if this brace
+ * ends the current interpolation
+ */
+
+private int
+interpol_push()
+{
+ if (interpol_top >= INTERPOL_STACK_SZ) {
+ L_err("string interpolation nesting too deep -- aborting");
+ interpol_top = -1;
+ return (1);
+ }
+ interpol_stk[++interpol_top] = 0;
+ yy_push_state(interpol);
+ return (0);
+}
+
+private void
+interpol_pop()
+{
+ ASSERT((interpol_top >= 0) && (interpol_top <= INTERPOL_STACK_SZ));
+ --interpol_top;
+ yy_pop_state();
+}
+
+private void
+interpol_lbrace()
+{
+ if (interpol_top >= 0) {
+ ASSERT(interpol_top <= INTERPOL_STACK_SZ);
+ ++interpol_stk[interpol_top];
+ }
+}
+
+private int
+interpol_rbrace()
+{
+ if (interpol_top >= 0) {
+ ASSERT(interpol_top <= INTERPOL_STACK_SZ);
+ return (interpol_stk[interpol_top]-- == 0);
+ } else {
+ return (0);
+ }
+}
diff --git a/generic/Ltypecheck.c b/generic/Ltypecheck.c
new file mode 100644
index 0000000..a1bf86a
--- /dev/null
+++ b/generic/Ltypecheck.c
@@ -0,0 +1,498 @@
+/*
+ * Type-checking helpers for the L programming language.
+ *
+ * Copyright (c) 2006-2008 BitMover, Inc.
+ */
+#include <stdio.h>
+#include "tclInt.h"
+#include "Lcompile.h"
+#include "Lgrammar.h"
+
+private int typeck_declType(Type *type, VarDecl *decl, int nameof_ok);
+private int typeck_decls(VarDecl *a, VarDecl *b);
+private void typeck_fmt(Expr *actuals);
+private int typeck_list(Type *a, Type *b);
+
+/* Create the pre-defined types. */
+void
+L_typeck_init()
+{
+ L_int = type_mkScalar(L_INT);
+ L_float = type_mkScalar(L_FLOAT);
+ L_string = type_mkScalar(L_STRING);
+ L_widget = type_mkScalar(L_WIDGET);
+ L_void = type_mkScalar(L_VOID);
+ L_poly = type_mkScalar(L_POLY);
+}
+
+private Tcl_Obj *typenmObj = NULL;
+
+private void
+str_add(char *s)
+{
+ if (typenmObj) {
+ Tcl_AppendPrintfToObj(typenmObj, " or %s", s);
+ } else {
+ typenmObj = Tcl_NewStringObj(s, -1);
+ Tcl_IncrRefCount(typenmObj);
+ }
+}
+
+char *
+L_type_str(Type_k kind)
+{
+ if (typenmObj) {
+ Tcl_DecrRefCount(typenmObj);
+ typenmObj = NULL;
+ }
+ if (kind & L_INT) str_add("int");
+ if (kind & L_FLOAT) str_add("float");
+ if (kind & L_STRING) str_add("string");
+ if (kind & L_WIDGET) str_add("widget");
+ if (kind & L_VOID) str_add("void");
+ if (kind & L_POLY) str_add("poly");
+ if (kind & L_HASH) str_add("hash");
+ if (kind & L_STRUCT) str_add("struct");
+ if (kind & L_ARRAY) str_add("array");
+ if (kind & L_LIST) str_add("list");
+ if (kind & L_FUNCTION) str_add("function");
+ if (kind & L_NAMEOF) str_add("nameof");
+ if (kind & L_CLASS ) str_add("class");
+ return (Tcl_GetString(typenmObj));
+}
+
+private void
+pr_err(Type_k got, Type_k want, char *bef, char *aft, void *node)
+{
+ Tcl_Obj *obj = Tcl_NewObj();
+
+ Tcl_IncrRefCount(obj);
+ if (bef) Tcl_AppendPrintfToObj(obj, "%s, ", bef);
+ Tcl_AppendPrintfToObj(obj, "expected type %s", L_type_str(want));
+ Tcl_AppendPrintfToObj(obj, " but got %s", L_type_str(got));
+ if (aft) Tcl_AppendPrintfToObj(obj, " %s", aft);
+ L_errf(node, Tcl_GetString(obj));
+ Tcl_DecrRefCount(obj);
+}
+
+void
+L_typeck_deny(Type_k deny, Expr *expr)
+{
+ ASSERT(expr->type);
+
+ if (hash_get(L->options, "poly")) return;
+
+ if (expr->type->kind & deny) {
+ L_errf(expr, "type %s illegal", L_type_str(expr->type->kind));
+ expr->type = L_poly; // minimize cascading errors
+ }
+}
+
+void
+L_typeck_expect(Type_k want, Expr *expr, char *msg)
+{
+ ASSERT(expr->type);
+
+ if (hash_get(L->options, "poly") ||
+ ((expr->type->kind | want) & L_POLY)) return;
+
+ unless (expr->type->kind & want) {
+ pr_err(expr->type->kind, want, NULL, msg, expr);
+ expr->type = L_poly; // minimize cascading errors
+ }
+}
+
+int
+L_typeck_compat(Type *lhs, Type *rhs)
+{
+ if ((lhs->kind == L_POLY) || (rhs->kind == L_POLY)) {
+ return (TRUE);
+ }
+ if (lhs->kind == L_FLOAT) {
+ return (rhs->kind & (L_INT|L_FLOAT));
+ } else {
+ return (L_typeck_same(lhs, rhs));
+ }
+}
+
+void
+L_typeck_assign(Expr *lhs, Type *rhs)
+{
+ if (hash_get(L->options, "poly")) return;
+ unless (lhs && rhs) return;
+
+ if ((rhs->kind == L_VOID) || (lhs->type->kind == L_VOID)) {
+ L_errf(lhs, "type void illegal");
+ }
+ unless (L_typeck_compat(lhs->type, rhs)) {
+ L_errf(lhs, "assignment of incompatible types");
+ }
+}
+
+void
+L_typeck_fncall(VarDecl *formals, Expr *call)
+{
+ int i, type_ok;
+ int rest_arg = 0;
+ Expr *actuals = call->b;
+
+ if (hash_get(L->options, "poly")) return;
+
+ for (i = 1; actuals && formals; ++i) {
+ if (isexpand(actuals)) return;
+ rest_arg = formals->flags & DECL_REST_ARG; // is it "...id"?
+ if (formals->flags & DECL_NAME_EQUIV) {
+ type_ok = (formals->type == actuals->type);
+ } else {
+ type_ok = L_typeck_compat(formals->type, actuals->type);
+ }
+ unless (type_ok || rest_arg) {
+ L_errf(call, "parameter %d has incompatible type", i);
+ }
+ if (typeis(formals->type, "FMT")) {
+ typeck_fmt(actuals);
+ }
+ actuals = actuals->next;
+ formals = formals->next;
+ }
+ if (actuals && !rest_arg) {
+ L_errf(call, "too many arguments for function %s",
+ call->a->str);
+ }
+ if (formals) {
+ unless ((formals->flags & DECL_REST_ARG) ||
+ (!formals->next && (formals->flags & DECL_OPTIONAL))) {
+ L_errf(call, "not enough arguments for function %s",
+ call->a->str);
+ }
+ }
+}
+
+/*
+ * Type check a FMT arg, like
+ * printf(FMT format, ...args)
+ * by checking that the number of % format specifiers in "format" matches the
+ * number of actuals in ...args. We can do this only if "format" is a
+ * string constant and there are no (expand) operators in the args list.
+ */
+private void
+typeck_fmt(Expr *actuals)
+{
+ int i, nargs = 0;
+ Expr *a;
+ Tcl_Obj *obj, **objv;
+
+ unless (isconst(actuals) && isstring(actuals)) return;
+
+ for (a = actuals->next; a; a = a->next) {
+ if (a->op == L_OP_EXPAND) return;
+ ++nargs;
+ }
+
+ obj = Tcl_NewObj();
+ objv = (Tcl_Obj **)ckalloc(nargs * sizeof(Tcl_Obj *));
+ for (i = 0; i < nargs; ++i) {
+ objv[i] = Tcl_NewIntObj(1);
+ Tcl_IncrRefCount(objv[i]);
+ }
+ if (Tcl_AppendFormatToObj(L->interp, obj, actuals->str,
+ nargs, objv) == TCL_ERROR) {
+ Tcl_ResetResult(L->interp);
+ L_warnf(actuals, "bad format specifier");
+ }
+ Tcl_DecrRefCount(obj);
+ for (i = 0; i < nargs; ++i) {
+ Tcl_DecrRefCount(objv[i]);
+ }
+ ckfree((char *)objv);
+}
+
+/*
+ * Typecheck the declaration of main() against the allowable forms:
+ *
+ * void|int main()
+ * void|int main(void)
+ * void|int main(string av[])
+ * void|int main(int ac, string av[])
+ * void|int main(int ac, string av[], string env{string})
+ */
+void
+L_typeck_main(VarDecl *decl)
+{
+ int n;
+ Type *type = decl->type;
+ VarDecl *v;
+
+ unless (isinttype(type->base_type) || isvoidtype(type->base_type)) {
+ L_errf(decl, "main must have int or void return type");
+ }
+
+ /*
+ * Avoid later unused-variable errors on the argc, argv, or
+ * env formals by marking them as used.
+ */
+ for (n = 0, v = type->u.func.formals; v; v = v->next, ++n) {
+ v->flags |= DECL_ARGUSED;
+ }
+
+ v = type->u.func.formals;
+ switch (n) {
+ case 0:
+ break;
+ case 1:
+ unless (isvoidtype(v->type) ||
+ isarrayoftype(v->type, L_STRING)) {
+ L_errf(v, "invalid parameter types for main()");
+ }
+ break;
+ case 2:
+ unless (isinttype(v->type) &&
+ isarrayoftype(v->next->type, L_STRING)) {
+ L_errf(v, "invalid parameter types for main()");
+ }
+ break;
+ case 3:
+ unless (isinttype(v->type) &&
+ isarrayoftype(v->next->type, L_STRING) &&
+ ishashoftype(v->next->next->type, L_STRING, L_STRING)) {
+ L_errf(v, "invalid parameter types for main()");
+ }
+ break;
+ default:
+ L_errf(v, "too many formal parameters for main()");
+ break;
+ }
+}
+
+/*
+ * Check that a declaration uses legal types. This basically checks
+ * for voids and name-of anywhere in the type where they aren't allowed.
+ */
+int
+L_typeck_declType(VarDecl *decl)
+{
+ return (typeck_declType(decl->type, decl, FALSE));
+}
+private int
+typeck_declType(Type *type, VarDecl *decl, int nameof_ok)
+{
+ int ret = 1;
+ char *s = NULL;
+ VarDecl *v;
+
+ switch (type->kind) {
+ case L_VOID:
+ s = "void";
+ ret = 0;
+ break;
+ case L_FUNCTION:
+ /* First check the return type. Void is legal here. */
+ unless (isvoidtype(type->base_type)) {
+ ret = typeck_declType(type->base_type, decl, FALSE);
+ }
+ /* Now look at the formals. */
+ v = type->u.func.formals;
+ for (v = type->u.func.formals; v; v = v->next) {
+ /* To type-check all formals, don't short-circuit. */
+ ret = typeck_declType(v->type, v, TRUE) && ret;
+ }
+ break;
+ case L_NAMEOF:
+ if (nameof_ok) {
+ /* Pass FALSE since name-of of a name-of is illegal. */
+ ret = typeck_declType(type->base_type, decl, FALSE);
+ } else {
+ s = "name-of";
+ ret = 0;
+ }
+ break;
+ case L_ARRAY:
+ ret = typeck_declType(type->base_type, decl, FALSE);
+ break;
+ case L_HASH:
+ ret = typeck_declType(type->base_type, decl, FALSE) &&
+ typeck_declType(type->u.hash.idx_type, decl, FALSE);
+ break;
+ case L_STRUCT:
+ for (v = type->u.struc.members; v; v = v->next) {
+ /* To type-check all members, don't short-circuit. */
+ ret = typeck_declType(v->type, v, FALSE) && ret;
+ }
+ break;
+ default:
+ break;
+ }
+ if (s) {
+ if (decl->id) {
+ L_errf(decl->id,
+ "type %s illegal in declaration of '%s'",
+ s, decl->id->str);
+ } else {
+ L_errf(decl, "type %s illegal", s);
+ }
+ }
+ return (ret);
+}
+
+/*
+ * Determine if two declaration lists have structurally equivalent
+ * type declarations.
+ */
+private int
+typeck_decls(VarDecl *a, VarDecl *b)
+{
+ for (; a && b; a = a->next, b = b->next) {
+ unless (L_typeck_same(a->type, b->type) &&
+ ((a->flags & (DECL_OPTIONAL | DECL_NAME_EQUIV)) ==
+ (b->flags & (DECL_OPTIONAL | DECL_NAME_EQUIV)))) {
+ return (0);
+ }
+ }
+ /* Not the same if one has more declarations. */
+ return !(a || b);
+}
+
+/*
+ * Check that a variable type is compatible with the element type of
+ * an array type or a list type (which can be compatible with an array
+ * type).
+ */
+int
+L_typeck_arrElt(Type *var, Type *array)
+{
+ switch (array->kind) {
+ case L_ARRAY:
+ // Var must be compat with array element type.
+ return (L_typeck_compat(var, array->base_type));
+ case L_LIST:
+ // Var must be compat with all list elements.
+ for (; array; array = array->next) {
+ unless (L_typeck_compat(var, array->base_type)) {
+ return (0);
+ }
+ }
+ return (1);
+ default:
+ return (0);
+ }
+}
+
+/*
+ * Determine if something is structurally compatible with a list type.
+ */
+private int
+typeck_list(Type *a, Type *b)
+{
+ Type *l, *t;
+ VarDecl *m;
+
+ ASSERT((a->kind == L_LIST) || (b->kind == L_LIST));
+
+ /* If only one of a,b is a list, put that in "l". */
+ if (a->kind == L_LIST) {
+ l = a;
+ t = b;
+ } else {
+ l = b;
+ t = a;
+ }
+
+ switch (t->kind) {
+ case L_ARRAY:
+ /*
+ * A list type is compatible with an array type iff all the
+ * list elements have the same type as the array base type.
+ */
+ for (; l; l = l->next) {
+ ASSERT(l->kind == L_LIST);
+ unless (L_typeck_compat(t->base_type, l->base_type)) {
+ return (0);
+ }
+ }
+ return (1);
+ case L_STRUCT:
+ /*
+ * A list type is compatible with a struct type iff the list
+ * element types match up with the struct member types.
+ */
+ m = t->u.struc.members;
+ while (m && l) {
+ ASSERT(l->kind == L_LIST);
+ unless (L_typeck_compat(l->base_type, m->type)) {
+ return (0);
+ }
+ m = m->next;
+ l = l->next;
+ }
+ return !(l || m); // not the same if one has more elements
+ case L_LIST:
+ /*
+ * Two list types are compatible iff element types
+ * match up, although one can have more.
+ */
+ for (; t && l; t = t->next, l = l->next) {
+ unless (L_typeck_same(l->base_type, t->base_type)) {
+ return (0);
+ }
+ }
+ return (1);
+ default:
+ return (0);
+ }
+}
+
+/*
+ * Determine if two types are structurally equivalent. Note that
+ * polys match anything and strings and widgets are compatible.
+ */
+int
+L_typeck_same(Type *a, Type *b)
+{
+ unless (a && b) return (0);
+
+ /* Polys match anything. */
+ if ((a->kind == L_POLY) || (b->kind == L_POLY)) return (1);
+
+ /* Strings and widgets are compatible. */
+ if ((a->kind & (L_STRING|L_WIDGET)) && (b->kind & (L_STRING|L_WIDGET))){
+ return (1);
+ }
+
+ if ((a->kind == L_LIST) || (b->kind == L_LIST)) {
+ return (typeck_list(a, b));
+ }
+
+ unless (a->kind == b->kind) return (0);
+
+ switch (a->kind) {
+ case L_INT:
+ case L_FLOAT:
+ case L_STRING:
+ case L_WIDGET:
+ case L_VOID:
+ return (1);
+ case L_ARRAY:
+ /* Element types must match (array sizes are ignored). */
+ return (L_typeck_same(a->base_type, b->base_type));
+ case L_HASH:
+ /* Element types must match and index types must match. */
+ return (L_typeck_same(a->base_type, b->base_type) &&
+ L_typeck_same(a->u.hash.idx_type, b->u.hash.idx_type));
+ case L_STRUCT:
+ /* Struct members must match in type and number
+ * but member names can be different. */
+ return (typeck_decls(a->u.struc.members, b->u.struc.members));
+ case L_NAMEOF:
+ return (L_typeck_same(a->base_type, b->base_type));
+ case L_FUNCTION:
+ /* Return types must match and all arg types must match. */
+ return (L_typeck_same(a->base_type, b->base_type) &&
+ typeck_decls(a->u.func.formals, b->u.func.formals));
+ case L_CLASS:
+ /* Must be the same class. */
+ return (a->u.class.clsdecl == b->u.class.clsdecl);
+ default:
+ L_bomb("bad type kind in L_typeck_same");
+ return (0);
+ }
+}
diff --git a/generic/blowfish.c b/generic/blowfish.c
new file mode 100644
index 0000000..c5ccecb
--- /dev/null
+++ b/generic/blowfish.c
@@ -0,0 +1,446 @@
+#include "blowfish.h"
+
+static u32 bfp[] =
+{
+ 0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344,
+ 0xa4093822, 0x299f31d0, 0x082efa98, 0xec4e6c89,
+ 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
+ 0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917,
+ 0x9216d5d9, 0x8979fb1b,
+};
+
+static u32 ks0[] =
+{
+ 0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7,
+ 0xb8e1afed, 0x6a267e96, 0xba7c9045, 0xf12c7f99,
+ 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
+ 0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e,
+ 0x0d95748f, 0x728eb658, 0x718bcd58, 0x82154aee,
+ 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
+ 0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef,
+ 0x8e79dcb0, 0x603a180e, 0x6c9e0e8b, 0xb01e8a3e,
+ 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
+ 0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440,
+ 0x55ca396a, 0x2aab10b6, 0xb4cc5c34, 0x1141e8ce,
+ 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
+ 0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e,
+ 0xafd6ba33, 0x6c24cf5c, 0x7a325381, 0x28958677,
+ 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
+ 0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032,
+ 0xef845d5d, 0xe98575b1, 0xdc262302, 0xeb651b88,
+ 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
+ 0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e,
+ 0x21c66842, 0xf6e96c9a, 0x670c9c61, 0xabd388f0,
+ 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
+ 0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98,
+ 0xa1f1651d, 0x39af0176, 0x66ca593e, 0x82430e88,
+ 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
+ 0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6,
+ 0x4ed3aa62, 0x363f7706, 0x1bfedf72, 0x429b023d,
+ 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
+ 0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7,
+ 0xe3fe501a, 0xb6794c3b, 0x976ce0bd, 0x04c006ba,
+ 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
+ 0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f,
+ 0x6dfc511f, 0x9b30952c, 0xcc814544, 0xaf5ebd09,
+ 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
+ 0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb,
+ 0x5579c0bd, 0x1a60320a, 0xd6a100c6, 0x402c7279,
+ 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
+ 0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab,
+ 0x323db5fa, 0xfd238760, 0x53317b48, 0x3e00df82,
+ 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
+ 0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573,
+ 0x695b27b0, 0xbbca58c8, 0xe1ffa35d, 0xb8f011a0,
+ 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
+ 0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790,
+ 0xe1ddf2da, 0xa4cb7e33, 0x62fb1341, 0xcee4c6e8,
+ 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
+ 0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0,
+ 0xd08ed1d0, 0xafc725e0, 0x8e3c5b2f, 0x8e7594b7,
+ 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
+ 0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad,
+ 0x2f2f2218, 0xbe0e1777, 0xea752dfe, 0x8b021fa1,
+ 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
+ 0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9,
+ 0x165fa266, 0x80957705, 0x93cc7314, 0x211a1477,
+ 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
+ 0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49,
+ 0x00250e2d, 0x2071b35e, 0x226800bb, 0x57b8e0af,
+ 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
+ 0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5,
+ 0x83260376, 0x6295cfa9, 0x11c81968, 0x4e734a41,
+ 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
+ 0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400,
+ 0x08ba6fb5, 0x571be91f, 0xf296ec6b, 0x2a0dd915,
+ 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
+ 0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a
+ };
+
+ static u32 ks1[]=
+ {
+ 0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623,
+ 0xad6ea6b0, 0x49a7df7d, 0x9cee60b8, 0x8fedb266,
+ 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
+ 0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e,
+ 0x3f54989a, 0x5b429d65, 0x6b8fe4d6, 0x99f73fd6,
+ 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
+ 0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e,
+ 0x09686b3f, 0x3ebaefc9, 0x3c971814, 0x6b6a70a1,
+ 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
+ 0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8,
+ 0xb03ada37, 0xf0500c0d, 0xf01c1f04, 0x0200b3ff,
+ 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
+ 0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701,
+ 0x3ae5e581, 0x37c2dadc, 0xc8b57634, 0x9af3dda7,
+ 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
+ 0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331,
+ 0x4e548b38, 0x4f6db908, 0x6f420d03, 0xf60a04bf,
+ 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
+ 0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e,
+ 0x5512721f, 0x2e6b7124, 0x501adde6, 0x9f84cd87,
+ 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
+ 0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2,
+ 0xef1c1847, 0x3215d908, 0xdd433b37, 0x24c2ba16,
+ 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
+ 0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b,
+ 0x043556f1, 0xd7a3c76b, 0x3c11183b, 0x5924a509,
+ 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
+ 0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3,
+ 0x771fe71c, 0x4e3d06fa, 0x2965dcb9, 0x99e71d0f,
+ 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
+ 0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4,
+ 0xf2f74ea7, 0x361d2b3d, 0x1939260f, 0x19c27960,
+ 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
+ 0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28,
+ 0xc332ddef, 0xbe6c5aa5, 0x65582185, 0x68ab9802,
+ 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
+ 0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510,
+ 0x13cca830, 0xeb61bd96, 0x0334fe1e, 0xaa0363cf,
+ 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
+ 0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e,
+ 0x648b1eaf, 0x19bdf0ca, 0xa02369b9, 0x655abb50,
+ 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
+ 0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8,
+ 0xf837889a, 0x97e32d77, 0x11ed935f, 0x16681281,
+ 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
+ 0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696,
+ 0xcdb30aeb, 0x532e3054, 0x8fd948e4, 0x6dbc3128,
+ 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
+ 0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0,
+ 0x45eee2b6, 0xa3aaabea, 0xdb6c4f15, 0xfacb4fd0,
+ 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
+ 0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250,
+ 0xcf62a1f2, 0x5b8d2646, 0xfc8883a0, 0xc1c7b6a3,
+ 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
+ 0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00,
+ 0x58428d2a, 0x0c55f5ea, 0x1dadf43e, 0x233f7061,
+ 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
+ 0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e,
+ 0xa6078084, 0x19f8509e, 0xe8efd855, 0x61d99735,
+ 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
+ 0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9,
+ 0xdb73dbd3, 0x105588cd, 0x675fda79, 0xe3674340,
+ 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
+ 0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7
+};
+
+static u32 ks2[] =
+{
+ 0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934,
+ 0x411520f7, 0x7602d4f7, 0xbcf46b2e, 0xd4a20068,
+ 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
+ 0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840,
+ 0x4d95fc1d, 0x96b591af, 0x70f4ddd3, 0x66a02f45,
+ 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
+ 0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a,
+ 0x28507825, 0x530429f4, 0x0a2c86da, 0xe9b66dfb,
+ 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
+ 0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6,
+ 0xaace1e7c, 0xd3375fec, 0xce78a399, 0x406b2a42,
+ 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
+ 0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2,
+ 0x3a6efa74, 0xdd5b4332, 0x6841e7f7, 0xca7820fb,
+ 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
+ 0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b,
+ 0x55a867bc, 0xa1159a58, 0xcca92963, 0x99e1db33,
+ 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
+ 0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3,
+ 0x95c11548, 0xe4c66d22, 0x48c1133f, 0xc70f86dc,
+ 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
+ 0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564,
+ 0x257b7834, 0x602a9c60, 0xdff8e8a3, 0x1f636c1b,
+ 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
+ 0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922,
+ 0x85b2a20e, 0xe6ba0d99, 0xde720c8c, 0x2da2f728,
+ 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
+ 0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e,
+ 0x0a476341, 0x992eff74, 0x3a6f6eab, 0xf4f8fd37,
+ 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
+ 0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804,
+ 0xf1290dc7, 0xcc00ffa3, 0xb5390f92, 0x690fed0b,
+ 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
+ 0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb,
+ 0x37392eb3, 0xcc115979, 0x8026e297, 0xf42e312d,
+ 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
+ 0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350,
+ 0x1a6b1018, 0x11caedfa, 0x3d25bdd8, 0xe2e1c3c9,
+ 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
+ 0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe,
+ 0x9dbc8057, 0xf0f7c086, 0x60787bf8, 0x6003604d,
+ 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
+ 0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f,
+ 0x77a057be, 0xbde8ae24, 0x55464299, 0xbf582e61,
+ 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
+ 0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9,
+ 0x7aeb2661, 0x8b1ddf84, 0x846a0e79, 0x915f95e2,
+ 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
+ 0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e,
+ 0xb77f19b6, 0xe0a9dc09, 0x662d09a1, 0xc4324633,
+ 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
+ 0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169,
+ 0xdcb7da83, 0x573906fe, 0xa1e2ce9b, 0x4fcd7f52,
+ 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
+ 0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5,
+ 0xf0177a28, 0xc0f586e0, 0x006058aa, 0x30dc7d62,
+ 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
+ 0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76,
+ 0x6f05e409, 0x4b7c0188, 0x39720a3d, 0x7c927c24,
+ 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
+ 0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4,
+ 0x1e50ef5e, 0xb161e6f8, 0xa28514d9, 0x6c51133c,
+ 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
+ 0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0
+};
+
+static u32 ks3[] =
+{
+ 0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b,
+ 0x5cb0679e, 0x4fa33742, 0xd3822740, 0x99bc9bbe,
+ 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
+ 0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4,
+ 0x5748ab2f, 0xbc946e79, 0xc6a376d2, 0x6549c2c8,
+ 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
+ 0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304,
+ 0xa1fad5f0, 0x6a2d519a, 0x63ef8ce2, 0x9a86ee22,
+ 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
+ 0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6,
+ 0x2826a2f9, 0xa73a3ae1, 0x4ba99586, 0xef5562e9,
+ 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
+ 0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593,
+ 0xe990fd5a, 0x9e34d797, 0x2cf0b7d9, 0x022b8b51,
+ 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
+ 0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c,
+ 0xe029ac71, 0xe019a5e6, 0x47b0acfd, 0xed93fa9b,
+ 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
+ 0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c,
+ 0x15056dd4, 0x88f46dba, 0x03a16125, 0x0564f0bd,
+ 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
+ 0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319,
+ 0x7533d928, 0xb155fdf5, 0x03563482, 0x8aba3cbb,
+ 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
+ 0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991,
+ 0xea7a90c2, 0xfb3e7bce, 0x5121ce64, 0x774fbe32,
+ 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
+ 0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166,
+ 0xb39a460a, 0x6445c0dd, 0x586cdecf, 0x1c20c8ae,
+ 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
+ 0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5,
+ 0x72eacea8, 0xfa6484bb, 0x8d6612ae, 0xbf3c6f47,
+ 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
+ 0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d,
+ 0x4040cb08, 0x4eb4e2cc, 0x34d2466a, 0x0115af84,
+ 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
+ 0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8,
+ 0x611560b1, 0xe7933fdc, 0xbb3a792b, 0x344525bd,
+ 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
+ 0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7,
+ 0x1a908749, 0xd44fbd9a, 0xd0dadecb, 0xd50ada38,
+ 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
+ 0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c,
+ 0xbf97222c, 0x15e6fc2a, 0x0f91fc71, 0x9b941525,
+ 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
+ 0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442,
+ 0xe0ec6e0e, 0x1698db3b, 0x4c98a0be, 0x3278e964,
+ 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
+ 0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8,
+ 0xdf359f8d, 0x9b992f2e, 0xe60b6f47, 0x0fe3f11d,
+ 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
+ 0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299,
+ 0xf523f357, 0xa6327623, 0x93a83531, 0x56cccd02,
+ 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
+ 0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614,
+ 0xe6c6c7bd, 0x327a140a, 0x45e1d006, 0xc3f27b9a,
+ 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
+ 0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b,
+ 0x53113ec0, 0x1640e3d3, 0x38abbd60, 0x2547adf0,
+ 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
+ 0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e,
+ 0x1948c25c, 0x02fb8a8c, 0x01c36ae4, 0xd6ebe1f9,
+ 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
+ 0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6
+};
+
+#define N 16
+
+static u32
+F(blf_ctx *bc, u32 x)
+{
+ u32 a, b, c, d, y;
+
+ d = x & 0x00FF;
+ x >>= 8;
+ c = x & 0x00FF;
+ x >>= 8;
+ b = x & 0x00FF;
+ x >>= 8;
+ a = x & 0x00FF;
+ y = bc->S[0][a] + bc->S[1][b];
+ y = y ^ bc->S[2][c];
+ y = y + bc->S[3][d];
+
+ return y;
+}
+
+static void
+Blowfish_encipher(blf_ctx *bc, u32 *xl, u32 *xr)
+{
+ u32 Xl, Xr;
+ u32 temp;
+ short i;
+
+ Xl = *xl;
+ Xr = *xr;
+
+ for (i = 0; i < N; ++i) {
+ Xl = Xl ^ bc->P[i];
+ Xr = F(bc, Xl) ^ Xr;
+
+ temp = Xl;
+ Xl = Xr;
+ Xr = temp;
+ }
+
+ temp = Xl;
+ Xl = Xr;
+ Xr = temp;
+
+ Xr = Xr ^ bc->P[N];
+ Xl = Xl ^ bc->P[N + 1];
+
+ *xl = Xl;
+ *xr = Xr;
+}
+
+static void
+Blowfish_decipher(blf_ctx *bc, u32 *xl, u32 *xr)
+{
+ u32 Xl, Xr;
+ u32 temp;
+ short i;
+
+ Xl = *xl;
+ Xr = *xr;
+
+ for (i = N + 1; i > 1; --i) {
+ Xl = Xl ^ bc->P[i];
+ Xr = F(bc, Xl) ^ Xr;
+
+ /* Exchange Xl and Xr */
+ temp = Xl;
+ Xl = Xr;
+ Xr = temp;
+ }
+
+ /* Exchange Xl and Xr */
+ temp = Xl;
+ Xl = Xr;
+ Xr = temp;
+
+ Xr = Xr ^ bc->P[1];
+ Xl = Xl ^ bc->P[0];
+
+ *xl = Xl;
+ *xr = Xr;
+}
+
+static short
+InitializeBlowfish(blf_ctx *bc, u8 key[], int keybytes)
+{
+ short i, j, k;
+ u32 data, datal, datar;
+
+ /* initialise p & s-boxes without file read */
+ for (i = 0; i < N+2; i++) {
+ bc->P[i] = bfp[i];
+ }
+ for (i = 0; i < 256; i++) {
+ bc->S[0][i] = ks0[i];
+ bc->S[1][i] = ks1[i];
+ bc->S[2][i] = ks2[i];
+ bc->S[3][i] = ks3[i];
+ }
+
+ j = 0;
+ for (i = 0; i < N + 2; ++i) {
+ data = 0x00000000;
+ for (k = 0; k < 4; ++k) {
+ data = (data << 8) | key[j];
+ j = j + 1;
+ if (j >= keybytes) j = 0;
+ }
+ bc->P[i] = bc->P[i] ^ data;
+ }
+
+ datal = 0x00000000;
+ datar = 0x00000000;
+
+ for (i = 0; i < N + 2; i += 2) {
+ Blowfish_encipher(bc, &datal, &datar);
+
+ bc->P[i] = datal;
+ bc->P[i + 1] = datar;
+ }
+
+ for (i = 0; i < 4; ++i) {
+ for (j = 0; j < 256; j += 2) {
+ Blowfish_encipher(bc, &datal, &datar);
+
+ bc->S[i][j] = datal;
+ bc->S[i][j + 1] = datar;
+ }
+ }
+ return 0;
+}
+
+void
+blf_key (blf_ctx *c, u8 *k, int len)
+{
+ InitializeBlowfish(c, k, len);
+}
+
+void
+blf_enc(blf_ctx *c, u32 *data, int blocks)
+{
+ u32 *d;
+ int i;
+
+ d = data;
+ for (i = 0; i < blocks; i++) {
+ Blowfish_encipher(c, d, d+1);
+ d += 2;
+ }
+}
+
+void
+blf_dec(blf_ctx *c, u32 *data, int blocks)
+{
+ u32 *d;
+ int i;
+
+ d = data;
+ for (i = 0; i < blocks; i++) {
+ Blowfish_decipher(c, d, d+1);
+ d += 2;
+ }
+}
diff --git a/generic/blowfish.h b/generic/blowfish.h
new file mode 100644
index 0000000..c6b4396
--- /dev/null
+++ b/generic/blowfish.h
@@ -0,0 +1,12 @@
+typedef unsigned int u32;
+typedef unsigned char u8;
+
+typedef struct {
+ u32 S[4][256];
+ u32 P[18];
+} blf_ctx;
+
+void blf_enc(blf_ctx *c, u32 *data, int blocks);
+void blf_dec(blf_ctx *c, u32 *data, int blocks);
+void blf_key(blf_ctx *c, unsigned char *key, int len);
+
diff --git a/generic/keydecode.c b/generic/keydecode.c
new file mode 100644
index 0000000..0ca011e
--- /dev/null
+++ b/generic/keydecode.c
@@ -0,0 +1,29 @@
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+char *
+keydecode(char *key)
+{
+ unsigned int len, half, i, j;
+ char *newkey;
+
+ if (key == NULL) {
+err: return (key);
+ }
+ len = strlen(key);
+ half = len / 2;
+ if ((len %2) != 0) goto err; /* len must be even */
+
+ newkey = malloc(len);
+
+ /* unpack the old bytes */
+ for (j = 1, i = 0; i < half; i++, j +=2) newkey[j] = key[i];
+
+ /* unpack the even bytes */
+ for (j = 0, i = half; i < len; i++, j +=2) newkey[j] = key[i];
+
+ memcpy(key, newkey, len);
+ free(newkey);
+ return (key);
+}
diff --git a/generic/tcl.h b/generic/tcl.h
index a08edde..7280b03 100644
--- a/generic/tcl.h
+++ b/generic/tcl.h
@@ -9,6 +9,7 @@
* Copyright (c) 1994-1998 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 by Scriptics Corporation.
* Copyright (c) 2002 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -611,6 +612,10 @@ typedef void (Tcl_ThreadCreateProc) (ClientData clientData);
#define TCL_REG_NEWLINE 000300 /* Newlines are line terminators. */
#define TCL_REG_CANMATCH 001000 /* Report details on partial/limited
* matches. */
+#define TCL_REG_BYTEOFFSET 002000 /* Use byte offsets instead of
+ character offsets. */
+#define TCL_REG_PCRE 0x08000000 /* Make sure it doesn't conflict with
+ * existing TCL_REG_* or PCRE_* bits */
/*
* Flags values passed to Tcl_RegExpExecObj.
@@ -807,7 +812,16 @@ typedef struct Tcl_ObjType {
*/
typedef struct Tcl_Obj {
- int refCount; /* When 0 the object will be freed. */
+#ifndef TCL_MEM_DEBUG
+ unsigned int undef:1; /* Used by L to mark an object as having
+ * the undef value. Steal a bit from
+ * refCount to avoid increasing the
+ * Tcl_Obj memory footprint. */
+ int refCount:31; /* When 0 the object will be freed. */
+#else
+ int refCount;
+ int undef;
+#endif
char *bytes; /* This points to the first byte of the
* object's string representation. The array
* must be followed by a null byte (i.e., at
@@ -1997,6 +2011,9 @@ typedef struct Tcl_Token {
* literal character prefix "{*}". This word is
* marked to be expanded - that is, broken into
* words after substitution is complete.
+ * TCL_TOKEN_PRAGMA - This token handles pragma directives that might
+ * switch the parser used. Currently only the L
+ * language is supported.
*/
#define TCL_TOKEN_WORD 1
@@ -2008,6 +2025,7 @@ typedef struct Tcl_Token {
#define TCL_TOKEN_SUB_EXPR 64
#define TCL_TOKEN_OPERATOR 128
#define TCL_TOKEN_EXPAND_WORD 256
+#define TCL_TOKEN_PRAGMA 512
/*
* Parsing error types. On any parsing error, one of these values will be
diff --git a/generic/tclBasic.c b/generic/tclBasic.c
index a09bf10..0cb278b 100644
--- a/generic/tclBasic.c
+++ b/generic/tclBasic.c
@@ -12,6 +12,7 @@
* Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
* Copyright (c) 2006-2008 by Joe Mistachkin. All rights reserved.
* Copyright (c) 2008 Miguel Sofer <msofer@users.sourceforge.net>
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -262,6 +263,23 @@ static const CmdInfo builtInCmds[] = {
{"yieldto", NULL, TclCompileYieldToCmd, TclNRYieldToObjCmd, CMD_IS_SAFE},
/*
+ * L Commands
+ */
+
+ {"L", Tcl_LObjCmd, NULL, NULL, 1},
+ {"shsplit", Tcl_ShSplitObjCmd, NULL, NULL, 1},
+ {"fgetline", Tcl_FGetlineObjCmd, NULL, NULL, 1},
+ {"angle_read_", Tcl_LAngleReadObjCmd, NULL, NULL, 1},
+ {"Lread_", Tcl_LReadCmd, NULL, NULL, 1},
+ {"Lwrite_", Tcl_LWriteCmd, NULL, NULL, 1},
+ {"Lrefcnt", Tcl_LRefCnt, NULL, NULL, 1},
+ {"defined", Tcl_LDefined, NULL, NULL, 1},
+ {"Lhtml", Tcl_LHtmlObjCmd, NULL, NULL, 1},
+ {"LgetNextLine_", Tcl_LGetNextLine, NULL, NULL, 1},
+ {"LgetNextLineInit_", Tcl_LGetNextLineInit, NULL, NULL, 1},
+ {"getdirx", Tcl_LGetDirX, NULL, NULL, 1},
+
+ /*
* Commands in the OS-interface. Note that many of these are unsafe.
*/
@@ -277,6 +295,8 @@ static const CmdInfo builtInCmds[] = {
{"fcopy", Tcl_FcopyObjCmd, NULL, NULL, CMD_IS_SAFE},
{"fileevent", Tcl_FileEventObjCmd, NULL, NULL, CMD_IS_SAFE},
{"flush", Tcl_FlushObjCmd, NULL, NULL, CMD_IS_SAFE},
+ {"getopt", Tcl_GetOptObjCmd, NULL, NULL, 0},
+ {"getoptReset", Tcl_GetOptResetObjCmd, NULL, NULL, 0},
{"gets", Tcl_GetsObjCmd, NULL, NULL, CMD_IS_SAFE},
{"glob", Tcl_GlobObjCmd, NULL, NULL, 0},
{"load", Tcl_LoadObjCmd, NULL, NULL, 0},
@@ -597,6 +617,13 @@ Tcl_CreateInterp(void)
iPtr->evalFlags = 0;
iPtr->scriptFile = NULL;
iPtr->flags = 0;
+#ifdef HAVE_PCRE
+#ifdef USE_DEFAULT_PCRE
+ if (getenv("TCL_REGEXP_CLASSIC") == NULL) { iPtr->flags |= INTERP_PCRE; }
+#else
+ if (getenv("TCL_REGEXP_PCRE") != NULL) { iPtr->flags |= INTERP_PCRE; }
+#endif
+#endif
iPtr->tracePtr = NULL;
iPtr->tracesForbiddingInline = 0;
iPtr->activeCmdTracePtr = NULL;
@@ -5181,6 +5208,23 @@ TclEvalEx(
TclContinuationsEnterDerived(objv[objectsUsed],
wordStart - outerScript, wordCLNext);
}
+
+ /*
+ * If this is the L command and we just processed the first
+ * command word (i.e., the "L"), inject an argument --line=%d
+ * before the next command word. This communicates the source
+ * line # to the L compiler.
+ */
+ if (!objectsUsed &&
+ (!strncmp("L", tokenPtr->start, tokenPtr->size) ||
+ !strncmp("Lhtml", tokenPtr->start, tokenPtr->size))) {
+ ++numWords;
+ ++objectsUsed;
+ ++objectsNeeded;
+ objv[objectsUsed] = Tcl_ObjPrintf("--line=%d", lines[0]+1);
+ Tcl_IncrRefCount(objv[objectsUsed]);
+ expand[objectsUsed] = 0;
+ }
} /* for loop */
iPtr->cmdFramePtr = eeFramePtr;
if (code != TCL_OK) {
diff --git a/generic/tclCmdIL.c b/generic/tclCmdIL.c
index d723e4b..d08ac02 100644
--- a/generic/tclCmdIL.c
+++ b/generic/tclCmdIL.c
@@ -12,6 +12,7 @@
* Copyright (c) 1998-1999 by Scriptics Corporation.
* Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
* Copyright (c) 2005 Donal K. Fellows.
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
diff --git a/generic/tclCmdMZ.c b/generic/tclCmdMZ.c
index 13f9e7d..c30bce2 100644
--- a/generic/tclCmdMZ.c
+++ b/generic/tclCmdMZ.c
@@ -130,24 +130,34 @@ Tcl_RegexpObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- int i, indices, match, about, offset, all, doinline, numMatchesSaved;
- int cflags, eflags, stringLength, matchLength;
+ int i, indices, about, offset, all, doinline;
+ int cflags, iflags, re_type;
+ Tcl_Obj *startIndex = NULL;
Tcl_RegExp regExpr;
- Tcl_Obj *objPtr, *startIndex = NULL, *resultPtr = NULL;
- Tcl_RegExpInfo info;
static const char *const options[] = {
"-all", "-about", "-indices", "-inline",
"-expanded", "-line", "-linestop", "-lineanchor",
- "-nocase", "-start", "--", NULL
+ "-nocase", "-start", "-type", "--", NULL
};
enum options {
REGEXP_ALL, REGEXP_ABOUT, REGEXP_INDICES, REGEXP_INLINE,
REGEXP_EXPANDED,REGEXP_LINE, REGEXP_LINESTOP,REGEXP_LINEANCHOR,
- REGEXP_NOCASE, REGEXP_START, REGEXP_LAST
+ REGEXP_NOCASE,REGEXP_START, REGEXP_TYPE, REGEXP_LAST
+ };
+ static CONST char *re_type_opts[] = {
+ "classic", "pcre", NULL
+ };
+ enum re_type_opts {
+ RETYPE_CLASSIC, RETYPE_PCRE,
};
indices = 0;
about = 0;
+#ifdef USE_DEFAULT_PCRE
+ re_type = RETYPE_PCRE;
+#else
+ re_type = RETYPE_CLASSIC;
+#endif
cflags = TCL_REG_ADVANCED;
offset = 0;
all = 0;
@@ -208,6 +218,15 @@ Tcl_RegexpObjCmd(
Tcl_IncrRefCount(startIndex);
break;
}
+ case REGEXP_TYPE:
+ if (++i >= objc) {
+ goto endOfForLoop;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[i], re_type_opts, "type",
+ 0, &re_type) != TCL_OK) {
+ goto optionError;
+ }
+ break;
case REGEXP_LAST:
i++;
goto endOfForLoop;
@@ -233,22 +252,16 @@ Tcl_RegexpObjCmd(
"regexp match variables not allowed when using -inline", -1));
Tcl_SetErrorCode(interp, "TCL", "OPERATION", "REGEXP",
"MIX_VAR_INLINE", NULL);
- goto optionError;
+ optionError:
+ if (startIndex) {
+ Tcl_DecrRefCount(startIndex);
+ }
+ return TCL_ERROR;
}
- /*
- * Handle the odd about case separately.
- */
-
- if (about) {
- regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
- if ((regExpr == NULL) || (TclRegAbout(interp, regExpr) < 0)) {
- optionError:
- if (startIndex) {
- Tcl_DecrRefCount(startIndex);
- }
- return TCL_ERROR;
- }
+ /* L undef never matches anything. */
+ if (objv[1]->undef) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
return TCL_OK;
}
@@ -258,10 +271,19 @@ Tcl_RegexpObjCmd(
* regexp to avoid shimmering problems.
*/
- objPtr = objv[1];
- stringLength = Tcl_GetCharLength(objPtr);
-
if (startIndex) {
+ int stringLength;
+
+ if ((enum re_type_opts) re_type == RETYPE_CLASSIC) {
+ stringLength = Tcl_GetCharLength(objv[1]);
+ } else {
+ if (objv[1]->typePtr == &tclByteArrayType) {
+ (void) Tcl_GetByteArrayFromObj(objv[1], &stringLength);
+ } else {
+ /* XXX validate offset by char length */
+ (void) Tcl_GetStringFromObj(objv[1], &stringLength);
+ }
+ }
TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
Tcl_DecrRefCount(startIndex);
if (offset < 0) {
@@ -269,201 +291,43 @@ Tcl_RegexpObjCmd(
}
}
+ /*
+ * Handle the odd about case separately, otherwise pass of to appropriate
+ * RE engine.
+ */
+
+ iflags = ((Interp *)interp)->flags;
+ if ((enum re_type_opts) re_type == RETYPE_PCRE) {
+ cflags |= TCL_REG_PCRE;
+ } else if (iflags & INTERP_PCRE) {
+ /* Prevent -type classic from being overridden compiling RE */
+ ((Interp *)interp)->flags &= ~(INTERP_PCRE);
+ }
regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
+ ((Interp *)interp)->flags = iflags;
if (regExpr == NULL) {
return TCL_ERROR;
}
- objc -= 2;
- objv += 2;
-
- if (doinline) {
- /*
- * Save all the subexpressions, as we will return them as a list
- */
-
- numMatchesSaved = -1;
- } else {
- /*
- * Save only enough subexpressions for matches we want to keep, expect
- * in the case of -all, where we need to keep at least one to know
- * where to move the offset.
- */
-
- numMatchesSaved = (objc == 0) ? all : objc;
- }
-
- /*
- * The following loop is to handle multiple matches within the same source
- * string; each iteration handles one match. If "-all" hasn't been
- * specified then the loop body only gets executed once. We terminate the
- * loop when the starting offset is past the end of the string.
- */
-
- while (1) {
- /*
- * Pass either 0 or TCL_REG_NOTBOL in the eflags. Passing
- * TCL_REG_NOTBOL indicates that the character at offset should not be
- * considered the start of the line. If for example the pattern {^} is
- * passed and -start is positive, then the pattern will not match the
- * start of the string unless the previous character is a newline.
- */
-
- if (offset == 0) {
- eflags = 0;
- } else if (offset > stringLength) {
- eflags = TCL_REG_NOTBOL;
- } else if (Tcl_GetUniChar(objPtr, offset-1) == (Tcl_UniChar)'\n') {
- eflags = 0;
- } else {
- eflags = TCL_REG_NOTBOL;
- }
-
- match = Tcl_RegExpExecObj(interp, regExpr, objPtr, offset,
- numMatchesSaved, eflags);
- if (match < 0) {
- return TCL_ERROR;
- }
-
- if (match == 0) {
- /*
- * We want to set the value of the intepreter result only when
- * this is the first time through the loop.
- */
-
- if (all <= 1) {
- /*
- * If inlining, the interpreter's object result remains an
- * empty list, otherwise set it to an integer object w/ value
- * 0.
- */
-
- if (!doinline) {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
- }
- return TCL_OK;
- }
- break;
- }
-
- /*
- * If additional variable names have been specified, return index
- * information in those variables.
- */
-
- Tcl_RegExpGetInfo(regExpr, &info);
- if (doinline) {
- /*
- * It's the number of substitutions, plus one for the matchVar at
- * index 0
- */
-
- objc = info.nsubs + 1;
- if (all <= 1) {
- resultPtr = Tcl_NewObj();
- }
- }
- for (i = 0; i < objc; i++) {
- Tcl_Obj *newPtr;
-
- if (indices) {
- int start, end;
- Tcl_Obj *objs[2];
-
- /*
- * Only adjust the match area if there was a match for that
- * area. (Scriptics Bug 4391/SF Bug #219232)
- */
-
- if (i <= info.nsubs && info.matches[i].start >= 0) {
- start = offset + info.matches[i].start;
- end = offset + info.matches[i].end;
-
- /*
- * Adjust index so it refers to the last character in the
- * match instead of the first character after the match.
- */
-
- if (end >= offset) {
- end--;
- }
- } else {
- start = -1;
- end = -1;
- }
-
- objs[0] = Tcl_NewLongObj(start);
- objs[1] = Tcl_NewLongObj(end);
-
- newPtr = Tcl_NewListObj(2, objs);
- } else {
- if (i <= info.nsubs) {
- newPtr = Tcl_GetRange(objPtr,
- offset + info.matches[i].start,
- offset + info.matches[i].end - 1);
- } else {
- newPtr = Tcl_NewObj();
- }
- }
- if (doinline) {
- if (Tcl_ListObjAppendElement(interp, resultPtr, newPtr)
- != TCL_OK) {
- Tcl_DecrRefCount(newPtr);
- Tcl_DecrRefCount(resultPtr);
- return TCL_ERROR;
- }
- } else {
- if (Tcl_ObjSetVar2(interp, objv[i], NULL, newPtr,
- TCL_LEAVE_ERR_MSG) == NULL) {
- return TCL_ERROR;
- }
+ if ((enum re_type_opts) re_type == RETYPE_CLASSIC) {
+ if (about) {
+ if (TclRegAbout(interp, regExpr) < 0) {
+ return TCL_ERROR;
}
+ return TCL_OK;
}
- if (all == 0) {
- break;
- }
-
- /*
- * Adjust the offset to the character just after the last one in the
- * matchVar and increment all to count how many times we are making a
- * match. We always increment the offset by at least one to prevent
- * endless looping (as in the case: regexp -all {a*} a). Otherwise,
- * when we match the NULL string at the end of the input string, we
- * will loop indefinately (because the length of the match is 0, so
- * offset never changes).
- */
-
- matchLength = (info.matches[0].end - info.matches[0].start);
-
- offset += info.matches[0].end;
-
- /*
- * A match of length zero could happen for {^} {$} or {.*} and in
- * these cases we always want to bump the index up one.
- */
-
- if (matchLength == 0) {
- offset++;
- }
- all++;
- if (offset >= stringLength) {
- break;
+ return TclRegexpClassic(interp, objc, objv, regExpr,
+ all, indices, doinline, offset);
+ } else {
+ if (about) {
+ /* XXX: implement PCRE about */
+ return TCL_OK;
}
- }
-
- /*
- * Set the interpreter's object result to an integer object with value 1
- * if -all wasn't specified, otherwise it's all-1 (the number of times
- * through the while - 1).
- */
- if (doinline) {
- Tcl_SetObjResult(interp, resultPtr);
- } else {
- Tcl_SetObjResult(interp, Tcl_NewIntObj(all ? all-1 : 1));
+ return TclRegexpPCRE(interp, objc, objv, regExpr,
+ all, indices, doinline, offset);
}
- return TCL_OK;
}
/*
@@ -490,27 +354,41 @@ Tcl_RegsubObjCmd(
int objc, /* Number of arguments. */
Tcl_Obj *const objv[]) /* Argument objects. */
{
- int idx, result, cflags, all, wlen, wsublen, numMatches, offset;
- int start, end, subStart, subEnd, match;
+ int idx, result, cflags, iflags, all, wlen, wsublen, numMatches, offset;
+ int start, end, subStart, subEnd, match, re_type, prevOffset;
+ int subMatchVarsElemc = 0;
Tcl_RegExp regExpr;
Tcl_RegExpInfo info;
Tcl_Obj *resultPtr, *subPtr, *objPtr, *startIndex = NULL;
+ Tcl_Obj **subMatchVarsElemv = NULL;
Tcl_UniChar ch, *wsrc, *wfirstChar, *wstring, *wsubspec, *wend;
static const char *const options[] = {
"-all", "-nocase", "-expanded",
"-line", "-linestop", "-lineanchor", "-start",
- "--", NULL
+ "-submatches", "-type", "--", NULL
};
enum options {
REGSUB_ALL, REGSUB_NOCASE, REGSUB_EXPANDED,
REGSUB_LINE, REGSUB_LINESTOP, REGSUB_LINEANCHOR, REGSUB_START,
- REGSUB_LAST
+ REGSUB_SUBMATCHES, REGSUB_TYPE, REGSUB_LAST
+ };
+ static CONST char *re_type_opts[] = {
+ "classic", "pcre", NULL
+ };
+ enum re_type_opts {
+ RETYPE_CLASSIC, RETYPE_PCRE,
};
+#ifdef USE_DEFAULT_PCRE
+ re_type = RETYPE_PCRE;
+#else
+ re_type = RETYPE_CLASSIC;
+#endif
cflags = TCL_REG_ADVANCED;
all = 0;
offset = 0;
+ prevOffset = 0;
resultPtr = NULL;
for (idx = 1; idx < objc; idx++) {
@@ -559,9 +437,27 @@ Tcl_RegsubObjCmd(
Tcl_IncrRefCount(startIndex);
break;
}
+ case REGSUB_TYPE:
+ if (++idx >= objc) {
+ goto endOfForLoop;
+ }
+ if (Tcl_GetIndexFromObj(interp, objv[idx], re_type_opts, "type",
+ 0, &re_type) != TCL_OK) {
+ goto optionError;
+ }
+ break;
case REGSUB_LAST:
idx++;
goto endOfForLoop;
+ case REGSUB_SUBMATCHES:
+ if (++idx >= objc) {
+ goto endOfForLoop;
+ }
+ if (TclListObjGetElements(interp, objv[idx], &subMatchVarsElemc,
+ &subMatchVarsElemv) != TCL_OK) {
+ goto optionError;
+ }
+ break;
}
}
@@ -580,8 +476,18 @@ Tcl_RegsubObjCmd(
objv += idx;
if (startIndex) {
- int stringLength = Tcl_GetCharLength(objv[1]);
+ int stringLength;
+ if ((enum re_type_opts) re_type == RETYPE_CLASSIC) {
+ stringLength = Tcl_GetCharLength(objv[1]);
+ } else {
+ if (objv[1]->typePtr == &tclByteArrayType) {
+ (void) Tcl_GetByteArrayFromObj(objv[1], &stringLength);
+ } else {
+ /* XXX validate offset by char length */
+ (void) Tcl_GetStringFromObj(objv[1], &stringLength);
+ }
+ }
TclGetIntForIndexM(NULL, startIndex, stringLength, &offset);
Tcl_DecrRefCount(startIndex);
if (offset < 0) {
@@ -660,7 +566,15 @@ Tcl_RegsubObjCmd(
goto regsubDone;
}
+ iflags = ((Interp *)interp)->flags;
+ if ((enum re_type_opts) re_type == RETYPE_PCRE) {
+ cflags |= TCL_REG_PCRE;
+ } else if (iflags & INTERP_PCRE) {
+ /* Prevent -type classic from being overridden compiling RE */
+ ((Interp *)interp)->flags &= ~(INTERP_PCRE);
+ }
regExpr = Tcl_GetRegExpFromObj(interp, objv[0], cflags);
+ ((Interp *)interp)->flags = iflags;
if (regExpr == NULL) {
return TCL_ERROR;
}
@@ -716,6 +630,7 @@ Tcl_RegsubObjCmd(
if (match == 0) {
break;
}
+ prevOffset = offset;
if (numMatches == 0) {
resultPtr = Tcl_NewUnicodeObj(wstring, 0);
Tcl_IncrRefCount(resultPtr);
@@ -764,6 +679,22 @@ Tcl_RegsubObjCmd(
wfirstChar = wsrc + 2;
wsrc++;
continue;
+ } else if (re_type == RETYPE_PCRE) {
+ switch (ch) {
+ case 'a': *wsrc = '\a'; break;
+ case 'e': *wsrc = '\e'; break;
+ case 'f': *wsrc = '\f'; break;
+ case 'n': *wsrc = '\n'; break;
+ case 'r': *wsrc = '\r'; break;
+ case 't': *wsrc = '\t'; break;
+ default: *wsrc = ch; break;
+ }
+ Tcl_AppendUnicodeToObj(resultPtr, wfirstChar,
+ wsrc - wfirstChar + 1);
+ *wsrc = '\\';
+ wfirstChar = wsrc + 2;
+ wsrc++;
+ continue;
} else {
continue;
}
@@ -825,6 +756,25 @@ Tcl_RegsubObjCmd(
}
/*
+ * Return the regexp submatches in the requested variables.
+ */
+ if (numMatches && subMatchVarsElemc) {
+ for (idx = 0; (idx <= info.nsubs) && (idx < subMatchVarsElemc); ++idx) {
+ subStart = info.matches[idx].start;
+ subEnd = info.matches[idx].end;
+ Tcl_Obj *obj = Tcl_NewUnicodeObj(wstring + prevOffset + subStart,
+ subEnd - subStart);
+ Tcl_IncrRefCount(obj);
+ if (Tcl_ObjSetVar2(interp, subMatchVarsElemv[idx], NULL, obj,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ Tcl_DecrRefCount(obj);
+ return (TCL_ERROR);
+ }
+ Tcl_DecrRefCount(obj);
+ }
+ }
+
+ /*
* Copy the portion of the source string after the last match to the
* result variable.
*/
diff --git a/generic/tclCompCmds.c b/generic/tclCompCmds.c
index 18da741..436be2a 100644
--- a/generic/tclCompCmds.c
+++ b/generic/tclCompCmds.c
@@ -8,6 +8,7 @@
* Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
* Copyright (c) 2002 ActiveState Corporation.
* Copyright (c) 2004-2013 by Donal K. Fellows.
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
diff --git a/generic/tclCompile.c b/generic/tclCompile.c
index f62ec14..2d959c0 100644
--- a/generic/tclCompile.c
+++ b/generic/tclCompile.c
@@ -7,6 +7,7 @@
*
* Copyright (c) 1996-1998 Sun Microsystems, Inc.
* Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -662,6 +663,51 @@ InstructionDesc const tclInstructionTable[] = {
{"lappendListStk", 1, -1, 0, {OPERAND_NONE}},
/* Lappend list to general variable.
* Stack: ... varName list => ... listVarContents */
+ {"rot", 2, 0, 1, {OPERAND_UINT1}},
+ /* Rotate the top opnd elements in the stack */
+ {"l-index", 5, -1, 1, {OPERAND_UINT4}},
+ /* Index into a nested struct/array/hash. opnd contains flags,
+ * index is stktop, object to index into is stknext. */
+ {"l-deep-write", 9, -1, 2, {OPERAND_UINT4, OPERAND_UINT4}},
+ /* Write via L deep pointer pushed by l-index above. opnd1 is a local
+ * var index of a var that points to the top-level object being
+ * indexed; it will be written if the top-level object needed to be
+ * copied by l-index for copy-on-write. opnd2 contains flags
+ * indicating whether to leave old or new value on stack top.
+ * stktop is the L deep pointer, stknext is the value to write. */
+ {"lsplit", 2, 0, 1, {OPERAND_UINT4}},
+ /* Perl-like string split. opnd is a flags word (see Expr_f),
+ * stack contains the limit (optional), then the delimeter
+ * (optional) then the string to split. */
+ {"l-defined", 1, 0, 0, {OPERAND_NONE}},
+ /* Test whether value at stackTop is the L undefined value. */
+ {"l-push-list-size", 1, 0, 0, {OPERAND_NONE}},
+ /* Store the size of the list at stktop in the internal L
+ * sizes stack. Sizes are used to implement the L END keyword. */
+ {"l-push-string-size", 1, 0, 0, {OPERAND_NONE}},
+ /* Store the length of the string at stktop in the internal L
+ * sizes stack. */
+ {"l-read-size", 1, 1, 0, {OPERAND_NONE}},
+ /* Push what's on the top of the internal L sizes stack. */
+ {"l-pop-size", 1, 0, 0, {OPERAND_NONE}},
+ /* Pop the internal L sizes stack. */
+ {"l-push-undef", 1, 1, 0, {OPERAND_NONE}},
+ /* Push the L undef object. */
+ {"expandRot", 2, 0, 1, {OPERAND_UINT1}},
+ /* Rotate the top opnd1 stack elements with those after
+ * the expand marker (see expandStart). */
+ {"l-lindex-stk", 2, 1, 1, {OPERAND_UINT1}},
+ /* push(listindex stktop opnd) except if opnd is <0 or
+ * > # list elements then push the L undef object. */
+ {"l-list-insert", 9, 0, 3, {OPERAND_LVT4, OPERAND_UINT4}},
+ /* Insert into list local var. Operands are local slot index,
+ * flags, and list index to insert before (0 means prepend,
+ * -1 means append). */
+ {"unsetLocal", 5, 0, 1, {OPERAND_LVT4}},
+ /* Unset the local variable at index op1. */
+ {"different-obj", 5, 0, 1, {OPERAND_LVT4}},
+ /* Determine whether the variable whose name is at stktop
+ * points to a different object as the given local. */
{NULL, 0, 0, 0, {OPERAND_NONE}}
};
@@ -1809,13 +1855,29 @@ TclCompileInvocation(
int numWords,
CompileEnv *envPtr)
{
- int wordIdx = 0, depth = TclGetStackDepth(envPtr);
+ int adjust = 0, wordIdx = 0, depth = TclGetStackDepth(envPtr);
+ char *cmd, *s;
+ Tcl_Obj *obj;
DefineLineInformation;
if (cmdObj) {
CompileCmdLiteral(interp, cmdObj, envPtr);
wordIdx = 1;
tokenPtr = TokenAfter(tokenPtr);
+ cmd = Tcl_GetString(cmdObj);
+ if (!strcmp("L", cmd) || !strcmp("Lhtml", cmd)) {
+ /*
+ * If this is the L or Lhtml command, push the argument --line=%d
+ * to it now. This communicates the source line # to the L
+ * compiler.
+ */
+ obj = Tcl_ObjPrintf("--line=%d", envPtr->line+1);
+ Tcl_IncrRefCount(obj);
+ s = TclGetString(obj);
+ adjust = TclRegisterNewLiteral(envPtr, s, strlen(s));
+ Tcl_DecrRefCount(obj);
+ TclEmitPush(adjust, envPtr);
+ }
}
for (; wordIdx < numWords; wordIdx++, tokenPtr = TokenAfter(tokenPtr)) {
@@ -1837,6 +1899,14 @@ TclCompileInvocation(
TclEmitPush(objIdx, envPtr);
}
+ /*
+ * Possible adjust for L-command argument injection (see comment
+ * above).
+ */
+ if (adjust) {
+ ++wordIdx;
+ }
+
if (wordIdx <= 255) {
TclEmitInvoke(envPtr, INST_INVOKE_STK1, wordIdx);
} else {
@@ -1853,7 +1923,8 @@ CompileExpanded(
int numWords,
CompileEnv *envPtr)
{
- int wordIdx = 0;
+ int adjust = 0, wordIdx = 0;
+ char *cmd;
DefineLineInformation;
int depth = TclGetStackDepth(envPtr);
@@ -1862,6 +1933,23 @@ CompileExpanded(
CompileCmdLiteral(interp, cmdObj, envPtr);
wordIdx = 1;
tokenPtr = TokenAfter(tokenPtr);
+ cmd = Tcl_GetString(cmdObj);
+ if (!strcmp("L", cmd) || !strcmp("Lhtml", cmd)) {
+ /*
+ * If this is the L or Lhtml command, push the argument --line=%d
+ * to it now. This communicates the source line # to the L
+ * compiler.
+ */
+ char *s;
+ Tcl_Obj *obj;
+
+ obj = Tcl_ObjPrintf("--line=%d", envPtr->line+1);
+ Tcl_IncrRefCount(obj);
+ s = TclGetString(obj);
+ adjust = TclRegisterNewLiteral(envPtr, s, strlen(s));
+ Tcl_DecrRefCount(obj);
+ TclEmitPush(adjust, envPtr);
+ }
}
for (; wordIdx < numWords; wordIdx++, tokenPtr = TokenAfter(tokenPtr)) {
@@ -1888,6 +1976,14 @@ CompileExpanded(
}
/*
+ * Possible adjust for L-command argument injection (see comment
+ * above).
+ */
+ if (adjust) {
+ ++wordIdx;
+ }
+
+ /*
* The stack depth during argument expansion can only be managed at
* runtime, as the number of elements in the expanded lists is not known
* at compile time. We adjust here the stack depth estimate so that it is
diff --git a/generic/tclCompile.h b/generic/tclCompile.h
index b89346d..ce20f4a 100644
--- a/generic/tclCompile.h
+++ b/generic/tclCompile.h
@@ -5,6 +5,7 @@
* Copyright (c) 1998-2000 by Scriptics Corporation.
* Copyright (c) 2001 by Kevin B. Kenny. All rights reserved.
* Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -821,8 +822,25 @@ typedef struct ByteCode {
#define INST_LAPPEND_LIST_ARRAY_STK 187
#define INST_LAPPEND_LIST_STK 188
+/* L stuff */
+#define INST_ROT 189
+#define INST_L_INDEX 190
+#define INST_L_DEEP_WRITE 191
+#define INST_L_SPLIT 192
+#define INST_L_DEFINED 193
+#define INST_L_PUSH_LIST_SIZE 194
+#define INST_L_PUSH_STR_SIZE 195
+#define INST_L_READ_SIZE 196
+#define INST_L_POP_SIZE 197
+#define INST_L_PUSH_UNDEF 198
+#define INST_EXPAND_ROT 199
+#define INST_L_LINDEX_STK 200
+#define INST_L_LIST_INSERT 201
+#define INST_UNSET_LOCAL 202
+#define INST_DIFFERENT_OBJ 203
+
/* The last opcode */
-#define LAST_INST_OPCODE 188
+#define LAST_INST_OPCODE 203
/*
* Table describing the Tcl bytecode instructions: their name (for displaying
diff --git a/generic/tclDisassemble.c b/generic/tclDisassemble.c
index 86f0e1d..027b2c4 100644
--- a/generic/tclDisassemble.c
+++ b/generic/tclDisassemble.c
@@ -794,7 +794,6 @@ PrintSourceToObj(
{
register const char *p;
register int i = 0, len;
- Tcl_UniChar ch = 0;
if (stringPtr == NULL) {
Tcl_AppendToObj(appendObj, "\"\"", -1);
@@ -803,65 +802,38 @@ PrintSourceToObj(
Tcl_AppendToObj(appendObj, "\"", -1);
p = stringPtr;
- for (; (*p != '\0') && (i < maxChars); p+=len) {
+ for (; (*p != '\0') && (i < maxChars); ++i, p+=len) {
+ Tcl_UniChar ch;
len = TclUtfToUniChar(p, &ch);
switch (ch) {
case '"':
Tcl_AppendToObj(appendObj, "\\\"", -1);
- i += 2;
continue;
case '\f':
Tcl_AppendToObj(appendObj, "\\f", -1);
- i += 2;
continue;
case '\n':
Tcl_AppendToObj(appendObj, "\\n", -1);
- i += 2;
continue;
case '\r':
Tcl_AppendToObj(appendObj, "\\r", -1);
- i += 2;
continue;
case '\t':
Tcl_AppendToObj(appendObj, "\\t", -1);
- i += 2;
continue;
case '\v':
Tcl_AppendToObj(appendObj, "\\v", -1);
- i += 2;
continue;
default:
-#if TCL_UTF_MAX > 4
- if (ch > 0xffff) {
- Tcl_AppendPrintfToObj(appendObj, "\\U%08x", ch);
- i += 10;
- } else
-#elif TCL_UTF_MAX > 3
- /* If len == 0, this means we have a char > 0xffff, resulting in
- * TclUtfToUniChar producing a surrogate pair. We want to output
- * this pair as a single Unicode character.
- */
- if (len == 0) {
- int upper = ((ch & 0x3ff) + 1) << 10;
- len = TclUtfToUniChar(p, &ch);
- Tcl_AppendPrintfToObj(appendObj, "\\U%08x", upper + (ch & 0x3ff));
- i += 10;
- } else
-#endif
if (ch < 0x20 || ch >= 0x7f) {
Tcl_AppendPrintfToObj(appendObj, "\\u%04x", ch);
- i += 6;
} else {
Tcl_AppendPrintfToObj(appendObj, "%c", ch);
- i++;
}
continue;
}
}
- if (*p != '\0') {
- Tcl_AppendToObj(appendObj, "...", -1);
- }
Tcl_AppendToObj(appendObj, "\"", -1);
}
@@ -1395,13 +1367,6 @@ Tcl_DisassembleObjCmd(
* Do the actual disassembly.
*/
- if (BYTECODE(codeObjPtr)->flags & TCL_BYTECODE_PRECOMPILED) {
- Tcl_SetObjResult(interp, Tcl_NewStringObj(
- "may not disassemble prebuilt bytecode", -1));
- Tcl_SetErrorCode(interp, "TCL", "OPERATION", "DISASSEMBLE",
- "BYTECODE", NULL);
- return TCL_ERROR;
- }
if (PTR2INT(clientData)) {
Tcl_SetObjResult(interp, DisassembleByteCodeAsDicts(codeObjPtr));
} else {
diff --git a/generic/tclExecute.c b/generic/tclExecute.c
index 7f65262..1510453 100644
--- a/generic/tclExecute.c
+++ b/generic/tclExecute.c
@@ -10,6 +10,7 @@
* Copyright (c) 2005-2007 by Donal K. Fellows.
* Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
* Copyright (c) 2006-2008 by Joe Mistachkin. All rights reserved.
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -18,7 +19,9 @@
#include "tclInt.h"
#include "tclCompile.h"
#include "tclOOInt.h"
+#include "tclRegexp.h"
#include "tommath.h"
+#include "Lcompile.h"
#include <math.h>
#if NRE_ENABLE_ASSERTS
@@ -76,7 +79,7 @@ int tclTraceExec = 0;
* expression opcodes (e.g., INST_LOR) in tclCompile.h.
*
* Does not include the string for INST_EXPON (and beyond), as that is
- * disjoint for backward-compatability reasons.
+ * disjoint for backward-compatibility reasons.
*/
static const char *const operatorStrings[] = {
@@ -840,6 +843,290 @@ ReleaseDictIterator(
objPtr->typePtr = NULL;
}
+
+/*
+ * The L "sizes stack" is a separate run-time stack managed by the
+ * INST_L_PUSH_LIST_SIZE, INST_L_PUSH_STR_SIZE, INST_L_READ_SIZE, and
+ * INST_L_POP_SIZE opcodes. The first two push onto this stack the length
+ * (size) of the list (string) at stktop. INST_L_READ_SIZE pushes onto the
+ * regular stack the size at the top of L sizes stack, and INST_L_POP_SIZE
+ * pops the L stack. These are used to implement the L END keyword with
+ * minimal overhead.
+ */
+static int *L_sizes_stack = NULL;
+static int L_sizes_stack_top = -1;
+static int L_sizes_stack_size = 0;
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * L_sizes_push --
+ *
+ * Push a size onto the internal L sizes stack.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline void
+L_sizes_push(int size)
+{
+ if ((L_sizes_stack_top+1) >= L_sizes_stack_size) {
+ if (L_sizes_stack_size == 0) {
+ L_sizes_stack_size = 32;
+ } else {
+ L_sizes_stack_size *= 2;
+ }
+ L_sizes_stack = (int *)ckrealloc((void *)L_sizes_stack,
+ L_sizes_stack_size * sizeof(int));
+ }
+ L_sizes_stack[++L_sizes_stack_top] = size;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * L_sizes_top --
+ *
+ * Return the stack top of the L internal sizes stack. The
+ * stack must not be empty when called.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline int
+L_sizes_top()
+{
+ if (L_sizes_stack_top < 0) Tcl_Panic("topped empty L sizes stack");
+ return (L_sizes_stack[L_sizes_stack_top]);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * L_sizes_pop --
+ *
+ * Pop the L internal sizes stack. The stack must not be empty when
+ * called.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static inline void
+L_sizes_pop()
+{
+ if (L_sizes_stack_top < 0) Tcl_Panic("popped empty L sizes stack");
+ --L_sizes_stack_top;
+}
+
+/*
+ * Special object types for the L language to store object pointers. These are
+ * created only by L bytecodes (INST_L_INDEX) and are left on the run-time
+ * stack only transiently to be consumed by other L bytecodes
+ * (INST_L_DEEP_WRITE). L_deepPtr1Type is used when indexing an array or
+ * hash. L_deepPtr2Type is used when indexing a string or doing a delete.
+ */
+
+static Tcl_ObjType L_deepPtr1Type = {
+ "l-deepType1",
+ NULL, /* freeIntRepProc */
+ NULL, /* dupIntRepProc */
+ NULL, /* updateStringProc */
+ NULL /* setFromAnyProc */
+};
+static Tcl_ObjType L_deepPtr2Type = {
+ "l-deepType2",
+ NULL, /* freeIntRepProc */
+ NULL, /* dupIntRepProc */
+ NULL, /* updateStringProc */
+ NULL /* setFromAnyProc */
+};
+
+/*
+ * For a L_deepPtr1Type, the internal rep fits into the Tcl_Obj internalRep
+ * field (two pointers). For a L_deepPtr2Type, we allocate a struct and point
+ * to it from the Tcl_Obj internalRep. The struct below is overlayed onto one
+ * of these two pieces of memory.
+ */
+typedef struct {
+ Tcl_Obj *topLevObj; // outer-most enclosing object
+ Tcl_Obj **elemPtrPtr; // ptr to the object being pointed to
+ // The following exist only in a L_deepPtr2Type.
+ Tcl_Obj *parentObj; // enclosing object
+ Tcl_Obj *idxObj; // index of array/hash/string
+ int flags;
+} L_DeepPtr;
+
+static inline int
+L_isDeepPtr(Tcl_Obj *objPtr)
+{
+ return ((objPtr->typePtr == &L_deepPtr1Type) ||
+ (objPtr->typePtr == &L_deepPtr2Type));
+}
+
+static inline L_DeepPtr *
+L_deepPtrGet(Tcl_Obj *objPtr)
+{
+ ASSERT(L_isDeepPtr(objPtr));
+ if (objPtr->typePtr == &L_deepPtr1Type) {
+ return (L_DeepPtr *)&objPtr->internalRep.otherValuePtr;
+ } else {
+ return (L_DeepPtr *)objPtr->internalRep.otherValuePtr;
+ }
+}
+
+/*
+ * Allocate an L deep-pointer object. flags tells us whether a small or large
+ * one is needed: a large one for an L_DELETE operation or a string index, and
+ * a small one for everything else.
+ */
+static inline Tcl_Obj *
+L_deepPtrNew(int flags, Tcl_Obj *objPtr, Tcl_Obj *idxObj, Tcl_Obj **elemPtrPtr)
+{
+ Tcl_Obj *deepPtrObj = Tcl_NewObj();
+ L_DeepPtr *deepPtr;
+
+ if (flags & (L_DELETE | L_IDX_STRING)) {
+ deepPtr = (L_DeepPtr *)ckalloc(sizeof(L_DeepPtr));
+
+ deepPtr->parentObj = objPtr;
+ Tcl_IncrRefCount(objPtr);
+
+ deepPtr->idxObj = idxObj;
+ Tcl_IncrRefCount(idxObj);
+
+ deepPtr->flags = flags;
+
+ deepPtrObj->typePtr = &L_deepPtr2Type;
+ deepPtrObj->internalRep.otherValuePtr = deepPtr;
+ } else {
+ ASSERT(flags & (L_IDX_ARRAY | L_IDX_HASH));
+ deepPtr = (L_DeepPtr *)&deepPtrObj->internalRep.otherValuePtr;
+
+ deepPtrObj->typePtr = &L_deepPtr1Type;
+ }
+
+ deepPtr->elemPtrPtr = elemPtrPtr;
+ Tcl_IncrRefCount(*elemPtrPtr);
+
+ deepPtr->topLevObj = objPtr;
+ Tcl_IncrRefCount(objPtr);
+
+ return (deepPtrObj);
+}
+
+/*
+ * Re-use the given deepPtr object. Note that once the compiler needs a large
+ * one, it never goes back to asking for a small one.
+ */
+static inline void
+L_deepPtrSet(Tcl_Obj *deepPtrObj, int flags, Tcl_Obj *objPtr, Tcl_Obj *idxObj,
+ Tcl_Obj **elemPtrPtr)
+{
+ L_DeepPtr *deepPtr = L_deepPtrGet(deepPtrObj);
+
+ // Ensured by caller.
+ ASSERT(*deepPtr->elemPtrPtr == objPtr);
+
+ // Assert !(flags & (L_DELETE|L_IDX_STRING)) => already a L_deepPtr1Type.
+ ASSERT((flags & (L_DELETE|L_IDX_STRING)) ||
+ (deepPtrObj->typePtr == &L_deepPtr1Type));
+
+ if (flags & (L_DELETE | L_IDX_STRING)) {
+ if (deepPtrObj->typePtr == &L_deepPtr1Type) {
+ // Have L_deepPtr1Type, need L_deepPtr2Type.
+ L_DeepPtr *newDeepPtr = (L_DeepPtr *)ckalloc(sizeof(L_DeepPtr));
+
+ newDeepPtr->topLevObj = deepPtr->topLevObj;
+
+ newDeepPtr->parentObj = objPtr;
+ Tcl_IncrRefCount(objPtr);
+
+ newDeepPtr->idxObj = idxObj;
+ Tcl_IncrRefCount(idxObj);
+
+ newDeepPtr->flags = flags;
+
+ deepPtrObj->typePtr = &L_deepPtr2Type;
+ deepPtrObj->internalRep.otherValuePtr = newDeepPtr;
+ deepPtr = newDeepPtr;
+ } else {
+ Tcl_Obj *oldParentObj = deepPtr->parentObj;
+ Tcl_Obj *oldIdxObj = deepPtr->idxObj;
+
+ deepPtr->parentObj = objPtr;
+ Tcl_IncrRefCount(objPtr);
+
+ deepPtr->idxObj = idxObj;
+ Tcl_IncrRefCount(idxObj);
+
+ deepPtr->flags = flags;
+
+ Tcl_DecrRefCount(oldParentObj);
+ Tcl_DecrRefCount(oldIdxObj);
+ }
+ }
+
+ deepPtr->elemPtrPtr = elemPtrPtr;
+ Tcl_IncrRefCount(*elemPtrPtr);
+
+ deepPtrObj->refCount = 0;
+}
+
+static inline void
+L_deepPtrFree(Tcl_Obj *deepPtrObj)
+{
+ L_DeepPtr *deepPtr;
+
+ unless (deepPtrObj) return;
+ if (deepPtrObj->typePtr == &L_deepPtr1Type) {
+ deepPtr = (L_DeepPtr *)&deepPtrObj->internalRep.otherValuePtr;
+ Tcl_DecrRefCount(deepPtr->topLevObj);
+ } else {
+ deepPtr = (L_DeepPtr *)deepPtrObj->internalRep.otherValuePtr;
+ Tcl_DecrRefCount(deepPtr->parentObj);
+ Tcl_DecrRefCount(deepPtr->idxObj);
+ Tcl_DecrRefCount(deepPtr->topLevObj);
+ ckfree((char *)deepPtr);
+ }
+ ASSERT(deepPtrObj->refCount == 1);
+ Tcl_DecrRefCount(deepPtrObj);
+}
+
+/*
+ * The following two functions save and set an object's refCount to 1 so that
+ * it can be modified, and restore it to its original value. This facilitates
+ * the L deep-dive bytecodes where we know an object is unshared but we may
+ * have stack or deepPtr refs to it. Experience has shown that the code is
+ * simpler if we just do this ugly hack.
+ */
+
+static inline int
+refCnt_save(Tcl_Obj *objPtr)
+{
+ int old = objPtr->refCount;
+ objPtr->refCount = 1;
+ return (old);
+}
+
+static inline void
+refCnt_restore(Tcl_Obj *objPtr, int old)
+{
+ ASSERT(objPtr->refCount == 1);
+ objPtr->refCount = old;
+}
+
+/*
+ * Duplicate part of struct Dict from tclDictObj.c; all we need is the
+ * first member. The deep-dive execution code uses it to traverse
+ * hashes. WARNING: this may break if dicts change their internal
+ * rep!
+ */
+typedef struct Dict {
+ Tcl_HashTable table; /* Object hash table to store mapping in. */
+} Dict;
+
+static Tcl_Obj **L_deepDive(Tcl_Interp *interp, Tcl_Obj *obj, Tcl_Obj *idxObj,
+ Expr_f flags);
/*
*----------------------------------------------------------------------
@@ -2666,6 +2953,25 @@ TEBCresume(
TRACE_WITH_OBJ(("%u => ", opnd), objResultPtr);
NEXT_INST_F(5, 0, 1);
+ case INST_ROT: {
+ int opnd;
+
+ opnd = TclGetInt1AtPtr(pc+1);
+ if (opnd > 0) {
+ objResultPtr = OBJ_AT_DEPTH(opnd);
+ memmove(&OBJ_AT_DEPTH(opnd), &OBJ_AT_DEPTH(opnd-1), opnd*sizeof(Tcl_Obj *));
+ OBJ_AT_TOS = objResultPtr;
+ TRACE_WITH_OBJ(("=> "), objResultPtr);
+ } else if (opnd < 0) {
+ opnd = -opnd;
+ objResultPtr = OBJ_AT_TOS;
+ memmove(&OBJ_AT_DEPTH(opnd-1), &OBJ_AT_DEPTH(opnd), opnd*sizeof(Tcl_Obj *));
+ OBJ_AT_DEPTH(opnd) = objResultPtr;
+ TRACE_WITH_OBJ(("=> "), objResultPtr);
+ }
+ NEXT_INST_F(2, 0, 0);
+ }
+
case INST_REVERSE: {
Tcl_Obj **a, **b;
@@ -2941,6 +3247,28 @@ TEBCresume(
NEXT_INST_F(5, 0, 0);
}
+ case INST_EXPAND_ROT: {
+ int depth;
+ int opnd = TclGetUInt1AtPtr(pc+1);
+ Tcl_Obj *objPtr = auxObjList;
+ char *save;
+
+ if (objPtr == NULL) {
+ TRACE(("%u => error: aux stack empty", opnd));
+ result = TCL_ERROR;
+ goto checkForCatch;
+ }
+ depth = CURR_DEPTH - PTR2INT(objPtr->internalRep.twoPtrValue.ptr1);
+ save = ckalloc(opnd * sizeof(Tcl_Obj *));
+ memmove(save, &OBJ_AT_DEPTH(opnd-1), opnd*sizeof(Tcl_Obj *));
+ memmove(&OBJ_AT_DEPTH(depth-opnd-1), &OBJ_AT_DEPTH(depth-1),
+ (depth-opnd)*sizeof(Tcl_Obj *));
+ memmove(&OBJ_AT_DEPTH(depth-1), save, opnd*sizeof(Tcl_Obj *));
+ ckfree(save);
+ TRACE(("%u %u =>", opnd, depth));
+ NEXT_INST_F(2, 0, 0);
+ }
+
case INST_EXPR_STK: {
ByteCode *newCodePtr;
@@ -3192,7 +3520,7 @@ TEBCresume(
* Start of INST_LOAD instructions.
*
* WARNING: more 'goto' here than your doctor recommended! The different
- * instructions set the value of some variables and then jump to some
+ * instructions set the value of some variables and then jump to somme
* common execution code.
*/
@@ -3756,7 +4084,7 @@ TEBCresume(
* Start of INST_INCR instructions.
*
* WARNING: more 'goto' here than your doctor recommended! The different
- * instructions set the value of some variables and then jump to somme
+ * instructions set the value of some variables and then jump to some
* common execution code.
*/
@@ -5029,7 +5357,9 @@ TEBCresume(
case INST_LIST_LENGTH:
TRACE(("\"%.30s\" => ", O2S(OBJ_AT_TOS)));
- if (TclListObjLength(interp, OBJ_AT_TOS, &length) != TCL_OK) {
+ if ((OBJ_AT_TOS)->undef) {
+ length = 0;
+ } else if (TclListObjLength(interp, OBJ_AT_TOS, &length) != TCL_OK) {
TRACE_ERROR(interp);
goto gotError;
}
@@ -5392,7 +5722,26 @@ TEBCresume(
value2Ptr = OBJ_AT_TOS;
valuePtr = OBJ_UNDER_TOS;
- if (valuePtr == value2Ptr) {
+ if (valuePtr->undef ^ value2Ptr->undef) {
+ /* L undef never equals anything that's defined. */
+ switch (*pc) {
+ case INST_EQ:
+ case INST_STR_EQ:
+ case INST_LT:
+ case INST_LE:
+ case INST_NEQ:
+ case INST_STR_NEQ:
+ match = 1;
+ break;
+ case INST_GT:
+ case INST_GE:
+ match = -1;
+ break;
+ case INST_STR_CMP:
+ match = 0;
+ break;
+ }
+ } else if (valuePtr == value2Ptr) {
match = 0;
} else {
/*
@@ -5426,8 +5775,8 @@ TEBCresume(
&& (valuePtr->bytes != NULL)
&& (s2len == value2Ptr->length)
&& (value2Ptr->bytes != NULL)) {
- s1 = valuePtr->bytes;
- s2 = value2Ptr->bytes;
+ s1 = TclGetString(valuePtr);
+ s2 = TclGetString(value2Ptr);
memCmpFn = memcmp;
} else {
s1 = (char *) Tcl_GetUnicode(valuePtr);
@@ -5516,7 +5865,11 @@ TEBCresume(
case INST_STR_LEN:
valuePtr = OBJ_AT_TOS;
- length = Tcl_GetCharLength(valuePtr);
+ if (valuePtr->undef) {
+ length = 0;
+ } else {
+ length = Tcl_GetCharLength(valuePtr);
+ }
TclNewIntObj(objResultPtr, length);
TRACE(("\"%.20s\" => %d\n", O2S(valuePtr), length));
NEXT_INST_F(1, 1, 1);
@@ -5998,7 +6351,10 @@ TEBCresume(
* both.
*/
- if ((valuePtr->typePtr == &tclStringType)
+ /* L undef never equals anything that's defined. */
+ if (valuePtr->undef ^ value2Ptr->undef) {
+ match = 0;
+ } else if ((valuePtr->typePtr == &tclStringType)
|| (value2Ptr->typePtr == &tclStringType)) {
Tcl_UniChar *ustring1, *ustring2;
@@ -6101,6 +6457,15 @@ TEBCresume(
TRACE(("\"%.30s\" \"%.30s\" => ", O2S(valuePtr), O2S(value2Ptr)));
/*
+ * cflags won't use PCRE flag indicator during compilation
+ * XXX may use TCL_REG_ADVANCED to indicate -type classic for
+ * XXX compilation, but currently -type isn't compiled
+ */
+ if (((Interp *)interp)->flags & INTERP_PCRE) {
+ cflags |= TCL_REG_PCRE;
+ }
+
+ /*
* Compile and match the regular expression.
*/
@@ -6111,8 +6476,12 @@ TEBCresume(
if (regExpr == NULL) {
TRACE_ERROR(interp);
goto gotError;
+ } else if (valuePtr->undef ^ value2Ptr->undef) {
+ /* L undef never equals anything that's defined. */
+ match = 0;
+ } else {
+ match = Tcl_RegExpExecObj(interp, regExpr, valuePtr, 0, 0, 0);
}
- match = Tcl_RegExpExecObj(interp, regExpr, valuePtr, 0, 0, 0);
if (match < 0) {
TRACE_ERROR(interp);
goto gotError;
@@ -6123,7 +6492,7 @@ TEBCresume(
/*
* Peep-hole optimisation: if you're about to jump, do jump from here.
- * Adjustment is 2 due to the nocase byte.
+ * Adjustment is 2 due to the cflags byte.
*/
JUMP_PEEPHOLE_F(match, 2, 2);
@@ -6184,6 +6553,11 @@ TEBCresume(
value2Ptr = OBJ_AT_TOS;
valuePtr = OBJ_UNDER_TOS;
+ /* L undef never equals anything that's defined. */
+ if (valuePtr->undef ^ value2Ptr->undef) {
+ iResult = (*pc == INST_NEQ);
+ goto foundResult;
+ }
if (GetNumberFromObj(NULL, valuePtr, &ptr1, &type1) != TCL_OK) {
/*
* At least one non-numeric argument - compare as strings.
@@ -6992,6 +7366,7 @@ TEBCresume(
for (j = 0; j < numVars; j++) {
if (valIndex >= listLen) {
TclNewObj(valuePtr);
+ valuePtr->undef = 1;
} else {
valuePtr = elements[valIndex];
}
@@ -7908,6 +8283,651 @@ TEBCresume(
* -----------------------------------------------------------------
*/
+ /*
+ * Opcodes for the L language.
+ */
+
+ case INST_L_INDEX: {
+ /*
+ * Index into an L array, hash, struct, or string, and return either
+ * the indexed value or an L "deep pointer". On entry, the stack is
+ * (the stack top is on the right):
+ *
+ * <obj | deep-ptr> <idx>
+ *
+ * <obj> is the object being indexed in to. An L deep pointer
+ * <deep-ptr> from a previous instance of this instruction also can be
+ * used; this is how multiple levels are indexed.
+ *
+ * On exit, the stack configuration depends on what flags are in
+ * the instruction:
+ *
+ * <elem-val> if flags & L_PUSH_VAL
+ * <deep-ptr> if flags & L_PUSH_PTR
+ * <elem-val> <deep-ptr> if flags & L_PUSH_VALPTR
+ * <deep-ptr> <elem-val> if flags & L_PUSH_PTRVAL
+ * (nothing) if flags & L_DISCARD
+ *
+ * where <elem-val> is the object in <obj> referenced by the given
+ * index and <deep-ptr> is an object of L_deepPtrType type that only
+ * this code and the INST_L_DEEP_WRITE bytecode know about. It is
+ * basically a pointer to <elem-val> that can be used to index or
+ * modify the element in-place later.
+ *
+ * If flags & L_VALUE, it is assumed that the element is going to be
+ * written later by INST_L_DEEP_WRITE, so if any part of the path to
+ * that element is shared, an unshared copy is made. If this results
+ * in the top-level object itself getting copied, the new obj gets
+ * written back into the local variable when the INST_L_DEEP_WRITE is
+ * done later. This is possible since the <deep-ptr> encapsulates a
+ * back-pointer to the top-level object.
+ */
+
+ Tcl_Obj **elemPtrPtr;
+ Tcl_Obj *idxObj, *objPtr;
+ Tcl_Obj *deepPtrObj = NULL;
+ L_DeepPtr *deepPtr = NULL;
+ int dropRefCnt = 0;
+ unsigned int flags = TclGetUInt4AtPtr(pc+1);
+ int lvalue = (flags & L_LVALUE);
+ int needPtr = (flags & (L_PUSH_PTR | L_PUSH_PTRVAL | L_PUSH_VALPTR));
+
+ // needPtr => L_PUSH_VAL not set
+ ASSERT(!needPtr || !(flags & L_PUSH_VAL));
+
+ /*
+ * Get the bytecode arguments -- the index and object being indexed in
+ * to. If the object is a deep pointer from an earlier instance of
+ * this bytecode, de-reference it and get the object from inside it.
+ */
+ idxObj = POP_OBJECT();
+ objPtr = POP_OBJECT();
+ if (L_isDeepPtr(objPtr)) {
+ deepPtrObj = objPtr;
+ deepPtr = L_deepPtrGet(deepPtrObj);
+ objPtr = *(deepPtr->elemPtrPtr);
+ /*
+ * Enclosing obj ref + deepPtr ref == 2. Not >2 because in
+ * previous iterations through here we already ensured the
+ * sub-object is an un-shared copy.
+ */
+ ASSERT (!lvalue || (objPtr->refCount == 2));
+ ASSERT (!Tcl_IsShared(deepPtrObj));
+ }
+
+ /*
+ * Drop the stack ref to the object being indexed. We have to do this
+ * now, because we might need to modify the object (e.g., to extend an
+ * array) and list operations on shared objects will fail. But if the
+ * stack ref is the only ref (which happens when you index a constant
+ * or a function's return value), we have to delay it or else the
+ * object will get deleted. A little ugly, but there's no way around
+ * this.
+ */
+ if (objPtr->refCount == 1) {
+ ASSERT(deepPtrObj == NULL);
+ dropRefCnt = 1;
+ } else {
+ /*
+ * This drops either the stack ref (deepPtrObj==NULL) or the
+ * deepPtr ref (objPtr=*elemPtrPtr in that case; this is why
+ * L_deepPtrSet() and L_deepPtrFree() do not drop the *elemPtrPtr
+ * ref).
+ */
+ Tcl_DecrRefCount(objPtr);
+ }
+
+ /*
+ * Special handling for l-values: ensure we have an un-shared copy.
+ * Note that only the top-level object, i.e., the target of the first
+ * index of a sequence of indices into a nested object, will get
+ * copied here. Sub-objects inside the top-level also need to be
+ * un-shared, but L_deepDive() copies those, so by the time we get
+ * back around here in the next iteration to index into *them*, they
+ * won't be shared (the ASSERT below verifies this).
+ */
+ if (lvalue && Tcl_IsShared(objPtr)) {
+ ASSERT(deepPtrObj == NULL);
+ objPtr = Tcl_DuplicateObj(objPtr);
+ Tcl_IncrRefCount(objPtr);
+ /*
+ * We're going to modify an element of this list in-place later,
+ * so also create an unshared copy of the internal list
+ * representation. Tcl_DuplicateObj() does not do this.
+ */
+ if (objPtr->typePtr == &tclListType) {
+ TclDuplicateListRep(objPtr);
+ }
+ dropRefCnt = 1;
+ }
+
+ /*
+ * Index into the object.
+ */
+ elemPtrPtr = L_deepDive(interp, objPtr, idxObj, flags);
+ if (!elemPtrPtr) {
+ if (dropRefCnt) Tcl_DecrRefCount(objPtr); // drop stack/deepPtr ref
+ Tcl_DecrRefCount(idxObj); // drop stack ref
+ result = TCL_ERROR;
+ goto checkForCatch;
+ }
+
+ /*
+ * If flags indicate a deep-ptr is needed, make an L_deepPtrType object
+ * that refers to the indexed element and stash the top-level object
+ * pointer and other bookkeeping in there. The top-level object is
+ * needed in the INST_L_DEEP_WRITE coming later to update the variable
+ * being written. If a deep ptr was already on the stack, recycle it
+ * (and note that it already points to the top-level object).
+ */
+ if (needPtr) {
+ if (deepPtrObj) {
+ L_deepPtrSet(deepPtrObj, flags, objPtr, idxObj, elemPtrPtr);
+ } else {
+ deepPtrObj = L_deepPtrNew(flags, objPtr, idxObj, elemPtrPtr);
+ }
+ }
+
+ /*
+ * Leave the value, deep-pointer, or both on the stack as requested by
+ * the input flags.
+ */
+ switch (flags &
+ (L_PUSH_VAL|L_PUSH_PTR|L_PUSH_PTRVAL|L_PUSH_VALPTR|L_DISCARD)) {
+ case L_PUSH_VAL:
+ PUSH_OBJECT(*elemPtrPtr);
+ L_deepPtrFree(deepPtrObj);
+ TRACE_WITH_OBJ(("L_PUSH_VAL => "), OBJ_AT_TOS);
+ break;
+ case L_PUSH_PTR:
+ PUSH_OBJECT(deepPtrObj);
+ TRACE_WITH_OBJ(("L_PUSH_PTR => "), OBJ_AT_TOS);
+ break;
+ case L_PUSH_PTRVAL:
+ PUSH_OBJECT(deepPtrObj);
+ PUSH_OBJECT(*elemPtrPtr);
+ TRACE(("L_PUSH_PTRVAL => \"%.30s\" \"%.30s\"",
+ O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
+ break;
+ case L_PUSH_VALPTR:
+ PUSH_OBJECT(*elemPtrPtr);
+ PUSH_OBJECT(deepPtrObj);
+ TRACE(("L_PUSH_VALPTR => \"%.30s\" \"%.30s\"",
+ O2S(OBJ_UNDER_TOS), O2S(OBJ_AT_TOS)));
+ break;
+ case L_DISCARD:
+ L_deepPtrFree(deepPtrObj);
+ TRACE(("L_DISCARD => \n"));
+ break;
+ default:
+ Tcl_Panic("illegal operand to INST_L_INDEX");
+ break;
+ }
+
+ /* Drop the stack refs. */
+ if (dropRefCnt) Tcl_DecrRefCount(objPtr);
+ Tcl_DecrRefCount(idxObj);
+
+ NEXT_INST_F(5, 0, 0);
+ }
+
+ case INST_L_DEEP_WRITE: {
+ /*
+ * Write to, or delete, an element of a hash/array/struct/string and
+ * store the top-level hash/array/struct/string object in a local.
+ * Leave on the stack the old element value, the new element value, or
+ * nothing, as requested.
+ *
+ * Stack on entry (the stack top is on the right):
+ *
+ * [<rval>] <l-deep-ptr> [<arrayIdx>]
+ *
+ * <l-deep-ptr> L deep pointer that is created only by
+ * INST_L_INDEX (above). This "points" to what
+ * we're indexing in to or deleting.
+ * <rval> Object to assign to the object pointed
+ * to by <l-deep-ptr>. Not present for L_DELETE.
+ * <arrayIdx> Array index. Preset only for L_INSERT_ELT
+ * and L_INSERT_LIST. An index of -1 means
+ * append.
+ *
+ * Instruction arguments:
+ *
+ * opnd1 (one byte): A local index. The top-level array/hash/struct/
+ * string object that is encapsulated in the <l-deep-ptr> is
+ * stored in this local. In older versions of deep dive,
+ * this used to be done with an extra bytecode.
+ *
+ * opnd2 (four bytes): flags, as follows:
+ *
+ * L_IDX_STRING, L_IDX_ARRAY, L_IDX_HASH, L_INSERT_ELT,
+ * L_INSERT_LIST, L_DELETE
+ * Indicates what kind of object we're indexing in to and whether
+ * we're writing a single element, deleting an element, or
+ * inserting an element or another list into a list (array).
+ * Mutually exclusive.
+ *
+ * L_PUSH_NEW, L_PUSH_OLD, L_DISCARD
+ * Whether to leave the new value, old value, or nothing on the
+ * stack. Mutually exclusive.
+ */
+
+ int arrayIdx = 0, ret, save;
+ Tcl_Obj *arrayIdxObj, *deepPtrObj, *oldvalObj, *rvalObj = NULL;
+ Tcl_Obj *currTopLevObj, *newTopLevObj;
+ Var *varPtr;
+ L_DeepPtr *deepPtr;
+ unsigned int flags, idx;
+
+ idx = TclGetUInt4AtPtr(pc+1);
+ flags = TclGetUInt4AtPtr(pc+5);
+ // assert flags & L_DELETE => !(flags & L_PUSH_NEW)
+ ASSERT(!(flags & L_DELETE) || !(flags & L_PUSH_NEW));
+
+ /* Pop the array index, if present. */
+ if (flags & (L_INSERT_ELT | L_INSERT_LIST)) {
+ arrayIdxObj = POP_OBJECT();
+ if (TclGetIntFromObj(NULL, arrayIdxObj, &arrayIdx) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot convert index to integer",
+ NULL);
+ result = TCL_ERROR;
+ goto checkForCatch;
+ }
+ Tcl_DecrRefCount(arrayIdxObj);
+ if (arrayIdx == -1) arrayIdx = INT_MAX;
+ }
+ /* Pop the other instruction arguments. */
+ deepPtrObj = POP_OBJECT();
+ unless (flags & L_DELETE) rvalObj = POP_OBJECT();
+ deepPtr = L_deepPtrGet(deepPtrObj);
+ ASSERT (!Tcl_IsShared(deepPtrObj));
+ if (deepPtrObj->typePtr == &L_deepPtr2Type) flags |= deepPtr->flags;
+
+ /*
+ * currTopLevObj is what the local currently points to. If it was
+ * shared, newTopLevObj got an unshared copy (made by INST_L_INDEX).
+ * We will write into the unshared copy in-place and set the var to it
+ * below.
+ */
+ varPtr = &(compiledLocals[idx]);
+ while (TclIsVarLink(varPtr)) {
+ varPtr = varPtr->value.linkPtr;
+ }
+ currTopLevObj = varPtr->value.objPtr;
+ newTopLevObj = deepPtr->topLevObj;
+
+ /*
+ * Write or append the new value to the indexed element, or delete the
+ * indexed element, as requested.
+ */
+ oldvalObj = *(deepPtr->elemPtrPtr);
+ switch (flags & (L_IDX_STRING|L_INSERT_ELT|L_INSERT_LIST|L_DELETE)) {
+ case L_IDX_STRING:
+ case L_IDX_STRING | L_DELETE: {
+ int len, str_idx;
+ Tcl_UniChar *tmp;
+ Tcl_Obj *newStr;
+ Tcl_Obj *target = deepPtr->parentObj;
+
+ /* Check for writing to index beyond string's end. */
+ TclGetIntFromObj(NULL, deepPtr->idxObj, &str_idx);
+ len = Tcl_GetCharLength(target);
+ if (str_idx > len) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp,
+ "index is more than one past end of string",
+ NULL);
+ result = TCL_ERROR;
+ goto checkForCatch;
+ }
+ /* Copy to newStr chars up to but skipping the given index. */
+ newStr = Tcl_GetRange(target, 0, str_idx-1);
+ Tcl_IncrRefCount(newStr);
+ unless (flags & L_DELETE) {
+ /* Append the rval obj. */
+ Tcl_AppendObjToObj(newStr, rvalObj);
+ }
+ /* Append to newStr all chars after the given index. */
+ if (str_idx < len) {
+ Tcl_Obj *r = Tcl_GetRange(target, str_idx+1, len-1);
+ Tcl_IncrRefCount(r);
+ Tcl_AppendObjToObj(newStr, r);
+ Tcl_DecrRefCount(r);
+ }
+ /*
+ * Assign newStr to target. Possible target ref counts:
+ * If a one-level index like s[2] = "x" and s unshared:
+ * deepPtr->topLevObj + deepPtr->parentObj + var ref (s)
+ * If a one-level index like s[2] = "x" and s was shared:
+ * deepPtr->topLevObj + deepPtr->parentObj
+ * (because INST_L_INDEX dup'd but s isn't pointing to it yet)
+ * Note that a multi-level index like s[0][2] = "x" is
+ * disallowed by the compiler.
+ */
+ ASSERT((target->refCount == 2) || (target->refCount == 3));
+ tmp = Tcl_GetUnicodeFromObj(newStr, &len);
+ save = refCnt_save(target);
+ Tcl_SetUnicodeObj(target, tmp, len);
+ refCnt_restore(target, save);
+ Tcl_DecrRefCount(newStr);
+ break;
+ }
+ case L_INSERT_ELT:
+ case L_INSERT_LIST: {
+ int objc;
+ Tcl_Obj **objv;
+
+ /*
+ * oldvalObj has a stack ref and a deepPtr ref, so drop one so
+ * we can append to it (it must be unshared), then restore it
+ * (since it's dropped later by L_deepPtrFree()).
+ */
+ ASSERT(oldvalObj->refCount == 2);
+ ASSERT(rvalObj);
+ Tcl_DecrRefCount(oldvalObj);
+ if (flags & L_INSERT_ELT) {
+ Tcl_ListObjReplace(interp, oldvalObj, arrayIdx, 0,
+ 1, &rvalObj);
+ } else {
+ Tcl_ListObjGetElements(interp, rvalObj, &objc, &objv);
+ Tcl_ListObjReplace(interp, oldvalObj, arrayIdx, 0,
+ objc, objv);
+ }
+ Tcl_IncrRefCount(oldvalObj);
+ Tcl_IncrRefCount(oldvalObj);
+ break;
+ }
+ case L_DELETE:
+ save = refCnt_save(deepPtr->parentObj);
+ if (deepPtr->flags & L_IDX_HASH) {
+ ret = Tcl_DictObjRemove(interp, deepPtr->parentObj,
+ deepPtr->idxObj);
+ } else if (deepPtr->flags & L_IDX_ARRAY) {
+ int i;
+ TclGetIntFromObj(NULL, deepPtr->idxObj, &i);
+ ret = Tcl_ListObjReplace(interp, deepPtr->parentObj,
+ i, 1, 0, NULL);
+ } else {
+ /* Not array or hash? error! */
+ ret = TCL_ERROR;
+ }
+ refCnt_restore(deepPtr->parentObj, save);
+ if (ret != TCL_OK) {
+ Tcl_Panic("err deleting element in INST_L_DEEP_WRITE");
+ }
+ break;
+ default:
+ *(deepPtr->elemPtrPtr) = rvalObj;
+ Tcl_IncrRefCount(rvalObj); // add parent obj ref
+ ASSERT(oldvalObj->refCount >= 2);
+ Tcl_DecrRefCount(oldvalObj); // drop old parent obj ref
+ break;
+ }
+
+ /*
+ * If the local pointed to a shared object when it was indexed, the
+ * INST_L_INDEX code made an un-shared copy of the obj and cached it
+ * in deepPtr. In that case, update the local to point to the
+ * un-shared copy.
+ */
+ if (currTopLevObj != newTopLevObj) { // update only if needed
+ if (TclIsVarDirectWritable(varPtr)) {
+ varPtr->value.objPtr = newTopLevObj;
+ Tcl_IncrRefCount(newTopLevObj); // add new var ref
+ Tcl_DecrRefCount(currTopLevObj); // lose old var ref
+ } else {
+ DECACHE_STACK_INFO();
+ if (!TclPtrSetVar(interp, varPtr, NULL, NULL, NULL,
+ newTopLevObj, TCL_LEAVE_ERR_MSG, idx)) {
+ Tcl_Panic("could not set var in INST_L_DEEP_WRITE");
+ }
+ CACHE_STACK_INFO();
+ }
+ }
+
+ switch (flags & (L_PUSH_OLD|L_PUSH_NEW|L_DISCARD)) {
+ case L_PUSH_OLD:
+ PUSH_OBJECT(oldvalObj);
+ TRACE_WITH_OBJ(("L_PUSH_OLD => "), OBJ_AT_TOS);
+ break;
+ case L_PUSH_NEW:
+ PUSH_OBJECT(rvalObj);
+ TRACE_WITH_OBJ(("L_PUSH_NEW => "), OBJ_AT_TOS);
+ break;
+ case L_DISCARD:
+ TRACE(("L_DISCARD =>\n"));
+ break;
+ default:
+ Tcl_Panic("Bad flags to INST_L_DEEP_WRITE");
+ break;
+ }
+
+ Tcl_DecrRefCount(oldvalObj); // drop old deepPtr ref
+ if (rvalObj) Tcl_DecrRefCount(rvalObj); // drop stack ref
+ L_deepPtrFree(deepPtrObj);
+
+ ASSERT(!Tcl_IsShared(newTopLevObj));
+
+#ifndef TCL_COMPILE_DEBUG
+ /* Peephole optimization. */
+ if (*(pc+6) == INST_POP) {
+ tosPtr--;
+ NEXT_INST_F(10, 0, 0);
+ }
+#endif
+ NEXT_INST_F(9, 0, 0);
+ }
+
+ case INST_L_SPLIT: {
+ int n;
+ Tcl_Obj *strObj = NULL;
+ Tcl_Obj *delimObj = NULL;
+ Tcl_Obj *limitObj = NULL;
+ unsigned int opnd = TclGetUInt4AtPtr(pc+1);
+
+ if (opnd & L_SPLIT_LIM) {
+ ASSERT(opnd & (L_SPLIT_RE | L_SPLIT_STR));
+ delimObj = OBJ_AT_DEPTH(2);
+ strObj = OBJ_AT_DEPTH(1);
+ limitObj = OBJ_AT_DEPTH(0);
+ n = 3;
+ } else if (opnd & (L_SPLIT_RE | L_SPLIT_STR)) {
+ delimObj = OBJ_AT_DEPTH(1);
+ strObj = OBJ_AT_DEPTH(0);
+ n = 2;
+ } else {
+ strObj = OBJ_AT_DEPTH(0);
+ n = 1;
+ }
+ objResultPtr = L_split(interp, strObj, delimObj, limitObj, opnd);
+ if (!objResultPtr) {
+ result = TCL_ERROR;
+ goto checkForCatch;
+ }
+ TRACE_WITH_OBJ(("0x%x => ", opnd), objResultPtr);
+ NEXT_INST_V(5, n, 1);
+ }
+
+ case INST_L_DEFINED: {
+ objResultPtr = constants[(OBJ_AT_TOS)->undef == 0];
+ TRACE_WITH_OBJ(("=> "), objResultPtr);
+ NEXT_INST_F(1, 1, 1);
+ }
+
+ case INST_L_PUSH_LIST_SIZE: {
+ int length;
+ Tcl_Obj *valuePtr;
+ L_DeepPtr *deepPtr;
+
+ valuePtr = OBJ_AT_TOS;
+
+ if (L_isDeepPtr(valuePtr)) {
+ deepPtr = L_deepPtrGet(valuePtr);
+ valuePtr = *deepPtr->elemPtrPtr;
+ }
+
+ result = TclListObjLength(interp, valuePtr, &length);
+ if (result == TCL_OK) {
+ L_sizes_push(length - 1);
+ TRACE(("%.20s => %d on L sizes stack\n", O2S(valuePtr), length));
+ NEXT_INST_F(1, 0, 0);
+ } else {
+ TRACE_WITH_OBJ(("%.30s => ERROR: ", O2S(valuePtr)),
+ Tcl_GetObjResult(interp));
+ goto checkForCatch;
+ }
+ }
+
+ case INST_L_PUSH_STR_SIZE: {
+ int length;
+ Tcl_Obj *valuePtr;
+ L_DeepPtr *deepPtr;
+
+ valuePtr = OBJ_AT_TOS;
+
+ if (L_isDeepPtr(valuePtr)) {
+ deepPtr = L_deepPtrGet(valuePtr);
+ valuePtr = *deepPtr->elemPtrPtr;
+ }
+
+ Tcl_GetUnicodeFromObj(valuePtr, &length);
+ L_sizes_push(length - 1);
+ TRACE(("%.20s => %d on L sizes stack\n", O2S(valuePtr), length));
+ NEXT_INST_F(1, 0, 0);
+ }
+
+ case INST_L_READ_SIZE: {
+ int length = L_sizes_top();
+ objResultPtr = Tcl_NewIntObj(length);
+ TRACE(("=> %d\n", length));
+ NEXT_INST_F(1, 0, 1);
+ }
+
+ case INST_L_POP_SIZE: {
+ L_sizes_pop();
+ NEXT_INST_F(1, 0, 0);
+ }
+
+ case INST_L_PUSH_UNDEF: {
+ objResultPtr = *L_undefObjPtrPtr();
+ NEXT_INST_F(1, 0, 1);
+ }
+
+ case INST_L_LINDEX_STK: {
+ int listc;
+ Tcl_Obj *list = OBJ_AT_TOS;
+ Tcl_Obj **listv;
+ unsigned int i = TclGetUInt1AtPtr(pc+1);
+
+ result = TclListObjGetElements(interp, list, &listc, &listv);
+ if (result != TCL_OK) {
+ goto checkForCatch;
+ }
+ if ((i >= 0) && (i < listc)) {
+ objResultPtr = listv[i];
+ } else {
+ objResultPtr = *L_undefObjPtrPtr();
+ }
+ NEXT_INST_F(2, 0, 1);
+ }
+
+ case INST_L_LIST_INSERT: {
+ int index, objc;
+ Tcl_Obj **objv;
+ Tcl_Obj *listPtr;
+ Tcl_Obj *indexPtr = POP_OBJECT();
+ Tcl_Obj *elemPtr = OBJ_AT_TOS;
+ unsigned int opnd = TclGetUInt4AtPtr(pc+1);
+ unsigned int flags = TclGetUInt4AtPtr(pc+5);
+ Var *varPtr = &(compiledLocals[opnd]);
+
+ while (TclIsVarLink(varPtr)) {
+ varPtr = varPtr->value.linkPtr;
+ }
+ listPtr = varPtr->value.objPtr;
+ if (Tcl_IsShared(listPtr)) {
+ listPtr = Tcl_DuplicateObj(listPtr);
+ TclPtrSetVar(interp, varPtr, NULL, NULL, NULL, listPtr, 0, opnd);
+ }
+ if (TclGetIntFromObj(NULL, indexPtr, &index) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot convert index to integer", NULL);
+ result = TCL_ERROR;
+ goto checkForCatch;
+ }
+ Tcl_DecrRefCount(indexPtr);
+ if (index == -1) index = INT_MAX; // -1 means append
+ if (flags & L_INSERT_ELT) {
+ result = Tcl_ListObjReplace(interp, listPtr, index, 0, 1, &elemPtr);
+ } else {
+ ASSERT(flags & L_INSERT_LIST);
+ Tcl_ListObjGetElements(interp, elemPtr, &objc, &objv);
+ result = Tcl_ListObjReplace(interp, listPtr, index, 0, objc, objv);
+ }
+ if (result != TCL_OK) {
+ goto checkForCatch;
+ }
+ NEXT_INST_F(9, 1, 0);
+ }
+
+ case INST_UNSET_LOCAL: {
+ unsigned int opnd = TclGetUInt4AtPtr(pc+1);
+ Var *varPtr = &compiledLocals[opnd];
+ Var *linkPtr;
+
+ /*
+ * This is intended to delete L's local temp variables, which are
+ * always scalars and never traced.
+ */
+ if (TclIsVarLink(varPtr)) {
+ linkPtr = varPtr->value.linkPtr;
+ if (TclIsVarInHash(linkPtr)) {
+ VarHashRefCount(linkPtr)--;
+ if (TclIsVarUndefined(linkPtr)) {
+ TclCleanupVar(linkPtr, NULL);
+ }
+ }
+ TclSetVarScalar(varPtr);
+ varPtr->value.linkPtr = NULL;
+ } else unless (TclIsVarUndefined(varPtr)) {
+ TclDecrRefCount(varPtr->value.objPtr);
+ TclSetVarUndefined(varPtr);
+ }
+ NEXT_INST_F(5, 0, 0);
+ }
+
+ case INST_DIFFERENT_OBJ: {
+ unsigned int opnd = TclGetUInt4AtPtr(pc+1);
+ Var *localVarPtr = &compiledLocals[opnd];
+ Var *otherVarPtr, *varPtr;
+ Tcl_Obj *varName = OBJ_AT_TOS;
+ Tcl_Obj *localObjPtr, *otherObjPtr;
+
+ otherVarPtr = TclObjLookupVar(interp, varName, NULL, TCL_GLOBAL_ONLY,
+ NULL, 0, 0, &varPtr);
+ if (otherVarPtr == NULL) {
+ Tcl_SetResult(interp, "variable not found", TCL_STATIC);
+ result = TCL_ERROR;
+ goto checkForCatch;
+ }
+ while (TclIsVarLink(otherVarPtr)) {
+ otherVarPtr = otherVarPtr->value.linkPtr;
+ }
+ while (TclIsVarLink(localVarPtr)) {
+ localVarPtr = localVarPtr->value.linkPtr;
+ }
+ if (!TclIsVarUndefined(localVarPtr) && !TclIsVarUndefined(otherVarPtr)) {
+ localObjPtr = localVarPtr->value.objPtr;
+ otherObjPtr = otherVarPtr->value.objPtr;
+ objResultPtr = constants[localObjPtr != otherObjPtr];
+ } else {
+ objResultPtr = constants[1];
+ }
+
+ NEXT_INST_F(5, 1, 1);
+ }
+
default:
Tcl_Panic("TclNRExecuteByteCode: unrecognized opCode %u", *pc);
} /* end of switch on opCode */
@@ -10750,6 +11770,373 @@ StringForResultCode(
#endif /* TCL_COMPILE_DEBUG */
/*
+ *----------------------------------------------------------------------
+ *
+ * L_deepDiveArray --
+ *
+ * Index one level into an L array or struct (represented as a Tcl list),
+ * using L semantics.
+ *
+ * Results:
+ * If flags & L_PUSH_VAL, the array is being indexed as an r-value.
+ * Otherwise, it is assumed that the indexed value will be written
+ * in-place later (i.e., used as an l-value), and this function does
+ * the magic necessary to allow that.
+ *
+ * For an r-value, this function returns a pointer to the indexed object
+ * pointer (i.e., a Tcl_Obj ** pointer into the lists's internal element
+ * array). If the index is < 0 or beyond the last element, a pointer to
+ * the L undef object is returned instead. If the index has the value
+ * undef, always return the undef object as the element value.
+ *
+ * For an l-value, if the indexed element is shared, an un-shared copy is
+ * made so that the indexed object later can be written in-place. Also,
+ * if the index is beyond the last element, the list is padded out with
+ * copies of the L undef object.
+ *
+ * Side effects:
+ * See above. The lists's string representation also is invalidated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj **
+L_deepDiveArray(
+ Tcl_Interp *interp,
+ Tcl_Obj *obj, /* object being indexed */
+ Tcl_Obj *idxObj, /* index (array subscript) into obj */
+ Expr_f flags)
+{
+ int i, idx, len, result;
+ Tcl_Obj **elemPtrs, **pad;
+ Tcl_Obj *subObj;
+ int lvalue = (flags & L_LVALUE);
+
+ if (L_isUndef(idxObj)) {
+ if (lvalue) {
+ Tcl_SetResult(interp, "cannot write to undefined array index",
+ NULL);
+ return (NULL);
+ } else {
+ Tcl_SetResult(interp, "cannot read from undefined array index",
+ NULL);
+ return (NULL);
+ }
+ }
+ if (TclGetIntFromObj(NULL, idxObj, &idx) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot convert index to integer", NULL);
+ return (NULL);
+ }
+ if (TclListObjGetElements(NULL, obj, &len, &elemPtrs) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot convert object to list", NULL);
+ return (NULL);
+ }
+
+ if (lvalue) {
+ if (idx < 0) {
+ if (flags & L_NEG_OK) {
+ return (L_undefObjPtrPtr());
+ } else {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot write to negative array index",
+ NULL);
+ return (NULL);
+ }
+ } else if (idx >= len) {
+ /* Auto extend the array. */
+ int n = idx - len + 1;
+ pad = (Tcl_Obj **)ckalloc(n * sizeof(Tcl_Obj *));
+ for (i = 0; i < n; ++i) {
+ pad[i] = *L_undefObjPtrPtr();
+ }
+ result = Tcl_ListObjReplace(interp, obj, len, 0, n, pad);
+ ckfree((char *)pad);
+ if (result != TCL_OK) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot convert object to list", NULL);
+ return (NULL);
+ }
+ }
+ if (TclListObjGetElements(interp, obj, &len, &elemPtrs) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot convert object to list", NULL);
+ return (NULL);
+ }
+ if (Tcl_IsShared(elemPtrs[idx])) {
+ /*
+ * Make an un-shared copy of the element. Because we're going to
+ * later modify it in place, if the element is itself a list, we
+ * have to also duplicate its internal list representation because
+ * Tcl_DuplicateObj() does not (it shares the internal list rep
+ * between the old and new Tcl_Objs).
+ */
+ subObj = Tcl_DuplicateObj(elemPtrs[idx]);
+ if (subObj->typePtr == &tclListType) {
+ TclDuplicateListRep(subObj);
+ }
+ TclListObjSetElement(NULL, obj, idx, subObj);
+ if (Tcl_IsShared(subObj)) {
+ subObj = Tcl_DuplicateObj(subObj);
+ }
+ if (TclListObjGetElements(interp, obj, &len, &elemPtrs) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot convert object to list", NULL);
+ return (NULL);
+ }
+ }
+ Tcl_InvalidateStringRep(obj);
+ return (&elemPtrs[idx]);
+ } else {
+ if ((idx < 0) || (idx >= len)) {
+ return (L_undefObjPtrPtr());
+ } else {
+ return (&elemPtrs[idx]);
+ }
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * L_deepDiveHash --
+ *
+ * Index one level into an L hash (represented as a Tcl dict),
+ * using L semantics.
+ *
+ * Results:
+ * If flags & L_PUSH_VAL, the hash is being indexed as an r-value.
+ * Otherwise, it is assumed that the indexed value will be written
+ * in-place later (i.e., used as an l-value), and this function does
+ * the magic necessary to allow that.
+ *
+ * For an r-value, this function returns a pointer to the indexed object
+ * pointer (i.e., a Tcl_Obj ** that points to the hash bucket). If the
+ * key does not exist, a pointer to the L undef object is returned
+ * instead.
+ *
+ * For an l-value, if the indexed element is shared, an un-shared copy is
+ * made so that the indexed object later can be written in-place. Also,
+ * if the key does not exist, it is added to the hash with a value of
+ * the L undef object.
+ *
+ * Side effects:
+ * See above. The hash's string representation also is invalidated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj **
+L_deepDiveHash(
+ Tcl_Interp *interp,
+ Tcl_Obj *obj, /* object being indexed */
+ Tcl_Obj *idxObj, /* index (key) into obj */
+ Expr_f flags)
+{
+ int result, tmp;
+ Tcl_Obj *objPtr;
+ Tcl_Obj **elt;
+ Dict *dict;
+ Tcl_HashEntry *hPtr;
+ int lvalue = (flags & L_LVALUE);
+
+ ASSERT(!lvalue || !Tcl_IsShared(obj)); // lvalue => obj is unshared
+
+ unless (Tcl_DictObjSize(NULL, obj, &tmp) == TCL_OK) {
+ /* Obj is not a dict and can't be converted to one. */
+ if (lvalue) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "not a hash", NULL);
+ return (NULL);
+ } else {
+ return (L_undefObjPtrPtr());
+ }
+ }
+
+ if (L_isUndef(idxObj)) {
+ static int undef_idx_ok = -1;
+
+ if (undef_idx_ok == -1) {
+ undef_idx_ok = getenv("BK_L_ALLOW_UNDEF_HASH_INDEX") != NULL;
+ }
+ if (undef_idx_ok == 1) {
+ unless (flags & L_LVALUE) {
+ return (L_undefObjPtrPtr());
+ }
+ } else {
+ if (flags & L_LVALUE) {
+ Tcl_SetResult(interp, "cannot write to undefined hash index",
+ NULL);
+ return (NULL);
+ } else {
+ Tcl_SetResult(interp, "cannot read from undefined hash index",
+ NULL);
+ return (NULL);
+ }
+ }
+ }
+
+ dict = (Dict *)obj->internalRep.otherValuePtr;
+ hPtr = Tcl_FindHashEntry(&dict->table, (char *)idxObj);
+ unless (hPtr) {
+ unless (lvalue) return (L_undefObjPtrPtr());
+ TclNewObj(objPtr);
+ Tcl_IncrRefCount(objPtr);
+ result = Tcl_DictObjPut(interp, obj, idxObj, objPtr);
+ Tcl_DecrRefCount(objPtr);
+#ifdef TCL_COMPILE_DEBUG
+ unless (result == TCL_OK) L_bomb("L deep-dive hash err");
+#else
+ (void)result; // quiet compiler warning
+#endif
+ hPtr = Tcl_FindHashEntry(&dict->table, (char *)idxObj);
+ }
+ elt = (Tcl_Obj **)(void *)&Tcl_GetHashValue(hPtr);
+ ASSERT(elt);
+ if (lvalue && Tcl_IsShared(*elt)) {
+ Tcl_DecrRefCount(*elt);
+ *elt = Tcl_DuplicateObj(*elt);
+ Tcl_IncrRefCount(*elt);
+ }
+ if (lvalue) Tcl_InvalidateStringRep(obj);
+ return (elt);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * L_deepDiveString --
+ *
+ * Index into a string for the L INST_L_INDEX bytecode.
+ *
+ * Results:
+ * Creates a new Tcl_Obj that contains a substring of obj. To be
+ * compatible with the other L_deepDive* functions, this function returns
+ * a Tcl_Obj** by stashing the Tcl_Obj* into the object itself and
+ * returning a pointer to that pointer.
+ *
+ * If the given index is negative, a run-time error is generated.
+ * If the index is beyond the end of the string, a pointer the L
+ * undefined object pointer is returned. If the index is undef,
+ * return undef if the string is being read else throw a run-time
+ * error.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj **
+L_deepDiveString(
+ Tcl_Interp *interp,
+ Tcl_Obj *obj, /* object being indexed */
+ Tcl_Obj *idxObj, /* index into obj */
+ Expr_f flags)
+{
+ int idx, len;
+ Tcl_Obj *newObj;
+ Tcl_UniChar ch;
+
+ if (L_isUndef(idxObj)) {
+ if (flags & L_LVALUE) {
+ Tcl_SetResult(interp, "cannot write to undefined string index",
+ NULL);
+ return (NULL);
+ } else {
+ Tcl_SetResult(interp, "cannot read from undefined string index",
+ NULL);
+ return (NULL);
+ }
+ }
+ if (TclGetIntFromObj(NULL, idxObj, &idx) != TCL_OK) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "cannot convert index to integer", NULL);
+ return (NULL);
+ }
+
+ if (idx < 0) {
+ Tcl_ResetResult(interp);
+ Tcl_AppendResult(interp, "negative string index illegal", NULL);
+ return (NULL);
+ } else if (idx < Tcl_GetCharLength(obj)) {
+ ch = Tcl_GetUniChar(obj, idx);
+ if (obj->typePtr == &tclByteArrayType) {
+ unsigned char uch = (unsigned char) ch;
+
+ newObj = Tcl_NewByteArrayObj(&uch, 1);
+ } else {
+ char buf[TCL_UTF_MAX];
+
+ len = Tcl_UniCharToUtf(ch, buf);
+ newObj = Tcl_NewStringObj(buf, len);
+ }
+ newObj->internalRep.twoPtrValue.ptr2 = newObj;
+ return (Tcl_Obj **)(void *)&(newObj->internalRep.twoPtrValue.ptr2);
+ } else {
+ return (L_undefObjPtrPtr());
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * L_deepDive --
+ *
+ * Index one level into an L array, hash, struct, or string,
+ * using L semantics.
+ *
+ * Results:
+ * If flags & L_PUSH_VAL, the object is being indexed as an r-value.
+ * Otherwise, it is assumed that the indexed value will be written
+ * in-place later (i.e., used as an l-value), and this function does
+ * the magic necessary to allow that.
+ *
+ * This function returns a pointer to the indexed object pointer (i.e., a
+ * Tcl_Obj **) that later can be used to modify the element in-place. If
+ * the indexed element does not exist, a pointer to the L undef object is
+ * returned instead.
+ *
+ * For an l-value, if the indexed element is shared, an un-shared copy is
+ * made so that the indexed object later can be written in-place.
+ *
+ * Side effects:
+ * See comments for L_deepDiveArray() and L_deepDiveHash(). The
+ * object's string representation also is invalidated.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj **
+L_deepDive(
+ Tcl_Interp *interp,
+ Tcl_Obj *obj,
+ Tcl_Obj *idxObj,
+ Expr_f flags)
+{
+ Tcl_Obj **ret = NULL;
+
+ switch (flags & (L_IDX_ARRAY | L_IDX_HASH | L_IDX_STRING)) {
+ case L_IDX_ARRAY:
+ ret = L_deepDiveArray(interp, obj, idxObj, flags);
+ break;
+ case L_IDX_HASH:
+ ret = L_deepDiveHash(interp, obj, idxObj, flags);
+ break;
+ case L_IDX_STRING:
+ ret = L_deepDiveString(interp, obj, idxObj, flags);
+ break;
+ default:
+ L_bomb("L_deepDive internal error");
+ break;
+ }
+ /* If we're going to write to obj, mark it as defined now. */
+ if (ret && (flags & L_LVALUE)) obj->undef = 0;
+ return (ret);
+}
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/generic/tclIO.c b/generic/tclIO.c
index 8e9e346..15b37b0 100644
--- a/generic/tclIO.c
+++ b/generic/tclIO.c
@@ -15,6 +15,9 @@
#include "tclInt.h"
#include "tclIO.h"
#include <assert.h>
+#ifndef MIN
+# define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
/*
* For each channel handler registered in a call to Tcl_CreateChannelHandler,
@@ -4168,6 +4171,48 @@ WillRead(
}
/*
+ *---------------------------------------------------------------------------
+ *
+ * Tcl_WriteObjN --
+ *
+ * Same as Tcl_WriteObj but takes the number of bytes to write.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+Tcl_WriteObjN(
+ Tcl_Channel chan, /* The channel to buffer output for. */
+ Tcl_Obj *objPtr, /* The object to write. */
+ int numBytes) /* The number of bytes to write. */
+{
+ /*
+ * Always use the topmost channel of the stack
+ */
+
+ Channel *chanPtr;
+ ChannelState *statePtr; /* State info for channel */
+ const char *src;
+ int srcLen;
+
+ statePtr = ((Channel *) chan)->state;
+ chanPtr = statePtr->topChanPtr;
+
+ if (CheckChannelErrors(statePtr, TCL_WRITABLE) != 0) {
+ return -1;
+ }
+ if (statePtr->encoding == NULL) {
+ src = (char *) Tcl_GetByteArrayFromObj(objPtr, &srcLen);
+ numBytes = MIN(numBytes, srcLen);
+ return WriteBytes(chanPtr, src, numBytes);
+ } else {
+ src = TclGetStringFromObj(objPtr, &srcLen);
+ numBytes = MIN(numBytes, srcLen);
+ return WriteChars(chanPtr, src, numBytes);
+ }
+}
+
+/*
*----------------------------------------------------------------------
*
* Write --
@@ -7777,6 +7822,16 @@ Tcl_GetChannelOption(
return TCL_OK;
}
}
+ if (len == 0 || HaveOpt(2, "-epipe")) {
+ if (len == 0) {
+ Tcl_DStringAppendElement(dsPtr, "-epipe");
+ }
+ Tcl_DStringAppendElement(dsPtr,
+ (flags & CHANNEL_EXIT_ON_EPIPE) ? "exit" : "error");
+ if (len > 0) {
+ return TCL_OK;
+ }
+ }
if (len == 0 || HaveOpt(1, "-translation")) {
if (len == 0) {
Tcl_DStringAppendElement(dsPtr, "-translation");
@@ -8030,6 +8085,29 @@ Tcl_SetChannelOption(
ResetFlag(statePtr, CHANNEL_EOF|CHANNEL_STICKY_EOF|CHANNEL_BLOCKED);
statePtr->inputEncodingFlags &= ~TCL_ENCODING_END;
return TCL_OK;
+ } else if (HaveOpt(2, "-epipe")) {
+ if (Tcl_SplitList(interp, newValue, &argc, &argv) == TCL_ERROR) {
+ return TCL_ERROR;
+ }
+ if (argc == 1) {
+ len = strlen(newValue);
+ if (strncmp(newValue, "exit", len) == 0) {
+ SetFlag(statePtr, CHANNEL_EXIT_ON_EPIPE);
+ ckfree((char *) argv);
+ return TCL_OK;
+ } else if (strncmp(newValue, "error", len) == 0) {
+ ResetFlag(statePtr, CHANNEL_EXIT_ON_EPIPE);
+ ckfree((char *) argv);
+ return TCL_OK;
+ }
+ }
+ if (interp) {
+ Tcl_AppendResult(interp,
+ "bad value for -epipe: must be one of exit or error",
+ NULL);
+ }
+ ckfree((char *) argv);
+ return TCL_ERROR;
} else if (HaveOpt(1, "-translation")) {
const char *readMode, *writeMode;
diff --git a/generic/tclIO.h b/generic/tclIO.h
index b799375..f7ce677 100644
--- a/generic/tclIO.h
+++ b/generic/tclIO.h
@@ -282,6 +282,8 @@ typedef struct ChannelState {
#define CHANNEL_CLOSEDWRITE (1<<21) /* Channel write side has been closed.
* No further Tcl-level write IO on
* the channel is allowed. */
+#define CHANNEL_EXIT_ON_EPIPE (1<<22) /* Exit on EPIPE (broken pipe) error
+ * on the stdout channel. */
/*
* The length of time to wait between synthetic timer events. Must be zero or
diff --git a/generic/tclIOCmd.c b/generic/tclIOCmd.c
index 834f225..1a0a2f9 100644
--- a/generic/tclIOCmd.c
+++ b/generic/tclIOCmd.c
@@ -10,6 +10,7 @@
*/
#include "tclInt.h"
+#include "tclIO.h"
/*
* Callback structure for accept callback in a TCP server.
@@ -203,6 +204,11 @@ Tcl_PutsObjCmd(
*/
error:
+ if ((chan == Tcl_GetStdChannel(TCL_STDOUT)) &&
+ (((Channel *)chan)->state->flags & CHANNEL_EXIT_ON_EPIPE)) {
+ Tcl_Exit(0);
+ /*NOTREACHED*/
+ }
if (!TclChanCaughtErrorBypass(interp, chan)) {
Tcl_SetObjResult(interp, Tcl_ObjPrintf("error writing \"%s\": %s",
TclGetString(chanObjPtr), Tcl_PosixError(interp)));
diff --git a/generic/tclIOSock.c b/generic/tclIOSock.c
index d578d19..8d8ee67 100644
--- a/generic/tclIOSock.c
+++ b/generic/tclIOSock.c
@@ -288,6 +288,35 @@ TclCreateSocketAddress(
}
/*
+ * Work around an omission in earlier versions of MinGW.
+ */
+#ifdef __MINGW32__
+char* WSAAPI
+gai_strerrorA(int ecode)
+{
+ static char message[1024+1];
+ DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS
+ | FORMAT_MESSAGE_MAX_WIDTH_MASK;
+ DWORD dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
+ FormatMessageA(dwFlags, NULL, ecode, dwLanguageId, (LPSTR)message, 1024, NULL);
+ return message;
+}
+
+WCHAR* WSAAPI
+gai_strerrorW(int ecode)
+{
+ static WCHAR message[1024+1];
+ DWORD dwFlags = FORMAT_MESSAGE_FROM_SYSTEM
+ | FORMAT_MESSAGE_IGNORE_INSERTS
+ | FORMAT_MESSAGE_MAX_WIDTH_MASK;
+ DWORD dwLanguageId = MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT);
+ FormatMessageW(dwFlags, NULL, ecode, dwLanguageId, (LPWSTR)message, 1024, NULL);
+ return message;
+}
+#endif
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/generic/tclIOUtil.c b/generic/tclIOUtil.c
index 1330c02..af544c3 100644
--- a/generic/tclIOUtil.c
+++ b/generic/tclIOUtil.c
@@ -13,6 +13,7 @@
* Copyright (c) 1991-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 2001-2004 Vincent Darley.
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -23,6 +24,7 @@
# include "tclWinInt.h"
#endif
#include "tclFileSystem.h"
+#include "Lcompile.h"
#ifdef TCL_TEMPLOAD_NO_UNLINK
#ifndef NO_FSTATFS
@@ -80,6 +82,8 @@ static void FsAddMountsToGlobResult(Tcl_Obj *resultPtr,
Tcl_Obj *pathPtr, const char *pattern,
Tcl_GlobTypeData *types);
static void FsUpdateCwd(Tcl_Obj *cwdObj, ClientData clientData);
+static Tcl_Obj * FsMaybeWrapInLLang(Tcl_Interp *interp,
+ Tcl_Obj *fileContents, const char *path);
static void FsRecacheFilesystemList(void);
static void Claim(void);
static void Disclaim(void);
@@ -1817,15 +1821,14 @@ Tcl_FSEvalFileEx(
oldScriptFile = iPtr->scriptFile;
iPtr->scriptFile = pathPtr;
Tcl_IncrRefCount(iPtr->scriptFile);
- string = Tcl_GetStringFromObj(objPtr, &length);
- /*
- * TIP #280 Force the evaluator to open a frame for a sourced file.
- */
+ objPtr = FsMaybeWrapInLLang(interp, objPtr, Tcl_GetString(pathPtr));
+ string = Tcl_GetStringFromObj(objPtr, &length);
+ /* TIP #280 Force the evaluator to open a frame for a sourced
+ * file. */
iPtr->evalFlags |= TCL_EVAL_FILE;
result = TclEvalEx(interp, string, length, 0, 1, NULL, string);
-
/*
* Now we have to be careful; the script may have changed the
* iPtr->scriptFile value, so we must reset it without assuming it still
@@ -1955,6 +1958,8 @@ TclNREvalFile(
iPtr->scriptFile = pathPtr;
Tcl_IncrRefCount(iPtr->scriptFile);
+ objPtr = FsMaybeWrapInLLang(interp, objPtr, Tcl_GetString(pathPtr));
+
/*
* TIP #280: Force the evaluator to open a frame for a sourced file.
*/
@@ -1975,7 +1980,6 @@ EvalFileCallback(
Tcl_Obj *oldScriptFile = data[0];
Tcl_Obj *pathPtr = data[1];
Tcl_Obj *objPtr = data[2];
-
/*
* Now we have to be careful; the script may have changed the
* iPtr->scriptFile value, so we must reset it without assuming it still
@@ -2010,6 +2014,47 @@ EvalFileCallback(
}
/*
+ * Handle L and html/L code.
+ *
+ * If the path ends in .l, precede the file contents with #lang L.
+ * If the path ends in .lhtml, with #lang Lhtml.
+ *
+ * Return a Tcl_Obj containing the potentially wrapped string.
+ */
+static Tcl_Obj *
+FsMaybeWrapInLLang(
+ Tcl_Interp *interp,
+ Tcl_Obj *fileContents,
+ const char *path)
+{
+ int flen;
+ int plen = strlen(path);
+ char *s = Tcl_GetStringFromObj(fileContents, &flen);
+ char *append = "";
+ Tcl_Obj *newContents;
+
+ /* Append a newline if not already there. */
+ if (flen && (s[flen-1] != '\n')) append = "\n";
+
+ if (((plen >= 2) && (path[plen-2] == '.') && (path[plen-1] == 'l')) ||
+ (L && L->global->forceL)) {
+ newContents = Tcl_ObjPrintf("#lang L --lineadj=-1\n%s%s#lang tcl",
+ s, append);
+ Tcl_DecrRefCount(fileContents);
+ Tcl_IncrRefCount(newContents);
+ fileContents = newContents;
+ if (L) L->global->forceL = 0;
+ } else if ((plen >= 6) && !strcmp(path+plen-6, ".lhtml")) {
+ newContents = Tcl_ObjPrintf("#lang Lhtml --lineadj=-1\n%s%s#lang tcl",
+ s, append);
+ Tcl_DecrRefCount(fileContents);
+ Tcl_IncrRefCount(newContents);
+ fileContents = newContents;
+ }
+ return fileContents;
+}
+
+/*
*----------------------------------------------------------------------
*
* Tcl_GetErrno --
diff --git a/generic/tclInt.h b/generic/tclInt.h
index 356d250..d90fb99 100644
--- a/generic/tclInt.h
+++ b/generic/tclInt.h
@@ -11,6 +11,7 @@
* Copyright (c) 2007 Daniel A. Steffen <das@users.sourceforge.net>
* Copyright (c) 2006-2008 by Joe Mistachkin. All rights reserved.
* Copyright (c) 2008 by Miguel Sofer. All rights reserved.
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -48,6 +49,9 @@
#else
#include <string.h>
#endif
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
#ifdef STDC_HEADERS
#include <stddef.h>
#else
@@ -2252,6 +2256,7 @@ typedef struct Interp {
* script in progress has been canceled thereby allowing
* the evaluation stack for the interp to be fully
* unwound.
+ * INTERP_PCRE Non-zero means use PCRE engine by default for REs
*
* WARNING: For the sake of some extensions that have made use of former
* internal values, do not re-use the flag values 2 (formerly ERR_IN_PROGRESS)
@@ -2264,6 +2269,7 @@ typedef struct Interp {
#define DONT_COMPILE_CMDS_INLINE 0x20
#define RAND_SEED_INITIALIZED 0x40
#define SAFE_INTERP 0x80
+#define INTERP_PCRE 0x100
#define INTERP_TRACE_IN_PROGRESS 0x200
#define INTERP_ALTERNATE_WRONG_ARGS 0x400
#define ERR_LEGACY_COPY 0x800
@@ -2484,7 +2490,7 @@ typedef struct List {
*
* DICT_PATH_UPDATE indicates that we are going to be doing an update at the
* tip of the path, so duplication of shared objects should be done along the
- * way.
+ * way.
*
* DICT_PATH_EXISTS indicates that we are performing an existance test and a
* lookup failure should therefore not be an error. If (and only if) this flag
@@ -2883,6 +2889,7 @@ MODULE_SCOPE void TclContinuationsCopy(Tcl_Obj *objPtr,
MODULE_SCOPE int TclConvertElement(const char *src, int length,
char *dst, int flags);
MODULE_SCOPE void TclDeleteNamespaceVars(Namespace *nsPtr);
+MODULE_SCOPE void TclDuplicateListRep(Tcl_Obj *objPtr);
MODULE_SCOPE int TclFindDictElement(Tcl_Interp *interp,
const char *dict, int dictLength,
const char **elementPtr, const char **nextPtr,
@@ -2989,6 +2996,9 @@ MODULE_SCOPE int TclIsSpaceProc(char byte);
MODULE_SCOPE int TclIsBareword(char byte);
MODULE_SCOPE Tcl_Obj * TclJoinPath(int elements, Tcl_Obj * const objv[]);
MODULE_SCOPE int TclJoinThread(Tcl_ThreadId id, int *result);
+MODULE_SCOPE void TclLInitCompiler(Tcl_Interp *interp);
+MODULE_SCOPE void TclLCleanupCompiler(ClientData clientData,
+ Tcl_Interp *interp);
MODULE_SCOPE void TclLimitRemoveAllHandlers(Tcl_Interp *interp);
MODULE_SCOPE Tcl_Obj * TclLindexList(Tcl_Interp *interp,
Tcl_Obj *listPtr, Tcl_Obj *argPtr);
@@ -3269,6 +3279,9 @@ MODULE_SCOPE int Tcl_FconfigureObjCmd(
MODULE_SCOPE int Tcl_FcopyObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_FGetlineObjCmd(ClientData dummy,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE Tcl_Command TclInitFileCmd(Tcl_Interp *interp);
MODULE_SCOPE int TclMakeFileCommandSafe(Tcl_Interp *interp);
MODULE_SCOPE int Tcl_FileEventObjCmd(ClientData clientData,
@@ -3286,6 +3299,12 @@ MODULE_SCOPE int Tcl_ForeachObjCmd(ClientData clientData,
MODULE_SCOPE int Tcl_FormatObjCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_GetOptObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_GetOptResetObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int Tcl_GetsObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -3311,9 +3330,24 @@ MODULE_SCOPE int Tcl_JoinObjCmd(ClientData clientData,
MODULE_SCOPE int Tcl_LappendObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LAngleReadObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int Tcl_LassignObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LDefined(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LGetNextLine(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LGetNextLineInit(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LGetDirX(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int Tcl_LindexObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -3335,6 +3369,12 @@ MODULE_SCOPE int Tcl_LoadObjCmd(ClientData clientData,
MODULE_SCOPE int Tcl_LrangeObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LReadCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LRefCnt(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int Tcl_LrepeatObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -3353,6 +3393,9 @@ MODULE_SCOPE int Tcl_LsetObjCmd(ClientData clientData,
MODULE_SCOPE int Tcl_LsortObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LWriteCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE Tcl_Command TclInitNamespaceCmd(Tcl_Interp *interp);
MODULE_SCOPE int TclNamespaceEnsembleCmd(ClientData dummy,
Tcl_Interp *interp, int objc,
@@ -3400,6 +3443,9 @@ MODULE_SCOPE int Tcl_SeekObjCmd(ClientData clientData,
MODULE_SCOPE int Tcl_SetObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_ShSplitObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
MODULE_SCOPE int Tcl_SplitObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
@@ -3454,6 +3500,16 @@ MODULE_SCOPE int Tcl_VwaitObjCmd(ClientData clientData,
MODULE_SCOPE int Tcl_WhileObjCmd(ClientData clientData,
Tcl_Interp *interp, int objc,
Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_LHtmlObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+MODULE_SCOPE int Tcl_PtrObjCmd(ClientData clientData,
+ Tcl_Interp *interp, int objc,
+ Tcl_Obj *const objv[]);
+
/*
*----------------------------------------------------------------
@@ -3959,6 +4015,17 @@ MODULE_SCOPE int TclObjCallVarTraces(Interp *iPtr, Var *arrayPtr,
int flags, int leaveErrMsg, int index);
/*
+ * The variant RE engines
+ */
+
+MODULE_SCOPE int TclRegexpClassic(Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[], Tcl_RegExp regExpr,
+ int all, int indices, int doinline, int offset);
+MODULE_SCOPE int TclRegexpPCRE(Tcl_Interp *interp, int objc,
+ Tcl_Obj *CONST objv[], Tcl_RegExp regExpr,
+ int all, int indices, int doinline, int offset);
+
+/*
* So tclObj.c and tclDictObj.c can share these implementations.
*/
@@ -4064,7 +4131,8 @@ typedef const char *TclDTraceStr;
*/
# define TclAllocObjStorageEx(interp, objPtr) \
- (objPtr) = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj))
+ (objPtr) = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj)); \
+ (objPtr)->undef = 0
# define TclFreeObjStorageEx(interp, objPtr) \
ckfree((char *) (objPtr))
@@ -4109,6 +4177,7 @@ MODULE_SCOPE void TclpFreeAllocCache(void *);
cachePtr->firstObjPtr = (objPtr)->internalRep.twoPtrValue.ptr1; \
--cachePtr->numObjects; \
} \
+ (objPtr)->undef = 0; \
} while (0)
# define TclFreeObjStorageEx(interp, objPtr) \
@@ -4150,6 +4219,7 @@ MODULE_SCOPE Tcl_Mutex tclObjMutex;
tclFreeObjList = (Tcl_Obj *) \
tclFreeObjList->internalRep.twoPtrValue.ptr1; \
Tcl_MutexUnlock(&tclObjMutex); \
+ (objPtr)->undef = 0; \
} while (0)
# define TclFreeObjStorageEx(interp, objPtr) \
diff --git a/generic/tclInterp.c b/generic/tclInterp.c
index 0da5d47..8929102 100644
--- a/generic/tclInterp.c
+++ b/generic/tclInterp.c
@@ -489,6 +489,7 @@ TclInterpInit(
Tcl_NRCreateCommand(interp, "interp", Tcl_InterpObjCmd, NRInterpCmd,
NULL, NULL);
+ TclLInitCompiler(interp);
Tcl_CallWhenDeleted(interp, InterpInfoDeleteProc, NULL);
return TCL_OK;
@@ -615,7 +616,8 @@ NRInterpCmd(
"eval", "exists", "expose",
"hide", "hidden", "issafe",
"invokehidden", "limit", "marktrusted", "recursionlimit",
- "slaves", "share", "target", "transfer",
+ "regexp", "slaves", "share", "target",
+ "transfer",
NULL
};
enum option {
@@ -624,7 +626,8 @@ NRInterpCmd(
OPT_EVAL, OPT_EXISTS, OPT_EXPOSE,
OPT_HIDE, OPT_HIDDEN, OPT_ISSAFE,
OPT_INVOKEHID, OPT_LIMIT, OPT_MARKTRUSTED,OPT_RECLIMIT,
- OPT_SLAVES, OPT_SHARE, OPT_TARGET, OPT_TRANSFER
+ OPT_REGEXP, OPT_SLAVES, OPT_SHARE, OPT_TARGET,
+ OPT_TRANSFER
};
if (objc < 2) {
@@ -1034,6 +1037,41 @@ NRInterpCmd(
Tcl_SetObjResult(interp, resultPtr);
return TCL_OK;
}
+ case OPT_REGEXP: {
+ int re_type;
+ Interp *slaveInterp;
+ static CONST char *re_type_opts[] = {
+ "classic", "pcre", NULL
+ };
+ enum re_type_opts {
+ RETYPE_CLASSIC, RETYPE_PCRE,
+ };
+ if (objc != 3 && objc != 4) {
+ Tcl_WrongNumArgs(interp, 2, objv, "path ?type?");
+ return TCL_ERROR;
+ }
+ slaveInterp = (Interp *) GetInterp(interp, objv[2]);
+ if (slaveInterp == NULL) {
+ return TCL_ERROR;
+ }
+ if (objc == 4) {
+ if (Tcl_GetIndexFromObj(interp, objv[3], re_type_opts, "type",
+ 0, &re_type) != TCL_OK) {
+ return TCL_ERROR;
+ }
+ if ((enum re_type_opts) re_type == RETYPE_PCRE) {
+ slaveInterp->flags |= INTERP_PCRE;
+ } else {
+ slaveInterp->flags &= ~(INTERP_PCRE);
+ }
+ }
+ if (slaveInterp->flags & INTERP_PCRE) {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("pcre", -1));
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewStringObj("classic", -1));
+ }
+ return TCL_OK;
+ }
case OPT_TRANSFER:
case OPT_SHARE: {
Tcl_Interp *masterInterp; /* The master of the slave. */
diff --git a/generic/tclListObj.c b/generic/tclListObj.c
index fa67ee6..72bc6da 100644
--- a/generic/tclListObj.c
+++ b/generic/tclListObj.c
@@ -577,6 +577,7 @@ Tcl_ListObjAppendElement(
if (listPtr->bytes == tclEmptyStringRep) {
Tcl_SetListObj(listPtr, 1, &objPtr);
+ listPtr->undef = 0;
return TCL_OK;
}
result = SetListFromAny(interp, listPtr);
@@ -691,6 +692,7 @@ Tcl_ListObjAppendElement(
*(&listRepPtr->elements + listRepPtr->elemCount) = objPtr;
Tcl_IncrRefCount(objPtr);
listRepPtr->elemCount++;
+ listPtr->undef = 0;
/*
* Invalidate any old string representation since the list's internal
@@ -865,6 +867,7 @@ Tcl_ListObjReplace(
if (listPtr->typePtr != &tclListType) {
if (listPtr->bytes == tclEmptyStringRep) {
if (!objc) {
+ listPtr->undef = 0;
return TCL_OK;
}
Tcl_SetListObj(listPtr, objc, NULL);
@@ -1058,6 +1061,7 @@ Tcl_ListObjReplace(
*/
TclInvalidateStringRep(listPtr);
+ listPtr->undef = 0;
return TCL_OK;
}
@@ -2000,6 +2004,48 @@ UpdateStringOfList(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * TclDuplicateListRep --
+ *
+ * Create an unshared copy of a list's internal representation.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * The object's internal representation is changed to point to
+ * a newly allocated copy of its old representation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TclDuplicateListRep(Tcl_Obj *objPtr)
+{
+ int i, numElems;
+ List *listRepPtr, *oldListRepPtr;
+ Tcl_Obj **elemPtrs, **oldElems;
+
+ listRepPtr = (List *)objPtr->internalRep.twoPtrValue.ptr1;
+ if (listRepPtr->refCount > 1) {
+ oldListRepPtr = listRepPtr;
+ numElems = listRepPtr->elemCount;
+ listRepPtr = NewListIntRep(listRepPtr->maxElemCount, NULL, 1);
+ oldElems = &oldListRepPtr->elements;
+ elemPtrs = &listRepPtr->elements;
+ for (i=0; i<numElems; i++) {
+ elemPtrs[i] = oldElems[i];
+ Tcl_IncrRefCount(elemPtrs[i]);
+ }
+ listRepPtr->elemCount = numElems;
+ listRepPtr->refCount++;
+ oldListRepPtr->refCount--;
+ objPtr->internalRep.twoPtrValue.ptr1 = (void *) listRepPtr;
+ }
+}
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/generic/tclMain.c b/generic/tclMain.c
index 927de7e..8c3888e 100644
--- a/generic/tclMain.c
+++ b/generic/tclMain.c
@@ -11,6 +11,7 @@
* Copyright (c) 1988-1994 The Regents of the University of California.
* Copyright (c) 1994-1997 Sun Microsystems, Inc.
* Copyright (c) 2000 Ajuba Solutions.
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -32,6 +33,7 @@
# endif
#endif
+#include "Lcompile.h"
#include "tclInt.h"
/*
@@ -309,9 +311,11 @@ Tcl_MainEx(
* but before starting to execute commands. */
Tcl_Interp *interp)
{
- Tcl_Obj *path, *resultPtr, *argvPtr, *appName;
+ Tcl_Obj *path, *resultPtr, *argvPtr, *appName, *LObj;
+ int commandLen;
+ char *commandStr;
const char *encodingName = NULL;
- int code, exitCode = 0;
+ int code, exitCode = 0, isL = 0;
Tcl_MainLoopProc *mainLoopProc;
Tcl_Channel chan;
InteractiveState is;
@@ -333,12 +337,18 @@ Tcl_MainEx(
if (NULL == Tcl_GetStartupScript(NULL)) {
/*
- * Check whether first 3 args (argv[1] - argv[3]) look like
+ * Check whether initial args (argv[1] and beyond) look like
* -encoding ENCODING FILENAME
* or like
- * FILENAME
+ * [-opt1] [-opt2] ... [-optn] FILENAME
*/
+ /* Create argv list obj for L. */
+ L->global->tclsh_argc = 1;
+ L->global->tclsh_argv = Tcl_NewObj();
+ Tcl_ListObjAppendElement(NULL, L->global->tclsh_argv,
+ NewNativeObj(argv[0], -1));
+
if ((argc > 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1]))
&& ('-' != argv[3][0])) {
Tcl_Obj *value = NewNativeObj(argv[2], -1);
@@ -347,10 +357,21 @@ Tcl_MainEx(
Tcl_DecrRefCount(value);
argc -= 3;
argv += 3;
- } else if ((argc > 1) && ('-' != argv[1][0])) {
- Tcl_SetStartupScript(NewNativeObj(argv[1], -1), NULL);
- argc--;
- argv++;
+ } else if (argc > 1) {
+ /* Pass over all options to look for a file name. */
+ int i;
+ Tcl_Obj *argObj;
+ for (i = 1; i < argc; ++i) {
+ argObj = NewNativeObj(argv[i], -1);
+ Tcl_ListObjAppendElement(NULL, L->global->tclsh_argv, argObj);
+ ++L->global->tclsh_argc;
+ if ('-' != argv[i][0]) {
+ Tcl_SetStartupScript(argObj, NULL);
+ argc -= i;
+ argv += i;
+ break;
+ }
+ }
}
}
@@ -365,12 +386,15 @@ Tcl_MainEx(
argv++;
Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewIntObj(argc), TCL_GLOBAL_ONLY);
+ L->global->script_argc = argc;
argvPtr = Tcl_NewListObj(0, NULL);
while (argc--) {
Tcl_ListObjAppendElement(NULL, argvPtr, NewNativeObj(*argv++, -1));
}
Tcl_SetVar2Ex(interp, "argv", NULL, argvPtr, TCL_GLOBAL_ONLY);
+ L->global->script_argv = argvPtr;
+ Tcl_IncrRefCount(argvPtr);
/*
* Set the "tcl_interactive" variable.
@@ -416,6 +440,31 @@ Tcl_MainEx(
path = Tcl_GetStartupScript(&encodingName);
if (path != NULL) {
+ int argc, i;
+ char *av0path;
+ Tcl_Obj **argvObjs, *pathObj;
+
+ /*
+ * Set L->global->forceL if argv[0] is "L", or "-L" or "--L" was given
+ * as a cmd-line option. This causes Tcl_FSEvalFileEx() to wrap the
+ * input file in a #lang L regardless of its extension.
+ */
+ if (L->global->tclsh_argv) {
+ Tcl_ListObjGetElements(interp, L->global->tclsh_argv, &argc,
+ &argvObjs);
+ pathObj = Tcl_FSGetNormalizedPath(interp, argvObjs[0]);
+ av0path = Tcl_GetString(pathObj);
+ if (av0path) {
+ L->global->forceL = (!strcmp(av0path+strlen(av0path)-2, "/L"));
+ }
+ for (i = 1; i < argc; ++i) {
+ if (!strcmp(Tcl_GetString(argvObjs[i]), "--L") ||
+ !strcmp(Tcl_GetString(argvObjs[i]), "-L")) {
+ L->global->forceL = 1;
+ }
+ }
+ }
+
Tcl_ResetResult(interp);
code = Tcl_FSEvalFileEx(interp, path, encodingName);
if (code != TCL_OK) {
@@ -462,6 +511,7 @@ Tcl_MainEx(
* Get a new value for tty if anyone writes to ::tcl_interactive
*/
+ Tcl_LinkVar(interp, "L", (char *) &isL, TCL_LINK_BOOLEAN);
Tcl_LinkVar(interp, "tcl_interactive", (char *) &is.tty, TCL_LINK_BOOLEAN);
is.input = Tcl_GetStdChannel(TCL_STDIN);
while ((is.input != NULL) && !Tcl_InterpDeleted(interp)) {
@@ -509,6 +559,17 @@ Tcl_MainEx(
}
/*
+ * Check for the #lang comments and sub them out for
+ * meaningful commands.
+ */
+ commandStr = Tcl_GetStringFromObj(is.commandPtr, &commandLen);
+ if (!isL && strncasecmp(commandStr, "#lang l", 7) == 0) {
+ Tcl_SetStringObj(is.commandPtr, "set ::L 1", -1);
+ } else if (isL && strncasecmp(commandStr, "#lang tcl", 9) == 0) {
+ Tcl_SetStringObj(is.commandPtr, "set('::L',0);", -1);
+ }
+
+ /*
* Add the newline removed by Tcl_GetsObj back to the string. Have
* to add it back before testing completeness, because it can make
* a difference. [Bug 1775878]
@@ -527,6 +588,18 @@ Tcl_MainEx(
is.prompt = PROMPT_START;
+ if (isL) {
+ LObj = Tcl_NewStringObj("L {", -1);
+ Tcl_AppendObjToObj(LObj, is.commandPtr);
+ if (commandStr[commandLen-1] != ';') {
+ Tcl_AppendToObj(LObj, ";", -1);
+ }
+ Tcl_AppendToObj(LObj, "}\n", -1);
+ Tcl_DecrRefCount(is.commandPtr);
+ is.commandPtr = LObj;
+ Tcl_IncrRefCount(is.commandPtr);
+ }
+
/*
* The final newline is syntactically redundant, and causes some
* error messages troubles deeper in, so lop it back off.
diff --git a/generic/tclNamesp.c b/generic/tclNamesp.c
index dfab185..65d4f39 100644
--- a/generic/tclNamesp.c
+++ b/generic/tclNamesp.c
@@ -4853,7 +4853,7 @@ TclLogCommandInfo(
{
register const char *p;
Interp *iPtr = (Interp *) interp;
- int overflow, limit = 150;
+ int overflow, limit = 150, line;
Var *varPtr, *arrayPtr;
if (iPtr->flags & ERR_ALREADY_LOGGED) {
@@ -4867,12 +4867,18 @@ TclLogCommandInfo(
if (command != NULL) {
/*
- * Compute the line number where the error occurred.
+ * Compute the line number where the error occurred, honoring #line
+ * directives generated by the L compiler.
*/
iPtr->errorLine = 1;
+ if (!strncmp(script,"#line ",6) && ((line = strtoul(script+6,NULL,10)) > 0)) {
+ iPtr->errorLine = line - 1;
+ }
for (p = script; p != command; p++) {
- if (*p == '\n') {
+ if (!strncmp(p,"\n#line ",7) && ((line = strtoul(p+7,NULL,10)) > 0)) {
+ iPtr->errorLine = line - 1;
+ } else if (*p == '\n') {
iPtr->errorLine++;
}
}
diff --git a/generic/tclObj.c b/generic/tclObj.c
index c641152..452160d 100644
--- a/generic/tclObj.c
+++ b/generic/tclObj.c
@@ -1064,6 +1064,7 @@ TclDbInitNewObj(
objPtr->bytes = tclEmptyStringRep;
objPtr->length = 0;
objPtr->typePtr = NULL;
+ objPtr->undef = 0;
#ifdef TCL_THREADS
/*
@@ -1576,6 +1577,7 @@ TclObjBeingDeleted(
(dupPtr)->typePtr = typePtr; \
} \
} \
+ (dupPtr)->undef = (objPtr)->undef; \
}
Tcl_Obj *
@@ -1886,6 +1888,10 @@ Tcl_GetBooleanFromObj(
register Tcl_Obj *objPtr, /* The object from which to get boolean. */
register int *boolPtr) /* Place to store resulting boolean. */
{
+ if (objPtr->undef) {
+ *boolPtr = 0;
+ return TCL_OK;
+ }
do {
if (objPtr->typePtr == &tclIntType) {
*boolPtr = (objPtr->internalRep.longValue != 0);
diff --git a/generic/tclParse.c b/generic/tclParse.c
index 95abc45..1a83df4 100644
--- a/generic/tclParse.c
+++ b/generic/tclParse.c
@@ -8,6 +8,7 @@
* Copyright (c) 1997 Sun Microsystems, Inc.
* Copyright (c) 1998-2000 Ajuba Solutions.
* Contributions from Don Porter, NIST, 2002. (not subject to US copyright)
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -16,6 +17,7 @@
#include "tclInt.h"
#include "tclParse.h"
#include <assert.h>
+#include "Last.h"
/*
* The following table provides parsing information about each possible 8-bit
@@ -160,6 +162,8 @@ const char tclCharTypeTable[] = {
* Prototypes for local functions defined in this file:
*/
+static int ParseLang(Tcl_Interp *interp, const char *src,
+ int numBytes, Tcl_Parse *parsePtr, int *scanned);
static inline int CommandComplete(const char *script, int numBytes);
static int ParseComment(const char *src, int numBytes,
Tcl_Parse *parsePtr);
@@ -171,6 +175,105 @@ static int ParseWhiteSpace(const char *src, int numBytes,
/*
*----------------------------------------------------------------------
*
+ * ParseLang --
+ * Scans up to numBytes bytes starting at src, consuming a Tcl lang
+ * directive.
+ *
+ * Results:
+ * Records in parsePtr information about the parse. Returns either
+ * TCL_BREAK, meaning the parsing should continue, TCL_OK meaning
+ * a Language directive was succesfully consumed, or TCL_ERROR meaning
+ * the lang directive was incomplete (missing end #lang or missing EOF)
+ * or there was some kind of an error
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+static int
+ParseLang(
+ Tcl_Interp *interp, /* Tcl interpreter */
+ CONST char *src, /* First character to parse. */
+ register int numBytes, /* Max number of bytes to scan. */
+ Tcl_Parse *parsePtr, /* Information about parse in progress.
+ * Updated if parsing indicates an incomplete
+ * command. */
+ int *scanned) /* How many bytes we used */
+{
+ register CONST char *p = src;
+ char *eol, *end;
+ Tcl_Token *tokenPtr;
+ Tcl_Parse optsParse;
+ int wordIdx;
+ char *message = "malformed pragma";
+
+ p += 5;
+ eol = strchr(p, '\n') + 1;
+ /* in case there's no \n, use the end of the string instead */
+ if (eol == (char *)1) {
+ eol = (char *)src + numBytes;
+ }
+ if (Tcl_ParseCommand(interp, p, eol - p, 0, &optsParse) != TCL_OK) {
+ goto error;
+ }
+ if (optsParse.numWords < 1) goto error;
+ tokenPtr = optsParse.tokenPtr;
+ if (tokenPtr->type != TCL_TOKEN_SIMPLE_WORD) goto error;
+ tokenPtr++;
+ if (!strncasecmp("tcl", tokenPtr->start, tokenPtr->size)) {
+ /* treat #lang tcl as a comment */
+ if (!parsePtr->commentStart) {
+ parsePtr->commentStart = src;
+ }
+ parsePtr->commentSize = eol - src;
+ parsePtr->commandStart = NULL;
+ parsePtr->commandSize = 0;
+ *scanned = eol - src;
+ return TCL_BREAK;
+ }
+ if (!strncmp("L", tokenPtr->start, tokenPtr->size) ||
+ !strncmp("Lhtml", tokenPtr->start, tokenPtr->size)) {
+ /* it's L code, so do the parse again, but side-effect the parsePtr
+ * this time */
+ Tcl_ParseCommand(interp, p, eol - p, 0, parsePtr);
+ /* now tack on one more word for the L code */
+ /* XXX strstr is not safe -- it expects a NULL on the end. */
+ end = strstr(eol, "\n#lang");
+ if (!end) {
+ end = (char *)src + numBytes - 1;
+ }
+ TclGrowParseTokenArray(parsePtr, 2);
+ wordIdx = parsePtr->numTokens;
+ tokenPtr = &parsePtr->tokenPtr[wordIdx];
+ tokenPtr->type = TCL_TOKEN_SIMPLE_WORD;
+ tokenPtr->start = eol;
+ tokenPtr->size = end - tokenPtr->start + 1;
+ tokenPtr->numComponents = 1;
+ parsePtr->numTokens++;
+ parsePtr->numWords++;
+
+ tokenPtr = &parsePtr->tokenPtr[wordIdx+1];
+ *tokenPtr = parsePtr->tokenPtr[wordIdx];
+ tokenPtr->type = TCL_TOKEN_TEXT;
+ tokenPtr->numComponents = 0;
+ parsePtr->numTokens++;
+ parsePtr->commandSize = end - p;
+ return TCL_OK;
+ }
+ error:
+ parsePtr->commandStart = src;
+ parsePtr->commandSize = eol - src;
+ if (interp) {
+ Tcl_SetResult(interp, message, TCL_STATIC);
+ }
+ Tcl_FreeParse(parsePtr);
+ return TCL_ERROR;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
* TclParseInit --
*
* Initialize the fields of a Tcl_Parse struct.
@@ -282,9 +385,10 @@ Tcl_ParseCommand(
* Parse any leading space and comments before the first word of the
* command.
*/
-
- scanned = ParseComment(start, numBytes, parsePtr);
- src = (start + scanned);
+ src = start;
+comments:
+ scanned = ParseComment(src, numBytes, parsePtr);
+ src += scanned;
numBytes -= scanned;
if (numBytes == 0) {
if (nested) {
@@ -293,6 +397,19 @@ Tcl_ParseCommand(
}
/*
+ * Check for lang
+ */
+
+ if (strncmp(src, "#lang", 5) == 0) {
+ int rc = ParseLang(interp, src, numBytes, parsePtr, &scanned);
+ if (rc != TCL_BREAK) return rc;
+ src += scanned;
+ numBytes -= scanned;
+ if (numBytes > 0)
+ goto comments;
+ }
+
+ /*
* The following loop parses the words of the command, one word in each
* iteration through the loop.
*/
@@ -1033,7 +1150,7 @@ ParseComment(
numBytes -= scanned;
} while (numBytes && (*p == '\n') && (p++,numBytes--));
- if ((numBytes == 0) || (*p != '#')) {
+ if ((numBytes == 0) || (*p != '#') || (strncmp(p, "#lang", 5) == 0)) {
break;
}
if (parsePtr->commentStart == NULL) {
diff --git a/generic/tclPipe.c b/generic/tclPipe.c
index 83fb818..1339d24 100644
--- a/generic/tclPipe.c
+++ b/generic/tclPipe.c
@@ -5,6 +5,7 @@
* as well as various utility routines used in managing subprocesses.
*
* Copyright (c) 1997 by Sun Microsystems, Inc.
+ * Copyright (c) 2007 BitMover, Inc.
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
diff --git a/generic/tclRegexp.c b/generic/tclRegexp.c
index ea25d4b..978316a 100644
--- a/generic/tclRegexp.c
+++ b/generic/tclRegexp.c
@@ -75,6 +75,12 @@ typedef struct ThreadSpecificData {
struct TclRegexp *regexps[NUM_REGEXPS];
/* Compiled forms of above strings. Also
* malloc-ed, or NULL if not in use yet. */
+#ifdef HAVE_PCRE
+ Tcl_RegExpIndices *matches; /* To support PCRE in Tcl_RegExpGetInfo, we
+ * need a classic info matches area to store
+ * data in. */
+ int matchelems; /* length of matches */
+#endif
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;
@@ -253,8 +259,21 @@ Tcl_RegExpRange(
} else {
string = regexpPtr->string;
}
- *startPtr = Tcl_UtfAtIndex(string, regexpPtr->matches[index].rm_so);
- *endPtr = Tcl_UtfAtIndex(string, regexpPtr->matches[index].rm_eo);
+ if (regexpPtr->flags & TCL_REG_PCRE) {
+#ifdef HAVE_PCRE
+ /* XXX We could check for tclByteArrayType objPtr */
+ int last = regexpPtr->details.rm_extend.rm_so; /* last offset */
+ *startPtr = Tcl_UtfAtIndex(string,
+ regexpPtr->matches[index].rm_so - last);
+ *endPtr = Tcl_UtfAtIndex(string,
+ regexpPtr->matches[index].rm_eo - last);
+#else
+ Tcl_Panic("Cannot get info for PCRE match");
+#endif
+ } else {
+ *startPtr = Tcl_UtfAtIndex(string, regexpPtr->matches[index].rm_so);
+ *endPtr = Tcl_UtfAtIndex(string, regexpPtr->matches[index].rm_eo);
+ }
}
}
@@ -432,9 +451,9 @@ Tcl_RegExpExecObj(
int flags) /* Regular expression execution flags. */
{
TclRegexp *regexpPtr = (TclRegexp *) re;
- Tcl_UniChar *udata;
- int length;
+ int i, length;
int reflags = regexpPtr->flags;
+ /* We could allow TCL_REG_PCRE to accept glob-fallback as well */
#define TCL_REG_GLOBOK_FLAGS \
(TCL_REG_ADVANCED | TCL_REG_NOSUB | TCL_REG_NOCASE)
@@ -464,15 +483,109 @@ Tcl_RegExpExecObj(
regexpPtr->string = NULL;
regexpPtr->objPtr = textObj;
- udata = Tcl_GetUnicodeFromObj(textObj, &length);
+ if (reflags & TCL_REG_PCRE) {
+#ifdef HAVE_PCRE
+ const char *matchstr;
+ int match, pcreeflags, nm = (regexpPtr->re.re_nsub + 1) * 3;
+ int byteOffset, wlen;
+ unsigned long pcreopts;
- if (offset > length) {
- offset = length;
- }
- udata += offset;
- length -= offset;
+ if (!(flags & TCL_REG_BYTEOFFSET)) {
+ wlen = Tcl_GetCharLength(textObj);
+ }
+ if (textObj->typePtr == &tclByteArrayType) {
+ matchstr = (const char*)Tcl_GetByteArrayFromObj(textObj, &length);
+ } else {
+ matchstr = (const char*)Tcl_GetStringFromObj(textObj, &length);
+ }
+
+ pcreeflags = 0;
+ if (flags & TCL_REG_NOTBOL) {
+ pcreeflags |= PCRE_NOTBOL;
+ }
+ pcre_fullinfo(regexpPtr->pcre, NULL, PCRE_INFO_OPTIONS, &pcreopts);
- return RegExpExecUniChar(interp, re, udata, length, nmatches, flags);
+ if (!(flags & TCL_REG_BYTEOFFSET)) {
+ /* To handle UTF8, convert offset from a char index to a byte offset. */
+ if (offset > wlen) {
+ offset = wlen;
+ }
+ byteOffset = Tcl_UtfAtIndex(matchstr, offset) - matchstr;
+ if (byteOffset > length) {
+ byteOffset = length;
+ }
+ } else {
+ if (offset > length) {
+ offset = length;
+ }
+ byteOffset = offset;
+ }
+
+ match = pcre_exec(regexpPtr->pcre, regexpPtr->study,
+ matchstr, length, byteOffset, pcreeflags,
+ (int *) regexpPtr->matches, nm);
+
+ if (!(flags & TCL_REG_BYTEOFFSET)) {
+ /*
+ * For UTF8, we need the matches array as char offsets, but pcre
+ * returns byte offsets. Do the conversion.
+ * This could be sped up for lots of matches.
+ */
+ for (i = 0; i < 2*match; ++i) {
+ int *p = &((int *)regexpPtr->matches)[i];
+ *p = Tcl_NumUtfChars(matchstr, *p);
+ }
+ }
+
+ /*
+ * Store last offset to support Tcl_RegExpGetInfo translation.
+ */
+ if (match == PCRE_ERROR_NOMATCH) {
+ regexpPtr->details.rm_extend.rm_so = -1;
+ } else {
+ regexpPtr->details.rm_extend.rm_so = offset;
+ }
+
+ /*
+ * Check for errors.
+ */
+
+ if (match == PCRE_ERROR_NOMATCH) {
+ return 0;
+ } else if (match == 0) {
+ if (interp != NULL) {
+ Tcl_AppendResult(interp,
+ "pcre_exec had insufficient capture space", NULL);
+ }
+ return -1;
+ } else if (match < -1) {
+ if (interp != NULL) {
+ char buf[32 + TCL_INTEGER_SPACE];
+ sprintf(buf, "pcre_exec returned error code %d", match);
+ Tcl_AppendResult(interp, buf, NULL);
+ }
+ return -1;
+ }
+ return 1;
+#else
+ if (interp != NULL) {
+ Tcl_AppendResult(interp, "PCRE not available", NULL);
+ }
+ return -1;
+#endif
+ } else {
+ Tcl_UniChar *udata;
+
+ udata = Tcl_GetUnicodeFromObj(textObj, &length);
+
+ if (offset > length) {
+ offset = length;
+ }
+ udata += offset;
+ length -= offset;
+
+ return RegExpExecUniChar(interp, re, udata, length, nmatches, flags);
+ }
}
/*
@@ -535,7 +648,32 @@ Tcl_RegExpGetInfo(
TclRegexp *regexpPtr = (TclRegexp *) regexp;
infoPtr->nsubs = regexpPtr->re.re_nsub;
- infoPtr->matches = (Tcl_RegExpIndices *) regexpPtr->matches;
+ if (regexpPtr->flags & TCL_REG_PCRE) {
+#ifdef HAVE_PCRE
+ ThreadSpecificData *tsdPtr = TCL_TSD_INIT(&dataKey);
+ int i, last, *matches = (int *) regexpPtr->matches;
+
+ /*
+ * This works both to initialize and extend matches as necessary
+ */
+ if (tsdPtr->matchelems <= infoPtr->nsubs) {
+ tsdPtr->matchelems = infoPtr->nsubs + 1;
+ tsdPtr->matches = (Tcl_RegExpIndices *)
+ ckrealloc((char *) tsdPtr->matches,
+ sizeof(Tcl_RegExpIndices) * tsdPtr->matchelems);
+ }
+ last = regexpPtr->details.rm_extend.rm_so; /* last offset */
+ for (i = 0; i <= infoPtr->nsubs; i++) {
+ tsdPtr->matches[i].start = matches[i*2] - last;
+ tsdPtr->matches[i].end = matches[i*2+1] - last;
+ }
+ infoPtr->matches = tsdPtr->matches;
+#else
+ Tcl_Panic("Cannot get info for PCRE match");
+#endif
+ } else {
+ infoPtr->matches = (Tcl_RegExpIndices *) regexpPtr->matches;
+ }
infoPtr->extendStart = regexpPtr->details.rm_extend.rm_so;
}
@@ -580,6 +718,10 @@ Tcl_GetRegExpFromObj(
regexpPtr = objPtr->internalRep.twoPtrValue.ptr1;
+ /* XXX Need to have case where -type classic isn't ignored in regexp/sub */
+ if ((interp != NULL) && (((Interp *)interp)->flags & INTERP_PCRE)) {
+ flags |= TCL_REG_PCRE;
+ }
if ((objPtr->typePtr != &tclRegexpType) || (regexpPtr->flags != flags)) {
pattern = TclGetStringFromObj(objPtr, &length);
@@ -906,38 +1048,126 @@ CompileRegexp(
*/
regexpPtr = ckalloc(sizeof(TclRegexp));
- regexpPtr->objPtr = NULL;
- regexpPtr->string = NULL;
+ memset(regexpPtr, 0, sizeof(TclRegexp));
+
+ regexpPtr->flags = flags;
regexpPtr->details.rm_extend.rm_so = -1;
regexpPtr->details.rm_extend.rm_eo = -1;
- /*
- * Get the up-to-date string representation and map to unicode.
- */
+ if (flags & TCL_REG_PCRE) {
+#ifdef HAVE_PCRE
+ pcre *pcre;
+ char *p, *cstring = (char *) string;
+ const char *errstr;
+ int erroffset, rc, nsubs, pcrecflags;
- Tcl_DStringInit(&stringBuf);
- uniString = Tcl_UtfToUniCharDString(string, length, &stringBuf);
- numChars = Tcl_DStringLength(&stringBuf) / sizeof(Tcl_UniChar);
+ /*
+ * Convert from Tcl classic to PCRE cflags
+ */
- /*
- * Compile the string and check for errors.
- */
+ /* XXX Should enable PCRE_UTF8 selectively on non-ByteArray Tcl_Obj */
+ pcrecflags = PCRE_NO_UTF8_CHECK | PCRE_DOLLAR_ENDONLY | PCRE_DOTALL;
+ for (i = 0, p = cstring; i < length; i++) {
+ if (UCHAR(*p++) > 0x80) {
+ pcrecflags |= PCRE_UTF8;
+ break;
+ }
+ }
+ if (flags & TCL_REG_NOCASE) {
+ pcrecflags |= PCRE_CASELESS;
+ }
+ if (flags & TCL_REG_EXPANDED) {
+ pcrecflags |= PCRE_EXTENDED;
+ }
+ /* TCL_REG_NLSTOP|TCL_REG_NLANCH == TCL_REG_NEWLINE */
+ if (flags & TCL_REG_NLSTOP) {
+ pcrecflags &= ~(PCRE_DOTALL);
+ }
+ if (flags & TCL_REG_NLANCH) {
+ pcrecflags |= PCRE_MULTILINE;
+ pcrecflags &= ~(PCRE_DOLLAR_ENDONLY);
+ }
- regexpPtr->flags = flags;
- status = TclReComp(&regexpPtr->re, uniString, (size_t) numChars, flags);
- Tcl_DStringFree(&stringBuf);
+ if (cstring[length] != 0) {
+ cstring = (char *) ckalloc(length + 1);
+ memcpy(cstring, string, length);
+ cstring[length] = 0;
+ }
+ pcre = pcre_compile(cstring, pcrecflags, &errstr, &erroffset, NULL);
+ regexpPtr->pcre = pcre;
+ if (cstring != (char *) string) {
+ ckfree(cstring);
+ }
+
+ if (pcre == NULL) {
+ ckfree((char *)regexpPtr);
+ Tcl_AppendResult(interp,
+ "couldn't compile pcre pattern: ", errstr, NULL);
+ return NULL;
+ }
+
+ regexpPtr->study = pcre_study(pcre, 0, &errstr);
+ if (errstr != NULL) {
+ pcre_free(pcre);
+ ckfree((char *)regexpPtr);
+ Tcl_AppendResult(interp,
+ "error studying pcre pattern: ", errstr, NULL);
+ return NULL;
+ }
- if (status != REG_OKAY) {
/*
- * Clean up and report errors in the interpreter, if possible.
+ * Allocate enough space for all of the subexpressions, plus one extra
+ * for the entire pattern.
*/
- ckfree(regexpPtr);
- if (interp) {
- TclRegError(interp,
- "couldn't compile regular expression pattern: ", status);
+ rc = pcre_fullinfo(pcre, NULL, PCRE_INFO_CAPTURECOUNT, &nsubs);
+ if (rc == 0) {
+ regexpPtr->re.re_nsub = nsubs;
+ regexpPtr->matches = (regmatch_t *)
+ ckalloc(sizeof(int) * (nsubs+1)*3);
}
+#else
+ Tcl_AppendResult(interp,
+ "couldn't compile pcre pattern: pcre unavailabe", NULL);
return NULL;
+#endif
+ } else {
+ /*
+ * Get the up-to-date string representation and map to unicode.
+ */
+
+ Tcl_DStringInit(&stringBuf);
+ uniString = Tcl_UtfToUniCharDString(string, length, &stringBuf);
+ numChars = Tcl_DStringLength(&stringBuf) / sizeof(Tcl_UniChar);
+
+ /*
+ * Compile the string and check for errors.
+ */
+
+ status = TclReComp(&regexpPtr->re, uniString, (size_t) numChars, flags);
+ Tcl_DStringFree(&stringBuf);
+
+ if (status != REG_OKAY) {
+ /*
+ * Clean up and report errors in the interpreter, if possible.
+ */
+
+ ckfree((char *)regexpPtr);
+ if (interp) {
+ TclRegError(interp,
+ "couldn't compile regular expression pattern: ",
+ status);
+ }
+ return NULL;
+ }
+
+ /*
+ * Allocate enough space for all of the subexpressions, plus one extra
+ * for the entire pattern.
+ */
+
+ regexpPtr->matches = (regmatch_t *) ckalloc(
+ sizeof(regmatch_t) * (regexpPtr->re.re_nsub + 1));
}
/*
@@ -955,14 +1185,6 @@ CompileRegexp(
}
/*
- * Allocate enough space for all of the subexpressions, plus one extra for
- * the entire pattern.
- */
-
- regexpPtr->matches =
- ckalloc(sizeof(regmatch_t) * (regexpPtr->re.re_nsub + 1));
-
- /*
* Initialize the refcount to one initially, since it is in the cache.
*/
@@ -1014,6 +1236,14 @@ static void
FreeRegexp(
TclRegexp *regexpPtr) /* Compiled regular expression to free. */
{
+#ifdef HAVE_PCRE
+ if (regexpPtr->flags & TCL_REG_PCRE) {
+ pcre_free(regexpPtr->pcre);
+ if (regexpPtr->study) {
+ pcre_free(regexpPtr->study);
+ }
+ } else
+#endif
TclReFree(&regexpPtr->re);
if (regexpPtr->globObjPtr) {
TclDecrRefCount(regexpPtr->globObjPtr);
@@ -1057,6 +1287,11 @@ FinalizeRegexp(
tsdPtr->patterns[i] = NULL;
}
+#ifdef HAVE_PCRE
+ if (tsdPtr->matches != NULL) {
+ ckfree((char *) tsdPtr->matches);
+ }
+#endif
/*
* We may find ourselves reinitialized if another finalization routine
* invokes regexps.
@@ -1066,6 +1301,448 @@ FinalizeRegexp(
}
/*
+ *----------------------------------------------------------------------
+ *
+ * TclRegexpClassic --
+ *
+ * This procedure processes a classic "regexp".
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclRegexpClassic(
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument objects. */
+ Tcl_RegExp regExpr,
+ int all,
+ int indices,
+ int doinline,
+ int offset)
+{
+ int i, match, numMatchesSaved, matchLength;
+ int eflags, stringLength;
+ Tcl_Obj *objPtr, *resultPtr = NULL;
+ Tcl_RegExpInfo info;
+
+ objPtr = objv[1];
+ stringLength = Tcl_GetCharLength(objPtr);
+
+ objc -= 2;
+ objv += 2;
+
+ if (doinline) {
+ /*
+ * Save all the subexpressions, as we will return them as a list
+ */
+
+ numMatchesSaved = -1;
+ } else {
+ /*
+ * Save only enough subexpressions for matches we want to keep, expect
+ * in the case of -all, where we need to keep at least one to know
+ * where to move the offset.
+ */
+
+ numMatchesSaved = (objc == 0) ? all : objc;
+ }
+
+ /*
+ * The following loop is to handle multiple matches within the same source
+ * string; each iteration handles one match. If "-all" hasn't been
+ * specified then the loop body only gets executed once. We terminate the
+ * loop when the starting offset is past the end of the string.
+ */
+
+ while (1) {
+ /*
+ * Pass either 0 or TCL_REG_NOTBOL in the eflags. Passing
+ * TCL_REG_NOTBOL indicates that the character at offset should not be
+ * considered the start of the line. If for example the pattern {^} is
+ * passed and -start is positive, then the pattern will not match the
+ * start of the string unless the previous character is a newline.
+ */
+
+ if (offset == 0) {
+ eflags = 0;
+ } else if (offset > stringLength) {
+ eflags = TCL_REG_NOTBOL;
+ } else if (Tcl_GetUniChar(objPtr, offset-1) == (Tcl_UniChar)'\n') {
+ eflags = 0;
+ } else {
+ eflags = TCL_REG_NOTBOL;
+ }
+
+ match = Tcl_RegExpExecObj(interp, regExpr, objPtr, offset,
+ numMatchesSaved, eflags);
+ if (match < 0) {
+ return TCL_ERROR;
+ }
+
+ if (match == 0) {
+ /*
+ * We want to set the value of the intepreter result only when
+ * this is the first time through the loop.
+ */
+
+ if (all <= 1) {
+ /*
+ * If inlining, the interpreter's object result remains an
+ * empty list, otherwise set it to an integer object w/ value
+ * 0.
+ */
+
+ if (!doinline) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+ }
+ return TCL_OK;
+ }
+ break;
+ }
+
+ /*
+ * If additional variable names have been specified, return index
+ * information in those variables.
+ */
+
+ Tcl_RegExpGetInfo(regExpr, &info);
+ if (doinline) {
+ /*
+ * It's the number of substitutions, plus one for the matchVar at
+ * index 0
+ */
+
+ objc = info.nsubs + 1;
+ if (all <= 1) {
+ resultPtr = Tcl_NewObj();
+ }
+ }
+ for (i = 0; i < objc; i++) {
+ Tcl_Obj *newPtr;
+
+ if (indices) {
+ int start, end;
+ Tcl_Obj *objs[2];
+
+ /*
+ * Only adjust the match area if there was a match for that
+ * area. (Scriptics Bug 4391/SF Bug #219232)
+ */
+
+ if (i <= info.nsubs && info.matches[i].start >= 0) {
+ start = offset + info.matches[i].start;
+ end = offset + info.matches[i].end;
+
+ /*
+ * Adjust index so it refers to the last character in the
+ * match instead of the first character after the match.
+ */
+
+ if (end >= offset) {
+ end--;
+ }
+ } else {
+ start = -1;
+ end = -1;
+ }
+
+ objs[0] = Tcl_NewLongObj(start);
+ objs[1] = Tcl_NewLongObj(end);
+
+ newPtr = Tcl_NewListObj(2, objs);
+ } else {
+ if (i <= info.nsubs) {
+ newPtr = Tcl_GetRange(objPtr,
+ offset + info.matches[i].start,
+ offset + info.matches[i].end - 1);
+ } else {
+ newPtr = Tcl_NewObj();
+ }
+ }
+ if (doinline) {
+ if (Tcl_ListObjAppendElement(interp, resultPtr, newPtr)
+ != TCL_OK) {
+ Tcl_DecrRefCount(newPtr);
+ Tcl_DecrRefCount(resultPtr);
+ return TCL_ERROR;
+ }
+ } else {
+ if (Tcl_ObjSetVar2(interp, objv[i], NULL, newPtr,
+ TCL_LEAVE_ERR_MSG) == NULL) {
+ return TCL_ERROR;
+ }
+ }
+ }
+
+ if (all == 0) {
+ break;
+ }
+
+ /*
+ * Adjust the offset to the character just after the last one in the
+ * matchVar and increment all to count how many times we are making a
+ * match. We always increment the offset by at least one to prevent
+ * endless looping (as in the case: regexp -all {a*} a). Otherwise,
+ * when we match the NULL string at the end of the input string, we
+ * will loop indefinately (because the length of the match is 0, so
+ * offset never changes).
+ */
+
+ matchLength = (info.matches[0].end - info.matches[0].start);
+
+ offset += info.matches[0].end;
+
+ /*
+ * A match of length zero could happen for {^} {$} or {.*} and in
+ * these cases we always want to bump the index up one.
+ */
+
+ if (matchLength == 0) {
+ offset++;
+ }
+ offset += info.matches[0].end;
+ all++;
+ eflags |= TCL_REG_NOTBOL;
+ if (offset >= stringLength) {
+ break;
+ }
+ }
+
+ /*
+ * Set the interpreter's object result to an integer object with value 1
+ * if -all wasn't specified, otherwise it's all-1 (the number of times
+ * through the while - 1).
+ */
+
+ if (doinline) {
+ Tcl_SetObjResult(interp, resultPtr);
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(all ? all-1 : 1));
+ }
+ return TCL_OK;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TclRegexpPCRE --
+ *
+ * This procedure processes a PCRE "regexp".
+ *
+ * Results:
+ * A standard Tcl result.
+ *
+ * Side effects:
+ * See the user documentation.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclRegexpPCRE(
+ Tcl_Interp *interp, /* Current interpreter. */
+ int objc, /* Number of arguments. */
+ Tcl_Obj *CONST objv[], /* Argument objects. */
+ Tcl_RegExp regExpr,
+ int all,
+ int indices,
+ int doinline,
+ int offset)
+{
+#ifdef HAVE_PCRE
+ int i, match, eflags, stringLength, matchelems, *matches;
+ Tcl_Obj *objPtr, *resultPtr = NULL;
+ const char *matchstr;
+ pcre *re;
+ pcre_extra *study;
+ TclRegexp *regexpPtr = (TclRegexp *) regExpr;
+
+ objPtr = objv[1];
+ if (objPtr->typePtr == &tclByteArrayType) {
+ matchstr = (const char*)Tcl_GetByteArrayFromObj(objPtr, &stringLength);
+ } else {
+ matchstr = (const char*)Tcl_GetStringFromObj(objPtr, &stringLength);
+ }
+
+ eflags = PCRE_NO_UTF8_CHECK;
+ if (offset > 0) {
+ /*
+ * Translate offset into correct placement for utf-8 chars.
+ * Add flag if using offset (string is part of a larger string), so
+ * that "^" won't match.
+ */
+
+ if (objPtr->typePtr != &tclByteArrayType) {
+ /* XXX: probably needs length restriction */
+ offset = Tcl_UtfAtIndex(matchstr, offset) - matchstr;
+ }
+ eflags |= PCRE_NOTBOL;
+ }
+
+ objc -= 2;
+ objv += 2;
+
+ /*
+ * The following loop is to handle multiple matches within the same source
+ * string; each iteration handles one match. If "-all" hasn't been
+ * specified then the loop body only gets executed once. We terminate the
+ * loop when the starting offset is past the end of the string.
+ */
+
+ re = regexpPtr->pcre;
+ study = regexpPtr->study;
+ matches = (int *) regexpPtr->matches;
+ matchelems = (int) (regexpPtr->re.re_nsub + 1) * 3;
+ while (1) {
+ match = pcre_exec(re, study, matchstr, stringLength,
+ offset, eflags, matches, matchelems);
+
+ if (match < -1) {
+ char buf[32 + TCL_INTEGER_SPACE];
+ sprintf(buf, "pcre_exec returned error code %d", match);
+ Tcl_AppendResult(interp, buf, NULL);
+ return TCL_ERROR;
+ }
+
+ if (match == 0) {
+ Tcl_AppendResult(interp,
+ "pcre_exec had insufficient capture space", NULL);
+ return TCL_ERROR;
+ }
+
+ if (match == PCRE_ERROR_NOMATCH) {
+ /*
+ * We want to set the value of the intepreter result only when
+ * this is the first time through the loop.
+ */
+
+ if (all <= 1) {
+ /*
+ * If inlining, the interpreter's object result remains an
+ * empty list, otherwise set it to an integer object w/ value
+ * 0.
+ */
+
+ if (!doinline) {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
+ }
+ return TCL_OK;
+ }
+ break;
+ }
+
+ /*
+ * If additional variable names have been specified, return index
+ * information in those variables.
+ */
+
+ if (doinline) {
+ /*
+ * It's the number of substitutions, plus one for the matchVar at
+ * index 0
+ */
+
+ objc = match;
+ if (all <= 1) {
+ resultPtr = Tcl_NewObj();
+ }
+ }
+ for (i = 0; i < objc; i++) {
+ Tcl_Obj *newPtr;
+ int start, end;
+
+ if (i < match) {
+ start = matches[i*2];
+ end = matches[i*2 + 1];
+ } else {
+ start = -1;
+ end = -1;
+ }
+ if (indices) {
+ Tcl_Obj *objs[2];
+
+ objs[0] = Tcl_NewLongObj(start);
+ objs[1] = Tcl_NewLongObj((end < 0) ? end : end - 1);
+
+ newPtr = Tcl_NewListObj(2, objs);
+ } else {
+ if (i < match) {
+ newPtr = Tcl_NewStringObj(matchstr + start, end - start);
+ } else {
+ newPtr = Tcl_NewObj();
+ }
+ }
+ if (doinline) {
+ if (Tcl_ListObjAppendElement(interp, resultPtr, newPtr)
+ != TCL_OK) {
+ Tcl_DecrRefCount(newPtr);
+ Tcl_DecrRefCount(resultPtr);
+ return TCL_ERROR;
+ }
+ } else {
+ Tcl_Obj *valuePtr;
+ valuePtr = Tcl_ObjSetVar2(interp, objv[i], NULL, newPtr, 0);
+ if (valuePtr == NULL) {
+ Tcl_AppendResult(interp, "couldn't set variable \"",
+ TclGetString(objv[i]), "\"", NULL);
+ return TCL_ERROR;
+ }
+ }
+ }
+
+ if (all == 0) {
+ break;
+ }
+
+ /*
+ * Adjust the offset to the character just after the last one in the
+ * matchVar and increment all to count how many times we are making a
+ * match. We always increment the offset by at least one to prevent
+ * endless looping (as in the case: regexp -all {a*} a). Otherwise,
+ * when we match the NULL string at the end of the input string, we
+ * will loop indefinately (because the length of the match is 0, so
+ * offset never changes).
+ * matches[1] is the match end point of the full RE match.
+ */
+
+ if (matches[0] == matches[1]) {
+ offset++;
+ } else {
+ offset = matches[1];
+ }
+ all++;
+ eflags |= PCRE_NOTBOL;
+ if (offset >= stringLength) {
+ break;
+ }
+ }
+
+ /*
+ * Set the interpreter's object result to an integer object with value 1
+ * if -all wasn't specified, otherwise it's all-1 (the number of times
+ * through the while - 1).
+ */
+
+ if (doinline) {
+ Tcl_SetObjResult(interp, resultPtr);
+ } else {
+ Tcl_SetObjResult(interp, Tcl_NewIntObj(all ? all-1 : 1));
+ }
+ return TCL_OK;
+#else /* !HAVE_PCRE */
+ Tcl_AppendResult(interp, "PCRE not available", NULL);
+ return TCL_ERROR;
+#endif
+}
+
+/*
* Local Variables:
* mode: c
* c-basic-offset: 4
diff --git a/generic/tclRegexp.h b/generic/tclRegexp.h
index 3b2433e..8ee674f 100644
--- a/generic/tclRegexp.h
+++ b/generic/tclRegexp.h
@@ -16,6 +16,10 @@
#include "regex.h"
+#ifdef HAVE_PCRE
+#include <pcre.h>
+#endif
+
/*
* The TclRegexp structure encapsulates a compiled regex_t, the flags that
* were used to compile it, and an array of pointers that are used to indicate
@@ -28,6 +32,10 @@ typedef struct TclRegexp {
int flags; /* Regexp compile flags. */
regex_t re; /* Compiled re, includes number of
* subexpressions. */
+#ifdef HAVE_PCRE
+ pcre *pcre; /* PCRE compile re */
+ pcre_extra *study; /* study of PCRE */
+#endif
const char *string; /* Last string passed to Tcl_RegExpExec. */
Tcl_Obj *objPtr; /* Last object passed to Tcl_RegExpExecObj. */
Tcl_Obj *globObjPtr; /* Glob pattern rep of RE or NULL if none. */
diff --git a/library/Lver.tcl b/library/Lver.tcl
new file mode 100644
index 0000000..0448c55
--- /dev/null
+++ b/library/Lver.tcl
@@ -0,0 +1 @@
+proc Lver {} { return "1.0" }
diff --git a/library/http/http.tcl b/library/http/http.tcl
index 5a05fa0..e4664ec 100644
--- a/library/http/http.tcl
+++ b/library/http/http.tcl
@@ -548,10 +548,11 @@ proc http::geturl {url args} {
# If a timeout is specified we set up the after event and arrange for an
# asynchronous socket connection.
- set sockopts [list -async]
+ set sockopts [list]
if {$state(-timeout) > 0} {
set state(after) [after $state(-timeout) \
[list http::reset $token timeout]]
+ lappend sockopts -async
}
# If we are using the proxy, we must pass in the full URL that includes
diff --git a/library/init.tcl b/library/init.tcl
index 85900d2..175768d 100644
--- a/library/init.tcl
+++ b/library/init.tcl
@@ -7,6 +7,7 @@
# Copyright (c) 1994-1996 Sun Microsystems, Inc.
# Copyright (c) 1998-1999 Scriptics Corporation.
# Copyright (c) 2004 by Kevin B. Kenny. All rights reserved.
+# Copyright (c) 2007 BitMover, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
@@ -816,3 +817,5 @@ proc tcl::CopyDirectory {action src dest} {
}
return
}
+
+source [file join $::tcl_library libl.tcl]
diff --git a/library/libl.tcl b/library/libl.tcl
new file mode 100644
index 0000000..017ed0a
--- /dev/null
+++ b/library/libl.tcl
@@ -0,0 +1,1926 @@
+# This file provides environment initialization and runtime library
+# support for the L language. It is loaded automatically by init.tcl.
+#
+# This stuff should probably be in its own namespace or only turned on when
+# processing L source. It breaks tcl scripts.
+#
+# Copyright (c) 2007-2009 BitMover, Inc.
+
+if {[info exists ::L_libl_initted]} { return }
+set ::L_libl_initted 1
+set ::L_putenv_bug -1
+
+set ::%%suppress_calling_main 0
+
+proc %%call_main_if_defined {} {
+ if {$::tcl_interactive} { return }
+ if {[llength [info proc main]] && !${::%%suppress_calling_main}} {
+ incr ::argc
+ if {![info exists ::argv]} { set ::argv {} }
+ if {![info exists ::argv0]} { set ::argv0 "L" }
+ set ::argv [linsert $::argv 0 $::argv0]
+ switch [llength [info args main]] {
+ 0 {
+ set ::%%suppress_calling_main 1
+ set ret [main]
+ }
+ 1 {
+ set ::%%suppress_calling_main 1
+ set ret [main $::argv]
+ }
+ 2 {
+ set ::%%suppress_calling_main 1
+ set ret [main $::argc $::argv]
+ }
+ 3 {
+ set ::%%suppress_calling_main 1
+ set ret [main $::argc $::argv [dict create {*}[array get ::env]]]
+ }
+ default {
+ error "Too many parameters for main()."
+ set ret 1
+ }
+ }
+ if {$ret == ""} { set ret 0 }
+ if {$ret != 0} { exit $ret }
+ }
+}
+
+# Warn if any of the functions in the %%L_fnsCalled hash are not defined.
+proc %%check_L_fns {} {
+ foreach f [dict keys ${::%%L_fnsCalled}] {
+ if {![llength [info commands $f]] && ![llength [info procs $f]]} {
+ puts stderr "L Warning: function $f not defined"
+ }
+ }
+}
+
+# This loads the Lver() command created by the build.
+if {[file exists [file join $::tcl_library Lver.tcl]]} {
+ source [file join $::tcl_library Lver.tcl]
+ package provide L [Lver]
+}
+
+#lang L
+#pragma fntrace=off
+/*
+ * Types for compatibility with older versions of the compiler.
+ * The tcl typedef lets the tcl cast work now that it's not
+ * hard-coded.
+ */
+typedef poly hash{poly};
+typedef poly tcl;
+
+typedef string FILE;
+typedef string FMT;
+typedef void &fnhook_t(int pre, int ac, poly av[], poly ret);
+
+struct stat {
+ int st_dev;
+ int st_ino;
+ int st_mode;
+ int st_nlink;
+ int st_uid;
+ int st_gid;
+ int st_size;
+ int st_atime;
+ int st_mtime;
+ int st_ctime;
+ string st_type;
+};
+
+typedef struct {
+ string argv[]; // args passed in
+ string path; // if defined, this is the path to the exe
+ // if not defined, the executable was not found
+ int exit; // if defined, the process exited with this val
+ int signal; // if defined, the signal that killed the process
+ string error; // if defined, an error message or output from stderr
+} STATUS;
+
+typedef struct dirent {
+ string name;
+ string type;
+ int hidden;
+} dirent;
+
+FILE stdin = "stdin";
+FILE stderr = "stderr";
+FILE stdout = "stdout";
+string stdio_lasterr;
+STATUS stdio_status;
+
+extern string ::argv[];
+extern int ::argc;
+extern string errorCode[];
+
+int optind = 0;
+string optarg, optopt;
+
+extern dirent[] getdirx(string path);
+extern string getopt(string av[], string opts, string lopts[]);
+extern void getoptReset(void);
+
+/* These are pre-defined identifiers set by the compiler. */
+extern int SYSTEM_ARGV__;
+extern int SYSTEM_IN_STRING__;
+extern int SYSTEM_IN_ARRAY__;
+extern int SYSTEM_IN_FILENAME__;
+extern int SYSTEM_IN_HANDLE__;
+extern int SYSTEM_OUT_STRING__;
+extern int SYSTEM_OUT_ARRAY__;
+extern int SYSTEM_OUT_FILENAME__;
+extern int SYSTEM_OUT_HANDLE__;
+extern int SYSTEM_ERR_STRING__;
+extern int SYSTEM_ERR_ARRAY__;
+extern int SYSTEM_ERR_FILENAME__;
+extern int SYSTEM_ERR_HANDLE__;
+extern int SYSTEM_BACKGROUND__;
+
+/* Used internally by popen() and pclose() for stderr callbacks. */
+typedef struct {
+ FILE pipe;
+ string cmd;
+ string cb;
+} stderr_ctxt_t;
+
+private stderr_ctxt_t callbacks{FILE};
+private int signame_to_num(string signame);
+
+string
+basename(string path)
+{
+ return (File_tail(path));
+}
+
+string
+caller(int stacks)
+{
+ string err;
+
+ try {
+ return (uplevel(1, "info level -${stacks}"));
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (undef);
+ }
+}
+
+int
+chdir(string dir)
+{
+ string err;
+
+ try {
+ cd(dir);
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+int
+chmod(string path, string permissions)
+{
+ string err;
+
+ try {
+ File_attributes(path, permissions: "0${permissions}");
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+int
+chown(string owner, string group, string path)
+{
+ string opts[] = {}, res;
+
+ if ((owner == "") && (group == "")) return (0);
+ unless (owner == "") {
+ push(&opts, {"-owner", owner});
+ }
+ unless (group == "") {
+ push(&opts, {"-group", group});
+ }
+ try {
+ File_attributes(path, (expand)opts);
+ return (0);
+ } catch (&res) {
+ stdio_lasterr = res;
+ return (-1);
+ }
+}
+
+int
+cpus(void)
+{
+ FILE f = fopen("/proc/cpuinfo", "r");
+ int n = 0;
+ string buf;
+
+ unless (f) return (1);
+ while (buf = <f>) {
+ if (buf =~ /^processor\s/) n++;
+ }
+ fclose(f);
+ return (n);
+}
+
+void
+die_(string func, int line, FMT fmt, ...args)
+{
+ warn_(func, line, fmt, (expand)args);
+ exit(1);
+}
+
+string
+dirname(string path)
+{
+ return (File_dirname(path));
+}
+
+int
+exists(string path)
+{
+ return (File_exists(path));
+}
+
+int
+fclose(_mustbetype FILE f)
+{
+ string err;
+
+ unless (f) return (-1);
+
+ try {
+ close(f);
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+FILE
+fopen(string path, string mode)
+{
+ int v = 0;
+ FILE f;
+ string err;
+
+ unless (path) {
+ warn("fopen: pathname is not defined");
+ return (undef);
+ }
+ unless (mode) {
+ warn("fopen: mode is not defined");
+ return (undef);
+ }
+
+ /* new mode, v, means be verbose w/ errors */
+ if (mode =~ /v/) {
+ mode =~ s/v//g;
+ v = 1;
+ }
+ try {
+ f = open(path, mode);
+ return (f);
+ } catch (&err) {
+ stdio_lasterr = err;
+ if (v) fprintf(stderr, "fopen(%s, %s) = %s\n", path, mode, err);
+ return (undef);
+ }
+}
+
+int
+Fprintf(string fname, FMT fmt, ...args)
+{
+ int ret;
+ FILE f;
+
+ unless (f = fopen(fname, "w")) return (-1);
+ ret = fprintf(f, fmt, (expand)args);
+ fclose(f);
+ return (ret);
+}
+
+int
+fprintf(_mustbetype FILE f, FMT fmt, ...args)
+{
+ string err;
+
+ try {
+ puts(nonewline: f, format(fmt, (expand)args));
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+int
+frename_(string oldPath, string newPath)
+{
+ string err;
+
+ try {
+ File_rename(oldPath, newPath);
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+string
+ftype(string path)
+{
+ string err;
+
+ try {
+ return (File_type(path));
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (undef);
+ }
+}
+
+string[]
+getdir(string dir, ...args)
+{
+ int i;
+ string pattern, ret[];
+
+ switch (length(args)) {
+ case 0:
+ pattern = "*";
+ break;
+ case 1:
+ pattern = args[0];
+ break;
+ default:
+ return (undef);
+ }
+ ret = lsort(glob(nocomplain:, directory: dir, pattern));
+
+ // Strip any leading ./
+ for (i = 0; i < length(ret); ++i) {
+ ret[i] =~ s|^\./||;
+ }
+ return (ret);
+}
+
+string
+getenv(string varname)
+{
+ string val;
+
+ try {
+ val = Array_get("::env", varname){varname};
+ return (length(val) ? val : undef);
+ } catch {
+ return (undef);
+ }
+}
+
+int
+getpid()
+{
+ return ((int)(pid()[END]));
+}
+
+void
+here_(string file, int line, string func)
+{
+ puts(stderr, "${func}() in ${basename(file)}:${line}");
+}
+
+int
+isdir(string path)
+{
+ return (File_isdirectory(path));
+}
+
+int
+isreg(string path)
+{
+ return (File_isfile(path));
+}
+
+int
+islink(string path)
+{
+ return (ftype(path) == "link");
+}
+
+int
+isspace(string buf)
+{
+ return (String_isSpace(strict:, buf));
+}
+
+string
+lc(string s)
+{
+ return (String_tolower(s));
+}
+
+int
+isalpha(string buf)
+{
+ return (String_isAlpha(strict:, buf));
+}
+
+int
+isalnum(string buf)
+{
+ return (String_isAlnum(strict:, buf));
+}
+
+int
+islower(string buf)
+{
+ return (String_isLower(strict:, buf));
+}
+
+int
+isupper(string buf)
+{
+ return (String_isUpper(strict:, buf));
+}
+
+int
+isdigit(string buf)
+{
+ return (String_isDigit(strict:, buf));
+}
+
+int
+iswordchar(string buf)
+{
+ return (String_isWordchar(strict:, buf));
+}
+
+int
+link(string sourcePath, string targetPath)
+{
+ string err;
+
+ try {
+ File_link(hard: targetPath, sourcePath);
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+int
+lstat(string path, struct stat &buf)
+{
+ string err, st_hash{string};
+
+ try {
+ File_lstat(path, "ret");
+ st_hash = Array_get("ret");
+ buf->st_dev = (int)st_hash{"dev"};
+ buf->st_ino = (int)st_hash{"ino"};
+ buf->st_mode = (int)st_hash{"mode"};
+ buf->st_nlink = (int)st_hash{"nlink"};
+ buf->st_uid = (int)st_hash{"uid"};
+ buf->st_gid = (int)st_hash{"gid"};
+ buf->st_size = (int)st_hash{"size"};
+ buf->st_atime = (int)st_hash{"atime"};
+ buf->st_mtime = (int)st_hash{"mtime"};
+ buf->st_ctime = (int)st_hash{"ctime"};
+ buf->st_type = st_hash{"type"};
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+private int tm_start = Clock_clicks(milliseconds:);
+
+int
+milli()
+{
+ return (Clock_clicks(milliseconds:) - tm_start);
+}
+
+void
+milli_reset()
+{
+ tm_start = Clock_clicks(milliseconds:);
+}
+
+int
+mkdir(string path)
+{
+ string err;
+
+ try {
+ File_mkdir(path);
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+int
+mtime(string path)
+{
+ try {
+ return (File_mtime(path));
+ } catch {
+ return (0);
+ }
+}
+
+string
+normalize(string path)
+{
+ return (File_normalize(path));
+}
+
+int
+ord(string c)
+{
+ int n = -1;
+
+ if (length(c)) scan(c[0], "%c", &n);
+ return (n);
+}
+
+int
+pclose(_mustbetype FILE f, _optional STATUS &status_ref)
+{
+ string err;
+ STATUS status;
+
+ // Put the pipe in blocking mode so that Tcl knows to throw
+ // an error if the program exited with exit_code != 0.
+ fconfigure(f, blocking: 1);
+
+ status.exit = 0;
+ try {
+ close(f);
+ } catch (&err) {
+ status.error = stdio_lasterr = err;
+ switch (errorCode[0]) {
+ case "CHILDSTATUS":
+ status.exit = (int)errorCode[2];
+ break;
+ case "CHILDKILLED":
+ status.signal = signame_to_num(errorCode[2]);
+ break;
+ }
+ }
+
+ // Call the user's callback.
+ if (callbacks{f}) {
+ stderr_cb_(callbacks{f});
+ undef(callbacks{f});
+ }
+
+ stdio_status = status;
+ if (defined(&status_ref)) status_ref = status;
+ return ((status.exit == 0) ? 0 : -1);
+}
+
+string
+platform()
+{
+ string p;
+
+ eval("set p $::tcl_platform(platform)");
+ return (p);
+}
+
+private void
+stderr_cb_(stderr_ctxt_t ctxt)
+{
+ if (Chan_names(ctxt.pipe) == "") return; // if closed
+ eval({ctxt.cb, ctxt.cmd, ctxt.pipe});
+ try {
+ if (eof(ctxt.pipe)) ::close(ctxt.pipe);
+ } catch {}
+}
+
+private void
+stderr_gui_cb_(_argused string cmd, FILE fd)
+{
+ string data;
+ widget top = ".__stderr";
+ widget f = top . ".f";
+ widget t = f . ".t";
+ widget vs = f . ".vs";
+ widget hs = f . ".hs";
+
+ unless (read(fd, &data)) return;
+
+ unless (Winfo_exists((string)top)) {
+ tk_make_readonly_tag_();
+
+ toplevel(top);
+ Wm_title((string)top, "Error Output");
+ Wm_protocol((string)top, "WM_DELETE_WINDOW",
+ "wm withdraw ${top}");
+ ttk::frame(f);
+ text(t, wrap: "none", highlightthickness: 0, insertwidth: 0,
+ xscrollcommand: "${hs} set",
+ yscrollcommand: "${vs} set");
+ bindtags(t, {t, "ReadonlyText", "all"});
+ ttk::scrollbar(vs, orient: "vertical", command: "${t} yview");
+ ttk::scrollbar(hs, orient: "horizontal", command: "${t} xview");
+ grid(t, row: 0, column: 0, sticky: "nesw");
+ grid(vs, row: 0, column: 1, sticky: "ns");
+ grid(hs, row: 1, column: 0, sticky: "ew");
+ Grid_rowconfigure((string)f, t, weight: 1);
+ Grid_columnconfigure((string)f, t, weight: 1);
+
+ ttk::frame("${top}.buttons");
+ ttk::button("${top}.buttons.close",
+ text: "Close", command: "wm withdraw ${top}");
+ pack("${top}.buttons.close", side: "right", padx: "5 15");
+ ttk::button("${top}.buttons.save",
+ text: "Save to Log", command: "tk_save_to_log_ ${t}");
+ pack("${top}.buttons.save", side: "right");
+
+ grid("${top}.buttons", row: 1, column: 0, sticky: "esw");
+
+ grid(f, row: 0, column: 0, sticky: "nesw");
+ Grid_rowconfigure((string)top, f, weight: 1);
+ Grid_columnconfigure((string)top, f, weight: 1);
+ }
+
+ unless(Winfo_viewable((string)top)) {
+ Wm_deiconify((string)top);
+ }
+
+ /* Make sure the error is not obscured by other windows. */
+ After_idle("raise ${top}");
+ Text_insertEnd(t, "cmd: ${cmd}\n" . data);
+ Update_idletasks();
+}
+
+FILE
+popen_(poly cmd, string mode, void &stderr_cb(string cmd, FILE f), int flags)
+{
+ int v = 0;
+ int redir;
+ FILE f, rdPipe, wrPipe;
+ string arg, argv[], err;
+ stderr_ctxt_t ctxt;
+
+ if (mode =~ /v/) {
+ mode =~ s/v//g;
+ v = 1;
+ }
+
+ if (flags & SYSTEM_ARGV__) {
+ argv = (string[])cmd;
+ cmd = join(" ", argv);
+ } else {
+ try {
+ argv = shsplit(cmd);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (undef);
+ }
+ }
+
+ /*
+ * Re-direct stderr to this process' stderr unless the caller
+ * redirected it inside their command or specified a callback.
+ */
+ redir = 0;
+ foreach (arg in argv) {
+ if (arg =~ /^2>/) {
+ redir = 1;
+ break;
+ }
+ }
+
+ unless (redir) {
+ /* Caller did not redirect stderr */
+ unless (flags & SYSTEM_OUT_HANDLE__) {
+ /* or give us a callback */
+ if (tk_loaded_()) {
+ stderr_cb = &stderr_gui_cb_;
+ } else {
+ push(&argv, "2>@stderr");
+ }
+ }
+ if (stderr_cb) {
+ try {
+ {rdPipe,wrPipe} = Chan_pipe();
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (undef);
+ }
+ fconfigure(rdPipe, blocking: "off", buffering: "line");
+ push(&argv, "2>@${wrPipe}");
+ ctxt.pipe = rdPipe;
+ ctxt.cmd = cmd;
+ ctxt.cb = (string)stderr_cb;
+ fileevent(rdPipe, "readable", {&stderr_cb_, ctxt});
+ }
+
+ /*
+ * If they didn't redirect, and they passed us undef as the
+ * callback argument, we end up doing nothing and just let
+ * Tcl eat stderr.
+ */
+ }
+
+ try {
+ f = open("|${argv}", mode);
+ if (wrPipe) ::close(wrPipe);
+ if (stderr_cb) callbacks{f} = ctxt;
+ return (f);
+ } catch (&err) {
+ stdio_lasterr = err;
+ if (v) fprintf(stderr, "popen(%s, %s) = %s\n", cmd, mode, err);
+ return (undef);
+ }
+}
+
+int
+printf(FMT fmt, ...args)
+{
+ try {
+ puts(nonewline:, format(fmt, (expand)args));
+ return (0);
+ } catch {
+ return (-1);
+ }
+}
+
+string
+require(...args)
+{
+ try {
+ return (Package_require((expand)args));
+ } catch {
+ return (undef);
+ }
+}
+
+int
+rmdir(string dir)
+{
+ string err;
+
+ try {
+ File_delete(dir);
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+void
+perror(...args)
+{
+ string msg = args[0];
+
+ if (defined(msg)) {
+ puts("${msg}: ${stdio_lasterr}");
+ } else {
+ puts(stdio_lasterr);
+ }
+}
+
+extern int ::L_putenv_bug;
+
+string
+putenv(FMT var_fmt, _argused ...args)
+{
+ string ret;
+
+ unless (var_fmt =~ /([^=]+)=(.*)/) return (undef);
+ if (::L_putenv_bug == -1) {
+ // test for macos-x86's putenv bug
+ eval("set ::env(_L_ENV_TEST) =====");
+ switch (ret=(string)getenv("_L_ENV_TEST")) {
+ case "=====":
+ ::L_putenv_bug = 0;
+ break;
+ case "====":
+ ::L_putenv_bug = 1;
+ break;
+ default:
+ die("fatal error: ret='${ret}'");
+ }
+ }
+ if (::L_putenv_bug && ($2[0] == "=")) {
+ if (::catch("set ::env(${$1}) [format =${$2} {*}$args]", &ret)) {
+ return (undef);
+ }
+ undef(ret[0]); // strip leading =
+ } else {
+ if (::catch("set ::env(${$1}) [format {${$2}} {*}$args]", &ret)) {
+ return (undef);
+ }
+ }
+ return (ret);
+}
+
+int
+size(string path)
+{
+ try {
+ return (File_size(path));
+ } catch {
+ return (-1);
+ }
+}
+
+void
+sleep(float seconds)
+{
+ after((int)(seconds * 1000));
+}
+
+string
+sprintf(_argused FMT fmt, _argused ...args)
+{
+ string err;
+
+ try {
+ return (format(fmt, (expand)args));
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (undef);
+ }
+}
+
+int
+stat(string path, struct stat &buf)
+{
+ string err, st_hash{string};
+
+ try {
+ File_stat(path, "ret");
+ st_hash = Array_get("ret");
+ buf->st_dev = (int)st_hash{"dev"};
+ buf->st_ino = (int)st_hash{"ino"};
+ buf->st_mode = (int)st_hash{"mode"};
+ buf->st_nlink = (int)st_hash{"nlink"};
+ buf->st_uid = (int)st_hash{"uid"};
+ buf->st_gid = (int)st_hash{"gid"};
+ buf->st_size = (int)st_hash{"size"};
+ buf->st_atime = (int)st_hash{"atime"};
+ buf->st_mtime = (int)st_hash{"mtime"};
+ buf->st_ctime = (int)st_hash{"ctime"};
+ buf->st_type = st_hash{"type"};
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+int
+strchr(string s, string c)
+{
+ return (String_first(c, s));
+}
+
+int
+streq(string a, string b)
+{
+ return (a == b);
+}
+
+int
+strlen(string s)
+{
+ return (length(s));
+}
+
+int
+strneq(string a, string b, int n)
+{
+ return (String_equal(length: n, a, b) != "0");
+}
+
+int
+strrchr(string s, string c)
+{
+ return (String_last(c, s));
+}
+
+int
+symlink(string sourcePath, string targetPath)
+{
+ string err;
+
+ try {
+ File_link(symbolic: targetPath, sourcePath);
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+private int
+signame_to_num(string signame)
+{
+ switch (signame) {
+ case "SIGHUP": return (1);
+ case "SIGINT": return (2);
+ case "SIGQUIT": return (3);
+ case "SIGABRT": return (6);
+ case "SIGKILL": return (9);
+ case "SIGALRM": return (14);
+ case "SIGTERM": return (15);
+ default: return (undef);
+ }
+}
+
+private struct {
+ FILE chIn;
+ FILE chOut;
+ FILE chErr;
+ string nmIn;
+ int flags;
+ STATUS status;
+ int started;
+} spawn_handles{int};
+
+/*
+ * This is used as a filevent handler for a spawned process' stdout.
+ * Read what's there and write it to whatever user output channel
+ * system_() set up for it. When we see EOF, close the process output
+ * channel and reap the exit status. Stuff it in a private global for
+ * eventual use by waitpid().
+ */
+private void
+spawn_checker_(FILE f)
+{
+ int mypid = pid(f)[END];
+ int flags = spawn_handles{mypid}.flags;
+ FILE chIn = spawn_handles{mypid}.chIn;
+ FILE chOut = spawn_handles{mypid}.chOut;
+
+ // Can't happen? But be paranoid.
+ unless (defined(chOut)) return;
+
+ ::catch("puts -nonewline $chOut [read $f]");
+
+ if (eof(f)) {
+ spawn_handles{mypid}.chOut = undef;
+
+ // Need to configure the channel to be blocking
+ // before we call close so it will fail with an
+ // error if there was one instead of ignoring it.
+ fconfigure(f, blocking: 1);
+
+ try {
+ close(f);
+ spawn_handles{mypid}.status.exit = 0;
+ } catch {
+ switch (errorCode[0]) {
+ case "CHILDSTATUS":
+ spawn_handles{mypid}.status.exit =
+ (int)errorCode[2];
+ break;
+ case "CHILDKILLED":
+ spawn_handles{mypid}.status.signal =
+ signame_to_num(errorCode[2]);
+ break;
+ }
+ }
+ if (flags & SYSTEM_OUT_FILENAME__) {
+ close(chOut);
+ }
+ if (flags & SYSTEM_ERR_FILENAME__) {
+ close(spawn_handles{mypid}.chErr);
+ }
+ if (flags & SYSTEM_IN_FILENAME__) {
+ close(chIn);
+ } else if (flags & (SYSTEM_IN_ARRAY__ | SYSTEM_IN_STRING__)) {
+ close(chIn);
+ unlink(spawn_handles{mypid}.nmIn);
+ }
+ set("::%L_pid${mypid}_done", 1); // waitpid() vwaits on this
+ set("::%L_zombies", 1); // and this
+ }
+}
+
+int
+system_(poly argv, poly in, poly &out_ref, poly &err_ref, STATUS &status_ref,
+ int flags)
+{
+ int mypid, ret = 0, userErrRedirect = 0, userOutRedirect = 0;
+ int spawn = (flags & SYSTEM_BACKGROUND__);
+ string arg, err, nmErr, nmIn, nmOut, out, path, res;
+ FILE chErr, chIn, chOut, f;
+ STATUS status;
+
+ /*
+ * Alias our locals "err" and "out" to the values of
+ * the "&err_ref" and "&out_ref" actuals. This lets us access
+ * these parameters whether they are passed by value or by
+ * reference. The system() API allows either and the flags arg
+ * tells us what the user passed in (the by-reference
+ * flavors are when you pass a string or array by reference,
+ * to get stdout or stderr; the by-value flavors are when you
+ * pass a file name or handle).
+ */
+ eval('unset err out');
+ eval('upvar 0 &err_ref err');
+ eval('upvar 0 &out_ref out');
+
+ /*
+ * If out or err were passed in by reference, check that the
+ * reference is defined. If not, then just ignore it.
+ */
+ if ((flags & (SYSTEM_OUT_STRING__ | SYSTEM_OUT_ARRAY__)) &&
+ !defined(&out_ref)) {
+ flags &= ~(SYSTEM_OUT_STRING__ | SYSTEM_OUT_ARRAY__);
+ }
+ if ((flags & (SYSTEM_ERR_STRING__ | SYSTEM_ERR_ARRAY__)) &&
+ !defined(&err_ref)) {
+ flags &= ~(SYSTEM_ERR_STRING__ | SYSTEM_ERR_ARRAY__);
+ }
+
+ unless (flags & SYSTEM_ARGV__) {
+ try {
+ argv = shsplit(argv);
+ } catch (&res) {
+ stdio_lasterr = res;
+ ret = undef;
+ goto out;
+ }
+ }
+ status.argv = argv;
+ status.exit = undef;
+ status.signal = undef;
+ if (length(path = auto_execok(argv[0]))) {
+ status.path = path;
+ } else {
+ status.path = undef;
+ ret = undef;
+ goto out;
+ }
+
+ /* Check for user I/O re-direction. */
+ foreach (arg in (string[])argv) {
+ switch (arg) {
+ case /^</:
+ if (flags & (SYSTEM_IN_HANDLE__ | SYSTEM_IN_FILENAME__ |
+ SYSTEM_IN_STRING__ | SYSTEM_IN_ARRAY__)) {
+ stdio_lasterr = "cannot both specify and re-direct stdin";
+ ret = undef;
+ goto out;
+ }
+ break;
+ case /^>/:
+ userOutRedirect = 1;
+ if (flags & (SYSTEM_OUT_HANDLE__ | SYSTEM_OUT_FILENAME__ |
+ SYSTEM_OUT_STRING__ | SYSTEM_OUT_ARRAY__)) {
+ stdio_lasterr = "cannot both specify and re-direct stdout";
+ ret = undef;
+ goto out;
+ }
+ break;
+ case /^2>/:
+ userErrRedirect = 1;
+ if (flags & (SYSTEM_ERR_HANDLE__ | SYSTEM_ERR_FILENAME__ |
+ SYSTEM_ERR_STRING__ | SYSTEM_ERR_ARRAY__)) {
+ stdio_lasterr = "cannot both specify and re-direct stderr";
+ ret = undef;
+ goto out;
+ }
+ break;
+ }
+ }
+
+ if (flags & (SYSTEM_IN_ARRAY__ | SYSTEM_IN_STRING__)) {
+ chIn = File_Tempfile(&nmIn);
+ if (flags & SYSTEM_IN_ARRAY__) {
+ in = join("\n", in);
+ puts(chIn, in);
+ } else {
+ puts(nonewline: chIn, in);
+ }
+ close(chIn);
+ chIn = fopen(nmIn, "r");
+ } else if (flags & SYSTEM_IN_FILENAME__) {
+ if (defined(in)) {
+ unless (defined(chIn = fopen(in, "r"))) {
+ ret = undef;
+ goto out;
+ }
+ }
+ } else if (flags & SYSTEM_IN_HANDLE__) {
+ unless (defined(in)) {
+ stdio_lasterr = "stdin channel not open";
+ ret = undef;
+ goto out;
+ }
+ chIn = in;
+ }
+ if (flags & (SYSTEM_OUT_STRING__ | SYSTEM_OUT_ARRAY__)) {
+ chOut = File_Tempfile(&nmOut);
+ } else if (flags & SYSTEM_OUT_FILENAME__) {
+ if (defined(out)) {
+ unless (defined(chOut = fopen(out, "w"))) {
+ ret = undef;
+ goto out;
+ }
+ }
+ } else if (flags & SYSTEM_OUT_HANDLE__) {
+ unless (defined(out)) {
+ stdio_lasterr = "stdout channel not open";
+ ret = undef;
+ goto out;
+ }
+ chOut = out;
+ } else unless (userOutRedirect) {
+ chOut = "stdout";
+ }
+ if (flags & (SYSTEM_ERR_STRING__ | SYSTEM_ERR_ARRAY__)) {
+ chErr = File_Tempfile(&nmErr);
+ } else if (flags & SYSTEM_ERR_FILENAME__) {
+ if (defined(err)) {
+ unless (defined(chErr = fopen(err, "w"))) {
+ ret = undef;
+ goto out;
+ }
+ }
+ } else if (flags & SYSTEM_ERR_HANDLE__) {
+ unless (defined(err)) {
+ stdio_lasterr = "stderr channel not open";
+ ret = undef;
+ goto out;
+ }
+ chErr = err;
+ } else unless (userErrRedirect) {
+ chErr = "stderr";
+ }
+
+ if (defined(chIn)) push(&argv, "<@${chIn}");
+ if (defined(chOut) && !spawn) push(&argv, ">@${chOut}");
+ if (defined(chErr)) push(&argv, "2>@${chErr}");
+
+ if (spawn) {
+ /* For spawn(). */
+ try {
+ f = open("|${argv}", "r");
+ mypid = pid(f)[END];
+ unless (defined(chOut)) chOut = "stdout";
+ spawn_handles{mypid}.chIn = chIn;
+ spawn_handles{mypid}.nmIn = nmIn;
+ spawn_handles{mypid}.chOut = chOut;
+ spawn_handles{mypid}.chErr = chErr;
+ spawn_handles{mypid}.status = status;
+ spawn_handles{mypid}.flags = flags;
+ spawn_handles{mypid}.started = 1;
+ unset(nocomplain: "::%L_pid${mypid}_done");
+ fconfigure(f, blocking: 0, buffering: "none");
+ fileevent(f, "readable", {&spawn_checker_, f});
+ return (mypid);
+ } catch (&res) {
+ stdio_lasterr = res;
+ ret = undef;
+ goto out;
+ }
+ } else {
+ /* For system(). */
+ try {
+ exec("--", (expand)argv);
+ ret = 0;
+ status.exit = ret;
+ } catch (&res) {
+ stdio_lasterr = res;
+ switch (errorCode[0]) {
+ case "CHILDSTATUS":
+ ret = (int)errorCode[2];
+ status.exit = ret;
+ break;
+ case "CHILDKILLED":
+ status.signal = signame_to_num(errorCode[2]);
+ ret = undef;
+ goto out;
+ default:
+ ret = undef;
+ goto out;
+ }
+ }
+ }
+
+ if (flags & (SYSTEM_OUT_STRING__ | SYSTEM_OUT_ARRAY__)) {
+ close(chOut);
+ if (defined(chOut = fopen(nmOut, "r"))) {
+ int n = read(chOut, &out_ref, -1);
+ if (n < 0) {
+ ret = undef;
+ goto out;
+ } else if (n == 0) {
+ out_ref = undef;
+ } else if (flags & SYSTEM_OUT_ARRAY__) {
+ // Chomp and split. Use Tcl's split since L's
+ // strips trailing null fields.
+ if (length((string)out_ref) &&
+ ((string)out_ref)[END] == "\n") {
+ ((string)out_ref)[END] = "";
+ }
+ out_ref = ::split(out_ref, "\n");
+ }
+ } else {
+ ret = undef;
+ goto out;
+ }
+ }
+ if (flags & (SYSTEM_ERR_STRING__ | SYSTEM_ERR_ARRAY__)) {
+ close(chErr);
+ if (defined(chErr = fopen(nmErr, "r"))) {
+ int n = read(chErr, &err_ref, -1);
+ if (n < 0) {
+ ret = undef;
+ goto out;
+ } else if (n == 0) {
+ err_ref = undef;
+ } else if (flags & SYSTEM_ERR_ARRAY__) {
+ // Chomp and split. Use Tcl's split since L's
+ // strips trailing null fields.
+ if (length((string)err_ref) &&
+ ((string)err_ref)[END] == "\n") {
+ ((string)err_ref)[END] = "";
+ }
+ err_ref = ::split(err_ref, "\n");
+ }
+ } else {
+ ret = undef;
+ }
+ }
+ out:
+ if (flags & (SYSTEM_IN_ARRAY__|SYSTEM_IN_FILENAME__|SYSTEM_IN_STRING__)) {
+ if (defined(chIn)) close(chIn);
+ }
+ if (flags & (SYSTEM_OUT_ARRAY__|SYSTEM_OUT_FILENAME__|SYSTEM_OUT_STRING__)) {
+ if (defined(chOut)) close(chOut);
+ }
+ if (flags & (SYSTEM_ERR_ARRAY__|SYSTEM_ERR_FILENAME__|SYSTEM_ERR_STRING__)) {
+ if (defined(chErr)) close(chErr);
+ }
+ if (flags & (SYSTEM_IN_ARRAY__ | SYSTEM_IN_STRING__)) {
+ if (defined(nmIn)) unlink(nmIn);
+ }
+ if (flags & (SYSTEM_OUT_ARRAY__ | SYSTEM_OUT_STRING__)) {
+ if (defined(nmOut)) unlink(nmOut);
+ }
+ if (flags & (SYSTEM_ERR_ARRAY__ | SYSTEM_ERR_STRING__) ) {
+ if (defined(nmErr)) unlink(nmErr);
+ }
+ stdio_status = status;
+ if (defined(&status_ref)) status_ref = status;
+ return (ret);
+}
+
+/* Like system() but do not re-direct stderr; used for `cmd`. */
+string
+backtick_(string cmd)
+{
+ string argv[], err, path, res;
+
+ stdio_status = undef;
+
+ try {
+ argv = shsplit(cmd);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (undef);
+ }
+
+ stdio_status.argv = argv;
+ if (length(path = auto_execok(argv[0]))) {
+ stdio_status.path = path;
+ }
+
+ try {
+ res = exec(ignorestderr: "--", (expand)argv);
+ stdio_status.exit = 0;
+ return (res);
+ } catch (&err) {
+ switch (errorCode[0]) {
+ case "CHILDSTATUS":
+ stdio_lasterr = "child process exited abnormally";
+ err =~ s/child process exited abnormally\z//;
+ stdio_status.exit = (int)errorCode[2];
+ break;
+ case "CHILDKILLED":
+ stdio_lasterr = err;
+ stdio_status.signal = signame_to_num(errorCode[2]);
+ break;
+ default:
+ stdio_lasterr = err;
+ return (undef);
+ }
+ return (err);
+ }
+}
+
+string
+trim(string s)
+{
+ return (String_trim(s));
+}
+
+int
+unlink(string path)
+{
+ string err;
+
+ try {
+ File_delete(path);
+ return (0);
+ } catch (&err) {
+ stdio_lasterr = err;
+ return (-1);
+ }
+}
+
+string
+uc(string s)
+{
+ return (String_toupper(s));
+}
+
+int
+waitpid(int pid, STATUS &status, int nohang)
+{
+ int p, running;
+
+ // If we don't call vwait, Tcl will never enter the
+ // event loop and call the rest of our code, so we
+ // want to force an update of the event loop before
+ // we do our checks.
+ if (nohang) update();
+
+ // If no pid, go find the first unreaped one.
+ while (pid == -1) {
+ running = 0;
+ foreach (p in keys(spawn_handles)) {
+ unless (defined(spawn_handles{p}.started)) {
+ continue;
+ }
+ if (Info_exists("::%L_pid${p}_done")) {
+ pid = p;
+ break;
+ } else {
+ running++;
+ }
+ }
+ if (pid >= 0) break;
+ if (nohang || !running) {
+ return (-1);
+ } else {
+ vwait("::%L_zombies");
+ }
+ }
+
+ unless (defined(spawn_handles{pid}.started)) return (-1);
+ unless (Info_exists("::%L_pid${pid}_done")) {
+ if (nohang) return (0);
+ vwait("::%L_pid${pid}_done");
+ }
+ stdio_status = spawn_handles{pid}.status;
+ if (defined(&status)) status = stdio_status;
+ undef(spawn_handles{pid});
+ return (pid);
+}
+
+int
+wait(STATUS &status)
+{
+ return (waitpid(-1, &status, 0));
+}
+
+void
+warn_(string file, int line, FMT fmt, ...args)
+{
+ string out = format(fmt, (expand)args);
+
+ unless (length(out) && (out[END] == "\n")) {
+ out .= " at ${file} line ${line}.\n";
+ }
+ puts(nonewline:, stderr, out);
+ flush(stderr);
+}
+
+/* L function tracing support. */
+
+extern string L_fnsDeclared{string}{string};
+private int L_start_level;
+private FILE L_fn_f = stderr;
+private int L_fn_tr_inhook = 0;
+
+/*
+ * Called once before each top-level proc generated by the L compiler
+ * is run (so we must be idempotent). Walk the list of all declared L
+ * functions and enable Tcl entry or exit traces on those marked with
+ * tracing attributes. When functions are compiled they inherit
+ * attributes from the #pragma or command-line attributes currently in
+ * effect. These can be overridden here with environment variables.
+ */
+void
+LtraceInit()
+{
+ string args{string}, s;
+
+ L_start_level = Info_level();
+
+ if (s = getenv("L_TRACE_HOOK")) args{"fnhook"} = s;
+ if (s = getenv("L_TRACE_ALL")) args{"fntrace"} = s;
+ if (s = getenv("L_TRACE_FILES")) args{"trace_files"} = s;
+ if (s = getenv("L_TRACE_FUNCS")) args{"trace_funcs"} = s;
+ if (s = getenv("L_TRACE_OUT")) args{"trace_out"} = s;
+ if (s = getenv("L_TRACE_DEPTH")) args{"trace_depth"} = s;
+ if (s = getenv("L_DISASSEMBLE")) args{"dis"} = s;
+ if (s = getenv("L_TRACE")) {
+ args{"trace_out"} = s;
+ args{"trace_funcs"} = "*";
+ }
+ Ltrace(args);
+}
+
+/*
+ * This is passed a hash of named args.
+ */
+void
+Ltrace(string args{string})
+{
+ string file, fn, func, hook, s, v, what;
+ string attrs{string};
+ string trace_files = args{"trace_files"};
+ string trace_funcs = args{"trace_funcs"};
+
+ /* Mark any function specified as a hook so we don't trace it. */
+ foreach (func=>attrs in L_fnsDeclared) {
+ hook = attrs{"fnhook"};
+ if (hook && L_fnsDeclared{hook}) {
+ L_fnsDeclared{hook}{"ishook"} = "yes";
+ tracefn(func, "remove", "enter", hook);
+ tracefn(func, "remove", "leave", hook);
+ }
+ }
+ hook = args{"fnhook"};
+
+ /*
+ * Valid formats for trace_out:
+ * trace_out=stdout|stderr send to stdout or stderr
+ * trace_out=host:port send to TCP socket
+ * trace_out=filename send to file
+ */
+ if (v=args{"trace_out"}) {
+ if (L_fn_f && (L_fn_f != stdout) && (L_fn_f != stderr)) {
+ fclose(L_fn_f);
+ L_fn_f = undef;
+ }
+ switch (v) {
+ case "stderr":
+ L_fn_f = stderr;
+ break;
+ case "stdout":
+ L_fn_f = stdout;
+ break;
+ case /^([^:]+):(\d+)$/:
+ try {
+ L_fn_f = socket($1, $2);
+ } catch {
+ warn("cannot connect to ${$1}:${$2} for "
+ "trace output\n");
+ }
+ break;
+ default:
+ L_fn_f = fopen(v, "w");
+ unless (L_fn_f) {
+ warn("cannot open file '${v}' for "
+ "trace output\n");
+ }
+ break;
+ }
+ }
+ if (v=args{"trace_depth"}) {
+ foreach (func=>attrs in L_fnsDeclared) {
+ if (attrs{"file"} == "libl.tcl") continue;
+ L_fnsDeclared{func}{"trace_depth"} = v;
+ }
+ }
+ /*
+ * If no trace_files or trace_funcs are given, then trace
+ * whatever functions are already marked for it.
+ *
+ * If trace_files or trace_funcs starts with +/-, add to or
+ * subtract from what is already marked for tracing.
+ *
+ * Otherwise, trace_files/trace_funcs is *setting* what to trace,
+ * so start by turning off all tracing.
+ */
+ if ((!trace_files && !trace_funcs) ||
+ ((trace_files[0] == "+") ||
+ (trace_files[0] == "-") ||
+ (trace_funcs[0] == "+") ||
+ (trace_funcs[0] == "-"))) {
+ foreach (func=>attrs in L_fnsDeclared) {
+ switch (attrs{"fntrace"}) {
+ case "on":
+ tracefn(func, "add", "enter", hook);
+ tracefn(func, "add", "leave", hook);
+ break;
+ case "entry":
+ tracefn(func, "add", "enter", hook);
+ tracefn(func, "remove", "leave", hook);
+ break;
+ case "exit":
+ tracefn(func, "remove", "enter", hook);
+ tracefn(func, "add", "leave", hook);
+ break;
+ case "off":
+ tracefn(func, "remove", "enter", hook);
+ tracefn(func, "remove", "leave", hook);
+ break;
+ }
+ }
+ } else {
+ foreach (func=>attrs in L_fnsDeclared) {
+ tracefn(func, "remove", "enter", hook);
+ tracefn(func, "remove", "leave", hook);
+ }
+ }
+ /*
+ * Turn on or off tracing for all functions.
+ */
+ if (v=args{"fntrace"}) {
+ foreach (func=>attrs in L_fnsDeclared) {
+ switch (v) {
+ case "on":
+ tracefn(func, "add", "enter", hook);
+ tracefn(func, "add", "leave", hook);
+ continue;
+ case "entry":
+ tracefn(func, "add", "enter", hook);
+ tracefn(func, "remove", "leave", hook);
+ continue;
+ case "exit":
+ tracefn(func, "remove", "enter", hook);
+ tracefn(func, "add", "leave", hook);
+ continue;
+ case "off":
+ tracefn(func, "remove", "enter", hook);
+ tracefn(func, "remove", "leave", hook);
+ continue;
+ }
+ }
+ }
+ if (trace_files) {
+ foreach (file in split(/[:,]/, trace_files)) {
+ switch (file[0]) {
+ case '+':
+ what = "add";
+ undef(file[0]);
+ break;
+ case '-':
+ what = "remove";
+ undef(file[0]);
+ break;
+ default:
+ what = "add";
+ break;
+ }
+ if ((file[0] == '/') && (file[END] == '/')) {
+ // Pattern is a regexp.
+ undef(file[0]);
+ undef(file[END]);
+ foreach (func=>attrs in L_fnsDeclared) {
+ if (attrs{"file"} =~ /${file}/) {
+ tracefn(func, what, "enter", hook);
+ tracefn(func, what, "leave", hook);
+ }
+ }
+ } else {
+ // Pattern is a glob.
+ foreach (func=>attrs in L_fnsDeclared) {
+ if (attrs{"file"} =~ /${file}/l) {
+ tracefn(func, what, "enter", hook);
+ tracefn(func, what, "leave", hook);
+ }
+ }
+ }
+ }
+ }
+ if (trace_funcs) {
+ foreach (func in split(/[:,]/, trace_funcs)) {
+ switch (func[0]) {
+ case '+':
+ what = "add";
+ undef(func[0]);
+ break;
+ case '-':
+ what = "remove";
+ undef(func[0]);
+ break;
+ default:
+ what = "add";
+ break;
+ }
+ // Lib L override.
+ if (func[0] == '!') {
+ what = "!" . what;
+ undef(func[0]);
+ }
+ if ((func[0] == '/') && (func[END] == '/')) {
+ // Pattern is a regexp.
+ undef(func[0]);
+ undef(func[END]);
+ foreach (fn=>attrs in L_fnsDeclared) {
+ if (attrs{"name"} =~ /${func}/) {
+ tracefn(fn, what, "enter", hook);
+ tracefn(fn, what, "leave", hook);
+ }
+ }
+ } else {
+ // Pattern is a glob.
+ foreach (fn=>attrs in L_fnsDeclared) {
+ if (attrs{"name"} =~ /${func}/l) {
+ tracefn(fn, what, "enter", hook);
+ tracefn(fn, what, "leave", hook);
+ }
+ }
+ }
+ }
+ }
+ /* Disassemble. */
+ if (v=args{"dis"}) {
+ if ((v == "1") || (v =~ /yes/i)) v = "*";
+ foreach (s in split(/[:,]/, v)) {
+ switch (s[0]) {
+ case '+':
+ what = "yes";
+ undef(s[0]);
+ break;
+ case '-':
+ what = "no";
+ undef(s[0]);
+ break;
+ default:
+ what = "yes";
+ break;
+ }
+ // Check pattern against both func and file names.
+ if ((s[0] == '/') && (s[END] == '/')) {
+ // Pattern is a regexp.
+ undef(s[0]);
+ undef(s[END]);
+ foreach (fn=>attrs in L_fnsDeclared) {
+ if ((attrs{"name"} =~ /${s}/) ||
+ (attrs{"file"} =~ /${s}/)) {
+ L_fnsDeclared{fn}{"dis"} = what;
+ }
+ }
+ } else {
+ // Pattern is a glob.
+ foreach (fn=>attrs in L_fnsDeclared) {
+ if ((attrs{"name"} =~ /${s}/l) ||
+ (attrs{"file"} =~ /${s}/l)) {
+ L_fnsDeclared{fn}{"dis"} = what;
+ }
+ }
+ }
+ }
+ foreach (fn=>attrs in L_fnsDeclared) {
+ if (attrs{"dis_done"}) continue;
+ if (attrs{"dis"} == "yes") {
+ s = ::tcl::unsupported::disassemble("proc", fn);
+ puts(L_fn_f, "Disassembly for ${fn}:");
+ puts(L_fn_f, s);
+ L_fnsDeclared{fn}{"dis_done"} = "yes";
+ }
+ }
+ }
+}
+
+/*
+ * Add or remove a Tcl proc trace. If specified, the hook arg
+ * overrides anything already specified for the function.
+ */
+private void
+tracefn(string fn, string what, string op, string hook)
+{
+ string attrs{string} = L_fnsDeclared{fn};
+ struct {
+ string op;
+ string cmd;
+ } trace, traces[];
+
+ // A leading ! allows lib L funcs to be traced.
+ if (what[0] == '!') {
+ undef(what[0]);
+ } else if (attrs{"file"} == "libl.tcl") {
+ return;
+ }
+ if (attrs{"ishook"}) goto remove;
+ switch (what) {
+ case "add":
+ // Do nothing if there's already a Tcl trace
+ if (Trace_infoExec(fn) =~ /{${op}/) { // yes, {$op
+ return;
+ }
+ if (hook) {
+ L_fnsDeclared{fn}{"fnhook"} = hook;
+ } else unless (attrs{"fnhook"}) {
+ L_fnsDeclared{fn}{"fnhook"} = "L_def_fn_hook";
+ }
+ if (L_fnsDeclared{fn}{"fnhook"} == "def") {
+ L_fnsDeclared{fn}{"fnhook"} = "L_def_fn_hook";
+ }
+ switch (op) {
+ case "enter":
+ Trace_addExec(fn, "enter", &L_fn_pre_hook);
+ break;
+ case "leave":
+ Trace_addExec(fn, "leave", &L_fn_post_hook);
+ break;
+ }
+ undef(L_fnsDeclared{fn}{"fntrace_${op}"});
+ break;
+ case "remove":
+remove:
+ traces = Trace_infoExec(fn);
+ foreach (trace in traces) {
+ if (trace.op == op) Trace_removeExec(fn, op, trace.cmd);
+ }
+ L_fnsDeclared{fn}{"fntrace_${op}"} = "off";
+ break;
+ }
+}
+
+void
+L_fn_pre_hook(string av[], _argused string op)
+{
+ string s;
+ string attrs{string} = L_fnsDeclared{av[0]};
+
+ if (L_fn_tr_inhook || (attrs{"fntrace_enter"} == "off") ||
+ ((s=attrs{"trace_depth"}) &&
+ ((Info_level() - L_start_level) > (int)s))) {
+ return;
+ }
+
+ /* Use the unmangled func name. */
+ av[0] = attrs{"name"};
+
+ ++L_fn_tr_inhook;
+ if (::catch("${attrs{"fnhook"}} 1 $av 0", &s)) {
+ /*
+ * Dump the error to stderr because the return below doesn't
+ * propagate the errorinfo up out of this trace hook to the
+ * traced proc although the Tcl docs say it should.
+ */
+ puts(stderr, "trace hook error: ${s}");
+ --L_fn_tr_inhook;
+ eval("return -code error -errorinfo $s");
+ }
+ --L_fn_tr_inhook;
+}
+
+void
+L_fn_post_hook(string av[], _argused string code, _argused string result,
+ _argused string op)
+{
+ string s;
+ string attrs{string} = L_fnsDeclared{av[0]};
+
+ if (L_fn_tr_inhook || (attrs{"fntrace_leave"} == "off") ||
+ ((s=attrs{"trace_depth"}) &&
+ ((Info_level() - L_start_level) > (int)s))) {
+ return;
+ }
+
+ /* Use the unmangled func name. */
+ av[0] = attrs{"name"};
+
+ ++L_fn_tr_inhook;
+ if (::catch("${attrs{"fnhook"}} 0 $av $result", &s)) {
+ /*
+ * Dump the error to stderr because the return below doesn't
+ * propagate the errorinfo up out of this trace hook to the
+ * traced proc although the Tcl docs say it should.
+ */
+ puts(stderr, "trace hook error: ${s}");
+ --L_fn_tr_inhook;
+ eval("return -code error -errorinfo $s");
+ }
+ --L_fn_tr_inhook;
+}
+
+private string
+argStr(poly arg)
+{
+ return (defined(arg) ? "'${arg}'" : "<undef>");
+}
+
+void
+L_def_fn_hook(int pre, poly av[], poly ret)
+{
+ int i;
+ int ac = length(av);
+
+ fprintf(L_fn_f, "%d: %s %s%s", milli(),
+ pre?"enter":"exit", av[0], i>1?":":"");
+ for (i = 1; i < ac; ++i) {
+ fprintf(L_fn_f, " %s", argStr(av[i]));
+ }
+ unless (pre) fprintf(L_fn_f, " ret %s", argStr(ret));
+ fprintf(L_fn_f, "\n");
+}
+
+/*
+ * Some GUI helper functions
+ */
+
+int
+tk_loaded_()
+{
+ return (Info_exists("::tk_patchLevel"));
+}
+
+void
+tk_make_readonly_tag_()
+{
+ string script, event, events[];
+
+ events = bind("Text");
+ foreach (event in events) {
+ script = bind("Text", event);
+ if (script =~ /%W (insert|delete|edit)/) continue;
+ if (script =~ /text(paste|insert|transpose)/i) continue;
+ script =~ s/tk_textCut/tk_textCopy/g;
+ bind("ReadonlyText", event, script);
+ }
+}
+
+void
+tk_save_to_log_(widget t)
+{
+ FILE fp;
+ string file, data;
+
+ file = tk_getSaveFile(parent: Winfo_toplevel((string)t));
+ if (file == "") return;
+
+ data = trim(Text_get(t, 1.0, "end"));
+
+ fp = fopen(file, "w");
+ puts(fp, data);
+ fclose(fp);
+}
+
+/*
+ * This is top-level run-time initialization code that gets called
+ * before main().
+ */
+
+/*
+ * Exit on a broken stdout pipe, so that things like
+ * tclsh myscript.l | more
+ * exit silently when you type 'q'.
+ */
+fconfigure(stdout, epipe: "exit");
+
+/*
+ * This catches accesses to an formal reference parameter when undef is
+ * passed in instead of a variable reference. Throw a run-time error.
+ */
+void
+L_undef_ref_parm_accessed_(_argused string name1, _argused string name2,
+ string op)
+{
+ string msg;
+
+ switch (op) {
+ case "read": msg = "read"; break;
+ case "write": msg = "written"; break;
+ default: return; // should be impossible
+ }
+ eval("return -code error -level 2 {undefined reference parameter ${msg}}");
+}
+string L_undef_ref_parm_ = "L_undef_ref_parm_ object";
+Trace_addVariable("::L_undef_ref_parm_", {"read","write"},
+ &L_undef_ref_parm_accessed_);
+
+#lang tcl
+set ::L_libl_done 1
diff --git a/library/tcltest/tcltest.tcl b/library/tcltest/tcltest.tcl
index 29ef778..1c56757 100644
--- a/library/tcltest/tcltest.tcl
+++ b/library/tcltest/tcltest.tcl
@@ -661,7 +661,8 @@ namespace eval tcltest {
} AcceptPattern matchFiles
# By default, skip files that appear to be SCCS lock files.
- Option -notfile l.*.test {
+ # XXX - busted.
+ Option -notfile SCCS/l.*.test {
Skip all test files that match the glob pattern given.
} AcceptPattern skipFiles
@@ -888,8 +889,8 @@ proc tcltest::DebugPArray {level arrayvar} {
# defined in ::tcltest. NOTE: Ought to construct with [info args] and
# [info default], but can't be bothered now. If [parray] changes, then
# this will need changing too.
-auto_load ::parray
-proc tcltest::parray {a {pattern *}} [info body ::parray]
+#auto_load ::parray
+#proc tcltest::parray {a {pattern *}} [info body ::parray]
# tcltest::DebugDo --
#
@@ -2694,6 +2695,7 @@ proc tcltest::GetMatchingDirectories {rootdir} {
#
# Arguments:
# shell being tested
+# arguments to pass to shell
#
# Results:
# None.
@@ -2701,7 +2703,7 @@ proc tcltest::GetMatchingDirectories {rootdir} {
# Side effects:
# None.
-proc tcltest::runAllTests { {shell ""} } {
+proc tcltest::runAllTests { {shell ""} {shellArgs ""} } {
variable testSingleFile
variable numTestFiles
variable numTests
@@ -2754,6 +2756,7 @@ proc tcltest::runAllTests { {shell ""} } {
set timeCmd {clock format [clock seconds]}
puts [outputChannel] "Tests began at [eval $timeCmd]"
+ set exit_status 0
# Run each of the specified tests
foreach file [lsort [GetMatchingFiles]] {
@@ -2778,7 +2781,7 @@ proc tcltest::runAllTests { {shell ""} } {
}
lappend childargv $opt $value
}
- set cmd [linsert $childargv 0 | $shell $file]
+ set cmd [linsert $childargv 0 | $shell {*}$shellArgs $file]
if {[catch {
incr numTestFiles
set pipeFd [open $cmd "r"]
@@ -2796,6 +2799,7 @@ proc tcltest::runAllTests { {shell ""} } {
}
if {$Failed > 0} {
lappend failFiles $testFile
+ set exit_status 1
}
} elseif {[regexp [join {
{^Number of tests skipped }
@@ -2823,6 +2827,7 @@ proc tcltest::runAllTests { {shell ""} } {
puts [outputChannel] "\nTests ended at [eval $timeCmd]"
cleanupTests 1
if {[info exists testFileFailures]} {
+ set exit_status 1
puts [outputChannel] "\nTest files exiting with errors: \n"
foreach file $testFileFailures {
puts [outputChannel] " [file tail $file]\n"
@@ -2842,7 +2847,7 @@ proc tcltest::runAllTests { {shell ""} } {
puts [outputChannel] ""
puts [outputChannel] [string repeat ~ 44]
}
- return
+ return $exit_status
}
#####################################################################
diff --git a/library/tm.tcl b/library/tm.tcl
index 55efda6..d3dabf4 100644
--- a/library/tm.tcl
+++ b/library/tm.tcl
@@ -49,7 +49,7 @@ namespace eval ::tcl::tm {
# The regex pattern a file name has to match to make it a Tcl Module.
- set pkgpattern {^([_[:alpha:]][:_[:alnum:]]*)-([[:digit:]].*)[.]tm$}
+ set pkgpattern {^([_[:alpha:]][\:_[:alnum:]]*)-([[:digit:]].*)[.]tm$}
# Export the public API
diff --git a/license.terms b/license.terms
index d8049cd..0c99e7f 100644
--- a/license.terms
+++ b/license.terms
@@ -1,7 +1,7 @@
This software is copyrighted by the Regents of the University of
California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState
-Corporation and other parties. The following terms apply to all files
-associated with the software unless explicitly disclaimed in
+Corporation, BitMover Inc, and other parties. The following terms apply
+to all files associated with the software unless explicitly disclaimed in
individual files.
The authors hereby grant permission to use, copy, modify, distribute,
diff --git a/tests/all.tcl b/tests/all.tcl
index 0a6f57f..8c0425d 100644
--- a/tests/all.tcl
+++ b/tests/all.tcl
@@ -18,5 +18,9 @@ configure {*}$argv -testdir [file dir [info script]]
if {[singleProcess]} {
interp debug {} -frame 1
}
-runAllTests
+if {[info exists ::env(TCLTEST_SHELL_OPTIONS)]} {
+ exit [runAllTests [interpreter] $::env(TCLTEST_SHELL_OPTIONS)]
+} else {
+ exit [runAllTests]
+}
proc exit args {}
diff --git a/tests/interp.test b/tests/interp.test
index 4bc9fe2..2588e8d 100644
--- a/tests/interp.test
+++ b/tests/interp.test
@@ -32,7 +32,7 @@ test interp-1.1 {options for interp command} -returnCodes error -body {
} -result {wrong # args: should be "interp cmd ?arg ...?"}
test interp-1.2 {options for interp command} -returnCodes error -body {
interp frobox
-} -result {bad option "frobox": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+} -result {bad option "frobox": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, regexp, slaves, share, target, or transfer}
test interp-1.3 {options for interp command} {
interp delete
} ""
@@ -50,13 +50,13 @@ test interp-1.6 {options for interp command} -returnCodes error -body {
} -result {wrong # args: should be "interp slaves ?path?"}
test interp-1.7 {options for interp command} -returnCodes error -body {
interp hello
-} -result {bad option "hello": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+} -result {bad option "hello": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, regexp, slaves, share, target, or transfer}
test interp-1.8 {options for interp command} -returnCodes error -body {
interp -froboz
-} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, regexp, slaves, share, target, or transfer}
test interp-1.9 {options for interp command} -returnCodes error -body {
interp -froboz -safe
-} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, slaves, share, target, or transfer}
+} -result {bad option "-froboz": must be alias, aliases, bgerror, cancel, create, debug, delete, eval, exists, expose, hide, hidden, issafe, invokehidden, limit, marktrusted, recursionlimit, regexp, slaves, share, target, or transfer}
test interp-1.10 {options for interp command} -returnCodes error -body {
interp target
} -result {wrong # args: should be "interp target path alias"}
@@ -3576,6 +3576,31 @@ test interp-36.7 {SlaveBgerror sets error handler of slave [1999035]} -setup {
unset -nocomplain result
interp delete slave
} -result foo
+test interp-37.1 {interp regexp} {
+ list [catch {interp regexp} msg] $msg
+} {1 {wrong # args: should be "interp regexp path ?type?"}}
+test interp-37.2 {interp regexp} {
+ list [catch {interp regexp {} invalid} msg] $msg
+} {1 {bad type "invalid": must be classic or pcre}}
+test interp-37.3 {interp regexp} {
+ list [catch {interp regexp {} classic bogus} msg] $msg
+} {1 {wrong # args: should be "interp regexp path ?type?"}}
+test interp-37.4 {interp regexp} -setup {
+ unset -nocomplain ::env(TCL_REGEXP_PCRE)
+ interp create slave
+} -body {
+ slave eval {interp regexp {}}
+} -cleanup {
+ interp delete slave
+} -result {classic}
+test interp-37.5 {interp regexp} -setup {
+ unset -nocomplain ::env(TCL_REGEXP_PCRE)
+ interp create slave
+} -body {
+ slave eval {interp regexp {} pcre}
+} -cleanup {
+ interp delete slave
+} -result {pcre}
test interp-37.1 {safe interps and min() and max(): Bug 2895741} -setup {
catch {interp delete a}
diff --git a/tests/l-core.test b/tests/l-core.test
new file mode 100644
index 0000000..4e6aae4
--- /dev/null
+++ b/tests/l-core.test
@@ -0,0 +1,22690 @@
+# Test the L language.
+# Copyright (c) 2007-2009 BitMover, Inc.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+ testConstraint exec [llength [info commands exec]]
+}
+
+# Run these tests first, before setting the _L_TEST env variable.
+
+test err-1.1 {test that syntax err causes no code to be run} -body {
+catch {L { syntax error }} try {}
+L { puts("this should not be run"); }
+} -output {}
+
+test err-1.2 {test that compiler warning causes no code to be run} -body {
+catch {L { int err_not_used; }} try {}
+L { puts("this should not be run"); }
+} -output {}
+
+test err-1.3 {test that compiler error causes no code to be run} -body {
+catch {L { int err_illegal_type = "bad"; }} try {}
+L { puts("this should not be run"); }
+} -output {}
+
+test err-1.4 {test that compiler error causes no code to be run 2} -body {
+catch {L {
+typedef int err1_4;
+class err1_4; // caught in parser; calls L_err() instead of L_errf()
+}} try {}
+L { puts("this should not be run"); }
+} -output {}
+
+# This causes L to keep running L code even after a compile error.
+set ::env(_L_TEST) 1
+
+test no-eq-ops-1 {test that old eq ops are now errors} -body {
+#lang L --line=1
+"s" eq "s";
+"s" ne "s";
+"s" lt "s";
+"s" le "s";
+"s" gt "s";
+"s" ge "s";
+} -returnCodes error -match regexp -result {.*1: L Error: illegal comparison operator
+.*2: L Error: illegal comparison operator
+.*3: L Error: illegal comparison operator
+.*4: L Error: illegal comparison operator
+.*5: L Error: illegal comparison operator
+.*6: L Error: illegal comparison operator
+}
+
+# This tells L to run in a backwards compatibility mode for
+# the old eq/ne/le/lt/ge/gt string-comparison operators.
+set ::env(_L_ALLOW_EQ_OPS) 1
+
+test lfile-1.0 {Test autowrapping of empty .l file} -setup {
+ set fname [makeFile {} lfile-1.0.l]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fname
+} -cleanup {
+ removeFile lfile-1.0.l
+} -result {}
+
+test lfile-1.1 {Test autowrapping of .l works} -setup {
+ set fname [makeFile {
+ void main() {
+ printf("hi mom\n");
+ }
+ } lfile-1.1.l]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fname
+} -cleanup {
+ removeFile lfile-1.1.l
+} -result {hi mom}
+
+test lfile-1.1 {Test #lang L wrapping with -L and --L cmd-line options} -setup {
+ set fname [makeFile {
+ void main() {
+ puts("this is L");
+ }
+ } lfile-1.1.n]
+} -constraints {
+ exec
+} -body {
+ set s1 [exec [interpreter] -L $fname]
+ set s2 [exec [interpreter] --L $fname]
+ puts $s1
+ puts $s2
+} -cleanup {
+ removeFile lfile-1.1.n
+} -output {this is L
+this is L
+}
+
+test lfile-1.3 {Test .l mapping via source command} -setup {
+ set fname [makeFile {printf("hello there");} lfile-1.3.l]
+} -body {
+ source $fname
+} -cleanup {
+ removeFile lfile-1.3.l
+} -output {hello there}
+
+test lfile-1.4 {Test that in a Tcl script L does not call a Tcl main} -body {
+proc main {} { puts "bad 1" }
+} -output {}
+
+test lfile-1.5 {Test that L mains in multiple interps get invoked} -body {
+#lang L --line=1
+void lfile_1_5()
+{
+ // Touch files instead of puts'ing since the slave interps seem
+ // to not get tcltest's puts so -output{} doesn't match it.
+
+ string cmd1 = <<'END'
+slave1 eval {#lang L
+void main() { fclose(fopen("interp1", "w")); }}
+END
+ string cmd2 = <<'END'
+slave2 eval {#lang L
+void main() { fclose(fopen("interp2", "w")); }}
+END
+ eval("interp create slave1");
+ eval("interp create slave2");
+ eval(cmd1);
+ eval(cmd2);
+ unless (exists("interp1")) puts("bad 1");
+ unless (exists("interp2")) puts("bad 2");
+}
+lfile_1_5();
+} -cleanup {
+ removeFile "interp1"
+ removeFile "interp2"
+} -output {}
+
+test lfile-1.6 {Test a Tcl file sourced from an L file} -setup {
+ set fname [makeFile {puts "in Tcl"} lfile-1.6.tcl]
+} -body {
+#lang L --line=1
+source("lfile-1.6.tcl");
+void lfile_1_6()
+{
+ puts("in L");
+}
+lfile_1_6();
+} -cleanup {
+ removeFile lfile-1.6.tcl
+} -output {in Tcl
+in L
+}
+
+test lhtml-1 {test lhtml in a .lhtml file} -setup {
+ set fname [makeFile {<?puts(nonewline: "line=${__LINE__} file=${__FILE__}");?>
+line2
+<?
+int lhtml1 = 4;
+?>
+line4
+<?unless (__LINE__ == 7) puts ("bad __LINE__=${__LINE__}");
+while (lhtml1--) puts(nonewline: "[${lhtml1}]");
+unless (__LINE__ == 9) puts ("bad __LINE__=${__LINE__}");
+?>
+this with <?= "an L string" ?> inline
+<?=__LINE__?>
+} lhtml-1.lhtml]
+} -body {
+#lang L
+void lhtml_1()
+{
+ int ret;
+ string got;
+ string tclsh = interpreter();
+ string want = <<'END'
+line=1 file=lhtml-1.lhtml
+line2
+
+line4
+[3][2][1][0]
+this with an L string inline
+12
+END
+ ret = system({tclsh, "lhtml-1.lhtml"}, undef, &got, undef);
+ unless (ret == 0) puts("bad 1");
+ unless (got == want) puts("bad 2 '${got}'");
+}
+lhtml_1();
+} -output {}
+
+test lhtml-2 {test #lang Lhtml} -body {
+#lang Lhtml --line=1
+line <?=__LINE__?> of Lhtml
+#lang tcl
+puts "tcl code"
+#lang Lhtml
+more Lhtml
+<?puts(nonewline: 1+2+3);?>
+} -output {line 1 of Lhtml
+tcl code
+more Lhtml
+6
+}
+
+test lhtml-3 {test errors in Lhtml document} -setup {
+ set fname [makeFile {<?puts(1+"bad1");?>
+<?puts(1+"bad2");
+puts(1+"bad3");
+?>
+line5
+<?
+puts(1+"bad4");
+?>
+} lhtml-3.lhtml]
+} -body {
+#lang L
+void lhtml_3()
+{
+ int ret;
+ string err, out;
+ string tclsh = interpreter();
+ string want = <<'END'
+lhtml-3.lhtml:1: L Error: expected type int or float but got string in arithmetic operator
+lhtml-3.lhtml:2: L Error: expected type int or float but got string in arithmetic operator
+lhtml-3.lhtml:3: L Error: expected type int or float but got string in arithmetic operator
+lhtml-3.lhtml:7: L Error: expected type int or float but got string in arithmetic operator
+END
+ ret = system({tclsh, "lhtml-3.lhtml"}, undef, &out, &err);
+ if (ret == 0) puts("bad 1");
+ unless (err =~ /${want}/) puts("bad 2 '${err}'");
+}
+lhtml_3();
+} -output {}
+
+test lhtml-4 {test lhtml document parsing} -body {
+# This test is from Oscar. Check that the Lhtml delims in the
+# embedded code are not mistaken for the real delims.
+#lang Lhtml
+<html>
+<head>
+<title>The TITLE</title>
+</head>
+<body>
+<h1>Header: <? printf("%s <? foo ?>", 2 + 2); ?></h1>
+</body>
+</html>
+} -output {<html>
+<head>
+<title>The TITLE</title>
+</head>
+<body>
+<h1>Header: 4 <? foo ?></h1>
+</body>
+</html>
+}
+
+test lhtml-5 {test lhtml with L loops} -body {
+#lang Lhtml
+<html>
+<tr>
+<? int lhtml5; ?>
+<? for (lhtml5 = 0; lhtml5 < 3; ++lhtml5) { ?>
+ <td><? puts(nonewline: lhtml5); ?></td>
+<? } ?>
+</tr>
+</html>
+} -output {<html>
+<tr>
+
+
+ <td>0</td>
+
+ <td>1</td>
+
+ <td>2</td>
+
+</tr>
+</html>
+}
+
+test lhtml-6 {test premature EOF in lhtml document} -body {
+#lang Lhtml --line=1
+<? // no ending delim
+} -returnCodes error -match regexp -result {.*2: L Error: premature EOF
+}
+
+test parse-1.0 {Test parsing an empty L script} -body {
+#lang L --line=1
+}
+
+test parse-1.1 {Test parsing an L script that is just white space} -body {
+#lang L --line=1
+
+
+
+}
+
+test opts-1 {test command options 1} -body {
+#lang L -nowarn
+void opts_1()
+{
+ int not_used; // not used warning should be suppressed
+ printf("good");
+}
+opts_1();
+} -output {good}
+
+test opts-2 {test command options 2} -body {
+#lang L --nowarn
+void opts_2()
+{
+ int not_used; // not used warning should be suppressed
+ printf("good");
+}
+opts_2();
+} -output {good}
+
+test opts-2.1 {test command options 3} -body {
+#lang L
+#pragma nowarn
+void opts_2_1()
+{
+ int not_used; // not used warning should be suppressed
+ printf("good");
+}
+opts_2_1();
+} -output {good}
+
+test opts-4 {test command options 4} -body {
+#lang L -poly
+void opts_4()
+{
+ string s = "3";
+ printf("%d", s+1); // would be an err w/o the -poly
+}
+opts_4();
+} -output {4}
+
+test opts-5 {test command options 5} -body {
+#lang L --poly
+void opts_5()
+{
+ string s = "3";
+ printf("%d", s+1); // would be an err w/o the --poly
+}
+opts_5();
+} -output {4}
+
+test opts-6.1.2 {test -norun command option} -body {
+#lang L -norun
+void opts_6_1_2()
+{
+ /* -norun means compile but do not run */
+ puts("should not see this");
+}
+opts_6_1_2();
+} -output {}
+
+test opts-6.1.3 {test --norun command option} -body {
+#lang L --norun
+void opts_6_1_3()
+{
+ /* --norun means compile but do not run */
+ puts("should not see this");
+}
+opts_6_1_3();
+} -output {}
+
+test opts-6.2 {test that --norun option compiles} -body {
+#lang L --norun
+void opts_6_2()
+{
+ string s = "This is
+ an error";
+}
+opts_6_2();
+} -returnCodes error -match regexp -result {.*missing string terminator.*}
+
+test opts-6.3 {test bad command option} -body {
+#lang L -bad
+void opts_6_3() {}
+} -returnCodes error -result {L Error: illegal option '-bad'
+}
+
+test opts-7 {test -nowarn command-line option} -setup {
+ set file [makeFile {
+ private void f() {
+ int not_used;
+ puts("good");
+ }
+ f();
+ } opts7.l .]
+} -constraints {
+ exec
+} -body {
+ # The script created above should not compile and run unless
+ # the command-line options are handled correctly.
+ set s1 [exec [interpreter] -nowarn $file]
+ set s2 [exec [interpreter] --nowarn $file]
+ puts $s1
+ puts $s2
+} -cleanup {
+ removeFile $file
+} -output "good\ngood\n"
+
+test opts-7.1 {test -norun command-line option} -setup {
+ set file [makeFile {
+ puts("should not get run");
+ } opts7.1.l .]
+} -constraints {
+ exec
+} -body {
+ # The script created above should be compiled but not run
+ # if the command-line options are handled correctly.
+ set s1 [exec [interpreter] -norun $file]
+ set s2 [exec [interpreter] --norun $file]
+ puts $s1
+ puts $s2
+} -cleanup {
+ removeFile $file
+} -output "\n\n"
+
+test opts-8 {test -poly command-line option} -setup {
+ set file [makeFile {
+ private void f() {
+ string s = "3";
+ printf("%d\n", s+1);
+ }
+ f();
+ } opts8.l .]
+} -constraints {
+ exec
+} -body {
+ # The script created above should not compile and run unless
+ # the command-line options are handled correctly.
+ set s1 [exec [interpreter] -poly $file]
+ set s2 [exec [interpreter] --poly $file]
+ puts $s1
+ puts $s2
+} -cleanup {
+ removeFile $file
+} -output "4\n4\n"
+
+test opts-9 {test multiple command-line options} -setup {
+ set file [makeFile {
+ private void f() {
+ int not_used;
+ string s = "3";
+ printf("%d\n", s+1);
+ }
+ f();
+ } opts9.l .]
+} -constraints {
+ exec
+} -body {
+ # The script created above should not compile and run unless
+ # the command-line options are handled correctly.
+ set s1 [exec [interpreter] -poly -nowarn $file]
+ set s2 [exec [interpreter] --poly --nowarn $file]
+ puts $s1
+ puts $s2
+} -cleanup {
+ removeFile $file
+} -output "4\n4\n"
+
+test opts-10 {test multiple command-line options with app args} -setup {
+ set file [makeFile {
+ void main(int ac, string av[]) {
+ int i;
+ string s;
+ for (i = 1; i < ac; ++i) s .= av[i];
+ puts(s);
+ }
+ } opts10.l .]
+} -constraints {
+ exec
+} -body {
+ # Check the application arguments are correctly passed to the L
+ # main() even in the presence of tclsh command-line args.
+ set s1 [exec [interpreter] $file]
+ set s2 [exec [interpreter] $file arg1]
+ set s3 [exec [interpreter] $file arg1 arg2]
+ set s4 [exec [interpreter] -nowarn $file]
+ set s5 [exec [interpreter] -nowarn $file arg1]
+ set s6 [exec [interpreter] -nowarn $file arg1 arg2]
+ set s7 [exec [interpreter] -nowarn -poly $file]
+ set s8 [exec [interpreter] -nowarn -poly $file arg1]
+ set s9 [exec [interpreter] -nowarn -poly $file arg1 arg2]
+ puts $s1
+ puts $s2
+ puts $s3
+ puts $s4
+ puts $s5
+ puts $s6
+ puts $s7
+ puts $s8
+ puts $s9
+} -cleanup {
+ removeFile $file
+} -output "\narg1\narg1arg2\n\narg1\narg1arg2\n\narg1\narg1arg2\n"
+
+test opts-11 {test bad command-line option} -setup {
+ set file [makeFile {
+ void main() {}
+ } opts11.l . ]
+} -body {
+#lang L --line=1
+void opts_11()
+{
+ int ret;
+ string err, out[];
+ string tclsh = eval("interpreter");
+
+ ret = system({tclsh, "--bad", "opts11.l"}, undef, &out, &err);
+ unless (ret == 1) puts("bad 1");
+ unless (err =~ /L Error: illegal option '--bad'/) puts("bad 2 ${err}");
+}
+opts_11();
+} -output {}
+
+test parse-1.2 {Test parsing an empty L file} -setup {
+ set fName [makeFile {} LFileTest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile LFileTest
+} -result {}
+
+test parse-1.3 {Test parsing an L file that just has whitespace} -setup {
+ set fName [makeFile {
+
+
+
+ } LFileTest]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fName
+} -cleanup {
+ removeFile LFileTest
+} -result {}
+
+test parse-1.4 {parse an L function named by a pattern} -body {
+#lang L --line=1
+poly Parse14Pattern_*(int a, ...rest)
+{
+ puts("${$1}${a}${rest}");
+}
+#lang tcl
+} -result {}
+
+test parse-1.5 {test handling of illegal character} -body {
+#lang L --line=1
+@
+} -returnCodes error -match glob -result {*1: L Error: illegal character
+@
+^
+}
+
+test parse-1.5.1 {test handling of illegal character in string interpolation} -body {
+#lang L --line=1
+"${3@}";
+} -returnCodes error -match glob -result {*1: L Error: illegal character
+"$\{3@
+ ^
+}
+# " sync up the quotes for emacs
+
+test parse-1.6 {test syntax error message 1} -body {
+#lang L --line=1
+void parse_1_6()
+{
+// Test that the err msg indenting is correct.
+// No tab.
+for()
+}
+} -returnCodes error -match glob -result {*5: L Error: syntax error, unexpected )
+for()
+ ^
+}
+
+test parse-1.7 {test syntax error message 2} -body {
+#lang L --line=1
+void parse_1_7()
+{
+ // Test that the err msg indenting is correct.
+ // 1 tab.
+ for()
+}
+} -returnCodes error -match glob -result {*5: L Error: syntax error, unexpected )
+ for()
+ ^
+}
+
+test parse-1.8 {test syntax error message 3} -body {
+#lang L --line=1
+void parse_1_8()
+{
+ // Test that the err msg indenting is correct.
+ // 1 tab and spaces.
+ for()
+}
+} -returnCodes error -match glob -result {*5: L Error: syntax error, unexpected )
+ for()
+ ^
+}
+
+test parse-1.9 {test syntax error message 4} -body {
+#lang L --line=1
+void parse_1_9()
+{
+ // Test that the err msg indenting is correct.
+ // 2 tabs.
+ for()
+}
+} -returnCodes error -match glob -result {*5: L Error: syntax error, unexpected )
+ for()
+ ^
+}
+
+test parse-1.10 {test syntax error message 5} -body {
+#lang L --line=1
+void parse_1_10()
+{
+ // Test that the err msg indenting is correct.
+ // 2 tabs with spaces in between.
+ for()
+}
+} -returnCodes error -match glob -result {*5: L Error: syntax error, unexpected )
+ for()
+ ^
+}
+
+test parse-1.11 {test syntax error message for error on line 1} -body {
+#lang L --line=1
+void parse_1_11() { for() } // syntax error on line 1
+} -returnCodes error -match glob -result {*1: L Error: syntax error, unexpected )
+void parse_1_11() \{ for()
+ ^
+}
+
+test scan-1.1 {test detection of run-away string 1} -body {
+#lang L --line=1
+void scan_1_1()
+{
+ string s = "This is bad
+ and should be an error";
+ puts(s);
+}
+} -returnCodes {error} -match regexp -result {.*missing string terminator \"\n}
+
+test scan-1.2 {test detection of run-away string 2} -body {
+#lang L --line=1
+void scan_1_2()
+{
+ string s = "This is bad
+}
+#"
+} -returnCodes {error} -match regexp -result {.*missing string terminator \"\n}
+
+test scan-1.3 {test detection of run-away string 3} -body {
+#lang L --line=1
+void scan_1_3()
+{
+ string s = 'This is bad
+ and should be an error';
+ puts(s);
+}
+} -returnCodes {error} -match regexp -result {.*missing string terminator \'\n}
+
+test scan-1.4 {test detection of run-away string 4} -body {
+#lang L --line=1
+void scan_1_4()
+{
+ string s = 'This is bad
+}
+#'
+} -returnCodes {error} -match regexp -result {.*missing string terminator \'\n}
+
+test scan-1.4.2 {test detection of run-away string 5} -body {
+#lang L --line=1
+void scan_1_4_2()
+{
+ string s = `echo this is bad
+}
+} -returnCodes {error} -match regexp -result {.*missing string terminator `\n}
+
+test scan-1.4.3 {test detection of run-away string 5} -body {
+#lang L --line=1
+void scan_1_4_3()
+{
+ string s = `echo this is bad
+>foo`;
+}
+} -returnCodes {error} -match regexp -result {.*missing string terminator `\n}
+
+test scan-1.4.4 {test detection of run-away regexp 1} -body {
+#lang L --line=1
+void scan_1_4_4()
+{
+ string s = "x";
+
+ s =~ /xbad_no_terminator;
+}
+} -returnCodes {error} -match regexp -result {.*run-away regular expression\n}
+
+test scan-1.4.5 {test detection of run-away regexp 2} -body {
+#lang L --line=1
+void scan_1_4_5()
+{
+ string s = "x";
+
+ s =~ s/x/bad_no_terminator;
+}
+} -returnCodes {error} -match regexp -result {.*run-away regular expression\n}
+
+test scan-1.4.6 {test detection of run-away regexp 3} -body {
+#lang L --line=1
+void scan_1_4_6()
+{
+ string s = "x";
+
+ s =~ s/xbad_no_terminator/x;
+}
+} -returnCodes {error} -match regexp -result {.*run-away regular expression\n}
+
+test scan-1.5 {check escapes in single-quoted strings} -body {
+#lang L --line=1
+void scan_1_5()
+{
+ string s;
+
+ s = '\a\t\n\001';
+ unless (length(s) == 10) puts("bad 1.0");
+ unless ((s[0] eq "\\") && (s[1] eq "a")) puts("bad 1.1");
+ unless ((s[2] eq "\\") && (s[3] eq "t")) puts("bad 1.2");
+ unless ((s[4] eq "\\") && (s[5] eq "n")) puts("bad 1.3");
+ unless ((s[6] eq "\\") && (s[7] eq "0")) puts("bad 1.4");
+ unless ((s[8] eq "0") && (s[9] eq "1")) puts("bad 1.5");
+
+ s = '\\\'';
+ unless (length(s) == 2) puts("bad 2.0");
+ unless ((s[0] eq "\\") && (s[1] eq "'")) puts("bad 2.1");
+
+ /*
+ * The following test doesn't work unless run from the
+ * command line. Perhaps tcltest is munging the string. ?
+ s = 'line\
+break';
+ unless (s eq "line\nbreak") puts("bad 3.1");
+ */
+}
+scan_1_5();
+} -output {}
+
+test scan-1.6 {check escapes in double-quoted strings} -body {
+#lang L --line=1
+void scan_1_6()
+{
+ string s;
+
+ s = "\a\t\n\r\\\"";
+ unless (length(s) == 6) puts("bad 1.0");
+ unless ((s[0] eq "a") && (s[1] eq "\t")) puts("bad 1.1");
+ unless ((s[2] eq "\n") && (s[3] eq "\r")) puts("bad 1.2");
+ unless ((s[4] eq "\\") && (s[5] eq "\"")) puts("bad 1.3");
+
+ /*
+ * The following test doesn't work unless run from the
+ * command line. Perhaps tcltest is munging the string. ?
+ s = "line\
+break";
+ unless (s eq "line\nbreak") puts("bad 2.1");
+ */
+}
+scan_1_6();
+} -output {}
+
+test scan-1.7 {test here documents 1} -body {
+#lang L --line=1
+void scan_1_7()
+{
+ /* Vary the whitespace. */
+
+ string s1,s2,s3,s4,s5,s6,s7,s8,s10,s11;
+
+ s1 = <<'E'
+str1
+E
+ unless (s1 eq "str1\n") puts("bad 1");
+
+ s2 = <<'EN'
+str2
+EN
+ unless (s2 eq "str2\n") puts("bad 2");
+
+ s3 = <<'END'
+str3
+END
+ unless (s3 eq "str3\n") puts("bad 3");
+
+ s4 =<<'END'
+str4
+END
+ unless (s4 eq "str4\n") puts("bad 4");
+
+ s5 = <<'END'
+str5
+END
+ unless (s5 eq "str5\n") puts("bad 5");
+
+ s6 = <<'END'
+str6
+END
+ unless (s6 eq "str6\n") puts("bad 6");
+
+ s7 = <<'END'
+str7
+END
+ unless (s7 eq "str7\n") puts("bad 7");
+
+ s8 =
+<<'END'
+str8
+END
+ unless (s8 eq "str8\n") puts("bad 8");
+
+ /*
+ * These test the patterns in the scanner that check for a ;
+ * after the end delim. Note that there are spaces after
+ * some of the ; below.
+ */
+
+ s10 = <<'END'
+NOTEND;
+NOTEND ;
+NOTEND;
+NOTEND ;
+END
+ unless (s10 eq "NOTEND;\nNOTEND ;\nNOTEND; \nNOTEND ; \n") {
+ puts("bad 10");
+ }
+
+ s11 = <<END
+NOTEND;
+NOTEND ;
+NOTEND;
+NOTEND ;
+END
+ unless (s11 eq "NOTEND;\nNOTEND ;\nNOTEND; \nNOTEND ; \n") {
+ puts("bad 11");
+ }
+
+ /* Semicolons are allowed after the delim now. */
+
+ s11 = <<END
+NOTEND;
+END;
+ unless (s11 == "NOTEND;\n") puts("bad 12");
+
+ s11 = <<'END'
+NOTEND;
+END;
+ unless (s11 == "NOTEND;\n") puts("bad 13");
+
+ /*
+ * Test whitespace prefix.
+ */
+
+ s11 =
+ <<END
+ line1
+
+ line2
+ ENDNOT
+ END;
+ unless (s11 == "line1\n\nline2\nENDNOT\n") puts("bad 19.1");
+
+ s11 =
+ <<'END'
+ line1
+
+ line2
+ ENDNOT
+ END;
+ unless (s11 == "line1\n\nline2\nENDNOT\n") puts("bad 19.2");
+}
+scan_1_7();
+} -output {}
+
+test scan-1.8 {test here documents 2} -body {
+#lang L --line=1 -nowarn
+string ::scan_1_8a;
+void scan_1_8()
+{
+ string s;
+ string foo = "foo";
+
+ /* Check string interpolation. */
+
+ s = <<END
+interpolated string ${foo}
+END
+ unless (s eq "interpolated string foo\n") puts("bad 1");
+
+ s = <<'END'
+uninterpolated string ${foo}
+END
+ unless (s eq "uninterpolated string \${foo}\n") puts("bad 2");
+
+ /*
+ * The scanner handles an ID inside a here document
+ * differently than a non-ID, so try both.
+ */
+
+ s = <<END
+${foo}
+aword
+two words
+END
+ unless (s eq "foo\naword\ntwo words\n") puts("bad 3");
+
+ s = <<'END'
+${foo}
+aword
+two words
+END
+ unless (s eq "\${foo}\naword\ntwo words\n") puts("bad 4");
+
+ /*
+ * Ensure delimeter isn't found mistakenly. It isn't
+ * allowed to have leading or trailing whitespace or
+ * anything else.
+ */
+
+ s = <<END
+EN
+EN D
+END
+ ENDx
+ENDEND
+END
+ unless (s eq "EN\nEN D\nEND \n ENDx\nENDEND\n") puts("bad 5");
+
+ s = <<'END'
+EN
+EN D
+END
+ ENDx
+ENDEND
+END
+ unless (s eq "EN\nEN D\nEND \n ENDx\nENDEND\n") puts("bad 6");
+
+ /*
+ * Check escapes:
+ * non-interpolated here doc:
+ * no escapes
+ * interpolated here doc:
+ * \\ \$ \` get escaped
+ * \<newline> gets ignored
+ * \x for anything else, not escaped
+ *
+ * We can't test \<newline> by simply writing it here because the
+ * tcltest parsing messes with it.
+ */
+
+ s = <<END
+$\\\$\`\n\tx
+END
+ unless (s eq "$\\$`\\n\\tx\n") puts("bad 9.1");
+
+ s = <<'END'
+a\tb\nc\\d\x\\\'
+END
+ unless (s eq "a\\tb\\nc\\\\d\\x\\\\\\'\n") puts("bad 9.2");
+
+ /*
+ * Checking \<newline> is tough since tcltest's parsing of
+ * the test source won't let \<newline> through. So create
+ * strings of L code and eval those.
+ *
+ * Note: The :: in front of the global scan_1_8a works around
+ * an L bug with global upvar shadows which will be fixed
+ * soon in a different cset.
+ */
+ // x\<newline>
+ // y
+ L("::scan_1_8a = <<END\nx\\\ny\nEND\n");
+ unless (::scan_1_8a eq "xy\n") puts("bad 9.3 ${::scan_1_8a}");
+ L("::scan_1_8a = <<'END'\nx\\\ny\nEND\n");
+ unless (::scan_1_8a eq "x\\\ny\n") puts("bad 9.4");
+ // x\<newline>
+ // y\<newline>
+ L("::scan_1_8a = <<END\nx\\\ny\\\nEND\n");
+ unless (::scan_1_8a eq "xy") puts("bad 9.5");
+ L("::scan_1_8a = <<'END'\nx\\\ny\\\nEND\n");
+ unless (::scan_1_8a eq "x\\\ny\\\n") puts("bad 9.6");
+ // \<newline>
+ L("::scan_1_8a = <<END\n\\\nEND\n");
+ unless (::scan_1_8a eq "") puts("bad 9.7");
+ L("::scan_1_8a = <<'END'\n\\\nEND\n");
+ unless (::scan_1_8a eq "\\\n") puts("bad 9.8");
+
+ /* Check `cmd` inside interpolated here document. */
+ s = <<END
+abc
+`perl -e 'print "cmd"'`
+def
+END
+ unless (s eq "abc\ncmd\ndef\n") puts("bad 20.1");
+
+ /* Check multiple `cmd` in a here document. */
+
+ s = <<END
+abc
+`perl -e 'print "cmd1"'``perl -e 'print "cmd2"'`
+def
+END
+ unless (s eq "abc\ncmd1cmd2\ndef\n") puts("bad 21.1");
+
+ s = <<END
+abc
+`perl -e 'print "cmd1"'``perl -e 'print "cmd2"'``perl -e 'print "cmd3"'`
+def
+END
+ unless (s eq "abc\ncmd1cmd2cmd3\ndef\n") puts("bad 21.2");
+}
+scan_1_8();
+} -output {}
+
+test scan-1.9 {test here document error 1} -body {
+#lang L --line=1
+void
+scan_1_9()
+{
+ /*
+ * Error, since nothing is allowed after the END except
+ * a newline.
+ */
+ string s1 = <<'END'err
+END
+}
+scan_1_9();
+} -returnCodes {error} -match regexp -result {.*8: L Error: illegal characters after here-document delimeter
+}
+
+test scan-1.10 {test here document error 2} -body {
+#lang L --line=1
+void
+scan_1_10()
+{
+ /*
+ * Error, since nothing is allowed after the END except
+ * a newline.
+ */
+ string s1 = <<END err
+END
+}
+scan_1_10();
+} -returnCodes {error} -match regexp -result {.*8: L Error: illegal characters after here-document delimeter
+}
+
+test scan-1.11 {test nested here documents error} -body {
+#lang L --line=1
+void
+scan_1_11()
+{
+ string s1, s2 = <<END
+${s1=<<BAD
+should be error
+BAD
+}
+END
+}
+scan_1_11();
+} -returnCodes {error} -match regexp -result ".*nested here documents illegal.*"
+
+test scan-1.12 {test here document error 3} -body {
+#lang L --line=1
+void
+scan_1_12()
+{
+ /*
+ * White space before or after the delim is illegal.
+ */
+
+ string s = << END
+ END;
+}
+scan_1_12();
+} -returnCodes {error} -match regexp -result {.*8: L Error: illegal characters before here-document delimeter
+}
+
+test scan-1.13 {test here document error 4} -body {
+#lang L --line=1
+void
+scan_1_13()
+{
+ /*
+ * White space before or after the delim is illegal.
+ */
+
+ string s = <<END
+ END;
+}
+scan_1_13();
+} -returnCodes {error} -match regexp -result {.*8: L Error: illegal characters after here-document delimeter
+}
+
+test scan-1.14 {test here document error 5} -body {
+#lang L --line=1
+void
+scan_1_14()
+{
+ /*
+ * <<-END as the delim works in the Bourne shell but is
+ * an error in L.
+ */
+
+ string s = <<-END
+ END;
+}
+scan_1_14();
+} -returnCodes {error} -match regexp -result {.*9: L Error: <<- unsupported, use =\\n\\t<<END to strip one leading tab
+}
+
+test scan-1.15 {test here document error 6} -body {
+#lang L --line=1
+void
+scan_1_15()
+{
+ /*
+ * <<-'END' as the delim works in the Bourne shell but is
+ * an error in L.
+ */
+
+ string s = <<-'END'
+ END;
+}
+scan_1_15();
+} -returnCodes {error} -match regexp -result {.*9: L Error: <<- unsupported, use =\\n\\t<<END to strip one leading tab
+}
+
+test scan-1.16 {check auto string concatenation} -body {
+#lang L --line=1
+void scan_1_16()
+{
+ string s;
+
+ s = "a"
+"b"
+"c";
+ unless (s eq "abc") puts("bad 1");
+
+ s = "d"
+ "e"
+ "f";
+ unless (s eq "def") puts("bad 2");
+
+ s = 'a'
+'b'
+'c';
+ unless (s eq "abc") puts("bad 3");
+
+ s = 'd'
+ 'e'
+ 'f';
+ unless (s eq "def") puts("bad 4");
+}
+scan_1_16();
+} -output {}
+
+test scan-1.17 {check \u escapes in strings} -body {
+#lang L --line=1
+void scan_1_17()
+{
+ string s;
+
+ s = "\u3";
+ unless (ord(s) == 0x3) puts("bad 1.1");
+ s = "\u34";
+ unless (ord(s) == 0x34) puts("bad 1.2");
+ s = "\u345";
+ unless (ord(s) == 0x345) puts("bad 1.3");
+ s = "\u3456";
+ unless (ord(s) == 0x3456) puts("bad 1.4");
+
+ s = "xy\u3z";
+ unless (length(s) == 4) puts("bad 2.1");
+ unless ((ord(s[2]) == 0x3) && (s[3] eq "z")) puts("bad 2.2");
+ s = "xy\u34z";
+ unless (length(s) == 4) puts("bad 2.3");
+ unless ((ord(s[2]) == 0x34) && (s[3] eq "z")) puts("bad 2.4");
+ s = "xy\u345z";
+ unless (length(s) == 4) puts("bad 2.5");
+ unless ((ord(s[2]) == 0x345) && (s[3] eq "z")) puts("bad 2.6");
+ s = "xy\u3456z";
+ unless (length(s) == 4) puts("bad 2.7");
+ unless ((ord(s[2]) == 0x3456) && (s[3] eq "z")) puts("bad 2.8");
+ s = "xy\u34567";
+ unless (length(s) == 4) puts("bad 2.9");
+ unless ((ord(s[2]) == 0x3456) && (s[3] eq "7")) puts("bad 2.10");
+}
+scan_1_17();
+} -output {}
+
+test scan-2.1 {test #line directive} -body {
+#lang L --line=1
+#line 1 "scan2-1.l"
+void scan_2_a()
+{
+ bad1;
+}
+
+#line 2 "scan2-2.l"
+void scan_2_b()
+{
+ bad2;
+}
+
+
+
+
+
+
+#line 13 "scan2-3.l"
+void scan_2_c()
+{
+ bad3;
+}
+} -returnCodes {error} -match regexp -result {scan2-1.l:3: L Error: undeclared variable: bad1
+scan2-2.l:4: L Error: undeclared variable: bad2
+scan2-3.l:15: L Error: undeclared variable: bad3
+}
+
+# This is test include-1.0 with #line's thrown in.
+test scan-2.2 {test #line directive with include files} -setup {
+ set fname [makeFile {#line 1 "foo.l"
+ ++scan_2_2;
+ unless (basename(__FILE__) eq "foo.l") puts("bad 1");
+ unless (__LINE__ == 3) puts("bad 2");
+ } scan-2.2.l [file dirname [info script]]]
+} -body {
+#lang L --line=1
+unless (__LINE__ == 1) puts("bad 1.1");
+int scan_2_2 = 0;
+puts(scan_2_2);
+unless (__LINE__ == 4) puts("bad 1.2");
+#include "scan-2.2.l"
+unless (__LINE__ == 6) puts("bad 1.3");
+puts(scan_2_2);
+// Check variations in spacing and punctation.
+// The compiler should include scan-2.2.l only once.
+#include "scan-2.2.l"
+unless (__LINE__ == 11) puts("bad 1.4");
+#include "scan-2.2.l"
+unless (__LINE__ == 13) puts("bad 1.5");
+#include "scan-2.2.l"
+unless (__LINE__ == 15) puts("bad 1.6");
+#include"scan-2.2.l"
+unless (__LINE__ == 17) puts("bad 1.7");
+puts(scan_2_2);
+} -cleanup {
+ removeFile $fname
+} -output {0
+1
+1
+}
+
+# This is test include-1.1 with #line's thrown in.
+test scan-2.3 {test #line directive with nested include files} -setup {
+#
+# The code for these files isn't indented because L recognizes
+# include() only when it starts at the beginning of the line.
+#
+ set fname1 [makeFile {#line 1 "foo1.l"
+#include "scan-2.3-2.l"
+unless (basename(__FILE__) eq "foo1.l") puts("bad 1");
+unless (__LINE__ == 3) puts("bad 2 ${__LINE__}");
+} scan-2.3-1.l [file dirname [info script]]]
+ set fname2 [makeFile {#line 1 "foo2.l"
+int scan_2_3a = 3;
+unless (basename(__FILE__) eq "foo2.l") puts("bad 3");
+unless (__LINE__ == 3) puts("bad 4");
+#include "scan-2.3-3.l"
+unless (basename(__FILE__) eq "foo2.l") puts("bad 5");
+unless (__LINE__ == 6) puts("bad 6 ${__LINE__}");
+} scan-2.3-2.l .]
+ set fname3 [makeFile {#line 1 "foo3.l"
+int scan_2_3b = 4;
+unless (basename(__FILE__) eq "foo3.l") puts("bad 7");
+unless (__LINE__ == 3) puts("bad 8");
+} scan-2.3-3.l .]
+} -body {
+#lang L
+#line 1 "foo4.l"
+unless (__LINE__ == 1) puts("bad 10.0");
+unless (__FILE__ eq "foo4.l") puts("bad 10.1");
+#include "scan-2.3-1.l"
+unless (__LINE__ == 4) puts("bad 10.1.2");
+unless (__FILE__ eq "foo4.l") puts("bad 10.2");
+unless (scan_2_3a == 3) puts("bad 10.3");
+unless (scan_2_3b == 4) puts("bad 10.4");
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+} -output {}
+
+test scan-2.4 {test malformed #line directives} -body {
+#lang L --line=1
+#line 0
+#line
+#line xyx
+} -returnCodes error -match regexp -result {.*1: L Error: malformed #line
+.*2: L Error: malformed #line
+.*3: L Error: malformed #line
+}
+
+test scan-3.1 {test line numbers in compile- and run-time messages, .l file} -setup {
+
+# This test creates three .l files. One is given to L, and the other two are
+# brought in via #include or source(). Several things are tested with the same
+# code. First, line #s in type errors which the compiler will complain about
+# unless compiling with --poly. Second, line #s in run-time errors which
+# selectively can be hit by setting the SCAN31 environment variable.
+# Third, __LINE__.
+
+#####################################################
+# scan-3.1-1.l
+ set fname1 [makeFile {
+string g = getenv("SCAN31");
+unless (__LINE__ == 3) puts("bad 1.1");
+if ("${basename(__FILE__)}:${__LINE__}" == g) g + 1; // line 4
+#include "scan-3.1-2.l"
+source("scan-3.1-3.l");
+unless (__LINE__ == 7) puts("bad 1.2");
+void main()
+{
+ f1();
+ f2();
+
+ if ("${basename(__FILE__)}:${__LINE__}" == g) g + 1; // line 13
+}
+puts("test ran");
+} scan-3.1-1.l .]
+
+#####################################################
+# scan-3.1-2.l
+ set fname2 [makeFile {
+/*
+ * This code conditionally causes a run-time error.
+ */
+unless (__LINE__ == 5) puts("bad 2.1");
+void f1() {
+ if ("${basename(__FILE__)}:${__LINE__}" == g) g + 1; // line 7
+}
+unless (__LINE__ == 9) puts("bad 2.2");
+} scan-3.1-2.l .]
+
+#####################################################
+# scan-3.1-3.l
+ set fname3 [makeFile {
+/*
+ * This code conditionally causes a run-time error.
+ */
+extern string ::g;
+unless (__LINE__ == 6) puts("bad 3.1");
+void f2() {
+ if ("${basename(__FILE__)}:${__LINE__}" == ::g) ::g + 1; // line 8
+}
+unless (__LINE__ == 10) puts("bad 3.2");
+} scan-3.1-3.l .]
+
+} -body {
+#lang L
+void scan31_chk(string cmd[], string expected{string}[])
+{
+ int bad, ret;
+ string err, exs[], k, out, s;
+
+ foreach (k=>exs in expected) {
+ putenv("SCAN31=%s", k);
+ ret = system(cmd, undef, &out, &err);
+ unless (ret == 1) puts("bad 2.1");
+ bad = 0;
+ foreach (s in exs) {
+ unless (err =~ /${s}/) {
+ puts("bad 2.2: expected '${s}'");
+ ++bad;
+ }
+ }
+ if (bad) {
+ puts("Got:");
+ puts("-----------------------------------------------");
+ puts(err);
+ puts("-----------------------------------------------");
+ }
+ }
+}
+void scan_3_1()
+{
+ int ret;
+ string err, out;
+ string expected{string}[];
+ string tclsh = interpreter();
+
+ /*
+ * The first run gets the compiler error messages.
+ */
+ expected = {
+ "0" => {
+ 'scan-3.1-1.l:4: L Error: expected type int',
+ 'scan-3.1-2.l:7: L Error: expected type int',
+ 'scan-3.1-1.l:13: L Error: expected type int',
+ },
+ };
+ scan31_chk({tclsh, "scan-3.1-1.l"}, expected);
+
+ /*
+ * The next run gets the run-time error messages.
+ * Use --poly so the type errors in the test code do not
+ * prevent compilation. Run several times and pass in the
+ * necessary cmd-line options so the code hits each of its
+ * various possible run-time errors.
+ */
+ expected = {
+ "scan-3.1-1.l:4" => {
+ 'use non-numeric string as operand of "\+"',
+ 'procedure "\d+%l_toplevel" line 4',
+ },
+ "scan-3.1-1.l:13" => {
+ 'use non-numeric string as operand of "\+"',
+ 'procedure "main" line 13',
+ },
+ "scan-3.1-2.l:7" => {
+ 'use non-numeric string as operand of "\+"',
+ 'procedure "f1" line 7',
+ 'procedure "main" line 10',
+ },
+ "scan-3.1-3.l:8" => {
+ 'use non-numeric string as operand of "\+"',
+ 'procedure "f2" line 8',
+ 'procedure "main" line 11',
+ },
+ };
+ scan31_chk({tclsh, "--poly", "scan-3.1-1.l"}, expected);
+
+ /*
+ * Finally, let the code run without any errors so that the
+ * checks of __LINE__ in it are run.
+ */
+ putenv("SCAN31=0");
+ ret = system({tclsh, "--poly", "scan-3.1-1.l"}, undef, &out, &err);
+ if (ret) puts("bad 3.1");
+ unless (out == "test ran\n") puts("bad 3.2");
+}
+scan_3_1();
+} -output {}
+
+test scan-3.2 {test line numbers in compile- and run-time messages, .tcl file} -setup {
+
+# This test is like scan-3.1 but with .tcl files instead of .l files.
+
+#####################################################
+# scan-3.2-1.tcl
+ set fname1 [makeFile {
+#lang L
+string g = getenv("SCAN31");
+unless (__LINE__ == 4) puts("bad 1.1");
+if ("${basename(__FILE__)}:${__LINE__}" == g) g + 1; // line 5
+#lang tcl
+# more Tcl code
+source scan-3.2-2.tcl
+#lang L
+unless (__LINE__ == 10) puts("bad 1.2");
+if ("${basename(__FILE__)}:${__LINE__}" == g) g + 1; // line 11
+f1();
+puts("test ran");
+} scan-3.2-1.tcl .]
+
+#####################################################
+# scan-3.2-2.tcl
+ set fname2 [makeFile {
+#lang L
+unless (__LINE__ == 3) puts("bad 2.1");
+if ("${basename(__FILE__)}:${__LINE__}" == g) g + 1; // line 4
+void f1() {
+ if ("${basename(__FILE__)}:${__LINE__}" == g) g + 1; // line 6
+}
+unless (__LINE__ == 8) puts("bad 2.2");
+} scan-3.2-2.tcl .]
+
+} -body {
+#lang L --nowarn
+void scan_3_2()
+{
+ int ret;
+ string err, out;
+ string expected{string}[];
+ string tclsh = interpreter();
+
+ /*
+ * The first run gets the compiler error messages in the
+ * first block of L code.
+ */
+ expected = {
+ "0" => {
+ 'scan-3.2-1.tcl:5: L Error: expected type int',
+ },
+ };
+ scan31_chk({tclsh, "scan-3.2-1.tcl"}, expected);
+
+ /*
+ * The next run gets the run-time error messages.
+ * Use --poly so the type errors in the test code do not
+ * prevent compilation. Run several times and pass in the
+ * necessary cmd-line options so the code hits each of its
+ * various possible run-time errors.
+ */
+ expected = {
+ "scan-3.2-1.tcl:5" => {
+ 'use non-numeric string as operand of "\+"',
+ 'procedure "\d+%l_toplevel" line 5',
+ },
+ "scan-3.2-1.tcl:11" => {
+ 'use non-numeric string as operand of "\+"',
+ 'procedure "\d+%l_toplevel" line 11',
+ },
+ "scan-3.2-2.tcl:4" => {
+ 'use non-numeric string as operand of "\+"',
+ 'procedure "\d+%l_toplevel" line 4',
+ },
+ "scan-3.2-2.tcl:6" => {
+ 'use non-numeric string as operand of "\+"',
+ 'procedure "f1" line 6',
+ 'procedure "\d+%l_toplevel" line 12',
+ },
+ };
+ scan31_chk({tclsh, "--poly", "scan-3.2-1.tcl"}, expected);
+
+ /*
+ * Finally, let the code run without any errors so that the
+ * checks of __LINE__ in it are run.
+ */
+ putenv("SCAN31=0");
+ ret = system({tclsh, "--poly", "scan-3.2-1.tcl"}, undef, &out, &err);
+ if (ret) puts("bad 3.1");
+ unless (out == "test ran\n") puts("bad 3.2");
+}
+scan_3_2();
+} -output {}
+
+test scan-4 {check for regression if "L" passed as an arg} -body {
+#lang L
+string scan_4f(...args)
+{
+ return (join(" ", args));
+}
+void scan_4()
+{
+ unless (eval("scan_4f a b") == "a b") puts("bad 1");
+ unless (eval("scan_4f L") == "L") puts("bad 2");
+ unless (eval("scan_4f L L") == "L L") puts("bad 3");
+ unless (eval("scan_4f a L") == "a L") puts("bad 4");
+ unless (eval("scan_4f L b") == "L b") puts("bad 5");
+ unless (eval("scan_4f a L b") == "a L b") puts("bad 6");
+}
+scan_4();
+} -output {}
+
+test scan-5 {check that trailing newline is scanned} -body {
+#lang L
+// The L-compiler scanner requires comments to end in a newline.
+#lang tcl
+# But a past compiler bug would eat them, causing syntax errors.
+#lang L
+// This test checks that case.
+} -output {}
+
+test scan-6 {test 'and','or','xor','not' unimplemented reserved words} -body {
+#lang L --line=1
+void scan_6()
+{
+ if (1 and 2) {}
+ if (1 or 2) {}
+ if (1 or (2 and 3)) {}
+ if (not 1 xor 2) {}
+}
+} -returnCodes error -match regexp -result {.*3: L Error: 'and','or','xor','not' are unimplemented reserved words
+.*4: L Error: 'and','or','xor','not' are unimplemented reserved words
+.*5: L Error: 'and','or','xor','not' are unimplemented reserved words
+.*6: L Error: 'and','or','xor','not' are unimplemented reserved words
+}
+
+test unicode-1 {test unicode in string constants and here documents} -body {
+#lang L --line=1
+void unicode_1()
+{
+ string h, j, s;
+
+ // This has twelve Hebrew characters including two ASCII spaces
+ // in an interpolated string (double quotes).
+ h = "זו השפה שלנו";
+ unless (length(h) == 12) puts("bad 1.1");
+ unless (ord(h[0]) == 0x05d6) puts("bad 1.2"); // Zayen
+ unless (ord(h[1]) == 0x05d5) puts("bad 1.3"); // Vav
+ unless (ord(h[2]) == 0x0020) puts("bad 1.4"); // space
+ unless (ord(h[3]) == 0x05d4) puts("bad 1.5"); // He
+ unless (ord(h[4]) == 0x05e9) puts("bad 1.6"); // Shin
+ unless (ord(h[5]) == 0x05e4) puts("bad 1.7"); // Pe
+ unless (ord(h[6]) == 0x05d4) puts("bad 1.8"); // He
+ unless (ord(h[7]) == 0x0020) puts("bad 1.9"); // space
+ unless (ord(h[8]) == 0x05e9) puts("bad 1.10"); // Shin
+ unless (ord(h[9]) == 0x05dc) puts("bad 1.11"); // Lamed
+ unless (ord(h[10]) == 0x05e0) puts("bad 1.12"); // Hun
+ unless (ord(h[11]) == 0x05d5) puts("bad 1.13"); // Vav
+ if (defined(h[12])) puts("bad 1.14");
+
+ // Same string as above except in an interpolated here
+ // document (and therefore with a trailing ASCII newline.
+ h = <<END
+זו השפה שלנו
+END
+ unless (length(h) == 13) puts("bad 2.1");
+ unless (ord(h[0]) == 0x05d6) puts("bad 2.2"); // Zayen
+ unless (ord(h[1]) == 0x05d5) puts("bad 2.3"); // Vav
+ unless (ord(h[2]) == 0x0020) puts("bad 2.4"); // space
+ unless (ord(h[3]) == 0x05d4) puts("bad 2.5"); // He
+ unless (ord(h[4]) == 0x05e9) puts("bad 2.6"); // Shin
+ unless (ord(h[5]) == 0x05e4) puts("bad 2.7"); // Pe
+ unless (ord(h[6]) == 0x05d4) puts("bad 2.8"); // He
+ unless (ord(h[7]) == 0x0020) puts("bad 2.9"); // space
+ unless (ord(h[8]) == 0x05e9) puts("bad 2.10"); // Shin
+ unless (ord(h[9]) == 0x05dc) puts("bad 2.11"); // Lamed
+ unless (ord(h[10]) == 0x05e0) puts("bad 2.12"); // Hun
+ unless (ord(h[11]) == 0x05d5) puts("bad 2.13"); // Vav
+ unless (ord(h[12]) == 0x0a) puts("bad 2.14"); // newline
+ if (defined(h[13])) puts("bad 2.15");
+
+ // This has 14 Kanji characters including two Kanji (0x3000) spaces
+ // in an uninterpolated string (single quotes).
+ j = '私は 日本語が 分かります';
+ unless (length(j) == 13) puts("bad 3.1");
+ unless (ord(j[0]) == 0x79c1) puts("bad 3.2");
+ unless (ord(j[1]) == 0x306f) puts("bad 3.3");
+ unless (ord(j[2]) == 0x3000) puts("bad 3.4");
+ unless (ord(j[3]) == 0x65e5) puts("bad 3.5");
+ unless (ord(j[4]) == 0x672c) puts("bad 3.6");
+ unless (ord(j[5]) == 0x8a9e) puts("bad 3.7");
+ unless (ord(j[6]) == 0x304c) puts("bad 3.8");
+ unless (ord(j[7]) == 0x3000) puts("bad 3.9");
+ unless (ord(j[8]) == 0x5206) puts("bad 3.10");
+ unless (ord(j[9]) == 0x304b) puts("bad 3.11");
+ unless (ord(j[10]) == 0x308a) puts("bad 3.12");
+ unless (ord(j[11]) == 0x307e) puts("bad 3.13");
+ unless (ord(j[12]) == 0x3059) puts("bad 3.14");
+ if (defined(j[13])) puts("bad 3.15");
+
+ // Same as above, but an uninterpolated here document.
+ j = <<'END'
+私は 日本語が 分かります
+END
+ unless (length(j) == 14) puts("bad 4.1");
+ unless (ord(j[0]) == 0x79c1) puts("bad 4.2");
+ unless (ord(j[1]) == 0x306f) puts("bad 4.3");
+ unless (ord(j[2]) == 0x3000) puts("bad 4.4");
+ unless (ord(j[3]) == 0x65e5) puts("bad 4.5");
+ unless (ord(j[4]) == 0x672c) puts("bad 4.6");
+ unless (ord(j[5]) == 0x8a9e) puts("bad 4.7");
+ unless (ord(j[6]) == 0x304c) puts("bad 4.8");
+ unless (ord(j[7]) == 0x3000) puts("bad 4.9");
+ unless (ord(j[8]) == 0x5206) puts("bad 4.10");
+ unless (ord(j[9]) == 0x304b) puts("bad 4.11");
+ unless (ord(j[10]) == 0x308a) puts("bad 4.12");
+ unless (ord(j[11]) == 0x307e) puts("bad 4.13");
+ unless (ord(j[12]) == 0x3059) puts("bad 4.14");
+ unless (ord(j[13]) == 0x0a) puts("bad 4.15");
+ if (defined(j[14])) puts("bad 4.16");
+
+ // Some diacritics.
+ s = "Algunos signos diacríticos del español";
+ unless (length(s) == 38) puts("bad 5.1");
+ unless (ord(s[20]) == 0x00ed) puts("bad 5.2");
+ unless (ord(s[35]) == 0x00f1) puts("bad 5.3");
+}
+unicode_1();
+} -output {}
+
+test unicode-2 {test manipulation of unicode strings} -body {
+#lang L --line=1
+void unicode_2()
+{
+ string h = "זו השפה שלנו";
+ string j = '私は 日本語が 分かります';
+
+ h .= j;
+ unless (h eq "זו השפה שלנו私は 日本語が 分かります") puts("bad 1.0");
+ unless (length(h) == 25) puts("bad 1.1");
+ unless (ord(h[0]) == 0x05d6) puts("bad 1.2");
+ unless (ord(h[1]) == 0x05d5) puts("bad 1.3");
+ unless (ord(h[2]) == 0x0020) puts("bad 1.4");
+ unless (ord(h[3]) == 0x05d4) puts("bad 1.5");
+ unless (ord(h[4]) == 0x05e9) puts("bad 1.6");
+ unless (ord(h[5]) == 0x05e4) puts("bad 1.7");
+ unless (ord(h[6]) == 0x05d4) puts("bad 1.8");
+ unless (ord(h[7]) == 0x0020) puts("bad 1.9");
+ unless (ord(h[8]) == 0x05e9) puts("bad 1.10");
+ unless (ord(h[9]) == 0x05dc) puts("bad 1.11");
+ unless (ord(h[10]) == 0x05e0) puts("bad 1.12");
+ unless (ord(h[11]) == 0x05d5) puts("bad 1.13");
+ unless (ord(h[12]) == 0x79c1) puts("bad 1.14");
+ unless (ord(h[13]) == 0x306f) puts("bad 1.15");
+ unless (ord(h[14]) == 0x3000) puts("bad 1.16");
+ unless (ord(h[15]) == 0x65e5) puts("bad 1.17");
+ unless (ord(h[16]) == 0x672c) puts("bad 1.18");
+ unless (ord(h[17]) == 0x8a9e) puts("bad 1.19");
+ unless (ord(h[18]) == 0x304c) puts("bad 1.20");
+ unless (ord(h[19]) == 0x3000) puts("bad 1.21");
+ unless (ord(h[20]) == 0x5206) puts("bad 1.22");
+ unless (ord(h[21]) == 0x304b) puts("bad 1.23");
+ unless (ord(h[22]) == 0x308a) puts("bad 1.24");
+ unless (ord(h[23]) == 0x307e) puts("bad 1.25");
+ unless (ord(h[24]) == 0x3059) puts("bad 1.26");
+ if (defined(h[25])) puts("bad 1.27");
+
+ // Delete one of the Kanji characters.
+ undef(h[12]);
+ unless (h eq "זו השפה שלנוは 日本語が 分かります") puts("bad 2.0");
+ unless (length(h) == 24) puts("bad 2.1");
+ unless (ord(h[0]) == 0x05d6) puts("bad 2.2");
+ unless (ord(h[11]) == 0x05d5) puts("bad 2.3");
+ unless (ord(h[12]) == 0x306f) puts("bad 2.4");
+ unless (ord(h[23]) == 0x3059) puts("bad 2.5");
+ if (defined(h[24])) puts("bad 2.6");
+
+ // Now delete the first space.
+ undef(h[2]);
+ unless (h eq "זוהשפה שלנוは 日本語が 分かります") puts("bad 3.0");
+ unless (length(h) == 23) puts("bad 3.1");
+ unless (ord(h[0]) == 0x05d6) puts("bad 3.2");
+ unless (ord(h[2]) == 0x05d4) puts("bad 3.3");
+ unless (ord(h[22]) == 0x3059) puts("bad 3.4");
+ if (defined(h[23])) puts("bad 3.5");
+}
+unicode_2();
+} -output {}
+
+test unicode-3 {test unicode strings in regexp and substitution} -body {
+#lang L --line=1
+void unicode_3()
+{
+ string h = "זו השפה שלנו";
+ string r;
+
+ /* These test wide chars in both regexp and string. */
+
+ unless (h =~ /זו/) puts("bad 1.1");
+ if (h =~ /ך/) puts("bad 1.2");
+ unless (h =~ /זו השפה שלנו/) puts("bad 1.3");
+ unless (h =~ /השפה שלנו/) puts("bad 1.4");
+ if (h =~ /^השפה שלנו/) puts("bad 1.5");
+ unless (h =~ /זו.*שלנו/) puts("bad 1.6");
+
+ h =~ s/ש//;
+ unless (length(h) == 11) puts("bad 2.1");
+ unless (h eq "זו הפה שלנו") puts("bad 2.2");
+ h = "זו השפה שלנו";
+ h =~ s/ש//g;
+ unless (length(h) == 10) puts("bad 2.3");
+ unless (h eq "זו הפה לנו") puts("bad 2.4");
+
+ h = "זו השפה שלנו";
+ r = "ש";
+ h =~ s/${r}//;
+ unless (length(h) == 11) puts("bad 3.1");
+ unless (h eq "זו הפה שלנו") puts("bad 3.2");
+ h = "זו השפה שלנו";
+ h =~ s/${r}//g;
+ unless (length(h) == 10) puts("bad 3.3");
+ unless (h eq "זו הפה לנו") puts("bad 3.4");
+
+ h = "זו השפה שלנו";
+ unless (h =~ /זו (השפ)ה שלנו/) puts("bad 4.1");
+ unless (length($1) == 3) puts("bad 4.2");
+ unless ($1 eq "השפ") puts("bad 4.3");
+
+ /* Test an ascii regexp and a wide string. */
+
+ h = "זו השפה שלנו";
+ unless (h =~ / /) puts("bad 10.1");
+ h =~ s/ //;
+ unless (h == "זוהשפה שלנו") puts("bad 10.2");
+ h = "זו השפה שלנו";
+ h =~ s/ //g;
+ unless (h == "זוהשפהשלנו") puts("bad 10.3");
+}
+unicode_3();
+} -output {}
+
+test unicode-4 {test file I/O with unicode strings} -body {
+#lang L --line=1
+void unicode_4()
+{
+ string h = "זו השפה שלנו";
+ string j = '私は 日本語が 分かります';
+ string s;
+ FILE f;
+
+ unless (f = fopen("unicode4", "w")) puts("bad 0.1");
+ fconfigure(f, encoding: "utf-8");
+ write(f, h, String_bytelength(h));
+ write(f, "\n", 1);
+ fprintf(f, "%s\n", j);
+ fclose(f);
+
+ unless (f = fopen("unicode4", "r")) puts("bad 0.2");
+ fconfigure(f, encoding: "utf-8");
+ s = <f>;
+ unless (length(s) == 12) puts("bad 1.1");
+ unless (ord(s[0]) == 0x05d6) puts("bad 1.2");
+ unless (ord(s[1]) == 0x05d5) puts("bad 1.3");
+ unless (ord(s[2]) == 0x0020) puts("bad 1.4");
+ unless (ord(s[3]) == 0x05d4) puts("bad 1.5");
+ unless (ord(s[4]) == 0x05e9) puts("bad 1.6");
+ unless (ord(s[5]) == 0x05e4) puts("bad 1.7");
+ unless (ord(s[6]) == 0x05d4) puts("bad 1.8");
+ unless (ord(s[7]) == 0x0020) puts("bad 1.9");
+ unless (ord(s[8]) == 0x05e9) puts("bad 1.10");
+ unless (ord(s[9]) == 0x05dc) puts("bad 1.11");
+ unless (ord(s[10]) == 0x05e0) puts("bad 1.12");
+ unless (ord(s[11]) == 0x05d5) puts("bad 1.13");
+ if (defined(s[12])) puts("bad 1.14");
+ s = <f>;
+ unless (length(s) == 13) puts("bad 3.1");
+ unless (ord(s[0]) == 0x79c1) puts("bad 3.2");
+ unless (ord(s[1]) == 0x306f) puts("bad 3.3");
+ unless (ord(s[2]) == 0x3000) puts("bad 3.4");
+ unless (ord(s[3]) == 0x65e5) puts("bad 3.5");
+ unless (ord(s[4]) == 0x672c) puts("bad 3.6");
+ unless (ord(s[5]) == 0x8a9e) puts("bad 3.7");
+ unless (ord(s[6]) == 0x304c) puts("bad 3.8");
+ unless (ord(s[7]) == 0x3000) puts("bad 3.9");
+ unless (ord(s[8]) == 0x5206) puts("bad 3.10");
+ unless (ord(s[9]) == 0x304b) puts("bad 3.11");
+ unless (ord(s[10]) == 0x308a) puts("bad 3.12");
+ unless (ord(s[11]) == 0x307e) puts("bad 3.13");
+ unless (ord(s[12]) == 0x3059) puts("bad 3.14");
+ if (defined(s[13])) puts("bad 3.15");
+ fclose(f);
+ unlink("unicode4");
+}
+unicode_4();
+} -output {}
+
+test unicode-5 {test split built-in with unicode strings} -body {
+#lang L --line=1
+void unicode_5()
+{
+ string a[], s;
+
+ // This contains ASCII spaces.
+ a = split("זו השפה שלנו");
+ unless (length(a) == 3) puts("bad 1.1");
+ unless (a[0] eq "זו") puts("bad 1.2");
+ unless (a[1] eq "השפה") puts("bad 1.3");
+ unless (a[2] eq "שלנו") puts("bad 1.4");
+
+ // Note that these aren't ASCII spaces.
+ a = split("私は 日本語が 分かります");
+ unless (length(a) == 3) puts("bad 2.1");
+ unless (a[0] eq "私は") puts("bad 2.2");
+ unless (a[1] eq "日本語が") puts("bad 2.3");
+ unless (a[2] eq "分かります") puts("bad 2.4");
+
+ // Split a unicode string with a unicode regexp.
+ a = split(/ש/, "זו השפה שלנו");
+ unless (length(a) == 3) puts("bad 3.1");
+ unless (a[0] eq "זו ה") puts("bad 3.2");
+ unless (a[1] eq "פה ") puts("bad 3.3");
+ unless (a[2] eq "לנו") puts("bad 3.4");
+
+ // Split a unicode string with an ascii regexp.
+ a = split(/ /, "זו השפה שלנו");
+ unless (length(a) == 3) puts("bad 4.1");
+ unless (a[0] eq "זו") puts("bad 4.2");
+ unless (a[1] eq "השפה") puts("bad 4.3");
+ unless (a[2] eq "שלנו") puts("bad 4.4");
+
+ // Split a string containing nulls.
+ s = Binary_format("a*a2a*", "x", "b", "yd"); // xb\0yd
+ a = split(/\0/, s);
+ unless (length(a) == 2) puts("bad 5.1");
+ unless (a[0] eq "xb") puts("bad 5.2");
+ unless (a[1] eq "yd") puts("bad 5.3");
+}
+unicode_5();
+} -output {}
+
+test cmdsubst-1 {test command substitution} -body {
+#lang L --line=1
+void cmdsubst_1()
+{
+ string cmd, s1, s2;
+
+ if (platform() eq "windows") {
+ cmd = "sh echo";
+ } else {
+ cmd = "echo";
+ }
+
+ `${cmd} testing1 >foo.txt`;
+ s1 = `cat foo.txt`;
+ unless (s1 eq "testing1") puts("bad 1.1");
+ `rm -f foo.txt`;
+
+ s1 = "testing2";
+ `${cmd} ${s1} >foo.txt`;
+ s1 = `cat foo.txt`;
+ unless (s1 eq "testing2") puts("bad 2.1");
+ `rm -f foo.txt`;
+
+ s1 = "testing3";
+ s2 = "xyz";
+ `${cmd} ${s1}${s2} >foo.txt`;
+ s1 = `cat foo.txt`;
+ unless (s1 eq "testing3xyz") puts("bad 3.1");
+ `rm -f foo.txt`;
+
+ s1 = "testing4";
+ s2 = "pdq";
+ `${cmd} ${s1}-${s2} >foo.txt`;
+ s1 = `cat foo.txt`;
+ unless (s1 eq "testing4-pdq") puts("bad 4.1");
+ `rm -f foo.txt`;
+
+ s1 = "testing";
+ s2 = "xyz";
+ `${cmd} ${s1}${5}${s2} ${"zyx"} >foo.txt`;
+ s1 = `cat foo.txt`;
+ unless (s1 eq "testing5xyz zyx") puts("bad 5.1");
+ `rm -f foo.txt`;
+
+ /*
+ * Check escapes:
+ * \$ \` \\ get escaped
+ * \<newline> gets ignored
+ * \x for anything else, does not get escaped
+ *
+ * These are a bit confusing. Once escaped by backtick
+ * processing, the command string undergoes Bourne-shell-style
+ * quoting. And because tcltest parsing messes with a
+ * \<newline> in the source, we can't simply write one of
+ * those here, so create strings of L code and eval those.
+ */
+
+ `${cmd} \r\n\t\a$x\$\\\\ \`backquote\` >foo.txt`;
+ s1 = `cat foo.txt`;
+ unless (s1 eq "rnta$x$\\ `backquote`") puts("bad 10.1");
+ `rm -f foo.txt`;
+
+ L("`${cmd} x\\\ny >foo.txt`;\n");
+ s1 = `cat foo.txt`;
+ unless (s1 eq "xy") puts("bad 10.2");
+ `rm -f foo.txt`;
+}
+cmdsubst_1();
+} -output {}
+
+test cmdsubst-2 {test command substitution errors} -body {
+#lang L --line=1
+void cmdsubst_2()
+{
+ string s = `a-nonexistent-command arg`;
+ if (defined(s)) puts("bad 1");
+}
+cmdsubst_2();
+} -output {}
+
+test proc-1.0 {Test L function definition.} -body {
+#lang L --line=1
+void proc_1_0(void) {
+ puts("foo");
+}
+#lang tcl
+proc_1_0
+} -output "foo\n"
+
+
+test proc-1.1 {Test L function returns.} -body {
+#lang L --line=1
+void proc_1_1_f1() {
+ puts("whiz");
+}
+string proc_1_1_f2() {
+ puts("bang");
+ return "foo";
+ return "bar";
+}
+void proc_1_1_f3() {
+ return;
+}
+void proc_1_1(void) {
+ puts(proc_1_1_f1());
+ puts(proc_1_1_f2());
+ puts(proc_1_1_f3());
+}
+#lang tcl
+proc_1_1
+} -output "whiz\n\nbang\nfoo\n\n"
+
+test proc-1.2 {Test L function parameters.} -body {
+#lang L --line=1
+void proc_1_2(string arg1, string arg2) {
+ puts(arg1);
+ puts(arg2);
+}
+#lang tcl
+proc_1_2 "val1" "val2"
+} -output "val1\nval2\n"
+
+test proc-1.3 {Test variable arity functions} -body {
+#lang L --line=1
+void proc_1_3_foo(...stuff) {
+ int i;
+ for (i=0; defined(stuff[i]); i++) {
+ printf("%s ", stuff[i]);
+ }
+ printf("\n");
+}
+void proc_1_3_bar(int a, ...stuff) {
+ puts(a);
+ puts(stuff);
+}
+void proc_1_3() {
+ proc_1_3_foo("a", "b", "c", "d");
+ proc_1_3_foo();
+ proc_1_3_bar(1, 2, 3, 4);
+ proc_1_3_bar(1);
+}
+#lang tcl
+proc_1_3
+} -output "a b c d \n\n1\n2 3 4\n1\n\n"
+
+test proc-1.4 {Ensure rest parameter comes last} -body {
+#lang L --line=1 -nowarn
+void proc_1_4(int a, ...b, int c) {
+ puts("oops");
+}
+#lang tcl
+proc_1_4
+} -returnCodes {error} -match glob -result "*:1: L Error: Rest parameter must be last\n"
+
+test proc-1.5 {test parameter multiple declaration} -body {
+#lang L --line=1 -nowarn
+void proc_1_5_1(int a, int a) {}
+void proc_1_5_2(int a, int a, int a) {}
+} -returnCodes error -match regexp -result {.*1: L Error: multiple declaration of local a
+.*2: L Error: multiple declaration of local a
+.*2: L Error: multiple declaration of local a
+}
+
+test proc-1.6 {check ignored function return value} -body {
+#lang L --line=1
+int proc_1_6_foo() { return (1); }
+void proc_1_6()
+{
+ /*
+ * This test checks that an ignored function's return value is
+ * properly popped off the run-time stack. If it's not, the
+ * unbalanced stack will cause a Tcl panic in a debug build.
+ */
+
+ int i;
+ int n = 100;
+
+ for (i = 0; i < n; ++i) {
+ proc_1_6_foo();
+ }
+}
+proc_1_6();
+} -output {}
+
+test proc-1.7 {check extern functions} -setup {
+ proc proc_1_7 {} { puts "good" }
+} -body {
+#lang L --line=1
+ extern void proc_1_7();
+ proc_1_7();
+} -output {good
+}
+
+test proc-1.8 {test (expand)} -body {
+#lang L --line=1
+string proc_1_8_concat(...args)
+{
+ poly p;
+ string s = "";
+
+ foreach (p in args) s .= p;
+ return (s);
+}
+int proc_1_8_sum(int a, int b, int c)
+{
+ return (a + b + c);
+}
+/* Return a string array of n elements, starting at "1" and counting up. */
+string[] proc_1_8_arr(int n)
+{
+ int i;
+ string s[];
+
+ for (i = 1; i <= n; ++i) push(&s, (string)i);
+ return (s);
+}
+void proc_1_8()
+{
+ int i1[] = { 10 };
+ int i2[] = { 20, 30 };
+ int i3[] = { 40, 50, 60 };
+ string s;
+ string sa[] = { "a", "b", "c" };
+ string sb[] = { "d", "e" };
+ poly p = { "a", "b", "c" };
+
+ unless (proc_1_8_concat((expand){}) eq "") puts("bad 0.1");
+
+ unless (proc_1_8_concat((expand)sa) eq "abc") puts("bad 1.1");
+ unless (proc_1_8_concat("x", (expand)sa) eq "xabc") puts("bad 2.1");
+ unless (proc_1_8_concat((expand)sa, "y") eq "abcy") puts("bad 3.1");
+ unless (proc_1_8_concat("x", (expand)sa, "y") eq "xabcy") {
+ puts("bad 4.1");
+ }
+ unless (proc_1_8_concat("x", (expand)sa, (expand)sb, "y") eq "xabcdey") {
+ puts("bad 5.1");
+ }
+ unless (proc_1_8_concat((expand)sa, (expand)sa, (expand)sa)
+ eq "abcabcabc") {
+ puts("bad 6.1");
+ }
+
+ unless (proc_1_8_sum((expand)i1, 2, 3) == 15) puts("bad 10.1");
+ unless (proc_1_8_sum((expand)i2, 2) == 52) puts("bad 11.1");
+ unless (proc_1_8_sum((expand)i3) == 150) puts("bad 12.1");
+
+ unless (proc_1_8_concat((expand)p) eq "abc") puts("bad 20.1");
+
+ unless (proc_1_8_concat((expand)proc_1_8_arr(1)) eq "1") {
+ puts("bad 30.1");
+ }
+ unless (proc_1_8_concat((expand)proc_1_8_arr(2)) eq "12") {
+ puts("bad 31.1");
+ }
+ unless (proc_1_8_concat((expand)proc_1_8_arr(3)) eq "123") {
+ puts("bad 32.1");
+ }
+
+ /* These test expand inside of a list {}. */
+
+ unless (proc_1_8_concat((expand){(expand){1}}) eq "1") {
+ puts("bad 40.1");
+ }
+ unless (proc_1_8_concat((expand){(expand){1,2}}) eq "12") {
+ puts("bad 40.3");
+ }
+ unless (proc_1_8_concat((expand){(expand){1,2,3}}) eq "123") {
+ puts("bad 40.5");
+ }
+
+ sa = { (expand){"1","2"}, "3", (expand){"4"}, "5", (expand){"6","7","8"} };
+ unless (length(sa) == 8) puts("bad 41.1");
+ unless (proc_1_8_concat((expand)sa) eq "12345678") puts("bad 41.2");
+
+ sa = { (expand)"1" };
+ unless ((length(sa) == 1) && (sa[0] eq "1")) puts("bad 42.1");
+ sa = { (expand)"1", (expand)"2" };
+ unless ((length(sa) == 2) && (sa[0] eq "1") && (sa[1] eq "2")) {
+ puts("bad 42.2");
+ }
+
+ /*
+ * Test some expands inside of nested calls to verify that
+ * they are not mistakenly caught as errors.
+ */
+ s = proc_1_8_concat((expand){"1"},
+ proc_1_8_concat((expand){"2"},
+ proc_1_8_concat((expand){"3","4"}),
+ (expand){"5","6"}),
+ (expand){"7"});
+ unless (s eq "1234567") puts("bad 45.1");
+}
+proc_1_8();
+} -output {}
+
+test proc-1.9 {test (expand) errors} -body {
+#lang L --line=1 --nowarn
+private int foo(...args) { return (0); }
+void proc_1_9()
+{
+ string a[];
+
+ foo((expand)a + 1);
+ foo(1 ? (expand)a : 1);
+ {(expand)a + 1};
+ {1 ? (expand)a : 1};
+ {"x", {1 ? (expand)a : 1}};
+ (expand)a;
+ foo((expand)a, (expand)a+1);
+ foo("x", foo((expand)a+1));
+}
+} -returnCodes error -match regexp -result {.*6: L Error: \(expand\) illegal in this context
+.*7: L Error: \(expand\) illegal in this context
+.*8: L Error: \(expand\) illegal in this context
+.*9: L Error: \(expand\) illegal in this context
+.*10: L Error: \(expand\) illegal in this context
+.*11: L Error: \(expand\) illegal in this context
+.*12: L Error: \(expand\) illegal in this context
+.*13: L Error: \(expand\) illegal in this context
+}
+
+test var-1.0 {Test L variable assignment and reference} -body {
+#lang L --line=1
+void var_1_0(void)
+{
+ string s;
+ s = "Hello";
+ puts(s);
+}
+#lang tcl
+var_1_0
+} -output "Hello\n"
+
+test var-1.1 {L global variables} -body {
+#lang L --line=1
+int lglobal1_1 = 1;
+void var_1_1(void)
+{
+ puts(lglobal1_1);
+}
+#lang tcl
+var_1_1
+} -output "1\n"
+
+
+test var-1.2 {L global variables, harder} -body {
+#lang L --line=1
+int lglobal1_2 = 3;
+void var_1_2(void)
+{
+ puts(lglobal1_2);
+ lglobal1_2 = 4;
+ var_1_2_aux();
+ puts(lglobal1_2);
+}
+
+void var_1_2_aux()
+{
+ puts(lglobal1_2);
+ lglobal1_2 = 5;
+}
+#lang tcl
+var_1_2
+} -output "3\n4\n5\n"
+
+test var-1.2.2 {L global variable access from inside function} -body {
+#lang L --line=1
+private int g = 123;
+void var_1_2_2()
+{
+ /*
+ * This tests a past compiler bug where the upvars for the
+ * global shadows were emitted at the point of variable use,
+ * which doesn't work if the use doesn't get executed, like
+ * the first reference to "g" below.
+ */
+ for (; 0; g);
+ unless (g == 123) puts("bad 1");
+}
+var_1_2_2();
+} -output {}
+
+test var-1.2.3 {L global variable access from inside class} -body {
+#lang L --line=1 -nowarn
+/*
+ * Like the above test (var-1.2.2) but with class variables as well.
+ */
+private int g = 321;
+class class_var_1_2_3a
+{
+ public int l1 = g; // should see the global "g"
+ public int g = 654; // shadows the global
+ public int l2 = g; // should see the local "g"
+}
+class class_var_1_2_3b
+{
+ public int l1 = g; // should see the global "g"
+ public int g = 456; // shadows the global
+ public int l2 = g; // should see the local "g"
+}
+void var_1_2_3()
+{
+ unless (g == 321) puts("bad 1");
+ unless (class_var_1_2_3a->l1 == 321) puts("bad 2");
+ unless (class_var_1_2_3a->g == 654) puts("bad 3");
+ unless (class_var_1_2_3a->l2 == 654) puts("bad 4");
+ unless (class_var_1_2_3b->l1 == 321) puts("bad 5");
+ unless (class_var_1_2_3b->g == 456) puts("bad 6");
+ unless (class_var_1_2_3b->l2 == 456) puts("bad 7");
+ if (1) {
+ int g = 987;
+ unless (g == 987) puts("bad 10");
+ }
+ unless (g == 321) puts("bad 20");
+}
+var_1_2_3();
+} -output {}
+
+test var-1.3 {A global array of structs} -body {
+#lang L --line=1
+
+struct var_1_3_point { int x, y; };
+struct var_1_3_point lglobal1_3[5];
+
+void var_1_3(void)
+{
+ int i = 0;
+
+ puts(lglobal1_3);
+ while (i < 5) {
+ lglobal1_3[i].x = i * 10;
+ lglobal1_3[i].y = i * 20;
+ i++;
+ }
+ puts(lglobal1_3);
+ var_1_3_aux(3);
+ puts(lglobal1_3);
+}
+
+void var_1_3_aux(int i)
+{
+ lglobal1_3[i].x = i * 35;
+ lglobal1_3[i].y = i * 45;
+}
+#lang tcl
+var_1_3
+} -output {
+{0 0} {10 20} {20 40} {30 60} {40 80}
+{0 0} {10 20} {20 40} {105 135} {40 80}
+}
+
+test var-1.4 {Test extern variables} -body {
+set var_1_4_v1 "extern test 1"
+set var_1_4_v2 "extern test 2"
+namespace eval var_1_4_ns {
+ variable foo "extern test 3"
+}
+#lang L --line=1
+extern string var_1_4_v1;
+extern string ::var_1_4_v2;
+extern string var_1_4_ns::foo;
+extern string ::var_1_4_ns::foo; // really the same var as var_1_4_ns::foo
+void var_1_4()
+{
+ unless (var_1_4_v1 eq "extern test 1") puts("bad 1");
+ unless (::var_1_4_v2 eq "extern test 2") puts("bad 2");
+ unless (var_1_4_ns::foo eq "extern test 3") puts("bad 3");
+ unless (::var_1_4_ns::foo eq "extern test 3") puts("bad 4");
+}
+var_1_4();
+} -output {}
+
+test var-1.5 {Variable function names} -body {
+#lang L --line=1
+void var_1_5() {
+ /*
+ * This used to be supported but is no longer (2/24/09).
+ * This is now an error.
+ */
+ string printfvar = "printf";
+ printfvar("Earth calling printf\n");
+}
+#lang tcl
+var_1_5
+} -returnCodes error -match regexp -result {.*7: L Error: 'printfvar' is declared but not as a function
+}
+
+test var-2 {test taking value of a function name} -body {
+#lang L --line=1
+void var_2()
+{
+ /* This used to cause a crash. */
+ puts(printf);
+}
+var_2();
+} -returnCodes error -match regexp -result {.*4: L Error: cannot use a function name as a value
+}
+
+test lang-1.0 {Test lang parsing} -body {
+# These are some Tcl Comments
+#lang L --line=1
+void lang_1_0(void)
+{
+ puts("worked");
+}
+
+#lang tcl
+# More comments
+ # starting after first column (space)
+ # starting after first column (tab)
+ # starting after first column (tab, space)
+#pragm -- not a pragma
+#pragmatic -- also not a pragma
+ #pragma -- yes, not a pragma
+# pragma -- not a pragma
+lang_1_0
+} -output "worked\n"
+
+test lang-2.0 {Test failure path in lang parsing} -body {
+#lang(foo)
+void lang_2_0(void)
+{
+ puts("worked");
+}
+
+#lang tcl
+lang_2_0
+} -returnCodes {error} -result {malformed pragma}
+
+# no output because we're not calling any functions
+test lang-3.0 {Test not switching back to Tcl} -body {
+#lang L --line=1
+void lang_3_0(void)
+{
+ puts("worked");
+}
+}
+
+test pragma-1 {test bad #pragma} -body {
+#lang L --line=1
+#pragma bad
+} -returnCodes error -match regexp -result {.*1: L Error: illegal attribute 'bad'
+}
+
+test decl-1.0 {Variable and parameter declaration syntax} -body {
+#lang L --line=1 -nowarn
+void decl_1_0_fun1() { }
+void decl_1_0_fun2(void) { }
+void decl_1_0_fun3() { }
+int fdecl_1_0_un4() { }
+void decl_1_0_fun5(int foo) { }
+hash decl_1_0_fun6(hash foo, hash bar[], hash baz[23]) { }
+void decl_1_0_fun7(int foo, float bar, hash baz, string quux, poly quuux) { }
+void decl_1_0_fun8() {
+ int foo, bar[], baz[84][42][1];
+ string foo1[19], mani[], padmi = "hum";
+ hash whee;
+ if (0) {
+ int bleh = 5;
+ } else {
+ if (1) {
+ poly padmi1 = "om";
+ puts(padmi1);
+ }
+ }
+}
+#lang tcl
+decl_1_0_fun8
+} -output "om\n";
+
+test decl-1.1 {Hairy literal hash syntax in initializers} -body {
+#lang L --line=1 -nowarn
+void initmewoo() {
+ hash h = { "key" => "val", "key2" => "val" };
+}
+#lang tcl
+}
+
+test decl-1.2 {Undeclared variable error} -body {
+#lang L --line=1
+void decl_1_2_undecl() {
+ foo = "bar";
+ puts(cheese);
+}
+#lang tcl
+decl_1_2_undecl
+} -returnCodes error -match glob -result {*L Error: undeclared variable: foo
+*L Error: undeclared variable: cheese
+}
+
+test decl-1.3 {Variable shadowing} -body {
+#lang L --line=1
+void decl_1_3_shadow() {
+ int foo = 1;
+ if (1) {
+ int foo = 2;
+ puts(foo);
+ }
+ puts(foo);
+}
+#lang tcl
+decl_1_3_shadow
+} -returnCodes error -match glob -result {*L Error: multiple declaration of local foo
+}
+
+test decl-1.3.1 {test variable shadowing warnings} -body {
+#lang L --line=1
+string decl_1_3_1g;
+private string decl_1_3_1gp;
+class decl_1_3_1cl
+{
+ public string decl_1_3_1cls;
+ instance {
+ public string decl_1_3_1inst;
+ };
+ public void foo(decl_1_3_1cl self)
+ {
+ string decl_1_3_1g = "";
+ string decl_1_3_1gp = "";
+ string decl_1_3_1cls = "";
+ string decl_1_3_1inst = "";
+ }
+}
+void decl_1_3_1()
+{
+ string decl_1_3_1g = "";
+ string decl_1_3_1gp = "";
+}
+} -returnCodes error -match regexp -result {.*11: L Warning: local variable decl_1_3_1g shadows a global declared at.*:1
+.*12: L Warning: local variable decl_1_3_1gp shadows a global declared at.*:2
+.*13: L Warning: local variable decl_1_3_1cls shadows a class variable declared at.*:5
+.*14: L Warning: local variable decl_1_3_1inst shadows a class instance variable declared at.*:7
+.*19: L Warning: local variable decl_1_3_1g shadows a global declared at.*:1
+.*20: L Warning: local variable decl_1_3_1gp shadows a global declared at.*:2
+}
+
+test decl-1.4 {Single dimensional initializers actually initialize} -body {
+#lang L --line=1
+void decl_1_4 () {
+ int foo[] = {4, 5, 6};
+ hash bar = {"foo" => 4, "bar" => 5, "baz" => 6};
+ struct { int x; int y; } point = { 1024, 768 };
+
+ printf("%s\n", foo);
+ printf("%s\n", bar);
+ printf("%s\n", point);
+}
+#lang tcl
+decl_1_4
+} -output "4 5 6\nfoo 4 bar 5 baz 6\n1024 768\n"
+
+# Test decl-1.5 removed.
+
+test decl-1.6 {Check scoping rule errors for globals and externs} -body {
+#lang L --line=1 -nowarn
+/*
+ * The L scoping rules are as follows:
+ *
+ * - A name multiply declared at the global scope is illegal.
+ * - A name multiply declared in a local scope or any enclosing scopes
+ * is illegal.
+ * - A local name hides a global of the same name.
+ * - A name is not visible outside the scope in which it is declared.
+ * - A name is not visible in a scope before it is declared.
+ *
+ * This test checks the error cases.
+ */
+int decl_1_6_g1 = decl_1_6_g2; // error -- g2 used before being declared
+int decl_1_6_g2;
+void foo_decl_1_6()
+{
+ decl_1_6_g3 = 1; // error -- g3 used before being declared
+}
+int decl_1_6_g3;
+void decl_1_6()
+{
+ int l;
+ int l; // error -- name already declared locally
+ puts(decl_1_6_extern); // error -- extern not yet declared
+ if (1) {
+ if (1) {
+ int decl_1_6_extern;
+ decl_1_6_extern = 3;
+ }
+ }
+ if (1) {
+ int l2;
+ int l; // error -- name already declared locally
+ if (1) {
+ int l2; // error -- name already declared locally
+ }
+ }
+}
+int decl_1_6_g2; // error -- multiply declared at global scope
+void decl_1_6_bad()
+{
+ extern int decl_1_6_g; // error -- externs illegal in local scopes
+}
+} -returnCodes error -match regexp -result {.*13: L Error: undeclared variable: decl_1_6_g2
+.*17: L Error: undeclared variable: decl_1_6_g3
+.*23: L Error: multiple declaration of local l
+.*24: L Error: undeclared variable: decl_1_6_extern
+.*33: L Error: multiple declaration of local l
+.*35: L Error: multiple declaration of local l2
+.*39: L Error: multiple declaration of global decl_1_6_g2
+.*42: L Error: externs legal only at global scope
+}
+
+test decl-1.7 {Check scoping rules for globals and externs} -body {
+#lang L --line=1 -nowarn
+/*
+ * This test checks the non-error cases of the scoping rules described
+ * above.
+ */
+extern string decl_1_7_extern;
+string decl_1_7_g1;
+string decl_1_7_g2 = "g2";
+string decl_1_7_g3;
+void decl_1_7()
+{
+ string s = decl_1_7_g2; // read the global
+ string decl_1_7_g2 = "g2local"; // now shadow the global
+
+ unless (s eq "g2") puts("bad 1");
+ unless (decl_1_7_g2 eq "g2local") puts("bad 2");
+
+ decl_1_7_extern = "ex";
+ unless (decl_1_7_extern eq "ex") puts("bad 3");
+
+ decl_1_7_g1 = "g1";
+ unless (decl_1_7_g1 eq "g1") puts("bad 4");
+
+ if (1) {
+ string decl_1_7_g1; // shadow a global, already referenced
+ string decl_1_7_g3; // shadow a global, not yet referenced
+ decl_1_7_g1 = "local1"; // sets the local
+ decl_1_7_g3 = "local3"; // sets the local
+ unless (decl_1_7_g1 eq "local1") puts("bad 5");
+ unless (decl_1_7_g3 eq "local3") puts("bad 6");
+ }
+ unless (decl_1_7_g1 eq "g1") puts("bad 7");
+}
+#lang tcl
+decl_1_7
+} -output ""
+
+test decl-1.7.5 {check legal multiple extern variable declarations} -body {
+set decl_1_7_5_var "extern test"
+#lang L --line=1
+extern string decl_1_7_5_var;
+extern string decl_1_7_5_var; // legal -- has same type as prior declaration
+void decl_1_7_5()
+{
+ unless (decl_1_7_5_var eq "extern test") puts("bad 1");
+}
+decl_1_7_5();
+} -output {}
+
+test decl-1.7.6 {check illegal multiple extern variable declarations} -body {
+#lang L --line=1
+extern string decl_1_7_6_var;
+extern int decl_1_7_6_var; // err -- not the same type
+} -returnCodes error -match regexp -result {.*2: L Error: extern re-declaration type does not match other declaration
+}
+
+test decl-1.8 {Check illegal variable names} -body {
+#lang L --line=1 -nowarn
+void _decl_1_8() // err -- function names cannot begin with _
+{
+ int _bad; // err -- locals cannot begin with _
+}
+} -returnCodes error -match regexp -result {.*1: L Error: function names cannot begin with _
+.*3: L Error: local variable names cannot begin with _
+}
+
+test decl-1.9 {Check mixing types on single decl line} -body {
+#lang L --line=1
+void decl_1_9() {
+ /*
+ * This is a regression test. L used to get the types wrong.
+ * This just checks that the compiler issues no type errors.
+ */
+ string h1{int}, s1;
+ string s2;
+ string h2{int};
+
+ s1 = s2;
+ h1 = h2;
+ s1 = "s1";
+ s2 = "s2";
+ h1{1} = "one";
+ h2{1} = "one";
+}
+#lang tcl
+decl_1_9
+} -output {}
+
+test decl-1.10 {multiple declaration of main in same script disallowed} -body {
+#lang L --line=1
+void main()
+{
+}
+void main()
+{
+}
+void main()
+{
+}
+} -returnCodes error -match regexp -result {.*4: L Error: function main already declared
+.*7: L Error: function main already declared
+}
+
+test decl-1.10.1 {argc, argv, or env should never cause unused-variable warning} -setup {
+ # Put these in their own files since only one main() can be defined.
+ makeFile {
+ void main(string argv[]) {}
+ } decl-1.10.1-1.l
+ makeFile {
+ void main(int argc, string argv[]) {}
+ } decl-1.10.1-2.l
+ makeFile {
+ void main(int argc, string argv[], string env{string}) {}
+ } decl-1.10.1-3.l
+} -body {
+#lang L --line=1
+void decl_1_10_1()
+{
+ int ret;
+ string tclsh = interpreter();
+ string out, err;
+
+ ret = system({tclsh, "decl-1.10.1-1.l"}, undef, &out, &err);
+ unless (ret == 0) puts("bad 1.1: ${out} ${err}");
+
+ ret = system({tclsh, "decl-1.10.1-2.l"}, undef, &out, &err);
+ unless (ret == 0) puts("bad 2.1: ${out} ${err}");
+
+ ret = system({tclsh, "decl-1.10.1-3.l"}, undef, &out, &err);
+ unless (ret == 0) puts("bad 3.1: ${out} ${err}");
+}
+decl_1_10_1();
+} -output {}
+
+test decl-1.11.1 {private globals 1} -body {
+#lang L --line=1
+private string priv_global = "test 1";
+private void priv_global_test_fn()
+{
+ puts(priv_global);
+}
+void decl_1_11_1()
+{
+ unless (priv_global eq "test 1") puts("bad decl_1_11_1");
+}
+priv_global_test_fn();
+decl_1_11_1();
+} -output "test 1\n"
+
+test decl-1.11.2 {private globals 2} -body {
+#lang L --line=1
+/*
+ * This test declares the same (private) names as the previous test.
+ * They should not clash.
+ */
+private string priv_global = "test 2";
+private void priv_global_test_fn()
+{
+ puts(priv_global);
+}
+priv_global_test_fn();
+/*
+ * Call the previous test's function. It should see the value of its
+ * own private global, not ours.
+ */
+decl_1_11_1();
+} -output "test 2\n"
+
+test decl-1.11.3 {test public/private global declaration errors} -body {
+#lang L --line=1 -nowarn
+private int decl_1_11_3_priv_first;
+int decl_1_11_3_priv_first;
+
+int decl_1_11_3_publ_first;
+private int decl_1_11_3_publ_first;
+
+private int two_privates;
+private int two_privates;
+
+private void decl_1_11_1() {} // already declared in earlier test
+
+private string stdin; // already declared in libl
+
+void decl_1_11_3()
+{
+ public string bad1;
+ private string bad2;
+}
+} -returnCodes {error} -match regexp -result {.*2: L Error: multiple declaration of global decl_1_11_3_priv_first
+.*5: L Error: multiple declaration of global decl_1_11_3_publ_first
+.*8: L Error: multiple declaration of global two_privates
+.*10: L Error: function decl_1_11_1 already declared
+.*12: L Error: multiple declaration of global stdin
+.*16: L Error: public/private qualifiers illegal for locals
+.*17: L Error: public/private qualifiers illegal for locals
+}
+
+test decl-1.12.1 {public globals 1} -body {
+#lang L --line=1
+/*
+ * This simply tests that the "public" qualifier on a global
+ * declaration acts like a no-op.
+ */
+public string decl_1_12_s = "public decl test";
+public void decl_1_12_1()
+{
+ puts(decl_1_12_s);
+}
+decl_1_12_1();
+} -output "public decl test\n"
+
+test decl-1.12.1 {public globals 2} -body {
+#lang L --line=1
+/* This is the second half of the test above. */
+public void decl_1_12_2()
+{
+ puts(decl_1_12_s); // print global defined in the previous test
+}
+decl_1_12_2();
+} -output "public decl test\n"
+
+test if-1.0 {If statements} -body {
+#lang L --line=1
+void if_1_0() {
+ if (1) puts("0 working");
+ if (0) {
+ puts("1 broken");
+ }
+ puts("between");
+ if (1) {
+ puts("1 working");
+ }
+}
+#lang tcl
+if_1_0
+} -output "0 working\nbetween\n1 working\n"
+
+
+test if-1.1 {If statements with else clauses and multistatement bodies} -body {
+#lang L --line=1
+void if_1_1() {
+ if (1) {
+ puts("1 working");
+ puts(".");
+ } else {
+ puts("1 broken");
+ puts(".");
+ }
+
+ if (0) {
+ puts("2 broken");
+ puts(".");
+ puts(".");
+ } else {
+ puts("2 working");
+ puts(".");
+ puts(".");
+ }
+}
+#lang tcl
+if_1_1
+} -output "1 working\n.\n2 working\n.\n.\n"
+
+
+test if-1.2 {"else if" clauses} -body {
+#lang L --line=1
+void if_1_2() {
+ if (0) {
+ puts("1 broken");
+ } else if (1) {
+ puts("1 working");
+ }
+
+ puts("between");
+
+ if (0) {
+ puts("2 broken");
+ } else if (0) {
+ puts("2.2 broken");
+ } else {
+ puts("2 working");
+ }
+}
+#lang tcl
+if_1_2
+} -output "1 working\nbetween\n2 working\n"
+
+test if-1.3 {nested if statements} -body {
+#lang L --line=1
+void if_1_3() {
+ if (1) {
+ puts("1 before");
+ if (0) {
+ puts("1 broken");
+ } else {
+ puts("1 working");
+ }
+ puts("1 after");
+ } else {
+ puts("1.1 broken");
+ }
+ puts("1 done");
+}
+#lang tcl
+if_1_3
+} -output "1 before\n1 working\n1 after\n1 done\n"
+
+test if-1.4 {else is only allowed with curly braces} -body {
+#lang L --line=1
+void if_1_4(void)
+{
+ if (0) puts("1 broken"); else puts("1 even more broken");
+}
+#lang tcl
+} -returnCodes error -match glob -result {*3: L Error: syntax error, unexpected else
+ if (0) puts("1 broken"); else
+ ^
+}
+
+test unless-1.0 {unless statements} -body {
+#lang L --line=1
+void unless_1_0() {
+ unless(0) puts("0 working");
+ unless(0) {
+ puts("1 working");
+ }
+ unless(1) {
+ puts("2 broken");
+ } else {
+ puts("2 working");
+ }
+ unless(1) {
+ puts("3 broken");
+ } else unless (1) {
+ puts("3.1 broken");
+ } else {
+ puts("3 working");
+ }
+}
+#lang tcl
+unless_1_0
+} -output "0 working\n1 working\n2 working\n3 working\n"
+
+test unless-1.1 {unless and if statements mixed} -body {
+#lang L --line=1
+void unless_1_1() {
+ unless(1) {
+ puts("1 broken");
+ } else if (0) {
+ puts("1.1 broken");
+ } else unless(0) {
+ puts("1 working");
+ }
+ puts("done");
+}
+#lang tcl
+unless_1_1
+} -output "1 working\ndone\n"
+
+test return-1.1 {return from void function allowed} -body {
+#lang L --line=1
+void return_1_1() { return; }
+} -returnCodes normal
+
+test return-1.2 {returning int from void function disallowed} -body {
+#lang L --line=1
+void return_1_2() { return 0; }
+} -returnCodes error -match regexp -result ".*void function cannot return value"
+
+test return-1.3 {returning string from void function disallowed} -body {
+#lang L --line=1
+void return_1_3() { return "str"; }
+} -returnCodes error -match regexp -result ".*void function cannot return value"
+
+test return-1.4 {returning float from void function disallowed} -body {
+#lang L --line=1
+void return_1_4() { return 2.99792458; }
+} -returnCodes error -match regexp -result ".*void function cannot return value"
+
+test return-1.5 {returning array from void function disallowed} -body {
+#lang L --line=1
+void return_1_5() {
+ int a[3];
+ return a;
+}
+} -returnCodes error -match regexp -result ".*void function cannot return value"
+
+test return-1.6 {returning hash from void function disallowed} -body {
+#lang L --line=1
+void return_1_6() {
+ hash h;
+ return h;
+}
+} -returnCodes error -match regexp -result ".*void function cannot return value"
+
+test return-1.7 {returning struct from void function disallowed} -body {
+#lang L --line=1
+void return_1_7() {
+ struct { int x,y; } s;
+ return s;
+}
+} -returnCodes error -match regexp -result ".*void function cannot return value"
+
+test return-1.8 {returning poly from void function disallowed} -body {
+#lang L --line=1
+void return_1_8() {
+ poly p;
+ return p;
+}
+} -returnCodes error -match regexp -result ".*void function cannot return value"
+
+test return-1.9.1 {return from global scope 1} -body {
+#lang L --line=1
+return;
+} -output {}
+
+test return-1.9.2 {return from global scope 2} -body {
+#lang L --line=1
+return(1);
+} -result {1} -output {}
+
+test return-1.9.3 {return from global scope 3} -body {
+#lang L --line=1
+return("ret");
+} -result {ret} -output {}
+
+test return-2.1 {int return value from int function allowed} -body {
+#lang L --line=1
+int return_2_1_f() { return 123; }
+unless (return_2_1_f() == 123) printf("BAD\n");
+} -output ""
+
+test return-2.2 {float return value from float function allowed} -body {
+#lang L --line=1
+float return_2_2_f() { return 123.456; }
+unless (return_2_2_f() == 123.456) printf("BAD\n");
+} -output ""
+
+test return-2.3 {string return value from string function allowed} -body {
+#lang L --line=1
+string return_2_3_f() { return "str"; }
+unless (return_2_3_f() eq "str") printf("BAD\n");
+} -output ""
+
+test return-2.4 {array return value from array function allowed} -body {
+#lang L --line=1
+int[] return_2_4_f()
+{
+ int a[3] = {2,3,5};
+ return a;
+}
+void return_2_4()
+{
+ int res[] = return_2_4_f();
+ unless ((res[0] == 2) && (res[1] == 3) && (res[2] == 5)) {
+ printf("BAD\n");
+ }
+}
+#lang tcl
+return_2_4
+} -output ""
+
+test return-2.5 {hash return value from hash function allowed} -body {
+#lang L --line=1
+hash return_2_5_f()
+{
+ hash h;
+ h{"one"} = 1;
+ h{"two"} = 2;
+ h{"ten"} = 10;
+ return h;
+}
+void return_2_5()
+{
+ hash res = return_2_5_f();
+ unless ((res{"one"} == 1) && (res{"two"} == 2) && (res{"ten"} == 10)) {
+ printf("BAD\n");
+ }
+}
+#lang tcl
+return_2_5
+} -output ""
+
+test return-2.6 {struct return value from struct function allowed} -body {
+#lang L --line=1
+struct return_2_6_s {
+ int x, y, z;
+};
+struct return_2_6_s return_2_6_f()
+{
+ struct return_2_6_s s;
+ s.x = 1;
+ s.y = 2;
+ s.z = 3;
+ return s;
+}
+void return_2_6()
+{
+ struct return_2_6_s res = return_2_6_f();
+ unless ((res.x == 1) && (res.y == 2) && (res.z == 3)) printf("BAD\n");
+}
+#lang tcl
+return_2_6
+} -output ""
+
+# Spot-check some of the type-checking cases to ensure that return-value
+# type checking is being done. Do not check all possible permutations.
+
+test return-3.1 {int return value from string function disallowed} -body {
+#lang L --line=1
+string return_3_1() { return 1; }
+} -returnCodes error -match regexp -result ".*incompatible return type"
+
+test return-3.2 {float return value from string function disallowed} -body {
+#lang L --line=1
+string return_3_2() { return 1.2; }
+} -returnCodes error -match regexp -result ".*incompatible return type"
+
+test return-3.3 {int return value from hash function disallowed} -body {
+#lang L --line=1
+hash return_3_3() { return 1; }
+} -returnCodes error -match regexp -result ".*incompatible return type"
+
+test return-3.4 {array return value from hash function disallowed} -body {
+#lang L --line=1
+hash return_3_4() { int a[3]; return a; }
+} -returnCodes error -match regexp -result ".*incompatible return type"
+
+test return-3.5 {int return value from struct function disallowed} -body {
+#lang L --line=1
+struct s35 {
+ int x, y;
+};
+struct s35 return_3_5() { return 1; }
+} -returnCodes error -match regexp -result ".*incompatible return type"
+
+test return-3.6 {hash return value from struct function disallowed} -body {
+#lang L --line=1
+struct s36 {
+ int x, y;
+};
+struct s36 return_3_6() { hash h; return h; }
+} -returnCodes error -match regexp -result ".*incompatible return type"
+
+test return-3.7 {int return value from array function disallowed} -body {
+#lang L --line=1
+int[] return_3_7() { return 1; }
+} -returnCodes error -match regexp -result ".*incompatible return type"
+
+test return-3.8 {struct return value from array function disallowed} -body {
+#lang L --line=1
+struct s38 {
+ int x, y;
+};
+int[] return_3_8() { struct s38 s; return s; }
+} -returnCodes error -match regexp -result ".*incompatible return type"
+
+test return-3.9 {hash return value from array function disallowed} -body {
+#lang L --line=1
+int[] return_3_9() { hash h; return h; }
+} -returnCodes error -match regexp -result ".*incompatible return type"
+
+test return-3.10 {void return value from non-void function disallowed} -body {
+#lang L --line=1
+int return_3_10_int() { return; }
+} -returnCodes error -match regexp -result ".*must specify return value"
+
+test return-3.11 {check not returning a value from functon error} -body {
+#lang L --line=1
+private string f()
+{
+ if (0) return ("not taken");
+}
+void return_3_10()
+{
+ f();
+}
+return_3_10();
+} -returnCodes error -match regexp -result {no value returned from function}
+
+test syntax-1.0 {single-line comments a la C++} -body {
+#lang L --line=1
+# this kind of comment valid only on line 1
+void syntax_1_0() {
+ // single-line comments are
+ puts("working"); //see?
+ //////cruftilioucious
+}
+
+#lang tcl
+syntax_1_0
+} -output "working\n"
+
+test syntax-1.0.1 {hash-comment errors} -body {
+#lang L --line=1
+ # err -- starts on column 2
+void syntax_1_0_1()
+{
+# err -- not on line 1
+ # err -- same
+}
+} -returnCodes {error} -match regexp -result {.*1: L Error: # comment must start at first column
+.*4: L Error: # comment valid only on line 1
+.*5: L Error: # comment valid only on line 1
+}
+
+test syntax-1.1 {structure syntax} -body {
+#lang L --line=1 -nowarn
+
+struct syntax_1_1_point {
+ int x, y;
+ string label;
+ float froboz[128];
+ struct { int m, n; } sub_struct;
+};
+
+void syntax_1_1() {
+ struct { string firstname; string lastname; } him;
+ struct { string firstname; string lastname; } me = {"john", "doe"};
+ struct syntax_1_1_point p1, p2 = {
+ 1, 2, "label", {1.0}, {1,2} } , p3;
+ puts("didn't crash");
+}
+
+#lang tcl
+syntax_1_1
+} -output "didn't crash\n"
+
+test syntax-1.2 {interpolated strings} -body {
+#lang L --line=1
+void syntax_1_2()
+{
+ string s = "xxx";
+ int h{int} = { 1=>1, 3 => 4 };
+ int hh{int}{int} = { 2 => {1=>3,4=>5} };
+ string hs{string} = { "1" => "1" };
+
+ /* Check interpolations at beginning, middle, and end of a string. */
+ unless ("${s} start" eq "xxx start") puts("bad 1.1");
+ unless ("middle ${s} start" eq "middle xxx start") puts("bad 1.2");
+ unless ("end ${s}" eq "end xxx") puts("bad 1.3");
+ unless ("1${s}${s}2" eq "1xxxxxx2") puts("bad 1.4");
+ unless ("1${s} ${s}2" eq "1xxx xxx2") puts("bad 1.5");
+ unless ("1${s}2${s}3${s}" eq "1xxx2xxx3xxx") puts("bad 1.6");
+
+ /* Test that braces are counted properly within an interpolation. */
+ unless ("a${h{3}}b" eq "a4b") puts("bad 2.1");
+ unless ("a${hh{2}{4}}b" eq "a5b") puts("bad 2.2");
+ unless ("a${hh{2}{h{1}}}b" eq "a3b") puts("bad 2.4");
+ unless ("a${hh{2}{h{h{1}}}}b" eq "a3b") puts("bad 2.5");
+ unless ("a${hh{2}{h{h{h{1}}}}}b" eq "a3b") puts("bad 2.6");
+
+ /*
+ * These have a right brace after the right brace that ends the
+ * interpolation. The left and right braces are still balanced
+ * because the tcl test parsing dies if they are not, but L does
+ * not require it inside strings.
+ */
+ unless ("{a${h{3}}}b" eq "{a4}b") puts("bad 3.1");
+ unless ("{a${hh{2}{4}}}b" eq "{a5}b") puts("bad 3.2");
+ unless ("{a${hh{2}{h{1}}}}b" eq "{a3}b") puts("bad 3.4");
+ unless ("{a${hh{2}{h{h{1}}}}}b" eq "{a3}b") puts("bad 3.5");
+ unless ("{a${hh{2}{h{h{h{1}}}}}}b" eq "{a3}b") puts("bad 3.6");
+
+ /* Test nested interpolations. */
+ unless ("1 ${"3 ${s} 4"} 2" eq "1 3 xxx 4 2") puts("bad 4.1");
+ unless ("1 ${"3 ${"5 ${s} 6"} 4"} 2" eq "1 3 5 xxx 6 4 2") {
+ puts("bad 4.2");
+ }
+ unless ("1 ${"3 ${"5 ${"7 ${s} 8"} 6"} 4"} 2" eq "1 3 5 7 xxx 8 6 4 2") {
+ puts("bad 4.3");
+ }
+
+ /* Test that braces are counted properly in nested interpolations. */
+ unless ("a ${hs{"${1}"}} b" eq "a 1 b") puts("bad 5.1");
+ unless ("a ${hs{hs{"${1}"}}} b" eq "a 1 b") puts("bad 5.2");
+ unless ("a ${hs{hs{"${h{1}}"}}} b" eq "a 1 b") puts("bad 5.2");
+ unless ("a ${hs{hs{"${h{h{1}}}"}}} b" eq "a 1 b") puts("bad 5.3");
+ unless ("a ${hs{"${h{h{1}}}"}} b" eq "a 1 b") puts("bad 5.4");
+}
+syntax_1_2();
+} -output {}
+
+test syntax-1.2.1 {check string interpolations nested too deeply} -body {
+#lang L --line=1
+void syntax_1_2_1()
+{
+ "1${"2${"3${"4${"5${"6${"7${"8${"9${"10${"11${12}"}"}"}"}"}"}"}"}"}"}";
+}
+} -returnCodes {error} -match regexp -result {.*3: L Error: string interpolation nesting too deep -- aborting
+}
+
+test syntax-1.3 {tcl options short-cut} -body {
+#lang L --line=1
+private string args(...args)
+{
+ return(join(" ", args));
+}
+void syntax_1_3()
+{
+ /*
+ * Test the Tcl option syntax (option:), and specifically that
+ * it works even with reserved words. The scanner includes
+ * the colon when scanning these just for this reason.
+ */
+
+ unless (args(one:) eq "-one") puts("bad 1");
+ unless (args(one: "x") eq "-one x") puts("bad 2");
+ unless (args(one:,"x") eq "-one x") puts("bad 3");
+ unless (args(one: "x","y") eq "-one x y") puts("bad 4");
+ unless (args(one:,"x","y") eq "-one x y") puts("bad 5");
+ unless (args(one: "x", two:) eq "-one x -two") puts("bad 6");
+ unless (args(one:,"x", two:) eq "-one x -two") puts("bad 7");
+ unless (args(one:,"x", two: "y") eq "-one x -two y") puts("bad 8");
+ unless (args(one:,"x", two:,"y") eq "-one x -two y") puts("bad 9");
+ unless (args(one:, two:) eq "-one -two") puts("bad 10");
+ unless (args(one:, two:, three:) eq "-one -two -three") puts("bad 11");
+
+ unless (args(break:) eq "-break") puts("bad 20");
+ unless (args(case:) eq "-case") puts("bad 20.2");
+ unless (args(class:) eq "-class") puts("bad 21");
+ unless (args(constructor:) eq "-constructor") puts("bad 22");
+ unless (args(continue:) eq "-continue") puts("bad 23");
+ unless (args(default:) eq "-default") puts("bad 23.2");
+ unless (args(destructor:) eq "-destructor") puts("bad 24");
+ unless (args(do:) eq "-do") puts("bad 25");
+ unless (args(else:) eq "-else") puts("bad 26");
+ unless (args(eq:) eq "-eq") puts("bad 27");
+ unless (args(expand:) eq "-expand") puts("bad 28");
+ unless (args(extern:) eq "-extern") puts("bad 29");
+ unless (args(float:) eq "-float") puts("bad 30");
+ unless (args(for:) eq "-for") puts("bad 31");
+ unless (args(foreach:) eq "-foreach") puts("bad 32");
+ unless (args(ge:) eq "-ge") puts("bad 33");
+ unless (args(goto:) eq "-goto") puts("bad 34");
+ unless (args(gt:) eq "-gt") puts("bad 35");
+ unless (args(if:) eq "-if") puts("bad 36");
+ unless (args(instance:) eq "-instance") puts("bad 37");
+ unless (args(int:) eq "-int") puts("bad 38");
+ unless (args(le:) eq "-le") puts("bad 39");
+ unless (args(lt:) eq "-lt") puts("bad 40");
+ unless (args(ne:) eq "-ne") puts("bad 41");
+ unless (args(poly:) eq "-poly") puts("bad 42");
+ unless (args(private:) eq "-private") puts("bad 43");
+ unless (args(public:) eq "-public") puts("bad 44");
+ unless (args(return:) eq "-return") puts("bad 45");
+ unless (args(split:) eq "-split") puts("bad 46");
+ unless (args(string:) eq "-string") puts("bad 47");
+ unless (args(struct:) eq "-struct") puts("bad 48");
+ unless (args(switch:) eq "-switch") puts("bad 48.2");
+ unless (args(typedef:) eq "-typedef") puts("bad 49");
+ unless (args(unless:) eq "-unless") puts("bad 50");
+ unless (args(void:) eq "-void") puts("bad 51");
+ unless (args(while:) eq "-while") puts("bad 52");
+}
+syntax_1_3();
+} -output {}
+
+test syntax-1.4 {string appendation} -body {
+#lang L --line=1
+void syntax_1_4() {
+ printf("these" "strings"
+ "stick" "together.\n");
+}
+#lang tcl
+syntax_1_4
+} -output "thesestringssticktogether.\n"
+
+test errmsg-1 {check cascading err msg avoidance, local var} -body {
+#lang L --line=1
+void errmsg_1()
+{
+ errmsg_1_i = 0;
+ ++errmsg_1_i;
+ ++errmsg_1_i;
+ ++errmsg_1_i;
+}
+int errmsg_1_i; // should *not* produce a multiply declared variable err
+} -returnCodes {error} -match regexp -result {^.*3: L Error: undeclared variable: errmsg_1_i
+\s*$}
+
+test errmsg-2 {check cascading err msg avoidance, global var} -body {
+#lang L --line=1
+++errmsg_2_g;
+++errmsg_2_g;
+++errmsg_2_g;
+int errmsg_2_g; // should *not* produce a multiply declared variable err
+} -returnCodes {error} -match regexp -result {^.*1: L Error: undeclared variable: errmsg_2_g
+\s*$}
+
+test errmsg-3 {check cascading err msg avoidance, class var} -body {
+#lang L --line=1
+class errmsg_3
+{
+ private int v1 = errmsg_3_undecl1+1;
+ public int errmsg_3_undecl1;
+ private int v2 = errmsg_3_undecl1+1;
+
+ private int v3 = errmsg_3_undecl2+1;
+ private int v4 = errmsg_3_undecl2+1;
+ public int errmsg_3_undecl2;
+ private int v5 = errmsg_3_undecl2+1;
+}
+int errmsg_3_undecl1;
+int errmsg_3_undecl2;
+} -returnCodes {error} -match regexp -result {^.*3: L Error: undeclared variable: errmsg_3_undecl1
+[^\n]+7: L Error: undeclared variable: errmsg_3_undecl2
+\s*$}
+
+test errmsg-4 {check cascading err msg avoidance, class instance var} -body {
+#lang L --line=1
+class errmsg_4
+{
+ instance {
+ private int v1 = errmsg_4_undecl1+1;
+ public int errmsg_4_undecl1;
+ private int v2 = errmsg_4_undecl1+1;
+
+ private int v3 = errmsg_4_undecl2+1;
+ private int v4 = errmsg_4_undecl2+1;
+ public int errmsg_4_undecl2;
+ private int v5 = errmsg_4_undecl2+1;
+ };
+}
+int errmsg_4_undecl1;
+int errmsg_4_undecl2;
+} -returnCodes {error} -match regexp -result {^.*4: L Error: undeclared variable: errmsg_4_undecl1
+[^\n]+8: L Error: undeclared variable: errmsg_4_undecl2
+\s*$}
+
+test op-1.0 {increment and decrement operators} -body {
+#lang L --line=1
+void op_1_0() {
+ int i = 1;
+
+ puts("pre:");
+ puts(i);
+ ++i;
+ puts(i);
+ puts(++i);
+ --i;
+ puts(i);
+ puts(--i);
+
+ puts("post:");
+ puts(i);
+ i++;
+ puts(i);
+ puts(i++);
+ puts(i);
+ i--;
+ puts(i);
+ puts(i--);
+ puts(i);
+}
+#lang tcl
+op_1_0
+} -output "pre:\n1\n2\n3\n2\n1\npost:\n1\n2\n2\n3\n2\n2\n1\n"
+
+test op-1.0.1 {increment and decrement operator side effects} -body {
+#lang L --line=1
+class op_1_0_1_cls
+{
+ instance { public int n; }
+}
+void op_1_0_1()
+{
+ /*
+ * This test checks that the argument to ++ or -- is evaluated
+ * exactly once.
+ */
+
+ int i;
+ int a[];
+ op_1_0_1_cls o[] = { op_1_0_1_cls_new(), op_1_0_1_cls_new() };
+
+ i = 0;
+ a[0] = 13;
+ ++(a[i++]);
+ unless ((i == 1) && (a[0] == 14)) puts("bad 1");
+
+ i = 0;
+ a[0] = 13;
+ (a[i++])++;
+ unless ((i == 1) && (a[0] == 14)) puts("bad 2");
+
+ i = 0;
+ o[0]->n = 13;
+ o[1]->n = 13;
+ ++(o[i++]->n);
+ unless ((i == 1) && (o[0]->n == 14)) puts("bad 3");
+ unless (o[1]->n == 13) puts("bad 3.1");
+
+ i = 0;
+ o[0]->n = 13;
+ o[1]->n = 13;
+ (o[i++]->n)++;
+ unless ((i == 1) && (o[0]->n == 14)) puts("bad 4");
+ unless (o[1]->n == 13) puts("bad 4.1");
+}
+op_1_0_1();
+} -output {}
+
+test op-1.1 {plus, minus, multiply, divide, and modulus operators} -body {
+#lang L --line=1
+void op_1_1() {
+ int i = 2;
+ puts(i + 5);
+ puts(i - 50);
+ puts(i * 500);
+ puts(i / 2);
+ puts(i / 4.0);
+ puts((i + 5) % 3);
+ // precedence
+ puts(i + i / i - i * i % i);
+}
+#lang tcl
+op_1_1
+} -output "7\n-48\n1000\n1\n0.5\n1\n3\n"
+
+test op-1.2 {unary plus and minus} -body {
+#lang L --line=1
+void op_1_2() {
+ int i = -2;
+ int j = +2;
+
+ puts(i);
+ i = i + -100;
+ puts(i);
+ puts(i * -3);
+ puts(-8 - -2);
+
+ puts(j);
+ j = j + +100;
+ puts(j);
+ puts(j * +3);
+ puts(+8 - +2);
+}
+#lang tcl
+op_1_2
+} -output "-2\n-102\n306\n-6\n2\n102\n306\n6\n"
+
+test op-1.3.1 {numeric comparison operators} -body {
+#lang L --line=1
+void op_1_3_1()
+{
+ unless (-1 < 1) puts("bad 1.1");
+ unless (1 > -1) puts("bad 1.2");
+ unless (1 == 1) puts("bad 1.3");
+ unless (1 <= 1) puts("bad 1.4");
+ unless (-1 <= 1) puts("bad 1.5");
+ unless (1 >= -1) puts("bad 1.6");
+ unless (1 >= 0) puts("bad 1.7");
+ unless (0 != 1) puts("bad 1.8");
+
+ if (1 < 1) puts("bad 2.1");
+ if (1 > 1) puts("bad 2.2");
+ if (1 == 0) puts("bad 2.3");
+ if (1 != 1) puts("bad 2.4");
+ if (1 <= -1) puts("bad 2.5");
+ if (-1 >= 1) puts("bad 2.6");
+
+ // Verify that these are numeric compares, not lexicographic.
+ unless ((int)"1" == (int)"01") puts("bad 3.1");
+ if ((int)"1" != (int)"01") puts("bad 3.2");
+ if ((int)"1" > (int)"01") puts("bad 3.3");
+ if ((int)"01" < (int)"1") puts("bad 3.4");
+ if ((int)" 2" <= (int)"1") puts("bad 3.5"); // note: it's space 2
+ if ((int)"1" >= (int)" 2") puts("bad 3.6");
+ unless ((int)"00" == (int)"0") puts("bad 3.7");
+}
+op_1_3_1();
+} -output {}
+
+test op-1.3.2 {string comparison operators} -body {
+#lang L --line=1
+void op_1_3_2()
+{
+ if ("0" == "00") puts("bad 1.1");
+ if ("1" == "01") puts("bad 1.2");
+ if (" 1" == "1") puts("bad 1.3");
+
+ unless ("0" < "1") puts("bad 2.1");
+ unless ("a" < "b") puts("bad 2.2");
+ unless ("2" > "1") puts("bad 2.3");
+ unless (" 2" < "1") puts("bad 2.4");
+ unless ("b" > "a") puts("bad 2.5");
+
+ unless ("0" <= "0") puts("bad 3.1");
+ unless ("0" <= "1") puts("bad 3.2");
+ unless ("a" <= "a") puts("bad 3.3");
+ unless ("a" <= "b") puts("bad 3.4");
+ unless ("1" >= "1") puts("bad 3.5");
+ unless ("2" >= "1") puts("bad 3.6");
+ unless ("a" >= "a") puts("bad 3.7");
+ unless ("b" >= "a") puts("bad 3.8");
+}
+op_1_3_2();
+} -output {}
+
+test op-1.3.3 {composite equality operator} -body {
+#lang L --line=1
+void op_1_3_3()
+{
+ string as1[], as2[];
+ int ai1[], ai2[];
+ string hs1{string}, hs2{string};
+ int hi1{string}, hi2{string};
+ string{string} ahs1[], ahs2[];
+ struct {
+ string a;
+ string b;
+ } sts1, sts2;
+ struct {
+ int a;
+ int b;
+ } sti1, sti2;
+
+ /*
+ * Cases to test:
+ * - Type contains only strings.
+ * - Type contains non-strings and that a numeric compare is done.
+ * - Array or hash w/same size, but same or different elts.
+ * - Array or hash that differs in size (w/fewer or greater elts).
+ */
+
+ as1 = { "one", "two", "three" };
+ as2 = { "one", "two", "three" };
+ unless (eq(as1,as2)) puts("bad 1.1");
+ as2 = { "one", "two" };
+ if (eq(as1,as2)) puts("bad 1.2");
+ as2 = { "one", "two", "three", "four" };
+ if (eq(as1,as2)) puts("bad 1.3");
+ as2 = { "one", "two", "four" };
+ if (eq(as1,as2)) puts("bad 1.4");
+
+ ai1 = { 1, 2, 3 };
+ ai2 = { 1, 2, 3 };
+ unless (eq(ai1,ai2)) puts("bad 2.1");
+ ai2 = { 1, 2 };
+ if (eq(ai1,ai2)) puts("bad 2.2");
+ ai2 = { 1, 2, 3, 4 };
+ if (eq(ai1,ai2)) puts("bad 2.3");
+ ai2 = { 1, 2, 4 };
+ if (eq(ai1,ai2)) puts("bad 2.4");
+ /* Check that a numeric compare is done. */
+ ai2 = (poly)"01 2 003";
+ unless (eq(ai1,ai2)) puts("bad 2.5");
+
+ hs1 = { "k1"=>"v1", "k2"=>"v2", "k3"=>"v3" };
+ hs2 = { "k1"=>"v1", "k2"=>"v2", "k3"=>"v3" };
+ unless (eq(hs1,hs2)) puts("bad 10.1");
+ hs2 = { "k1"=>"v1", "k2"=>"v2" };
+ if (eq(hs1,hs2)) puts("bad 10.2");
+ hs2 = { "k1"=>"v1", "k2"=>"v2", "k3"=>"v3", "k4"=>"v4" };
+ if (eq(hs1,hs2)) puts("bad 10.3");
+ hs2 = { "k1"=>"v1", "k2"=>"v2", "k4"=>"v4" };
+ if (eq(hs1,hs2)) puts("bad 10.4");
+
+ hi1 = { "1"=>1, "2"=>2, "3"=>3 };
+ hi2 = { "1"=>1, "2"=>2, "3"=>3 };
+ unless (eq(hi1,hi2)) puts("bad 11.1");
+ hi2 = { "1"=>1, "2"=>2, "3"=>3, "4"=>4 };
+ if (eq(hi1,hi2)) puts("bad 11.2");
+ hi2 = { "1"=>1, "2"=>2 };
+ if (eq(hi1,hi2)) puts("bad 11.3");
+ hi2 = { "1"=>1, "2"=>2, "4"=>4 };
+ if (eq(hi1,hi2)) puts("bad 11.4");
+ /* Check that a numeric compare is done. */
+ hi2 = (poly)"1 01 2 2 3 003";
+ unless (eq(hi1,hi2)) puts("bad 11.5");
+
+ sts1 = { "a", "b" };
+ sts2 = { "a", "b" };
+ unless (eq(sts1,sts2)) puts("bad 20.1");
+ sts2 = { "a", "c" };
+ if (eq(sts1,sts2)) puts("bad 20.1");
+
+ sti1 = { 1, 2 };
+ sti2 = { 1, 2 };
+ unless (eq(sti1,sti2)) puts("bad 21.1");
+ sti2 = { 1, 3 };
+ if (eq(sti1,sti2)) puts("bad 21.2");
+ /* Check that a numeric compare is done. */
+ sti2 = (poly)"01 002";
+ unless (eq(sti1,sti2)) puts("bad 21.3");
+
+ /*
+ * More cases (prompted by bugs):
+ * - hash w/underlying dict elements added in different order
+ * - two hashes w/same key but different value
+ */
+
+ hs1 = { "k1"=>"v1", "k2"=>"v2" };
+ hs2 = { "k2"=>"v2", "k1"=>"v1" };
+ unless (eq(hs1,hs2)) puts("bad 22.1");
+
+ hs1 = { "k"=>"v1" };
+ hs2 = { "k"=>"v2" };
+ if (eq(hs1,hs2)) puts("bad 22.2");
+
+ push(&ahs1, hs1);
+ push(&ahs1, hs2);
+ push(&ahs2, hs1);
+ push(&ahs2, hs2);
+ unless (eq(ahs1,ahs2)) puts("bad 23.1");
+}
+op_1_3_3();
+} -output {}
+
+test op-1.3.4 {composite equality operator 2} -body {
+#lang L --line=1
+void op_1_3_4()
+{
+ /*
+ * Test a composite type w/numerics that contains a composite
+ * type without them. The outer type must be compared element
+ * by element but the inner type can be compared with a single
+ * string comparison of its string rep.
+ */
+
+ struct {
+ int i;
+ struct {
+ string a[];
+ string b[];
+ } st;
+ int j;
+ } st1, st2;
+
+ st1 = { 1, { {"a","b"}, {"c","d"} }, 2 };
+ st2 = { 1, { {"a","b"}, {"c","d"} }, 2 };
+ unless (eq(st1,st2)) puts("bad 1.1");
+
+ st1 = { 1, { {"a","b"}, {"c","d"} }, 2 };
+ st2 = { 1, { {"a","b"}, {"c","e"} }, 2 };
+ if (eq(st1,st2)) puts("bad 1.2");
+
+ st1 = { 1, { {"a","b"}, {"c","d"} }, 2 };
+ st2 = { 1, { {"a","b"}, {"c","d"} }, 3 };
+ if (eq(st1,st2)) puts("bad 1.3");
+
+ st1 = { 1, { {"a","b"}, {"c","d"} }, 2 };
+ st2 = (poly)"1 {{a b} {c d}} 2";
+ unless (eq(st1,st2)) puts("bad 1.4");
+}
+op_1_3_4();
+} -output {}
+
+test op-1.3.5 {composite comparison errors} -body {
+#lang L --line=1
+void op_1_3_5()
+{
+ string sa[];
+ string ha{string};
+ struct {
+ int i, j;
+ } st;
+
+ sa != sa;
+ sa < sa;
+ sa <= sa;
+ sa > sa;
+ sa >= sa;
+
+ ha != ha;
+ ha < ha;
+ ha <= ha;
+ ha > ha;
+ ha >= ha;
+
+ st != st;
+ st < st;
+ st <= st;
+ st > st;
+ st >= st;
+}
+} -returnCodes {error} -match regexp -result {.*9: L Error: only eq\(\) allowed on non-scalar types
+.*10: L Error: only eq\(\) allowed on non-scalar types
+.*11: L Error: only eq\(\) allowed on non-scalar types
+.*12: L Error: only eq\(\) allowed on non-scalar types
+.*13: L Error: only eq\(\) allowed on non-scalar types
+.*15: L Error: only eq\(\) allowed on non-scalar types
+.*16: L Error: only eq\(\) allowed on non-scalar types
+.*17: L Error: only eq\(\) allowed on non-scalar types
+.*18: L Error: only eq\(\) allowed on non-scalar types
+.*19: L Error: only eq\(\) allowed on non-scalar types
+.*21: L Error: only eq\(\) allowed on non-scalar types
+.*22: L Error: only eq\(\) allowed on non-scalar types
+.*23: L Error: only eq\(\) allowed on non-scalar types
+.*24: L Error: only eq\(\) allowed on non-scalar types
+.*25: L Error: only eq\(\) allowed on non-scalar types
+}
+
+test op-1.4 {lexicographic comparison operators} -body {
+#lang L --line=1
+void op_1_4() {
+ // These operators are now obsolete, but with the _L_ALLOW_EQ_OPS env
+ // variable set, the compiler will allow them.
+
+ if ("aa" lt "ab") { puts("1okay"); } else { puts("1broken"); }
+ if ("ab" gt "aa") { puts("2okay"); } else { puts("2broken"); }
+ if ("aa" eq "aa") { puts("3okay"); } else { puts("3broken"); }
+ if ("aa" le "aa") { puts("4okay"); } else { puts("4broken"); }
+ if ("aa" le "ab") { puts("5okay"); } else { puts("5broken"); }
+ if ("aa" ge "aa") { puts("6okay"); } else { puts("6broken"); }
+ if ("ab" ge "aa") { puts("7okay"); } else { puts("7broken"); }
+ if ("aa" ne "ab") { puts("8okay"); } else { puts("8broken"); }
+ // now from the other side
+ puts("--");
+ if ("aa" lt "aa") { puts("1broken"); } else { puts("1okay"); }
+ if ("aa" gt "aa") { puts("2broken"); } else { puts("2okay"); }
+ if ("ab" eq "aa") { puts("3broken"); } else { puts("3okay"); }
+ if ("aa" ne "aa") { puts("4broken"); } else { puts("4okay"); }
+ if ("ab" le "aa") { puts("5broken"); } else { puts("5okay"); }
+ if ("aa" ge "ab") { puts("6broken"); } else { puts("6okay"); }
+
+ // Verify that these do not use Tcl's numeric compare.
+ // These are exactly the opposite tests to those at the end of
+ // op-1.3 above.
+ if ("1" eq "01") puts("bad 1");
+ unless ("1" ne "01") puts("bad 2");
+ unless ("1" gt "01") puts("bad 3");
+ unless ("01" lt "1") puts("bad 4");
+ unless (" 2" le "1") puts("bad 5");
+ unless ("1" ge " 2") puts("bad 6");
+}
+#lang tcl
+op_1_4
+} -output "1okay\n2okay\n3okay\n4okay\n5okay\n6okay\n7okay\n8okay
+--\n1okay\n2okay\n3okay\n4okay\n5okay\n6okay\n"
+
+
+test op-1.5 {boolean operators} -body {
+#lang L --line=1
+void op_1_5() {
+ int true = 1, false = 0;
+ if (true && true) { puts("1okay"); } else { puts("1broken"); }
+ if (!false) { puts("2okay"); } else { puts("2broken"); }
+ if (false || true) { puts("3okay"); } else { puts("3broken"); }
+ if (true && !false) { puts("4okay"); } else { puts("4broken"); }
+ // && has higher precedence than ||
+ if (false && false || true) { puts("5okay"); } else { puts("5broken"); }
+ // now from the other side
+ puts("--");
+ if (true && !true) { puts("1broken"); } else { puts("1okay"); }
+ if (false || false) { puts("2broken"); } else { puts("2okay"); }
+ if (!true) { puts("3broken"); } else { puts("3okay"); }
+
+}
+#lang tcl
+op_1_5
+} -output "1okay\n2okay\n3okay\n4okay\n5okay\n--\n1okay\n2okay\n3okay\n"
+
+
+test op-1.6 {bitwise operators} -body {
+#lang L --line=1
+void op_1_6(){
+ int bits = 715827882;
+
+ puts(bits << 1);
+ puts(bits >> 1);
+ puts(bits >> 29);
+ puts(-1 << 10);
+ puts(-1024 >> 9);
+ puts(~bits);
+ puts(bits & ~bits);
+ puts(bits | ~bits);
+ puts(bits ^ (bits + 1));
+
+}
+#lang tcl
+op_1_6
+} -output "1431655764\n357913941\n1\n-1024\n-2\n-715827883\n0\n-1\n1\n"
+
+
+test op-1.7 {logical operator short-circuiting} -body {
+#lang L --line=1
+int
+puts_int(string str) {
+ puts(str);
+ return 9;
+}
+void op_1_7(){
+ puts(0 && puts_int("1"));
+ puts(1 && puts_int("2"));
+ puts(0 || puts_int("3"));
+ puts(1 || puts_int("4"));
+}
+#lang tcl
+op_1_7
+} -output "0\n2\n9\n3\n9\n1\n"
+
+test op-1.8 {compound assignment operators, simple lvalues} -body {
+#lang L --line=1
+void op_1_8() {
+ int foo = 0;
+
+ puts(foo += 2);
+ puts(foo);
+ puts(foo -= 3);
+ puts(foo);
+ puts(foo *= 4);
+ puts(foo);
+ puts(foo /= -2);
+ puts(foo);
+ foo = 17;
+ puts(foo %= 7);
+ puts(foo);
+ puts(foo |= 9);
+ puts(foo);
+ puts(foo &= 8);
+ puts(foo);
+ puts(foo ^= 9);
+ puts(foo);
+ puts(foo <<= 3);
+ puts(foo);
+ puts(foo >>= 2);
+ puts(foo);
+}
+#lang tcl
+op_1_8
+} -output "2\n2\n-1\n-1\n-4\n-4\n2\n2\n3\n3\n11\n11\n8\n8\n1\n1\n8\n8\n2\n2\n"
+
+test op-1.9 {compound assignment operators, array lvalues} -body {
+#lang L --line=1
+void op_1_9() {
+ int foo[4] = {0,0,0,0};
+
+ puts(foo[2] += 2);
+ puts(foo[2]);
+ puts(foo[2] -= 3);
+ puts(foo[2]);
+ puts(foo[2] *= 4);
+ puts(foo[2]);
+ puts(foo[2] /= -2);
+ puts(foo[2]);
+ foo[2] = 17;
+ puts(foo[2] %= 7);
+ puts(foo[2]);
+ puts(foo[2] |= 9);
+ puts(foo[2]);
+ puts(foo[2] &= 8);
+ puts(foo[2]);
+ puts(foo[2] ^= 9);
+ puts(foo[2]);
+ puts(foo[2] <<= 3);
+ puts(foo[2]);
+ puts(foo[2] >>= 2);
+ puts(foo[2]);
+ puts(foo);
+}
+#lang tcl
+op_1_9
+} -output "2\n2\n-1\n-1\n-4\n-4\n2\n2\n3\n3\n11\n11\n8\n8\n1\n1\n8\n8\n2\n2\n0 0 2 0\n"
+
+test op-1.10 {short-circuit conditionals} -body {
+#lang L --line=1
+void op_1_10()
+{
+ /*
+ * Ensure that conditionals of type string are tested properly
+ * in the short-circuited operators (i.e., tested for defined).
+ */
+
+ int i = 0, j;
+ string s;
+
+ if (s && ++i) j = 1;
+ unless (i == 0) puts("bad 1");
+
+ if (s || ++i) j = 1;
+ unless (i == 1) puts("bad 2");
+}
+#lang tcl
+op_1_10
+} -output {}
+
+test op-1.11 {comma operator} -body {
+#lang L --line=1 -nowarn
+int op_1_11_f(int a, int b, int c) { return (b); }
+string op_1_11_s(string a, string b, string c, string d)
+{
+ return ((string)concat(a,b,c,d));
+}
+void op_1_11()
+{
+ /*
+ * Check precedence and associativity of comma operator.
+ * Should be the lowest and left associative, and not get
+ * confused with comma as an arg seperator. Also check that
+ * the value of a,b is b.
+ */
+
+ int i;
+ int j = 2, k = 0; // declares j & k; is not a comma op
+ int l = (1,2), m = (1,2,3,4,5);
+ string s;
+
+ unless ((j == 2) && (k == 0)) puts("bad d1");
+ unless (l == 2) puts("bad d2");
+ unless (m == 5) puts("bad d3");
+
+ i = 1,2;
+ unless (i == 1) puts("bad 1");
+ unless ((i = 1,2) == 2) puts("bad 2");
+ unless (op_1_11_f(1, 2, 3) == 2) puts("bad 3");
+ unless (op_1_11_f(1, (2,3), 4) == 3) puts("bad 4");
+ unless (op_1_11_s("a", "b", kw:"d") eq "a b -kw d") puts("bad 5");
+ unless (op_1_11_s("a", kw:"b", "c") eq "a -kw b c") puts("bad 6");
+ unless (op_1_11_s(kw:"a", "b", "c") eq "-kw a b c") puts("bad 7");
+ unless (op_1_11_s("a", ("b","c"), kw: "d") eq "a c -kw d") {
+ puts("bad 8");
+ }
+
+ i = (1,2,3);
+ unless (i == 3) puts("bad 10");
+ i = (1,2,3,4);
+ unless (i == 4) puts("bad 11");
+ i = (1,2),(3,4);
+ unless (i == 2) puts("bad 12");
+ i = ((1,2),(3,4));
+ unless (i == 4) puts("bad 13");
+
+ /*
+ * Check that the type of a,b is the type of b.
+ */
+ i = ("s", 11);
+ unless (i == 11) puts("bad t1");
+ s = (1, "s");
+ unless (s eq "s") puts("bad t2");
+
+ /*
+ * For loops should just automatically get the use of comma op.
+ */
+ i = j = -1;
+ for (i=0,j=10; i < 10; ++i,j+=10) ;
+ unless ((i == 10) && (j == 110)) puts("bad f1");
+}
+#lang tcl
+op_1_11
+} -output {}
+
+test op-1.12 {test string concat operator} -body {
+#lang L --line=1
+void op_1_12()
+{
+ string a, b, c;
+ string as[];
+ string hs{string};
+ widget w;
+ poly p;
+ struct {
+ string a, b, c;
+ } st;
+
+ unless ("a" . "b" eq "ab") puts("bad 1.1");
+ unless ("ab" . "cd" eq "abcd") puts("bad 1.2");
+ unless ("ab" . "cd" . "ef" eq "abcdef") puts("bad 1.3");
+ unless ("ab" . "cd" . "ef" . "gh" eq "abcdefgh") puts("bad 1.4");
+ unless ("" . "a" eq "a") puts("bad 1.5");
+ unless ("a" . "" eq "a") puts("bad 1.6");
+ unless ("" . "a" . "" eq "a") puts("bad 1.7");
+ unless ("" . "" . """" . "a" . "" eq "a") puts("bad 1.8");
+ unless ("" . "" eq "") puts("bad 1.9");
+ unless ("" . "" . "" eq "") puts("bad 1.10");
+
+ a = "a";
+ b = "b";
+ c = "c";
+ unless (a . b . c eq "abc") puts("bad 2.1");
+
+ p = "a";
+ unless (p . "b" eq "ab") puts("bad 3.1");
+
+ /* Test precedence. "." should be lower than [], {}, and -> */
+
+ as[0] = "a";
+ as[1] = "b";
+ as[2] = "c";
+ unless (as[0] . as[1] . as[2] eq "abc") puts("bad 10.1");
+ hs{"a"} = "a";
+ hs{"b"} = "b";
+ hs{"c"} = "c";
+ unless (hs{"a"} . hs{"b"} . hs{"c"} eq "abc") puts("bad 10.2");
+ st.a = "a";
+ st.b = "b";
+ st.c = "c";
+ unless (st.a . st.b . st.c eq "abc") puts("bad 10.3");
+
+ /* Check varying whitespace around the "." */
+
+ unless ("a" . "b" eq "ab") puts("bad 20.1");
+ unless ("a" . "b" eq "ab") puts("bad 20.2");
+ unless ("a" . "b" eq "ab") puts("bad 20.3");
+ unless ("a" . "b" eq "ab") puts("bad 20.4"); // tab
+ unless ("a" . "b" eq "ab") puts("bad 20.5"); // tab
+ unless ("a" .
+ "b" eq "ab") puts("bad 20.6");
+ unless ("a"
+ . "b" eq "ab") puts("bad 20.7");
+ unless ("a" .
+ "b" .
+ "c" eq "abc") puts("bad 20.8");
+
+ /* Check .= */
+
+ a = "a";
+ a .= "bcd";
+ unless (a eq "abcd") puts("bad 30.1");
+ b = "e";
+ unless ((a.=b) eq "abcde") puts("bad 30.2");
+
+ as[0] = "0";
+ as[0] .= "123";
+ unless (as[0] eq "0123") puts("bad 31.1");
+
+ a = "0234";
+ a[0] .= "1";
+ unless (a eq "01234") puts("bad 32.1");
+
+ /* String and widget should both work. */
+
+ a = "a";
+ w = "w";
+ unless ((a . w) eq "aw") puts("bad 33.1");
+ unless ((w . a) eq "wa") puts("bad 33.2");
+ unless ((w . w) eq "ww") puts("bad 33.3");
+
+ a .= w;
+ unless (a eq "aw") puts("bad 34.1");
+ a = "a";
+ w .= a;
+ unless (w eq "wa") puts("bad 34.2");
+ w = "w";
+ w .= w;
+ unless (w eq "ww") puts("bad 34.3");
+
+ w = "abc";
+ unless (w =~ /b/) puts("bad 35.1");
+ w =~ s/ab/x/;
+ unless (w eq "xc") puts("bad 35.2");
+}
+op_1_12();
+} -output {}
+
+test op-1.13 {test string concat type errors} -body {
+#lang L --line=1
+void op_1_13()
+{
+ int i, j;
+ string s;
+ float f;
+ int h{string};
+
+ i . j;
+ i . f;
+ h{"bad"} . i;
+ i . "s";
+ "s" . f;
+ h{"bad"} . "s";
+
+ i .= "s";
+ i .= j;
+ s .= i;
+}
+} -returnCodes {error} -match regexp -result {.*8: L Error: expected type string.*
+.*9: L Error: expected type string.*
+.*10: L Error: expected type string.*
+.*11: L Error: expected type string.*
+.*12: L Error: expected type string.*
+.*13: L Error: expected type string.*
+.*15: L Error: expected type string.*
+.*16: L Error: expected type string.*
+.*17: L Error: assignment of incompatible types
+}
+
+test op-1.14 {test "." and "->" as struct selection operators} -body {
+#lang L --line=1
+struct op14 {
+ int i, j;
+ struct {
+ int k;
+ } s;
+};
+void op_1_14_ref(struct op14 &st)
+{
+ st->i = 7;
+ st->s.k = 8;
+}
+void op_1_14_val(struct op14 st)
+{
+ st.i = 8;
+ st.s.k = 9;
+}
+void op_1_14()
+{
+ struct op14 st = { 5, 6, {7} };
+
+ unless (st.i == 5) puts("bad 1.1");
+ unless (st.j == 6) puts("bad 1.2");
+
+ op_1_14_ref(&st);
+ unless (st.i == 7) puts("bad 2.1");
+ unless (st.s.k == 8) puts("bad 2.2");
+
+ op_1_14_val(st);
+ unless (st.i == 7) puts("bad 3.1");
+ unless (st.s.k == 8) puts("bad 3.2");
+}
+op_1_14();
+} -output {}
+
+test op-1.15 {check "." and "->" usage errors} -body {
+#lang L --line=1
+struct op15 {
+ int i, j;
+ struct {
+ int k;
+ } s;
+};
+void op_1_15_ref(struct op14 &st)
+{
+ st.i = 7; // err
+ st->s->k = 8; // the ->k part is an err
+}
+void op_1_15_val(struct op14 st)
+{
+ st->i = 8; // err
+}
+void op_1_15()
+{
+ struct op14 st;
+
+ st->i = st.j; // st->i is an err
+}
+} -returnCodes {error} -match regexp -result {.*9: L Error: \. illegal on call-by-reference parms; use -> instead
+.*10: L Error: -> illegal except on call-by-reference parms; use \. instead
+.*14: L Error: -> illegal except on call-by-reference parms; use \. instead
+.*20: L Error: -> illegal except on call-by-reference parms; use \. instead
+}
+
+test op-1.16 {check ? : operator} -body {
+#lang L --line=1
+string op_1_16_f(...args) { return (join("", args)); }
+void op_1_16()
+{
+ int i;
+ float f;
+ string s;
+
+ /* Check spacing variations. */
+
+ s = "bad";
+ 0 ? puts("bad 1.1") : (s = "good");
+ unless (s eq "good") puts("bad 1.2");
+
+ s = "bad";
+ 0? puts("bad 2.1") : (s = "good");
+ unless (s eq "good") puts("bad 2.2");
+
+ s = "bad";
+ 0?puts("bad 3.1") : (s = "good");
+ unless (s eq "good") puts("bad 3.2");
+
+ s = "bad";
+ 0?puts("bad 4.1"): (s = "good");
+ unless (s eq "good") puts("bad 4.2");
+
+ s = "bad";
+ 0?puts("bad 5.1"):(s = "good");
+ unless (s eq "good") puts("bad 5.2");
+
+ s = "bad";
+ 1 ? (s = "good") : puts("bad 6.1");
+ unless (s eq "good") puts("bad 6.2");
+
+ /* Check that id: parses properly. */
+
+ i = 0;
+ unless ((1?i:1) == 0) puts("bad 6.3");
+
+ /* Exactly one of the expressions must ever be executed. */
+
+ i = 0;
+ 0 ? ++i : ++i;
+ unless (i == 1) puts("bad 7.1");
+ i = 0;
+ 1 ? ++i : ++i;
+ unless (i == 1) puts("bad 7.2");
+
+ /* Check value. */
+
+ s = 0 ? "bad" : "good";
+ unless (s eq "good") puts("bad 10.1");
+
+ s = 1 ? "good" : "bad";
+ unless (s eq "good") puts("bad 11.1");
+
+ /*
+ * Check typing. If either expr is a float and the other is compatible
+ * with that, we get a float. If either is a poly, we get a poly.
+ */
+
+ f = 0 ? 0 : 3.14;
+ unless (f == 3.14) puts("bad 12.1");
+ f = 1 ? 6.28 : 0;
+ unless (f == 6.28) puts("bad 12.2");
+ f = 1 ? 1.11 : 0.0;
+ unless (f == 1.11) puts("bad 12.3");
+ f = 1 ? 12 : -1;
+ unless (f == 12) puts("bad 12.4");
+
+ s = "bad";
+ s = 0 ? "bad" : (poly)13;
+ unless (s eq "13") puts("bad 12.5");
+ s = "bad";
+ s = 1 ? (poly)13 : "bad";
+ unless (s eq "13") puts("bad 12.6");
+
+ /*
+ * Check precedence -- ? : should be between = and || in the
+ * precedence hierarchy.
+ */
+ i = 1 ? 1 || puts("bad 20.1") : 1 || puts("bad 20.2");
+
+ /* Should have no confusion with the opt: argument syntax. */
+ s = op_1_16_f(o1: 0 ? "bad": "good", o2: "3");
+ unless (s eq "-o1good-o23") puts("bad 20.3");
+
+ /*
+ * This checks that the run-time stack is kept balanced when
+ * the value of the ternary expression is ignored (if it's
+ * not, we'll probably crash).
+ */
+ for (i = 0; i < 10000; ++i) {
+ 0 ? 1 : 2;
+ (0 ? 1 : 2) , (0 ? 1 : 2);
+ }
+
+ /* Try some nested ?: */
+ i = 0 ? 1 ? 11:12 : 13;
+ unless(i == 13) puts("bad 30.1");
+ i = 1 ? 1 ? 11:12 : 13;
+ unless(i == 11) puts("bad 30.2");
+ i = 1 ? 0 ? 11:12 : 13;
+ unless(i == 12) puts("bad 30.3");
+}
+op_1_16();
+} -output {}
+
+test op-1.17 {check type errors in ? : operator} -body {
+#lang L --line=1
+void op_1_17()
+{
+ int i;
+ float f;
+ string s;
+
+ s = 0 ? 1 : 2;
+ i = 0 ? "a" : "b";
+ f = 0 ? "a" : "b";
+
+ /* The type of these ?: is float. */
+ i = 0 ? f : i;
+ i = 0 ? i : f;
+ i = 0 ? f : f;
+
+ /* These have exprs with incompatible types. */
+ s = 0 ? 1 : "2";
+ s = 0 ? "1" : 2;
+}
+} -returnCodes {error} -match regexp -result {.*7: L Error: assignment of incompatible types
+.*8: L Error: assignment of incompatible types
+.*9: L Error: assignment of incompatible types
+.*12: L Error: assignment of incompatible types
+.*13: L Error: assignment of incompatible types
+.*14: L Error: assignment of incompatible types
+.*17: L Error: incompatible types in \? : expressions
+.*18: L Error: incompatible types in \? : expressions
+}
+
+test cast-1.0 { Casts to integer and float } -body {
+#lang L --line=1
+void cast_1_0() {
+ printf("%d\n", (int)1.9);
+ printf("%f\n", (float)5);
+ (int)1.9;
+ (float)5;
+}
+#lang tcl
+cast_1_0
+} -output "1\n5.000000\n"
+
+test cast-1.1 {invalid casts from string to int or float} -body {
+#lang L --line=1
+void cast_1_1()
+{
+ if (defined((int)"asdf")) puts("bad 1");
+ if (defined((float)"asdf")) puts("bad 2");
+}
+cast_1_1();
+} -output {}
+
+test cast-1.3 { Cast to string } -body {
+#lang L --line=1
+void cast_1_3()
+{
+ string s;
+ widget w = "w";
+ poly p = "p";
+ int a[] = { 1, 2 };
+ int h{string} = { "a"=>1, "b"=>2 };
+ struct { int i,j; } st = { 5, 6 };
+
+ /* This checks not only cast functionality but also type checking. */
+
+ s = (string)1;
+ unless (s eq "1") puts("bad 1");
+
+ s = (string)3.14159;
+ unless (s =~ /3.14159/) puts("bad 2");
+
+ s = (string)"ok";
+ unless (s eq "ok") puts("bad 3");
+
+ s = (string)w;
+ unless (s eq "w") puts("bad 4");
+
+ s = (string)a;
+ unless (s eq "1 2") puts("bad 5");
+
+ s = (string)h;
+ unless (s eq "a 1 b 2") puts("bad 6");
+
+ s = (string)st;
+ unless (s eq "5 6") puts("bad 7");
+
+ s = (string)p;
+ unless (s eq "p") puts("bad 8");
+}
+#lang tcl
+cast_1_3
+} -output {}
+
+test cast-1.4 { Invalid cast from function } -body {
+#lang L --line=1
+void cast_1_4()
+{
+ int i;
+ float f;
+ string s;
+ widget w;
+ int h{string};
+
+ i = (int)cast_1_4;
+ f = (float)cast_1_4;
+ s = (string)cast_1_4;
+ s = (tcl)cast_1_4;
+ w = (widget)cast_1_4;
+ h = (hash)cast_1_4;
+}
+#lang tcl
+cast_1_4
+} -returnCodes {error} -match regexp -result {.*9: L Error: type function illegal
+.*10: L Error: type function illegal
+.*11: L Error: type function illegal
+.*12: L Error: type function illegal
+.*13: L Error: type function illegal
+.*14: L Error: type function illegal
+}
+
+test cast-1.5 {cast to hash} -body {
+#lang L --line=1
+void cast_1_5()
+{
+ int n = 0;
+ string k;
+ string a[] = { "k1","v1", "k2","v2", "k3","v3" };
+ poly h{poly};
+
+ h = (hash)a;
+ unless (h{"k1"} eq "v1") puts("bad 1");
+ unless (h{"k2"} eq "v2") puts("bad 2");
+ unless (h{"k3"} eq "v3") puts("bad 3");
+ foreach (k in h) ++n;
+ unless (n == 3) puts("bad 4");
+}
+#lang tcl
+cast_1_5
+} -output {}
+
+test cast-1.6 {cast to various structured types} -body {
+#lang L --line=1
+struct s {
+ int i;
+ string s;
+ struct {
+ string h{int};
+ int i;
+ } st;
+};
+void cast_1_6()
+{
+ struct s st;
+ int a[], i, n;
+ string h{int};
+
+ /* Cast a string to a struct s. */
+ st = (struct s)"1 str { { 1 one 2 two } 33 }";
+ unless ((st.i == 1) && (st.s eq "str")) puts("bad 1");
+ unless ((st.st.h{1} eq "one") && (st.st.h{2} eq "two")) puts("bad 2");
+ unless (st.st.i == 33) puts("bad 3");
+
+ /* Same as above except casting from a composite constant. */
+ st = (struct s) {
+ 1,
+ "str",
+ {
+ { 1=>"one", 2=>"two" },
+ 33
+ }
+ };
+ unless ((st.i == 1) && (st.s eq "str")) puts("bad 4");
+ unless ((st.st.h{1} eq "one") && (st.st.h{2} eq "two")) puts("bad 5");
+ unless (st.st.i == 33) puts("bad 6");
+
+ /* Cast a string to a struct s but spell out the entire struct type. */
+ st = (struct { int i; string s; struct { string h{int}; int i; } st; })
+ "1 str { { 1 one 2 two } 33 }";
+ unless ((st.i == 1) && (st.s eq "str")) puts("bad 7");
+ unless ((st.st.h{1} eq "one") && (st.st.h{2} eq "two")) puts("bad 8");
+ unless (st.st.i == 33) puts("bad 9");
+
+ /* Same as above except casting from a composite constant. */
+ st = (struct { int i; string s; struct { string h{int}; int i; } st; })
+ {
+ 1,
+ "str",
+ {
+ { 1=>"one", 2=>"two" },
+ 33
+ }
+ };
+ unless ((st.i == 1) && (st.s eq "str")) puts("bad 10");
+ unless ((st.st.h{1} eq "one") && (st.st.h{2} eq "two")) puts("bad 11");
+ unless (st.st.i == 33) puts("bad 12");
+
+ a = (int[])"1 2 3";
+ n = 0;
+ foreach (i in a) {
+ unless (i == (n+1)) puts("bad 10");
+ ++n;
+ }
+ if (n != 3) puts("bad 11");
+
+ h = (string{int})"1 one 2 two 3 three";
+ unless ((h{1} eq "one") && (h{2} eq "two") && (h{3} eq "three")) {
+ puts("bad 20");
+ }
+ n = 0;
+ foreach (i in h) ++n;
+ unless (n == 3) puts("bad 21");
+}
+#lang tcl
+cast_1_6
+} -output {}
+
+test cast-1.7 {cast an lvalue} -body {
+#lang L --line=1
+typedef struct {
+ string type;
+ poly val;
+} c17_Xml;
+void cast_1_7()
+{
+ int i;
+ float f;
+ c17_Xml x;
+
+ /*
+ * These used to be various bugs with casts. There were
+ * problems with casting an l-value.
+ */
+
+ (int)i = 123;
+ unless(i == 123) puts("bad 1.1");
+ ++(int)i;
+ unless(i == 124) puts("bad 1.2");
+
+ (float)f = 1.1;
+ unless (f == 1.1) puts("bad 2.1");
+
+ x.type = "dict";
+ ((string{string})(x.val)){"key"} = "val";
+ unless (x.type eq "dict") puts("bad 3.1");
+ unless ((tcl)x eq "dict {key val}") puts("bad 3.2");
+
+ x.type = "type";
+ x.val = {};
+ ((string{string})(x.val)){"key"} = "val";
+ unless (x.type eq "type") puts("bad 4.1");
+ unless ((tcl)x eq "type {key val}") puts("bad 4.2");
+
+ x.type = "integer";
+ x.val = 0;
+ ++(int)x.val;
+ unless (x.type eq "integer") puts("bad 5.1");
+ unless (x.val == 1) puts("bad 5.2");
+ unless ((tcl)x eq "integer 1") puts("bad 5.3");
+}
+cast_1_7();
+} -output {}
+
+test array-1.0 { Single-dimensional array creation and indexing } -body {
+#lang L --line=1
+void array_1_0() {
+ int array[3];
+
+ array[0] = 1;
+ array[1] = 2;
+ array[2] = 3;
+ puts(array[2]);
+}
+#lang tcl
+array_1_0
+} -output "3\n"
+
+test array-1.1 { Multi-dimensional array creation and indexing } -body {
+#lang L --line=1
+void array_1_1() {
+ int array[4][3][2];
+
+ puts(array);
+ array[0][0][0] = 1;
+ array[1][1][1] = 2;
+ array[2][2][0] = 3;
+ array[3][0][1] = 4;
+ puts(array);
+}
+#lang tcl
+array_1_1
+} -output "
+1 {{} {{} 2}} {{} {} 3} {{{} 4}}\n"
+
+
+test array-1.2 {increment and decrement on array elements} -body {
+#lang L --line=1
+void array_1_2() {
+ int foo[5] = {0,0,0,0,0};
+
+ foo[3] = 0;
+ for (foo[3]=0; foo[3]<5; foo[3]++);
+ puts(foo);
+
+ puts("pre:");
+ puts(foo[3]);
+ ++foo[3];
+ puts(foo[3]);
+ puts(++foo[3]);
+ --foo[3];
+ puts(foo[3]);
+ puts(--foo[3]);
+
+ puts("post:");
+ puts(foo[3]);
+ foo[3]++;
+ puts(foo[3]);
+ puts(foo[3]++);
+ puts(foo[3]);
+ foo[3]--;
+ puts(foo[3]);
+ puts(foo[3]--);
+ puts(foo[3]);
+ puts(foo);
+}
+#lang tcl
+array_1_2
+} -output "0 0 0 5 0\npre:\n5\n6\n7\n6\n5\npost:\n5\n6\n6\n7\n6\n6\n5\n0 0 0 5 0\n"
+
+test array-1.3 {1d arrays with no length auto-extend by one at a time} -body {
+#lang L --line=1
+void array_1_3() {
+ int foo[];
+
+ foo[0] = 4;
+ foo[1] = 5;
+ foo[2] = 6;
+ puts(foo);
+}
+#lang tcl
+array_1_3
+} -output "4 5 6\n"
+
+test array-1.4 {extend arrays using push and pop} -body {
+#lang L --line=1
+void array_1_4() {
+ int foo[];
+
+ push(&foo, 1);
+ push(&foo, 2);
+ push(&foo, 3);
+ puts(foo);
+ puts(pop(&foo));
+ puts(foo);
+ puts(pop(&foo));
+ puts(foo);
+ puts(pop(&foo));
+ puts(foo);
+ puts(pop(&foo));
+ puts(foo);
+}
+#lang tcl
+array_1_4
+} -output "1 2 3\n3\n1 2\n2\n1\n1\n\n\n\n"
+
+test strindex-1 {string indexing} -body {
+#lang L --line=1
+void strindex_1()
+{
+ int i;
+ string s, s2;
+ struct {
+ string s;
+ } st;
+ string sa[];
+ string sh{string};
+ widget w;
+
+ s = "abcd";
+ s[0] = "x";
+ unless (s eq "xbcd") puts("bad 1.1");
+ s[1] = "y";
+ unless (s eq "xycd") puts("bad 1.2");
+ s[2] = "z";
+ unless (s eq "xyzd") puts("bad 1.3");
+ s[3] = "q";
+ unless (s eq "xyzq") puts("bad 1.4");
+ s[3] = "";
+ unless (s eq "xyz") puts("bad 1.5");
+ s[0] = "";
+ unless (s eq "yz") puts("bad 1.6");
+ s[0] = "";
+ unless (s eq "z") puts("bad 1.7");
+ s[0] = "";
+ unless (s eq "") puts("bad 1.8");
+ s = "abcd";
+ if (defined(s[4])) puts("bad 1.9");
+
+ st.s = "abcd";
+ st.s[0] = "x";
+ unless (st.s eq "xbcd") puts("bad 2.1");
+ st.s[1] = "y";
+ unless (st.s eq "xycd") puts("bad 2.2");
+ st.s[2] = "z";
+ unless (st.s eq "xyzd") puts("bad 2.3");
+ st.s[3] = "q";
+ unless (st.s eq "xyzq") puts("bad 2.4");
+ st.s[3] = "";
+ unless (st.s eq "xyz") puts("bad 2.5");
+ st.s[0] = "";
+ unless (st.s eq "yz") puts("bad 2.6");
+ st.s[0] = "";
+ unless (st.s eq "z") puts("bad 2.7");
+ st.s[0] = "";
+ unless (st.s eq "") puts("bad 2.8");
+ st.s = "abcd";
+ if (defined(st.s[4])) puts("bad 2.9");
+
+ sa[0] = "abcd";
+ sa[0][0] = "x";
+ unless (sa[0] eq "xbcd") puts("bad 3.1");
+ sa[0][1] = "y";
+ unless (sa[0] eq "xycd") puts("bad 3.2");
+ sa[0][2] = "z";
+ unless (sa[0] eq "xyzd") puts("bad 3.3");
+ sa[0][3] = "q";
+ unless (sa[0] eq "xyzq") puts("bad 3.4");
+ sa[0][3] = "";
+ unless (sa[0] eq "xyz") puts("bad 3.5");
+ sa[0][0] = "";
+ unless (sa[0] eq "yz") puts("bad 3.6");
+ sa[0][0] = "";
+ unless (sa[0] eq "z") puts("bad 3.7");
+ sa[0][0] = "";
+ unless (sa[0] eq "") puts("bad 3.8");
+ sa[0] = "abcd";
+ if (defined(sa[0][4])) puts("bad 3.9");
+
+ sh{"zero"} = "abcd";
+ sh{"zero"}[0] = "x";
+ unless (sh{"zero"} eq "xbcd") puts("bad 4.1");
+ sh{"zero"}[1] = "y";
+ unless (sh{"zero"} eq "xycd") puts("bad 4.2");
+ sh{"zero"}[2] = "z";
+ unless (sh{"zero"} eq "xyzd") puts("bad 4.3");
+ sh{"zero"}[3] = "q";
+ unless (sh{"zero"} eq "xyzq") puts("bad 4.4");
+ sh{"zero"}[3] = "";
+ unless (sh{"zero"} eq "xyz") puts("bad 4.5");
+ sh{"zero"}[0] = "";
+ unless (sh{"zero"} eq "yz") puts("bad 4.6");
+ sh{"zero"}[0] = "";
+ unless (sh{"zero"} eq "z") puts("bad 4.7");
+ sh{"zero"}[0] = "";
+ unless (sh{"zero"} eq "") puts("bad 4.8");
+ sh{"zero"} = "abcd";
+ if (defined(sh{"zero"}[4])) puts("bad 4.9");
+
+ s = "abcd";
+ s[1] =~ s/n/nochange/;
+ unless (s eq "abcd") puts("bad 5.1");
+ s[0] =~ s/n/nochange/;
+ unless (s eq "abcd") puts("bad 5.2");
+ s[3] =~ s/n/nochange/;
+ unless (s eq "abcd") puts("bad 5.3");
+ s[0] =~ s/a/was-a/;
+ unless (s eq "was-abcd") puts("bad 5.4");
+ s[5] =~ s/b/was-b/;
+ unless (s eq "was-awas-bcd") puts("bad 5.5");
+ s[11] =~ s/d/was-d/;
+ unless (s eq "was-awas-bcwas-d") puts("bad 5.6");
+ s[0] =~ s/w//;
+ unless (s eq "as-awas-bcwas-d") puts("bad 5.7");
+ s[0] =~ s/a//;
+ unless (s eq "s-awas-bcwas-d") puts("bad 5.8");
+ s[1] =~ s/-//;
+ unless (s eq "sawas-bcwas-d") puts("bad 5.9");
+ s[12] =~ s/d//;
+ unless (s eq "sawas-bcwas-") puts("bad 5.10");
+
+ s = "0123456789";
+ for (i = 0; i < 10; ++i) {
+ s[i] =~ s/${i}/${i+1}/;
+ }
+ unless (s eq "12345678910") puts("bad 6.1");
+
+ /*
+ * Ensure that an un-shared copy of the string is made.
+ */
+ s = "xyzzy";
+ s2 = s; // s2 and s now share the same Tcl_Obj
+ s[1] = "x";
+ unless (s eq "xxzzy") puts("bad 7.1");
+ unless (s2 eq "xyzzy") puts("bad 7.2");
+
+ /* Should work with widgets too. */
+ w = "wid";
+ unless ((w[0] eq "w") && (w[END] eq "d")) puts("bad 8.1");
+}
+strindex_1();
+} -output {}
+
+test strindex-2 {string indexing errors 1} -body {
+#lang L --line=1
+void strindex_2()
+{
+ string s = "bad";
+ s[-1] = "x"; // run-time error
+}
+strindex_2();
+} -returnCodes error -result {negative string index illegal}
+
+test strindex-3 {string indexing errors 2} -body {
+#lang L --line=1
+void strindex_3()
+{
+ string s = "bad";
+ puts (s[-1]); // run-time error
+}
+strindex_3();
+} -returnCodes error -result {negative string index illegal}
+
+test strindex-4 {string indexing errors 3} -body {
+#lang L --line=1
+void strindex_4()
+{
+ string s = "bad";
+ s[-1] =~ s/b/bad/; // run-time error
+}
+strindex_4();
+} -returnCodes error -result {negative string index illegal}
+
+test strindex-5 {string indexing index using comma expression} -body {
+#lang L --line=1
+void strindex_5()
+{
+ /*
+ * This checks an obscure case to ensure that a string index
+ * whose value is discarded -- the first expression in a comma
+ * expression -- is compiled properly.
+ */
+
+ string s = "abcde";
+
+ /* The value of "fgh"[0] is discarded in the "s" index expression. */
+ unless (s[ "fgh"[0], 2 ] eq "c") puts("bad 1");
+}
+strindex_5();
+} -output {}
+
+test strindex-6 {writing to a string index beyond end of string} -body {
+#lang L --line=1
+void strindex_6()
+{
+ string s = "good";
+ s[END+2] = "bad"; // run-time error
+}
+strindex_6();
+} -returnCodes error -result {index is more than one past end of string}
+
+test strindex-7 {multi-index string indexing} -body {
+#lang L --line=1
+void strindex_7()
+{
+ string s = "value";
+
+ s[0][0] = "x";
+ s[0][0][0] = "x";
+}
+strindex_7();
+} -returnCodes error -match regexp -result {.*5: L Error: cannot index a string index
+.*6: L Error: cannot index a string index
+}
+
+test slice-1 {string slicing} -body {
+#lang L --line=1
+string slice_1_f(string s) { return (s); }
+void slice_1()
+{
+ int i, j;
+ string s;
+ widget w;
+
+ s = "";
+ unless (s[0..0] eq "") puts("bad 1.1");
+
+ s = "a";
+ unless (s[0..0] eq "a") puts("bad 2.1");
+
+ s = "abcdefg";
+ unless (s[0..0] eq "a") puts("bad 3.1");
+ unless (s[0..1] eq "ab") puts("bad 3.2");
+ unless (s[0..2] eq "abc") puts("bad 3.3");
+ unless (s[0..3] eq "abcd") puts("bad 3.4");
+ unless (s[0..4] eq "abcde") puts("bad 3.5");
+ unless (s[1..1] eq "b") puts("bad 3.6");
+ unless (s[1..2] eq "bc") puts("bad 3.7");
+ unless (s[1..3] eq "bcd") puts("bad 3.8");
+ unless (s[1..4] eq "bcde") puts("bad 3.9");
+ unless (s[2..2] eq "c") puts("bad 3.10");
+ unless (s[2..3] eq "cd") puts("bad 3.11");
+ unless (s[2..4] eq "cde") puts("bad 3.12");
+ unless (s[3..3] eq "d") puts("bad 3.13");
+ unless (s[3..4] eq "de") puts("bad 3.14");
+ unless (s[4..4] eq "e") puts("bad 3.15");
+ unless (s[0..10] eq "abcdefg") puts("bad 3.20");
+ unless (s[-1..0] eq "a") puts("bad 3.21");
+ unless (s[-1..1] eq "ab") puts("bad 3.22");
+ unless (s[-1..10] eq "abcdefg") puts("bad 3.23");
+ unless (s[2..1] eq "") puts("bad 3.24");
+
+ s = "0123456789";
+ unless (s[2..4][0..0] eq "2") puts("bad 4.1");
+ unless (s[2..4][1..1] eq "3") puts("bad 4.2");
+ unless (s[1..8][1..6][1..4][1..2] eq "45") puts("bad 4.3");
+
+ s = "0123456789";
+ unless (slice_1_f(s)[2..4][0..0] eq "2") puts("bad 5.1");
+ unless (slice_1_f(s)[2..4][1..1] eq "3") puts("bad 5.2");
+ unless (slice_1_f(s)[1..8][1..6][1..4][1..2] eq "45") puts("bad 5.3");
+
+ s = "0123456789";
+ i = 2;
+ j = 4;
+ unless (s[i..j] eq "234") puts("bad 6.1");
+ unless (s[i-1..j] eq "1234") puts("bad 6.2");
+ unless (s[i-1..j+1] eq "12345") puts("bad 6.3");
+
+ w = "0123456789";
+ unless (s[2..4][0..0] eq "2") puts("bad 7.1");
+ unless (s[2..4][1..1] eq "3") puts("bad 7.2");
+ unless (s[1..8][1..6][1..4][1..2] eq "45") puts("bad 7.3");
+}
+slice_1();
+} -output {}
+
+test slice-2 {array slicing} -body {
+#lang L --line=1
+string slice_2_tostr(int a[])
+{
+ int i;
+ string ret = "";
+
+ foreach (i in a) ret = sprintf("%s<%i>", ret, i);
+ return (ret);
+}
+void slice_2()
+{
+ int ai[];
+ string s;
+
+ ai = { 0, 1, 2, 3, 4 };
+ unless (slice_2_tostr(ai[0..0]) eq "<0>") puts("bad 1.1");
+ unless (slice_2_tostr(ai[0..1]) eq "<0><1>") puts("bad 1.2");
+ unless (slice_2_tostr(ai[0..2]) eq "<0><1><2>") puts("bad 1.3");
+ unless (slice_2_tostr(ai[0..3]) eq "<0><1><2><3>") puts("bad 1.4");
+ unless (slice_2_tostr(ai[0..4]) eq "<0><1><2><3><4>") puts("bad 1.5");
+ unless (slice_2_tostr(ai[1..1]) eq "<1>") puts("bad 1.6");
+ unless (slice_2_tostr(ai[1..2]) eq "<1><2>") puts("bad 1.7");
+ unless (slice_2_tostr(ai[1..3]) eq "<1><2><3>") puts("bad 1.8");
+ unless (slice_2_tostr(ai[1..4]) eq "<1><2><3><4>") puts("bad 1.9");
+ unless (slice_2_tostr(ai[2..2]) eq "<2>") puts("bad 1.10");
+ unless (slice_2_tostr(ai[2..3]) eq "<2><3>") puts("bad 1.11");
+ unless (slice_2_tostr(ai[2..4]) eq "<2><3><4>") puts("bad 1.12");
+ unless (slice_2_tostr(ai[3..3]) eq "<3>") puts("bad 1.13");
+ unless (slice_2_tostr(ai[3..4]) eq "<3><4>") puts("bad 1.14");
+ unless (slice_2_tostr(ai[4..4]) eq "<4>") puts("bad 1.15");
+
+ s = slice_2_tostr(ai[0..3][0..2]);
+ unless (s eq "<0><1><2>") puts("bad 2.1");
+ s = slice_2_tostr(ai[0..3][0..2][0..1]);
+ unless (s eq "<0><1>") puts("bad 2.2");
+ s = slice_2_tostr(ai[0..3][0..2][0..1][0..0]);
+ unless (s eq "<0>") puts("bad 2.3");
+
+ s = slice_2_tostr(ai[1..3][0..2]);
+ unless (s eq "<1><2><3>") puts("bad 3.1");
+ s = slice_2_tostr(ai[1..3][0..1]);
+ unless (s eq "<1><2>") puts("bad 3.2");
+ s = slice_2_tostr(ai[1..3][0..2][0..2][0..2][0..2]);
+ unless (s eq "<1><2><3>") puts("bad 3.3");
+
+ /* Check expressions as slice indices. */
+ s = slice_2_tostr(ai[1-1..2+1][0*10..2]);
+ unless (s eq "<0><1><2>") puts("bad 4.1");
+ s = slice_2_tostr(ai[1-1..ai[2..2][0]+1][0*10..ai[2]]);
+ unless (s eq "<0><1><2>") puts("bad 4.2");
+
+ /* Check slices of lists. */
+ s = slice_2_tostr({0,1,2,3,4}[1..3]);
+ unless (s eq "<1><2><3>") puts("bad 5.1");
+}
+slice_2();
+} -output {}
+
+test slice-2.1 {array slicing 2} -body {
+#lang L --line=1
+void slice_2_1()
+{
+ /*
+ * Althgouh probably not recommended style, these should work.
+ */
+
+ struct s1 {
+ int i1, i2, i3, i4;
+ } st1;
+ struct s2 {
+ int i1, i2;
+ } st2;
+
+ st2 = (struct s2){1,2,3,4}[1..2];
+ unless ((st2.i1 == 2) && (st2.i2 == 3)) puts("bad 1");
+
+ st1 = { 5, 6, 7, 8 };
+ st2 = (struct s2) ((int[])st1)[1..2];
+ unless ((st2.i1 == 6) && (st2.i2 == 7)) puts("bad 2");
+}
+slice_2_1();
+} -output {}
+
+test slice-3 {array slice errors} -body {
+#lang L --line=1
+void slice_3()
+{
+ int i;
+ float f;
+ struct {
+ int i, j;
+ } st;
+ int h{int};
+
+ i = i[0..1];
+ f = f[0..1];
+ i = st[0..1];
+ i = h[0..1];
+}
+} -returnCodes error -match regexp -result {.*10: L Error: illegal type for slice
+.*11: L Error: illegal type for slice
+.*12: L Error: illegal type for slice
+.*13: L Error: illegal type for slice
+}
+
+test slice-4 {array slice index errors} -body {
+#lang L --line=1
+void slice_4()
+{
+ int a[], i;
+ float f;
+
+ i = a[0.0..1];
+ i = a[0..1.0];
+ i = a[0.0..1.0];
+ i = a[f..1];
+ i = a[0..f];
+ i = a[f..f];
+ i = a[a..a];
+
+ a[0..1] = { 0, 1 }; // invalid l-value
+}
+} -returnCodes error -match regexp -result {.*6: L Error: first slice index not an int
+.*7: L Error: second slice index not an int
+.*8: L Error: first slice index not an int
+.*8: L Error: second slice index not an int
+.*9: L Error: first slice index not an int
+.*10: L Error: second slice index not an int
+.*11: L Error: first slice index not an int
+.*11: L Error: second slice index not an int
+.*12: L Error: first slice index not an int
+.*12: L Error: second slice index not an int
+.*14: L Error: invalid l-value in assignment
+}
+
+test end-1 {test END keyword for string indices} -body {
+#lang L --line=1
+int end_1_f(int end) {
+ unless ("abc"[END] eq "c") puts("bad f.1");
+ return (end);
+}
+void end_1()
+{
+ int e1, e2, e3;
+ string s, s1, s2, s3;
+ string as[];
+
+ /* Ensure END works and can be used in a full-blown expression. */
+ s = "abcde";
+ as[0] = "123";
+ as[1] = "456";
+ as[2] = "789";
+ unless (s[END] eq "e") puts("bad 1.1");
+ unless (s[END-1] eq "d") puts("bad 1.2");
+ unless (s[END-2] eq "c") puts("bad 1.3");
+ unless (s[END/2+2] eq "e") puts("bad 1.4");
+ unless (s[end_1_f(END)/2+2] eq "e") puts("bad 1.5");
+ unless (s[END-END+END-END+END*0+END] eq "e") puts("bad 1.6");
+ unless ("xyz123"[END] eq "3") puts("bad 1.7");
+
+ /*
+ * These check END for something that is represented on the
+ * run-time stack as an L deep-ptr (as[0]).
+ */
+ unless (as[0][END] eq "3") puts("bad 1.8");
+ unless (as[1][END] eq "6") puts("bad 1.9");
+ unless (as[2][END] eq "9") puts("bad 1.10");
+
+ /* Grab the value of END and verify it. */
+ e1 = -1;
+ s = "abcde";
+ unless (s[0,e1=END] eq "e") puts("bad 2.1");
+ unless (e1 == 4) puts("bad 2.2");
+ e1 = -1;
+ unless (s[e1=END,0] eq "a") puts("bad 2.3");
+ unless (e1 == 4) puts("bad 2.4");
+
+ /* Check nested ENDs. */
+ e1 = e2 = -1;
+ s1 = "abcde"[ s2="fgh"[e2=END], e1=END ];
+ unless ((s1 eq "e") && (s2 eq "h")) puts("bad 3.1");
+ unless ((e1 == 4) && (e2 == 2)) puts("bad 3.2");
+ e1 = e2 = -1;
+ s1 = "abcde"[ s2="fgh"[ s3="pqrstuvwxyz"[e3=END], e2=END ], e1=END ];
+ unless ((s1 eq "e") && (s2 eq "h") && (s3 eq "z")) puts("bad 3.3");
+ unless ((e1 == 4) && (e2 == 2) && (e3 == 10)) puts("bad 3.4");
+}
+end_1();
+} -output {}
+
+test end-2 {test END keyword for arrays} -body {
+#lang L --line=1
+int end_2_f(int end) {
+ unless ({7,8,9}[END] == 9) puts("bad f.1");
+ return (end);
+}
+int[] end_2_foo(int x) { return ({x,x+1,x+2}); }
+void end_2()
+{
+ int e1, e2, e3, i1, i2, i3;
+ int a[], aa[][];
+
+ /* Ensure END works and can be used in a full-blown expression. */
+ a = {1,2,3};
+ unless (a[END] == 3) puts("bad 1.1");
+ unless (a[END-1] == 2) puts("bad 1.2");
+ unless (a[END-2] == 1) puts("bad 1.3");
+ unless (a[END/2] == 2) puts("bad 1.4");
+ unless (a[END/2+END/2] == 3) puts("bad 1.5");
+ unless (a[END-END-END-END+END+END] == 1) puts("bad 1.6");
+ unless (a[end_1_f(END)/2+1] == 3) puts("bad 1.7");
+ unless ({1,2,3}[END] == 3) puts("bad 1.8");
+ unless ({1,2,3}[END-1] == 2) puts("bad 1.9");
+ unless ({1,2,3}[END-2] == 1) puts("bad 1.10");
+
+ /*
+ * These check END for something that is represented on the
+ * run-time stack as an L deep-ptr (aa[0]).
+ */
+ aa[0] = {4,5,6};
+ aa[1] = {7,8,9};
+ aa[2] = {10,11,12};
+ unless (aa[0][END] == 6) puts("bad 2.1");
+ unless (aa[1][END] == 9) puts("bad 2.2");
+ unless (aa[2][END] == 12) puts("bad 2.3");
+
+ /* Grab the value of END and verify it. */
+ e1 = -1;
+ a = {1,2,3};
+ unless (a[0,e1=END] == 3) puts("bad 3.1");
+ unless (e1 == 2) puts("bad 3.2");
+ e1 = -1;
+ unless (a[e1=END,0] == 1) puts("bad 3.3");
+ unless (e1 == 2) puts("bad 3.4");
+ e1 = -1;
+ if (defined({}[e1=END])) puts("bad 3.5");
+ unless (e1 == -1) puts("bad 3.6");
+
+ /* Check nested ENDs. */
+ e1 = e2 = e3 = -1;
+ i1 = {1,2,3}[ i2={4,5,6,7}[e2=END], e1=END ];
+ unless ((i1 == 3) && (i2 == 7)) puts("bad 4.1");
+ unless ((e1 == 2) && (e2 == 3)) puts("bad 4.2");
+ e1 = e2 = e3 = -1;
+ i1 = {1,2,3}[ i2={4,5,6,7}[ i3={8,9}[e3=END], e2=END ], e1=END ];
+ unless ((i1 == 3) && (i2 == 7) && (i3 == 9)) puts("bad 4.3");
+ unless ((e1 == 2) && (e2 == 3) && (e3 == 1)) puts("bad 4.4");
+
+ /* Some multiple ENDs. */
+ aa = { {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12} };
+ e1 = e2 = -1;
+ unless (aa[e1=END][e2=END] == 12) puts("bad 5.1");
+ unless ((e1 == 3) && (e2 == 2)) puts("bad 5.2");
+
+ /* Check a[f(END)[b..c]] */
+ a = { 1,2,3 };
+ e1 = -1;
+ a[e1=end_2_foo(END+0)[0..1][0]];
+ unless (e1 == 2) puts("bad 7.1");
+}
+end_2();
+} -output {}
+
+test end-3 {test END usage for string append} -body {
+#lang L --line=1
+void end_3()
+{
+ int i;
+ string s;
+ string atoz="abcdefghijklmnopqrstuvwxyz";
+
+ s = "";
+ for (i = 0; i < 26; ++i) {
+ s[END+1] = atoz[i];
+ }
+ for (i = 0; i < 26; ++i) {
+ unless (s[i] eq atoz[i]) printf("bad 1.1 i=%d", i);
+ }
+ if (defined(s[i])) puts("bad 1.2");
+ unless (s eq "abcdefghijklmnopqrstuvwxyz") puts("bad 1.3");
+}
+end_3();
+} -output {}
+
+test end-4 {test END usage for array append} -body {
+#lang L --line=1
+void end_4()
+{
+ int e1, e2, i;
+ int a[], aa[][];
+
+ a = {};
+ for (i = 0; i < 100; ++i) {
+ a[END+1] = i;
+ }
+ for (i = 0; i < 100; ++i) {
+ unless (a[i] == i) printf("bad 1.1 i=%d\n", i);
+ }
+ if (defined(a[i])) puts("bad 1.2");
+
+ aa = {};
+ e1 = e2 = -2;
+ aa[(e1=END)+1][(e2=END)+1] = 100;
+ unless ((e1 == -1) && (e2 == -1)) puts("bad 2.1");
+ unless (aa[e1=END][e2=END] == 100) puts("bad 2.2");
+ unless ((e1 == 0) && (e2 == 0)) puts("bad 2.3");
+
+ aa = {};
+ for (i = 0; i < 10; ++i) {
+ aa[END+1][END+1] = i;
+ aa[END][END+1] = 10*i;
+ }
+ for (i = 0; i < 10; ++i) {
+ unless (aa[i][0] == i) puts("bad 3.1");
+ unless (aa[i][1] == 10*i) puts("bad 3.2");
+ if (defined(aa[i][2])) puts("bad 3.3");
+ }
+ if (defined(aa[i][0])) puts("bad 3.4");
+}
+end_4();
+} -output {}
+
+test end-5 {test END with recursion} -body {
+#lang L --line=1
+int end_5_f(int lim, int n)
+{
+ int a[], e, i;
+
+ /* Put n things into a[]. */
+ for (i = 0; i < n; ++i) a[END+1] = i;
+
+ if (n < lim) {
+ /* e should get END+1; i.e., the # of things in a[] */
+ a[e = (END+end_5_f(lim,n+1)+END)/2 + 1];
+ unless (e == n) printf("bad n=%d, e=%d\n", n, e);
+ }
+ return (0);
+}
+void end_5()
+{
+ /*
+ * This test makes sure we can have lots of different ENDs all
+ * stacked up at once.
+ */
+ end_5_f(100, 0);
+}
+end_5();
+} -output {}
+
+test end-6 {test END errors} -body {
+#lang L --line=1
+int END; // err -- cannot declare global w/name "END"
+void END() {} // err -- cannot declare function w/name "END"
+void end_6()
+{
+ int END, i; // err -- cannot declare variable w/name "END"
+ string h{int};
+
+ i = END; // err -- cannot use END outside of an array or string index
+ h{END}; // err -- cannot use END in a hash index
+}
+} -returnCodes error -match regexp -result {.*1: L Error: cannot use END.*
+.*2: L Error: cannot use END.*
+.*5: L Error: cannot use END.*
+.*8: L Error: END illegal.*
+.*9: L Error: END illegal.*
+}
+
+test end-7 {test END in string slices} -body {
+#lang L --line=1
+void end_7()
+{
+ string s;
+
+ s = "123456789";
+ unless (s[0..END] eq "123456789") puts("bad 1.0");
+ unless (s[0..END] eq s) puts("bad 1.1");
+ unless (s[1..END] eq "23456789") puts("bad 1.2");
+ unless (s[2..END] eq "3456789") puts("bad 1.3");
+ unless (s[2..END-1] eq "345678") puts("bad 1.4");
+ unless (s[2..END-2] eq "34567") puts("bad 1.5");
+ unless (s[END-1..END] eq "89") puts("bad 1.6");
+ unless (s[END-1..END-1] eq "8") puts("bad 1.7");
+}
+end_7();
+} -output {}
+
+test end-8 {test END in array slices} -body {
+#lang L --line=1
+void end_8()
+{
+ string a[];
+
+ a = { "1", "2", "3", "4", "5", "6" };
+ unless (join(" ", a[0..END]) eq "1 2 3 4 5 6") puts("bad 1.1");
+ unless (join(" ", a[1..END]) eq "2 3 4 5 6") puts("bad 1.2");
+ unless (join(" ", a[2..END]) eq "3 4 5 6") puts("bad 1.3");
+ unless (join(" ", a[2..END-1]) eq "3 4 5") puts("bad 1.4");
+ unless (join(" ", a[2..END-2]) eq "3 4") puts("bad 1.5");
+ unless (join(" ", a[END-1..END]) eq "5 6") puts("bad 1.6");
+ unless (join(" ", a[END-1..END-1]) eq "5") puts("bad 1.7");
+}
+end_8();
+} -output {}
+
+test end-10 {check END ignored in comma expression} -body {
+#lang L --line=1
+void end_10()
+{
+ int i;
+ int a[] = {1,2,3};
+
+ /*
+ * This tests that an ignored END does not leave anything on
+ * the run-time stack (which would case a crash).
+ */
+ for (i = 0; i < 100; ++i) a[END,0];
+}
+end_10();
+} -output {}
+
+test end-11 {check deeply nested ENDs} -body {
+#lang L
+void end_11()
+{
+ /*
+ * Test that 40 ENDs can stack up.
+ */
+
+ int a[] = { 1, 0, 0 };
+ int i;
+
+ i = a[END-1 + a[END-1 + a[END-1 + a[END-1 + a[END-1 +
+ a[END-1 + a[END-1 + a[END-1 + a[END-1 + a[END-1 +
+ a[END-1 + a[END-1 + a[END-1 + a[END-1 + a[END-1 +
+ a[END-1 + a[END-1 + a[END-1 + a[END-1 + a[END-1 +
+ a[END-1 + a[END-1 + a[END-1 + a[END-1 + a[END-1 +
+ a[END-1 + a[END-1 + a[END-1 + a[END-1 + a[END-1 +
+ a[END-1 + a[END-1 + a[END-1 + a[END-1 + a[END-1 +
+ a[END-1 + a[END-1 + a[END-1 + a[END-1 +
+ a[END]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]];
+ unless (i == 0) puts("bad");
+}
+end_11();
+} -output {}
+
+test end-12 {check END in various contexts} -body {
+#lang L
+int end_12f(int a, int b)
+{
+ unless (a == b) {
+ puts("bad ${a} ${b}");
+ }
+ return (a);
+}
+void end_12()
+{
+ int a[] = { 1, 2, 3 };
+ int i;
+ struct {
+ string h{string}[];
+ } st;
+
+ // END in an arg list
+ a[end_12f(END,2)];
+ a[end_12f(2,END)];
+ a[end_12f(END+0,2)];
+ a[end_12f(2,0+END)];
+
+ // END is an id, array index
+ i = a[END];
+ unless (i == 3) puts("bad 1");
+
+ // END is an id, array slice
+ a[0..(i=END)];
+ unless (i == 2) puts("bad 2.1");
+ a[(i=END)..END];
+ unless (i == 2) puts("bad 2.2");
+
+ // END in a unary op
+ i = a[+END];
+ unless (i == 3) puts("bad 3");
+
+ // END in a binary op
+ a[i=END+END];
+ unless (i == 4) puts("bad 4");
+
+ // END in a trinary op
+ i = 0;
+ a[END==2 ? (i=END) : (i=0)];
+ unless (i == 2) puts("bad 5");
+
+ // A regression test for a bug that used to crash the compiler
+ // when it looked for END in an index expression that has a cast.
+ push(&st.h{(string)0}, "x");
+ push(&st.h{(string)0}, "y");
+ push(&st.h{(string)0}, "z");
+ unless (st.h{"0"} == {"x","y","z"}) puts("bad 6");
+}
+end_12();
+} -output {}
+
+test loop-1.0 {while loops} -body {
+#lang L --line=1
+void loop_1_0() {
+ int i = 0;
+ while (i++ < 5) puts (i);
+ while (i) {
+ int j = i--;
+ puts(j);
+ }
+}
+#lang tcl
+loop_1_0
+} -output "1\n2\n3\n4\n5\n6\n5\n4\n3\n2\n1\n"
+test loop-1.1 {for loops} -body {
+#lang L --line=1
+void loop_1_1() {
+ int i;
+ for (i=1; i<7; i++) {
+ puts(i);
+ }
+ puts("-*-");
+ for ( ; i; i--) {
+ puts(i);
+ }
+}
+#lang tcl
+loop_1_1
+} -output "1\n2\n3\n4\n5\n6\n-*-\n7\n6\n5\n4\n3\n2\n1\n"
+
+test loop-1.2 {do loops} -body {
+#lang L --line=1
+void loop_1_2()
+{
+ int i;
+
+ /* Do loops must iterate at least once. */
+ i = 0;
+ do {
+ ++i;
+ } while (0);
+ unless (i == 1) puts("bad 1");
+
+ i = 0;
+ do {
+ ++i;
+ puts(i);
+ } while (i < 4);
+}
+#lang tcl
+loop_1_2
+} -output "1\n2\n3\n4\n"
+
+test loop-1.2.0 {simple foreach loops} -body {
+#lang L --line=1
+struct sl120 {
+ int i;
+ int j;
+ string s;
+};
+void
+loop_1_2_0()
+{
+ int k, vi;
+ string vs;
+ float vf;
+ hash h0 = { };
+ hash h1 = { 0=>1 };
+ hash h2 = { 0=>1, 1=>2 };
+ hash h3 = { 0=>1, 1=>2, 2=>3 };
+ int ai0[];
+ int ai1[1] = { 11 };
+ int ai2[2] = { 22, 23 };
+ int ai3[3] = { 33, 34, 35 };
+ string as0[0];
+ string as1[1] = { "a" };
+ string as2[2] = { "b", "c" };
+ string as3[3] = { "d", "e", "f" };
+ float af0[0];
+ float af1[1] = { 1.1 };
+ float af2[2] = { 2.1, 2.2 };
+ float af3[3] = { 3.1, 3.2, 3.3 };
+ struct sl120 vc;
+ struct sl120 ac[3];
+
+ printf("start\n");
+ foreach (k in h0) {
+ printf("h0 has %d\n", k);
+ }
+ foreach (k in h1) {
+ printf("h1 has %d\n", k);
+ }
+ foreach (k in h2) {
+ printf("h2 has %d\n", k);
+ }
+ foreach (k in h3) {
+ printf("h3 has %d\n", k);
+ }
+ foreach (k=>vi in h0) {
+ printf("h0 has %d=>%d\n", k, vi);
+ }
+ foreach (k=>vi in h1) {
+ printf("h1 has %d=>%d\n", k, vi);
+ }
+ foreach (k=>vi in h2) {
+ printf("h2 has %d=>%d\n", k, vi);
+ }
+ foreach (k=>vi in h3) {
+ printf("h3 has %d=>%d\n", k, vi);
+ }
+ foreach (vi in ai0) {
+ printf("ai0 has %d\n", vi);
+ }
+ foreach (vi in ai1) {
+ printf("ai1 has %d\n", vi);
+ }
+ foreach (vi in ai2) {
+ printf("ai2 has %d\n", vi);
+ }
+ foreach (vi in ai3) {
+ printf("ai3 has %d\n", vi);
+ }
+ foreach (vs in as0) {
+ printf("as0 has %s\n", vs);
+ }
+ foreach (vs in as1) {
+ printf("as1 has %s\n", vs);
+ }
+ foreach (vs in as2) {
+ printf("as2 has %s\n", vs);
+ }
+ foreach (vs in as3) {
+ printf("as3 has %s\n", vs);
+ }
+ foreach (vf in af0) {
+ printf("af0 has %1.1f\n", vf);
+ }
+ foreach (vf in af1) {
+ printf("af1 has %1.1f\n", vf);
+ }
+ foreach (vf in af2) {
+ printf("af2 has %1.1f\n", vf);
+ }
+ foreach (vf in af3) {
+ printf("af3 has %1.1f\n", vf);
+ }
+ foreach (vf in ai0) {
+ printf("ai0 has %1.1f\n", vf);
+ }
+ foreach (vf in ai1) {
+ printf("ai1 has %1.1f\n", vf);
+ }
+ foreach (vf in ai2) {
+ printf("ai2 has %1.1f\n", vf);
+ }
+ foreach (vf in ai3) {
+ printf("ai3 has %1.1f\n", vf);
+ }
+ ac[0].i = 1;
+ ac[0].j = 2;
+ ac[0].s = "a";
+ ac[1].i = 11;
+ ac[1].j = 22;
+ ac[1].s = "aa";
+ ac[2].i = 111;
+ ac[2].j = 222;
+ ac[2].s = "aaa";
+ foreach (vc in ac) {
+ printf("ac has %d,%d,%s\n", vc.i, vc.j, vc.s);
+ }
+ printf("end\n");
+}
+#lang tcl
+loop_1_2_0
+} -output "start
+h1 has 0
+h2 has 0
+h2 has 1
+h3 has 0
+h3 has 1
+h3 has 2
+h1 has 0=>1
+h2 has 0=>1
+h2 has 1=>2
+h3 has 0=>1
+h3 has 1=>2
+h3 has 2=>3
+ai1 has 11
+ai2 has 22
+ai2 has 23
+ai3 has 33
+ai3 has 34
+ai3 has 35
+as1 has a
+as2 has b
+as2 has c
+as3 has d
+as3 has e
+as3 has f
+af1 has 1.1
+af2 has 2.1
+af2 has 2.2
+af3 has 3.1
+af3 has 3.2
+af3 has 3.3
+ai1 has 11.0
+ai2 has 22.0
+ai2 has 23.0
+ai3 has 33.0
+ai3 has 34.0
+ai3 has 35.0
+ac has 1,2,a
+ac has 11,22,aa
+ac has 111,222,aaa
+end
+"
+
+test loop-1.2.1 {foreach loops over arrays of arrays} -body {
+#lang L --line=1
+void
+loop_121_fill2(int d1, int d2, int &a[][])
+{
+ int i, j;
+
+ for (i = 0; i < d1; ++i) {
+ for (j = 0; j < d2; ++j) {
+ a[i][j] = i*10 + j;
+ }
+ }
+}
+
+void
+loop_121_fill3(int d1, int d2, int d3, int &a[][][])
+{
+ int i, j, k;
+
+ for (i = 0; i < d1; ++i) {
+ for (j = 0; j < d2; ++j) {
+ for (k = 0; k < d3; ++k) {
+ a[i][j][k] = i*100 + j*10 + k;
+ }
+ }
+ }
+}
+
+void
+loop_1_2_1()
+{
+ int vi;
+ int ai[3];
+ int aii[4][3];
+ int aiii[5][4][3];
+
+ loop_121_fill2(4, 3, &aii);
+ loop_121_fill3(5, 4, 3, &aiii);
+
+ printf("test 1\n");
+ foreach (ai in aii) {
+ foreach (vi in ai) {
+ printf("aii has %d\n", vi);
+ }
+ }
+
+ printf("test 2\n");
+ foreach (aii in aiii) {
+ foreach (ai in aii) {
+ foreach (vi in ai) {
+ printf("aiii has %d\n", vi);
+ }
+ }
+ }
+
+ printf("end\n");
+}
+loop_1_2_1();
+} -output "test 1
+aii has 0
+aii has 1
+aii has 2
+aii has 10
+aii has 11
+aii has 12
+aii has 20
+aii has 21
+aii has 22
+aii has 30
+aii has 31
+aii has 32
+test 2
+aiii has 0
+aiii has 1
+aiii has 2
+aiii has 10
+aiii has 11
+aiii has 12
+aiii has 20
+aiii has 21
+aiii has 22
+aiii has 30
+aiii has 31
+aiii has 32
+aiii has 100
+aiii has 101
+aiii has 102
+aiii has 110
+aiii has 111
+aiii has 112
+aiii has 120
+aiii has 121
+aiii has 122
+aiii has 130
+aiii has 131
+aiii has 132
+aiii has 200
+aiii has 201
+aiii has 202
+aiii has 210
+aiii has 211
+aiii has 212
+aiii has 220
+aiii has 221
+aiii has 222
+aiii has 230
+aiii has 231
+aiii has 232
+aiii has 300
+aiii has 301
+aiii has 302
+aiii has 310
+aiii has 311
+aiii has 312
+aiii has 320
+aiii has 321
+aiii has 322
+aiii has 330
+aiii has 331
+aiii has 332
+aiii has 400
+aiii has 401
+aiii has 402
+aiii has 410
+aiii has 411
+aiii has 412
+aiii has 420
+aiii has 421
+aiii has 422
+aiii has 430
+aiii has 431
+aiii has 432
+end
+"
+
+test loop-1.2.2 {foreach with int variable lists} -body {
+#lang L --line=1
+void
+loop_1_2_2()
+{
+ int i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12;
+ int a[12] = { 1,2,3,4,5,6,7,8,9,10,11,12 };
+
+ printf("test 1\n");
+ foreach (i1 in a) {
+ printf("a has %d\n", i1);
+ }
+ printf("test 2\n");
+ foreach (i1,i2 in a) {
+ printf("a has %d,%d\n", i1, i2);
+ }
+ printf("test 3\n");
+ foreach (i1,i2,i3 in a) {
+ printf("a has %d,%d,%d\n", i1, i2, i3);
+ }
+ printf("test 4\n");
+ foreach (i1,i2,i3,i4 in a) {
+ printf("a has %d,%d,%d,%d\n", i1, i2, i3, i4);
+ }
+ printf("test 5\n");
+ foreach (i1,i2,i3,i4,i5,i6 in a) {
+ printf("a has %d,%d,%d,%d,%d,%d\n", i1, i2, i3, i4, i5, i6);
+ }
+ printf("test 6\n");
+ foreach (i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12 in a) {
+ printf("a has %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d\n",
+ i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12);
+ }
+ printf("end\n");
+}
+loop_1_2_2();
+} -output "test 1
+a has 1
+a has 2
+a has 3
+a has 4
+a has 5
+a has 6
+a has 7
+a has 8
+a has 9
+a has 10
+a has 11
+a has 12
+test 2
+a has 1,2
+a has 3,4
+a has 5,6
+a has 7,8
+a has 9,10
+a has 11,12
+test 3
+a has 1,2,3
+a has 4,5,6
+a has 7,8,9
+a has 10,11,12
+test 4
+a has 1,2,3,4
+a has 5,6,7,8
+a has 9,10,11,12
+test 5
+a has 1,2,3,4,5,6
+a has 7,8,9,10,11,12
+test 6
+a has 1,2,3,4,5,6,7,8,9,10,11,12
+end
+"
+
+test loop-1.2.3 {foreach with string variable lists} -body {
+#lang L --line=1
+void
+loop_1_2_3()
+{
+ string s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14;
+ string a[12] = { "a","b","c","d","e","f","g","h","i","j","k","l" };
+
+ printf("test 1\n");
+ foreach (s1 in a) {
+ printf("a has %s\n", s1);
+ }
+ printf("test 2\n");
+ foreach (s1,s2 in a) {
+ printf("a has %s,%s\n", s1, s2);
+ }
+ printf("test 3\n");
+ foreach (s1,s2,s3 in a) {
+ printf("a has %s,%s,%s\n", s1, s2, s3);
+ }
+ printf("test 4\n");
+ foreach (s1,s2,s3,s4 in a) {
+ printf("a has %s,%s,%s,%s\n", s1, s2, s3, s4);
+ }
+ printf("test 5\n");
+ foreach (s1,s2,s3,s4,s5,s6 in a) {
+ printf("a has %s,%s,%s,%s,%s,%s\n", s1, s2, s3, s4, s5, s6);
+ }
+ printf("test 6\n");
+ foreach (s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12 in a) {
+ printf("a has %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
+ s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12);
+ }
+
+ /*
+ * The following tests have a number of loop variables that
+ * isn't divisible by the number of list elements. On the
+ * last iteration, the stragglers should get undef.
+ */
+
+ printf("test 7\n");
+ foreach (s1,s2,s3,s4,s5 in a) {
+ printf("a has %s,%s,%s,%s,%s\n", s1, s2, s3, s4, s5);
+ if (s1 eq "k") {
+ unless (defined(s2)) puts("bad 1.1");
+ if (defined(s3)) puts("bad 1.2");
+ if (defined(s4)) puts("bad 1.3");
+ if (defined(s5)) puts("bad 1.4");
+ }
+ }
+
+ printf("test 8\n");
+ foreach (s1,s2,s3,s4,s5,s6,s7 in a) {
+ printf("a has %s,%s,%s,%s,%s,%s,%s\n",
+ s1, s2, s3, s4, s5, s6, s7);
+ if (s1 eq "h") {
+ unless (defined(s2)) puts("bad 2.1");
+ unless (defined(s3)) puts("bad 2.2");
+ unless (defined(s4)) puts("bad 2.3");
+ unless (defined(s5)) puts("bad 2.4");
+ if (defined(s6)) puts("bad 2.5");
+ if (defined(s7)) puts("bad 2.6");
+ }
+ }
+
+ printf("test 9\n");
+ foreach (s1,s2,s3,s4,s5,s6,s7,s8 in a) {
+ printf("a has %s,%s,%s,%s,%s,%s,%s,%s\n",
+ s1, s2, s3, s4, s5, s6, s7, s8);
+ if (s1 eq "i") {
+ unless (defined(s2)) puts("bad 3.1");
+ unless (defined(s3)) puts("bad 3.2");
+ unless (defined(s4)) puts("bad 3.3");
+ if (defined(s5)) puts("bad 3.4");
+ if (defined(s6)) puts("bad 3.5");
+ if (defined(s7)) puts("bad 3.6");
+ if (defined(s8)) puts("bad 3.7");
+ }
+ }
+
+ printf("test 10\n");
+ foreach (s1,s2,s3,s4,s5,s6,s7,s8,s9 in a) {
+ printf("a has %s,%s,%s,%s,%s,%s,%s,%s,%s\n",
+ s1, s2, s3, s4, s5, s6, s7, s8, s9);
+ if (s1 eq "j") {
+ unless (defined(s2)) puts("bad 4.1");
+ unless (defined(s3)) puts("bad 4.2");
+ if (defined(s4)) puts("bad 4.3");
+ if (defined(s5)) puts("bad 4.4");
+ if (defined(s6)) puts("bad 4.5");
+ if (defined(s7)) puts("bad 4.6");
+ if (defined(s8)) puts("bad 4.7");
+ if (defined(s9)) puts("bad 4.8");
+ }
+ }
+
+ printf("test 11\n");
+ foreach (s1,s2,s3,s4,s5,s6,s7,s8,s9,s10 in a) {
+ printf("a has %s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
+ s1, s2, s3, s4, s5, s6, s7, s8, s9, s10);
+ if (s1 eq "k") {
+ unless (defined(s2)) puts("bad 4.1");
+ if (defined(s3)) puts("bad 4.2");
+ if (defined(s4)) puts("bad 4.3");
+ if (defined(s5)) puts("bad 4.4");
+ if (defined(s6)) puts("bad 4.5");
+ if (defined(s7)) puts("bad 4.6");
+ if (defined(s8)) puts("bad 4.7");
+ if (defined(s9)) puts("bad 4.8");
+ if (defined(s10)) puts("bad 4.9");
+ }
+ }
+
+ printf("test 12\n");
+ foreach (s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11 in a) {
+ printf("a has %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
+ s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11);
+ if (s1 eq "l") {
+ if (defined(s2)) puts("bad 5.1");
+ if (defined(s3)) puts("bad 5.2");
+ if (defined(s4)) puts("bad 5.3");
+ if (defined(s5)) puts("bad 5.4");
+ if (defined(s6)) puts("bad 5.5");
+ if (defined(s7)) puts("bad 5.6");
+ if (defined(s8)) puts("bad 5.7");
+ if (defined(s9)) puts("bad 5.8");
+ if (defined(s10)) puts("bad 5.9");
+ if (defined(s11)) puts("bad 5.10");
+ }
+ }
+
+ printf("test 13\n");
+ foreach (s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13 in a) {
+ printf("a has %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
+ s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13);
+ unless (defined(s2)) puts("bad 6.1");
+ unless (defined(s3)) puts("bad 6.2");
+ unless (defined(s4)) puts("bad 6.3");
+ unless (defined(s5)) puts("bad 6.4");
+ unless (defined(s6)) puts("bad 6.5");
+ unless (defined(s7)) puts("bad 6.6");
+ unless (defined(s8)) puts("bad 6.7");
+ unless (defined(s9)) puts("bad 6.8");
+ unless (defined(s10)) puts("bad 6.9");
+ unless (defined(s11)) puts("bad 6.10");
+ unless (defined(s12)) puts("bad 6.11");
+ if (defined(s13)) puts("bad 6.12");
+ }
+
+ printf("test 14\n");
+ foreach (s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14 in a) {
+ printf("a has %s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n",
+ s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13,
+ s14);
+ unless (defined(s2)) puts("bad 7.1");
+ unless (defined(s3)) puts("bad 7.2");
+ unless (defined(s4)) puts("bad 7.3");
+ unless (defined(s5)) puts("bad 7.4");
+ unless (defined(s6)) puts("bad 7.5");
+ unless (defined(s7)) puts("bad 7.6");
+ unless (defined(s8)) puts("bad 7.7");
+ unless (defined(s9)) puts("bad 7.8");
+ unless (defined(s10)) puts("bad 7.9");
+ unless (defined(s11)) puts("bad 7.10");
+ unless (defined(s12)) puts("bad 7.11");
+ if (defined(s13)) puts("bad 7.12");
+ if (defined(s14)) puts("bad 7.13");
+ }
+
+ printf("end\n");
+}
+loop_1_2_3();
+} -output "test 1
+a has a
+a has b
+a has c
+a has d
+a has e
+a has f
+a has g
+a has h
+a has i
+a has j
+a has k
+a has l
+test 2
+a has a,b
+a has c,d
+a has e,f
+a has g,h
+a has i,j
+a has k,l
+test 3
+a has a,b,c
+a has d,e,f
+a has g,h,i
+a has j,k,l
+test 4
+a has a,b,c,d
+a has e,f,g,h
+a has i,j,k,l
+test 5
+a has a,b,c,d,e,f
+a has g,h,i,j,k,l
+test 6
+a has a,b,c,d,e,f,g,h,i,j,k,l
+test 7
+a has a,b,c,d,e
+a has f,g,h,i,j
+a has k,l,,,
+test 8
+a has a,b,c,d,e,f,g
+a has h,i,j,k,l,,
+test 9
+a has a,b,c,d,e,f,g,h
+a has i,j,k,l,,,,
+test 10
+a has a,b,c,d,e,f,g,h,i
+a has j,k,l,,,,,,
+test 11
+a has a,b,c,d,e,f,g,h,i,j
+a has k,l,,,,,,,,
+test 12
+a has a,b,c,d,e,f,g,h,i,j,k
+a has l,,,,,,,,,,
+test 13
+a has a,b,c,d,e,f,g,h,i,j,k,l,
+test 14
+a has a,b,c,d,e,f,g,h,i,j,k,l,,
+end
+"
+
+test loop-1.2.4 {foreach loops with large loop body (>127 bytes of bytecode)} -body {
+#lang L --line=1
+void
+loop_1_2_4()
+{
+ int i, k, v;
+ int a[3] = { 1,2,3 };
+ hash h = { 1=>2, 2=>3, 3=>4 };
+
+ printf("start\n");
+ foreach (i in a) {
+ /* Just do whatever to rack up bytecodes. */
+ int x = 1, y = 1, z = 1;
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19) puts("bad 1.1");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199) puts("bad 1.2");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999) puts("bad 1.3");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19999) puts("bad 1.4");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199999) puts("bad 1.5");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999999) puts("bad 1.6");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19999999) puts("bad 1.7");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199999999) puts("bad 1.8");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999999999) puts("bad 1.9");
+ x = y = z = 1;
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19) puts("bad 2.1");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199) puts("bad 2.2");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999) puts("bad 2.3");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19999) puts("bad 2.4");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199999) puts("bad 2.5");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999999) puts("bad 2.6");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19999999) puts("bad 2.7");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199999999) puts("bad 2.8");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999999999) puts("bad 2.9");
+ printf("a has %d\n", i);
+ }
+ foreach (k=>v in h) {
+ /* Just do whatever to rack up bytecodes. */
+ int x = 1, y = 1, z = 1;
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19) puts("bad 3.1");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199) puts("bad 3.2");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999) puts("bad 3.3");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19999) puts("bad 3.4");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199999) puts("bad 3.5");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999999) puts("bad 3.6");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19999999) puts("bad 3.7");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199999999) puts("bad 3.8");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999999999) puts("bad 3.9");
+ x = y = z = 1;
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19) puts("bad 4.1");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199) puts("bad 4.2");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999) puts("bad 4.3");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19999) puts("bad 4.4");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199999) puts("bad 4.5");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999999) puts("bad 4.6");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 19999999) puts("bad 4.7");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 199999999) puts("bad 4.8");
+ x = x+y*z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y+z+x*y;
+ unless (x == 1999999999) puts("bad 4.9");
+ printf("h has %d=>%d\n", k, v);
+ }
+ printf("end\n");
+}
+loop_1_2_4();
+} -output "start
+a has 1
+a has 2
+a has 3
+h has 1=>2
+h has 2=>3
+h has 3=>4
+end
+"
+
+test loop-1.2.5 {check hash foreach type checking} -body {
+#lang L --line=1
+void loop_1_2_5()
+{
+ int i1, i2;
+ string s1, s2;
+ string h{int};
+
+ foreach (s1=>s2 in h) ;
+ foreach (s1=>i2 in h) ;
+ foreach (i1=>i2 in h) ;
+}
+#lang tcl
+} -returnCodes error -match regexp -result {.*7: L Error: loop index key type incompatible.*
+.*8: L Error: loop index value type incompatible.*
+.*8: L Error: loop index key type incompatible.*
+.*9: L Error: loop index value type incompatible.*
+}
+
+test loop-1.2.6 {test foreach over string} -body {
+#lang L --line=1
+void loop_1_2_6()
+{
+ int i;
+ string a, b, c, d;
+ string as[];
+ poly p;
+
+ a = "x";
+ foreach (a in "") puts("bad 1.1");
+ if (defined(a)) puts("bad 1.2");
+
+ /* as[0] has the value undef */
+ a = "x";
+ if (defined(as[0])) puts("bad 2.0");
+ foreach(a in as[0]) puts("bad 2.1");
+ if (defined(a)) puts("bad 2.2");
+
+ i = 0;
+ foreach(a in "0123456789") {
+ unless (a eq (string)i++) printf("bad 2.1 i=%d\n", i);
+ }
+ i = 0;
+ foreach(p in "0123456789") {
+ unless (p eq (string)i++) printf("bad 2.2 i=%d\n", i);
+ }
+ i = 0;
+ foreach(a,b in "0123456789") {
+ unless (a eq (string)i++) printf("bad 3.1 i=%d\n", i);
+ unless (b eq (string)i++) printf("bad 3.2 i=%d\n", i);
+ }
+ i = 0;
+ foreach(a,b,c in "0123456789") {
+ unless (a eq (string)i++) printf("bad 4.1 i=%d\n", i);
+ if (i == 10) {
+ if (defined(b)) puts("bad 4.2 b undef");
+ if (defined(c)) puts("bad 4.2 c undef");
+ } else {
+ unless (b eq (string)i++) printf("bad 4.3 i=%d\n", i);
+ unless (c eq (string)i++) printf("bad 4.4 i=%d\n", i);
+ }
+ }
+ i = 0;
+ foreach(a,b,c,d in "0123456789") {
+ unless (a eq (string)i++) printf("bad 5.1 i=%d\n", i);
+ unless (b eq (string)i++) printf("bad 5.2 i=%d\n", i);
+ if (i == 10) {
+ if (defined(c)) puts("bad 5.2 b undef");
+ if (defined(d)) puts("bad 5.2 c undef");
+ } else {
+ unless (c eq (string)i++) printf("bad 5.3 i=%d\n", i);
+ unless (d eq (string)i++) printf("bad 5.4 i=%d\n", i);
+ }
+ }
+}
+loop_1_2_6();
+} -output {}
+
+test loop-1.2.7 {test foreach over string type errors} -body {
+#lang L --line=1
+class loop_1_2_7_class {}
+void loop_1_2_7()
+{
+ int i;
+ float f;
+ int a[];
+ int h{int};
+ loop_1_2_7_class o;
+ struct { int i,j; } st;
+
+ foreach(i in "string") {}
+ foreach(f in "string") {}
+ foreach(h in "string") {}
+ foreach(a in "string") {}
+ foreach(o in "string") {}
+ foreach(st in "string") {}
+}
+} -returnCodes error -match regexp -result {.*11: L Error: loop index not of string type
+.*12: L Error: loop index not of string type
+.*13: L Error: loop index not of string type
+.*14: L Error: loop index not of string type
+.*15: L Error: loop index not of string type
+.*16: L Error: loop index not of string type
+}
+
+test loop-1.2.7.1 {test foreach over <> errors} -body {
+#lang L --line=1
+void loop_1_2_7_1()
+{
+ int i;
+ string s;
+ FILE f;
+
+ foreach(s in <>) {}
+ foreach(s in <f>) {}
+ foreach(s in <1>) {}
+ foreach(i in <s>) {}
+ foreach(s,i in <s>) {}
+ foreach(i,s in <s>) {}
+ foreach(s,i,s in <s>) {}
+}
+loop_1_2_7_1();
+} -returnCodes error -match regexp -result {.*7: L Error: this form is disallowed; did you mean while \(buf = <>\)\?
+.*8: L Error: this form is disallowed; did you mean while \(buf = <F>\)\?
+.*9: L Error: in foreach, arg to <> must be a string
+.*10: L Error: loop index i not of string type
+.*11: L Error: loop index i not of string type
+.*12: L Error: loop index i not of string type
+}
+
+test loop-1.2.8 {test foreach type errors} -body {
+#lang L --line=1 -nowarn
+void loop_1_2_8()
+{
+ int i;
+ float f;
+ string s;
+ poly p;
+ struct { int i,j; } st;
+
+ foreach(s in p) ;
+ foreach(s in st) ;
+ foreach(s in {1}) ;
+ foreach(s in {1,2}) ;
+ foreach(s in {"s",1}) ;
+ foreach(s in {1,"s"}) ;
+ foreach(i,f in {1.0,2.0});
+ foreach(f,i in {1.0,2.0});
+
+ /* This could be made to work, but at present it's a type error. */
+ foreach(i,s in {1,"a"});
+}
+} -returnCodes error -match regexp -result {.*9: L Error: foreach expression must be array, hash, or string
+.*10: L Error: foreach expression must be array, hash, or string
+.*11: L Error: loop index type incompatible with array element type
+.*12: L Error: loop index type incompatible with array element type
+.*13: L Error: loop index type incompatible with array element type
+.*14: L Error: loop index type incompatible with array element type
+.*15: L Error: loop index type incompatible with array element type
+.*16: L Error: loop index type incompatible with array element type
+.*19: L Error: loop index type incompatible with array element type
+}
+
+test loop-1.2.9 {test foreach syntax errors} -body {
+#lang L --line=1
+void loop_1_2_9()
+{
+ string k, v;
+ string h{string};
+
+ /*
+ * This test was added after un-reserving the keyword "in",
+ * used in foreach loops. In the grammar, "in" was replaced
+ * with an id. Verify that using anything other than "in" is
+ * a syntax error.
+ */
+
+ foreach (k=>v bad h) ;
+}
+} -returnCodes error -match glob -result {*13: L Error: syntax error*
+ foreach (k=>v bad h) ;
+ ^
+}
+
+test loop-1.2.10 {test foreach syntax errors} -body {
+#lang L --line=1
+void loop_1_2_10()
+{
+ string k, v;
+ string h{string};
+
+ /*
+ * Second part of above test (we can test only one syntax
+ * error at a time).
+ */
+
+ foreach (k bad "xyz") ;
+}
+} -returnCodes error -match glob -result {*11: L Error: syntax error*
+ foreach (k bad "xyz") ;
+ ^
+}
+
+test loop-1.2.10.1 {test foreach usage errors} -body {
+#lang L --line=1 -nowarn
+void loop_1_2_10_1()
+{
+ string k, s, v;
+ string a[];
+
+ /* These are all errors. */
+
+ foreach (k=>v in a) {}
+ foreach (k=>v in s) {}
+}
+} -returnCodes error -match glob -result {*8: L Error: => illegal in foreach over arrays
+*9: L Error: => illegal in foreach over strings
+}
+
+test loop-1.2.11 {test that "in" is not reserved} -body {
+#lang L --line=1
+void loop_1_2_11()
+{
+ /*
+ * Verify that "in" is no longer a reserved word.
+ */
+
+ int in = 123;
+ unless (in == 123) puts("bad");
+}
+loop_1_2_11();
+} -output {}
+
+test loop-1.2.12 {check that loop counter is undef on foreach loop fall-through} -body {
+#lang L --line=1
+void loop_1_2_12()
+{
+ int i;
+ string k, s, t, u, v;
+ string as[];
+ string ah{string};
+
+ s = "abc";
+ i = 0;
+ t = "xyz";
+ unless (defined(t)) puts("bad 1.1");
+ foreach (t in s) { ++i; }
+ unless (i == 3) puts("bad 1.2");
+ if (defined(t)) puts("bad 1.3");
+
+ s = "abcd";
+ i = 0;
+ t = u = "xyz";
+ unless (defined(t) && defined(u)) puts("bad 2.1");
+ foreach (t,u in s) { ++i; }
+ unless (i == 2) puts("bad 2.2");
+ if (defined(t) || defined(u)) puts("bad 2.3");
+
+ as = { "1", "2", "3" };
+ i = 0;
+ s = "xyz";
+ unless (defined(s)) puts("bad 2.1");
+ foreach (s in as) { ++i; }
+ unless (i == 3) puts("bad 3.2");
+ if (defined(s)) puts("bad 3.3");
+
+ as = { "1", "2", "3", "4" };
+ i = 0;
+ s = t = "xyz";
+ unless (defined(s) && defined(t)) puts("bad 4.1");
+ foreach (s,t in as) { ++i; }
+ unless (i == 2) puts("bad 4.2");
+ if (defined(s) || defined(t)) puts("bad 4.3");
+
+ ah = { "k1"=>"1", "k2"=>"2", "k3"=>"3" };
+ i = 0;
+ k = "xyz";
+ unless (defined(k)) puts("bad 5.1");
+ foreach (k in ah) { ++i; }
+ unless (i == 3) puts("bad 5.2");
+ if (defined(k)) puts("bad 5.3");
+
+ i = 0;
+ k = "xyz";
+ v = "qrs";
+ unless (defined(k) && defined(v)) puts("bad 4.1");
+ foreach (k=>v in ah) { ++i; }
+ unless (i == 3) puts("bad 4.2");
+ if (defined(k) || defined(v)) puts("bad 4.3");
+}
+loop_1_2_12();
+} -output {}
+
+test loop-1.2.13 {test foreach over a list type} -body {
+#lang L --line=1
+private int equals(poly a[], poly b[])
+{
+ unless (length(a) == length(b)) return (0);
+ while (defined(a[0])) {
+ unless (defined(a[0]) == defined(b[0])) return (0);
+ unless (a[0] == b[0]) return (0);
+ // shift
+ undef(a[0]);
+ undef(b[0]);
+ }
+ assert(!defined(b[0]));
+ return (1);
+}
+
+void loop_1_2_13()
+{
+ int i, i2, i3, ai[];
+ string s, s2, s3, as[];
+ float f, f2, f3, af[];
+
+ /* First do a quick test of the equals() helper function. */
+ ai = {1,2,3};
+ unless (equals(ai, {1,2,3})) puts("bad 0.1");
+ if (equals(ai, {1,2})) puts("bad 0.2");
+ if (equals(ai, {1,2,3,4})) puts("bad 0.3");
+ if (equals(ai, {1,3,2})) puts("bad 0.4");
+ as = {"a","b","c"};
+ unless (equals(as, {"a","b","c"})) puts("bad 0.5");
+ if (equals(as, {"a","b"})) puts("bad 0.6");
+ if (equals(as, {"a","b","c","d"})) puts("bad 0.7");
+ if (equals(as, {"a","c","b"})) puts("bad 0.8");
+ af = {1, 2.2, 3};
+ unless (equals(af, {1,2.2,3})) puts("bad 0.9");
+ if (equals(af, {1,2.2})) puts("bad 0.10");
+ if (equals(af, {1,2.2,3,4})) puts("bad 0.11");
+ if (equals(af, {1,3,2.2})) puts("bad 0.12");
+
+ undef(ai);
+ foreach (i in {1}) push(&ai, i);
+ unless (equals(ai, {1})) puts("bad 1.1");
+
+ undef(ai);
+ foreach (i in {1,2}) push(&ai, i);
+ unless (equals(ai, {1,2})) puts("bad 2.1");
+
+ undef(ai);
+ foreach (i in {1,2,3}) push(&ai, i);
+ unless (equals(ai, {1,2,3})) puts("bad 3.1");
+
+ undef(ai);
+ foreach (i,i2 in {1,2,3}) {
+ push(&ai, i);
+ if (defined(i2)) push(&ai, i2);
+ }
+ unless (equals(ai, {1,2,3})) puts("bad 4.1");
+
+ undef(ai);
+ foreach (i,i2,i3 in {1,2,3}) {
+ push(&ai, i);
+ push(&ai, i2);
+ push(&ai, i3);
+ }
+ unless (equals(ai, {1,2,3})) puts("bad 5.1");
+
+ undef(as);
+ foreach (s in {"a"}) push(&as, s);
+ unless (equals(as, {"a"})) puts("bad 10.1");
+
+ undef(as);
+ foreach (s in {"a","b"}) push(&as, s);
+ unless (equals(as, {"a","b"})) puts("bad 10.2");
+
+ undef(as);
+ foreach (s in {"a","b","c"}) push(&as, s);
+ unless (equals(as, {"a","b","c"})) puts("bad 10.3");
+
+ undef(as);
+ foreach (s,s2 in {"a","b","c"}) {
+ push(&as, s);
+ if (defined(s2)) push(&as, s2);
+ }
+ unless (equals(as, {"a","b","c"})) puts("bad 10.4");
+
+ undef(as);
+ foreach (s,s2,s3 in {"a","b","c"}) {
+ push(&as, s);
+ push(&as, s2);
+ push(&as, s3);
+ }
+ unless (equals(as, {"a","b","c"})) puts("bad 10.5");
+
+ undef(af);
+ foreach (f in {1}) push(&af, f);
+ unless (equals(af, {1})) puts("bad 20.1");
+
+ undef(af);
+ foreach (f in {1.1}) push(&af, f);
+ unless (equals(af, {1.1})) puts("bad 20.2");
+
+ undef(af);
+ foreach (f in {1.1,2}) push(&af, f);
+ unless (equals(af, {1.1,2})) puts("bad 20.3");
+
+ undef(af);
+ foreach (f in {1.1,2,3.3}) push(&af, f);
+ unless (equals(af, {1.1,2,3.3})) puts("bad 20.4");
+
+ undef(af);
+ foreach (f,f2 in {1.1,2,3.3}) {
+ push(&af, f);
+ if (defined(f2)) push(&af, f2);
+ }
+ unless (equals(af, {1.1,2,3.3})) puts("bad 20.5");
+
+ undef(af);
+ foreach (f,f2,f3 in {1.1,2,3.3}) {
+ push(&af, f);
+ push(&af, f2);
+ push(&af, f3);
+ }
+ unless (equals(af, {1.1,2,3.3})) puts("bad 20.6");
+}
+loop_1_2_13();
+} -output {}
+
+test loop-1.2.14 {test empty condition in for statement} -body {
+#lang L --line=1
+void loop_1_2_14()
+{
+ int i = 0;
+
+ for (;; ++i) {
+ break;
+ }
+ unless (i == 0) puts("bad 1");
+
+ i = 0;
+ for (;;) {
+ ++i;
+ break;
+ }
+ unless (i == 1) puts("bad 2");
+}
+loop_1_2_14();
+} -output {}
+
+test loop-1.2.15 {test foreach <string>} -body {
+#lang L
+string l1_2_15(string s)
+{
+ string t, ret = "";
+
+ foreach (t in <s>) ret .= "<${t?t:'undef'}>";
+ if (t) puts("bad l1_2_15");
+ return (ret);
+}
+string l1_2_15_2(string s)
+{
+ string t1, t2, ret = "";
+
+ foreach (t1,t2 in <s>) ret .= "<${t1?t1:'undef'}>[${t2?t2:'undef'}]";
+ if (t1 || t2) puts("bad l1_2_15_2");
+ return (ret);
+}
+string l1_2_15_3(string s)
+{
+ string t1, t2, t3, ret = "";
+
+ foreach (t1,t2,t3 in <s>) {
+ ret .= "<${t1?t1:'undef'}>[${t2?t2:'undef'}]{${t3?t3:'undef'}}";
+ }
+ if (t1 || t2 || t3) puts("bad l1_2_15_3");
+ return (ret);
+}
+void loop_1_2_15()
+{
+ string s, t;
+
+ /* Check a stride of 1, \n line endings. */
+
+ unless (l1_2_15(undef) == "") puts("bad 1.1");
+ unless (l1_2_15("") == "") puts("bad 1.2");
+
+ unless (l1_2_15("l1") == "<l1>") puts("bad 2.1");
+ unless (l1_2_15("l1\n") == "<l1>") puts("bad 2.2");
+
+ unless (l1_2_15("l1\nl2") == "<l1><l2>") puts("bad 3.1");
+ unless (l1_2_15("l1\nl2\n") == "<l1><l2>") puts("bad 3.2");
+
+ unless (l1_2_15("l1\nl2\nl3") == "<l1><l2><l3>") puts("bad 4.1");
+ unless (l1_2_15("l1\nl2\nl3\n") == "<l1><l2><l3>") puts("bad 4.2");
+
+ /* Check a stride of 1, \r\n line endings. */
+
+ unless (l1_2_15("l1\r\n") == "<l1>") puts("bad 5.1");
+
+ unless (l1_2_15("l1\r\nl2") == "<l1><l2>") puts("bad 6.1");
+ unless (l1_2_15("l1\r\nl2\r\n") == "<l1><l2>") puts("bad 6.2");
+
+ unless (l1_2_15("l1\r\nl2\r\nl3") == "<l1><l2><l3>") puts("bad 7.1");
+ unless (l1_2_15("l1\r\nl2\r\nl3\r\n") == "<l1><l2><l3>") puts("bad 7.2");
+
+ /* Check a stride of 2, \n line endings. */
+
+ unless (l1_2_15_2(undef) == "") puts("bad 10.1");
+ unless (l1_2_15_2("") == "") puts("bad 10.2");
+
+ unless (l1_2_15_2("l1") == "<l1>[undef]") puts("bad 11.1");
+ unless (l1_2_15_2("l1\n") == "<l1>[undef]") puts("bad 11.2");
+
+ unless (l1_2_15_2("l1\nl2") == "<l1>[l2]") puts("bad 12.1");
+ unless (l1_2_15_2("l1\nl2\n") == "<l1>[l2]") puts("bad 12.2");
+
+ unless (l1_2_15_2("l1\nl2\nl3") == "<l1>[l2]<l3>[undef]") {
+ puts("bad 13.1");
+ }
+ unless (l1_2_15_2("l1\nl2\nl3\n") == "<l1>[l2]<l3>[undef]") {
+ puts("bad 13.2");
+ }
+
+ unless (l1_2_15_2("l1\nl2\nl3\nl4") == "<l1>[l2]<l3>[l4]") {
+ puts("bad 14.1");
+ }
+ unless (l1_2_15_2("l1\nl2\nl3\nl4\n") == "<l1>[l2]<l3>[l4]") {
+ puts("bad 14.2");
+ }
+
+ /* Check a stride of 2, \r\n line endings. */
+
+ unless (l1_2_15_2("l1\r\n") == "<l1>[undef]") puts("bad 15.1");
+
+ unless (l1_2_15_2("l1\r\nl2") == "<l1>[l2]") puts("bad 16.1");
+ unless (l1_2_15_2("l1\r\nl2\r\n") == "<l1>[l2]") puts("bad 16.2");
+
+ unless (l1_2_15_2("l1\r\nl2\r\nl3") == "<l1>[l2]<l3>[undef]") {
+ puts("bad 17.1");
+ }
+ unless (l1_2_15_2("l1\r\nl2\r\nl3\r\n") == "<l1>[l2]<l3>[undef]") {
+ puts("bad 17.2");
+ }
+
+ unless (l1_2_15_2("l1\r\nl2\r\nl3\r\nl4") == "<l1>[l2]<l3>[l4]") {
+ puts("bad 18.1");
+ }
+ unless (l1_2_15_2("l1\r\nl2\r\nl3\r\nl4\r\n") == "<l1>[l2]<l3>[l4]") {
+ puts("bad 18.2");
+ }
+
+ /* Check a stride of 3, \n line endings. */
+
+ unless (l1_2_15_3(undef) == "") puts("bad 20.1");
+ unless (l1_2_15_3("") == "") puts("bad 20.2");
+
+ unless (l1_2_15_3("l1") == "<l1>[undef]{undef}") puts("bad 21.1");
+ unless (l1_2_15_3("l1\n") == "<l1>[undef]{undef}") puts("bad 21.2");
+
+ unless (l1_2_15_3("l1\nl2") == "<l1>[l2]{undef}") puts("bad 22.1");
+ unless (l1_2_15_3("l1\nl2\n") == "<l1>[l2]{undef}") puts("bad 22.2");
+
+ unless (l1_2_15_3("l1\nl2\nl3") == "<l1>[l2]{l3}") puts("bad 23.1");
+ unless (l1_2_15_3("l1\nl2\nl3\n") == "<l1>[l2]{l3}") puts("bad 23.2");
+
+ unless (l1_2_15_3("l1\nl2\nl3\nl4") == "<l1>[l2]{l3}<l4>[undef]{undef}") {
+ puts("bad 24.1");
+ }
+ unless (l1_2_15_3("l1\nl2\nl3\nl4\n") == "<l1>[l2]{l3}<l4>[undef]{undef}") {
+ puts("bad 24.2");
+ }
+
+ unless (l1_2_15_3("l1\nl2\nl3\nl4\nl5") == "<l1>[l2]{l3}<l4>[l5]{undef}") {
+ puts("bad 25.1");
+ }
+ unless (l1_2_15_3("l1\nl2\nl3\nl4\nl5\n") == "<l1>[l2]{l3}<l4>[l5]{undef}") {
+ puts("bad 25.2");
+ }
+
+ unless (l1_2_15_3("l1\nl2\nl3\nl4\nl5\nl6") == "<l1>[l2]{l3}<l4>[l5]{l6}") {
+ puts("bad 26.1");
+ }
+ unless (l1_2_15_3("l1\nl2\nl3\nl4\nl5\nl6\n") == "<l1>[l2]{l3}<l4>[l5]{l6}") {
+ puts("bad 26.2");
+ }
+
+ /* Check a stride of 3, \r\n line endings. */
+
+ unless (l1_2_15_3("l1\r\n") == "<l1>[undef]{undef}") puts("bad 27.1");
+
+ unless (l1_2_15_3("l1\r\nl2") == "<l1>[l2]{undef}") puts("bad 28.1");
+ unless (l1_2_15_3("l1\r\nl2\r\n") == "<l1>[l2]{undef}") puts("bad 28.2");
+
+ unless (l1_2_15_3("l1\r\nl2\r\nl3") == "<l1>[l2]{l3}") {
+ puts("bad 29.1");
+ }
+ unless (l1_2_15_3("l1\r\nl2\r\nl3\r\n") == "<l1>[l2]{l3}") {
+ puts("bad 29.2");
+ }
+
+ unless (l1_2_15_3("l1\r\nl2\r\nl3\r\nl4") == "<l1>[l2]{l3}<l4>[undef]{undef}") {
+ puts("bad 30.1");
+ }
+ unless (l1_2_15_3("l1\r\nl2\r\nl3\r\nl4\r\n") == "<l1>[l2]{l3}<l4>[undef]{undef}") {
+ puts("bad 30.2");
+ }
+
+ unless (l1_2_15_3("l1\r\nl2\r\nl3\r\nl4\r\nl5") == "<l1>[l2]{l3}<l4>[l5]{undef}") {
+ puts("bad 31.1");
+ }
+ unless (l1_2_15_3("l1\r\nl2\r\nl3\r\nl4\r\nl5\r\n") == "<l1>[l2]{l3}<l4>[l5]{undef}") {
+ puts("bad 31.2");
+ }
+
+ unless (l1_2_15_3("l1\r\nl2\r\nl3\r\nl4\r\nl5\r\nl6") == "<l1>[l2]{l3}<l4>[l5]{l6}") {
+ puts("bad 32.1");
+ }
+ unless (l1_2_15_3("l1\r\nl2\r\nl3\r\nl4\r\nl5\r\nl6\r\n") == "<l1>[l2]{l3}<l4>[l5]{l6}") {
+ puts("bad 32.2");
+ }
+
+ /* Check break and continue from inside the foreach. */
+
+ t = "";
+ foreach (s in <"l1\nl2\nl3\nl4\n">) {
+ t .= "b<${s}>";
+ if (s == "l1") continue;
+ if (s == "l2") break;
+ t .= "a<${s}>";
+ }
+ unless (t == "b<l1>b<l2>") puts("bad 50.1 ${t}");
+ unless (s == "l2") puts("bad 50.2");
+}
+loop_1_2_15();
+} -output {}
+
+test loop-1.2.15.1 {test foreach <string>} -body {
+#lang L
+void loop_1_2_15_1()
+{
+ string s = "1\n2\n\3\n4\n";
+ string k, v;
+
+ foreach (k => v in <s>) printf("%s,%s\n", k, v);
+}
+loop_1_2_15_1();
+} -returnCodes error -match regexp -result {.*: L Error: => illegal in foreach over strings}
+
+test loop-1.3 {continue statements} -body {
+#lang L --line=1
+void loop_1_3_for_continue()
+{
+ int i;
+
+ for (i = 0; i < 5; i++) {
+ if (i == 2) continue;
+ puts(i);
+ }
+}
+
+void loop_1_3_foreach_continue()
+{
+ string k, l, v;
+ string as[] = { "1", "2", "3", "4", "5" };
+ hash h;
+
+ h{"a"} = "x";
+ h{"b"} = "y";
+ h{"c"} = "z";
+
+ printf("foreach test 1\n");
+ foreach (k => v in h) {
+ if (k eq "b") continue;
+ printf("%s => %s\n", k, v);
+ }
+
+ printf("foreach test 2\n");
+ foreach (l in h) {
+ if (l eq "c") continue;
+ foreach (k => v in h) {
+ if (k eq "b") continue;
+ printf("%s: %s => %s\n", l, k, v);
+ }
+ }
+
+ printf("foreach test 3\n");
+ foreach (v in as) {
+ if ((v ge "2") && (v le "4")) continue;
+ printf("%s\n", v);
+ }
+
+ printf("foreach test 4\n");
+ foreach (l in "abcdefg") {
+ if ((l ge "d") && (l le "f")) continue;
+ printf("%s\n", l);
+ }
+}
+
+void loop_1_3_do_while_continue()
+{
+ int i;
+
+ printf("do while test\n");
+ i = -1;
+ do {
+ ++i;
+ if ((i == 1) || (i == 2)) continue;
+ puts(i);
+ } while (i < 5);
+}
+
+void loop_1_3_while_continue()
+{
+ int i;
+
+ printf("while test\n");
+ i = -1;
+ while (i < 5) {
+ ++i;
+ if ((i == 1) || (i == 2)) continue;
+ puts(i);
+ };
+}
+
+void loop_1_3()
+{
+ loop_1_3_for_continue();
+ loop_1_3_foreach_continue();
+ loop_1_3_do_while_continue();
+ loop_1_3_while_continue();
+}
+#lang tcl
+loop_1_3
+} -output {0
+1
+3
+4
+foreach test 1
+a => x
+c => z
+foreach test 2
+a: a => x
+a: c => z
+b: a => x
+b: c => z
+foreach test 3
+1
+5
+foreach test 4
+a
+b
+c
+g
+do while test
+0
+3
+4
+5
+while test
+0
+3
+4
+5
+}
+
+test loop-1.4 {break statements} -body {
+#lang L --line=1
+void loop_1_4_foreach_break()
+{
+ string k, l, v;
+ string as[] = { "1", "2", "3", "4", "5" };
+ hash h;
+
+ h{"a"} = "x";
+ h{"b"} = "y";
+ h{"c"} = "z";
+ foreach (l in h) {
+ foreach (k => v in h) {
+ if (k eq "b") break;
+ }
+ }
+ printf("loops over, k is %s, v is %s\n", k, v);
+
+ foreach (l in as) {
+ if (l eq "3") break;
+ }
+ printf("l is %s\n", l);
+
+ foreach (l in "abcdefg") {
+ if (l eq "c") break;
+ }
+ printf("l is %s\n", l);
+}
+
+void loop_1_4_for_break()
+{
+ int i;
+
+ for (i = 0; i < 10; i++) {
+ puts(i);
+ if (i == 5) {
+ puts("attempting to break");
+ break;
+ }
+ }
+ printf("at the end of the day, i is %d\n", i);
+}
+
+void loop_1_4_do_while_break()
+{
+ int i;
+
+ i = 0;
+ do {
+ ++i;
+ if (i == 3) break;
+ } while (i < 5);
+ printf("do while i = %d\n", i);
+}
+
+void loop_1_4_while_break()
+{
+ int i;
+
+ i = 0;
+ while (i < 5) {
+ ++i;
+ if (i == 3) break;
+ }
+ printf("while i = %d\n", i);
+}
+
+void loop_1_4()
+{
+ loop_1_4_foreach_break();
+ loop_1_4_for_break();
+ loop_1_4_do_while_break();
+ loop_1_4_while_break();
+}
+
+#lang tcl
+loop_1_4
+} -output {loops over, k is b, v is y
+l is 3
+l is c
+0
+1
+2
+3
+4
+5
+attempting to break
+at the end of the day, i is 5
+do while i = 3
+while i = 3
+}
+
+test loop-1.5 {continues in nested foreach loops} -body {
+#lang L --line=1
+void
+loop_1_5_fill3(int d1, int d2, int d3, int &a[][][])
+{
+ int i, j, k;
+
+ for (i = 0; i < d1; ++i) {
+ for (j = 0; j < d2; ++j) {
+ for (k = 0; k < d3; ++k) {
+ a[i][j][k] = (i+1)*100 + (j+1)*10 + k+1;
+ }
+ }
+ }
+}
+
+void
+loop_1_5()
+{
+ int d1, d2, vi;
+ int ai[3];
+ int aii[3][3];
+ int aiii[3][3][3];
+
+ loop_1_5_fill3(3, 3, 3, &aiii);
+
+ printf("test 1\n");
+ foreach (aii in aiii) {
+ foreach (ai in aii) {
+ foreach (vi in ai) {
+ // Omit all even numbers.
+ if ((vi%2) == 0) continue;
+ printf("aiii has %d\n", vi);
+ }
+ }
+ }
+ printf("test 2\n");
+ d1 = d2 = 0;
+ foreach (aii in aiii) {
+ ++d1;
+ foreach (ai in aii) {
+ ++d2;
+ // Omit 11x.
+ if (d2 == 1) continue;
+ foreach (vi in ai) {
+ printf("aiii has %d\n", vi);
+ }
+ }
+ }
+ printf("test 3\n");
+ d1 = d2 = 0;
+ foreach (aii in aiii) {
+ ++d1;
+ // Omit 1xx.
+ if (d1 == 1) continue;
+ foreach (ai in aii) {
+ ++d2;
+ foreach (vi in ai) {
+ printf("aiii has %d\n", vi);
+ }
+ }
+ }
+ printf("test 4\n");
+ d1 = d2 = 0;
+ foreach (aii in aiii) {
+ ++d1;
+ // Omit 1xx.
+ if (d1 == 1) continue;
+ foreach (ai in aii) {
+ ++d2;
+ // Omit 21x.
+ if (d2 == 1) continue;
+ foreach (vi in ai) {
+ printf("aiii has %d\n", vi);
+ }
+ }
+ }
+ printf("test 5\n");
+ d1 = d2 = 0;
+ foreach (aii in aiii) {
+ ++d1;
+ // Omit 1xx.
+ if (d1 == 1) continue;
+ foreach (ai in aii) {
+ ++d2;
+ // Omit 21x.
+ if (d2 == 1) continue;
+ foreach (vi in ai) {
+ // Omit 3xx.
+ if (vi >= 300) continue;
+ printf("aiii has %d\n", vi);
+ }
+ }
+ }
+ printf("end\n");
+}
+
+loop_1_5();
+} -output "test 1
+aiii has 111
+aiii has 113
+aiii has 121
+aiii has 123
+aiii has 131
+aiii has 133
+aiii has 211
+aiii has 213
+aiii has 221
+aiii has 223
+aiii has 231
+aiii has 233
+aiii has 311
+aiii has 313
+aiii has 321
+aiii has 323
+aiii has 331
+aiii has 333
+test 2
+aiii has 121
+aiii has 122
+aiii has 123
+aiii has 131
+aiii has 132
+aiii has 133
+aiii has 211
+aiii has 212
+aiii has 213
+aiii has 221
+aiii has 222
+aiii has 223
+aiii has 231
+aiii has 232
+aiii has 233
+aiii has 311
+aiii has 312
+aiii has 313
+aiii has 321
+aiii has 322
+aiii has 323
+aiii has 331
+aiii has 332
+aiii has 333
+test 3
+aiii has 211
+aiii has 212
+aiii has 213
+aiii has 221
+aiii has 222
+aiii has 223
+aiii has 231
+aiii has 232
+aiii has 233
+aiii has 311
+aiii has 312
+aiii has 313
+aiii has 321
+aiii has 322
+aiii has 323
+aiii has 331
+aiii has 332
+aiii has 333
+test 4
+aiii has 221
+aiii has 222
+aiii has 223
+aiii has 231
+aiii has 232
+aiii has 233
+aiii has 311
+aiii has 312
+aiii has 313
+aiii has 321
+aiii has 322
+aiii has 323
+aiii has 331
+aiii has 332
+aiii has 333
+test 5
+aiii has 221
+aiii has 222
+aiii has 223
+aiii has 231
+aiii has 232
+aiii has 233
+end
+"
+
+test loop-1.6 {breaks in nested foreach loops} -body {
+#lang L --line=1
+void
+loop_1_6_fill3(int d1, int d2, int d3, int &a[][][])
+{
+ int i, j, k;
+
+ for (i = 0; i < d1; ++i) {
+ for (j = 0; j < d2; ++j) {
+ for (k = 0; k < d3; ++k) {
+ a[i][j][k] = (i+1)*100 + (j+1)*10 + k+1;
+ }
+ }
+ }
+}
+
+void
+loop_1_6()
+{
+ int d1, d2, vi;
+ int ai[3];
+ int aii[3][3];
+ int aiii[3][3][3];
+
+ loop_1_6_fill3(3, 3, 3, &aiii);
+
+ printf("test 1\n");
+ foreach (aii in aiii) {
+ foreach (ai in aii) {
+ foreach (vi in ai) {
+ // Should have no output.
+ break;
+ printf("aiii has %d\n", vi);
+ }
+ }
+ }
+ printf("test 2\n");
+ d1 = d2 = 0;
+ foreach (aii in aiii) {
+ ++d1;
+ foreach (ai in aii) {
+ ++d2;
+ // Omit 13x.
+ if (d2 == 3) break;
+ foreach (vi in ai) {
+ printf("aiii has %d\n", vi);
+ }
+ }
+ }
+ printf("test 3\n");
+ d1 = d2 = 0;
+ foreach (aii in aiii) {
+ ++d1;
+ // Omit [23]xx.
+ if (d1 == 2) break;
+ foreach (ai in aii) {
+ ++d2;
+ foreach (vi in ai) {
+ printf("aiii has %d\n", vi);
+ }
+ }
+ }
+ printf("end\n");
+}
+
+loop_1_6();
+} -output "test 1
+test 2
+aiii has 111
+aiii has 112
+aiii has 113
+aiii has 121
+aiii has 122
+aiii has 123
+aiii has 211
+aiii has 212
+aiii has 213
+aiii has 221
+aiii has 222
+aiii has 223
+aiii has 231
+aiii has 232
+aiii has 233
+aiii has 311
+aiii has 312
+aiii has 313
+aiii has 321
+aiii has 322
+aiii has 323
+aiii has 331
+aiii has 332
+aiii has 333
+test 3
+aiii has 111
+aiii has 112
+aiii has 113
+aiii has 121
+aiii has 122
+aiii has 123
+aiii has 131
+aiii has 132
+aiii has 133
+end
+"
+
+test loop-1.6.1 {test break and continue errors} -body {
+#lang L --line=1
+/*
+ * Try a break and continue in various (non-loop) constructs
+ * that open up a new scope in the compiler. All of these
+ * should be errors.
+ */
+void loop_1_6_1()
+{
+ break;
+ continue;
+ {
+ break;
+ continue;
+ }
+ if (1) {
+ break;
+ continue;
+ } else {
+ break;
+ continue;
+ }
+ switch (1) {
+ case 1:
+ continue;
+ }
+}
+break;
+continue;
+} -returnCodes error -match regexp -result {.*8: L Error: break allowed only inside switch and loop statements
+.*9: L Error: continue allowed only inside loops
+.*11: L Error: break allowed only inside switch and loop statements
+.*12: L Error: continue allowed only inside loops
+.*15: L Error: break allowed only inside switch and loop statements
+.*16: L Error: continue allowed only inside loops
+.*18: L Error: break allowed only inside switch and loop statements
+.*19: L Error: continue allowed only inside loops
+.*23: L Error: continue allowed only inside loops
+.*26: L Error: break allowed only inside switch and loop statements
+.*27: L Error: continue allowed only inside loops
+}
+
+test loop-1.7 {test loop condition with regexp captures} -body {
+#lang L --line=1
+void loop_1_7()
+{
+ /*
+ * This checks for an earlier compiler bug where the loop
+ * condition was sometimes compiled before the loop body,
+ * causing any regexp capture variable references to possibly
+ * become undeclared-variable references.
+ */
+
+ int it;
+
+ it = 0;
+ while ("abc" =~ /(a)(b)/) {
+ ++it;
+ unless (($1 eq "a") && ($2 eq "b")) {
+ puts("bad 1.1");
+ }
+ break;
+ }
+ unless (it == 1) puts("bad 1.2");
+
+ /* Use more captures than last time. */
+ for (it = 0; "abcd" =~ /(a)(b)(c)(d)/; ) {
+ ++it;
+ unless (($1 eq "a") && ($2 eq "b") && ($3 eq "c") &&
+ ($4 eq "d")) {
+ puts("bad 2.1");
+ }
+ break;
+ }
+ unless (it == 1) puts("bad 2.2");
+}
+loop_1_7();
+} -output {}
+
+test switch-1.1 {check switch statement, if-then-else code} -body {
+#lang L --line=1
+/*
+ * This test exercises the case of non-constant case expressions in
+ * switch statements, for which the compiler generates if-then-else
+ * style code. Only one case value must be non-constant, which is why
+ * you see "0+zero" etc below.
+ */
+void switch_1_1()
+{
+ int a, b, c, d, i;
+ int zero = 0;
+ int ia[] = { 3, 1, 4, 1 };
+ string m, mm, mvar, s, s1, s2, s3, s4, s5;
+ string sa[] = { "abc", "def", "ghi", "JkL" };
+ widget w;
+
+ /* Test empty switch statement. */
+ i = 0;
+ switch (++i) {}
+ unless (i == 1) puts("bad 0.1");
+
+ /* Test string and regexp matching. */
+ s = "";
+ for (i = 0; i < length(sa); ++i) {
+ switch (sa[i]) {
+ case "abc":
+ unless (i == 0) puts("bad 1.1");
+ s .= "a";
+ break;
+ case /de/:
+ unless (i == 1) puts("bad 1.2");
+ s .= "d";
+ break;
+ case /a*c*f*g/:
+ unless (i == 2) puts("bad 1.3");
+ s .= "g";
+ break;
+ case /jkl/:
+ puts("bad 1.4");
+ break;
+ case /jkl/i:
+ unless (i == 3) puts("bad 1.5");
+ s .= "j";
+ break;
+ case "bad":
+ puts("bad 1.6");
+ break;
+ case /also bad/:
+ puts("bad 1.7");
+ break;
+ }
+ }
+ unless (s eq "adgj") puts("bad 1.9");
+
+ /* Test matching on ints. */
+ s = "";
+ for (i = 0; i < length(ia); ++i) {
+ switch (ia[i]) {
+ case 0+zero: // for a non-constant case value
+ puts("bad 2.1");
+ break;
+ case 1:
+ unless ((i == 1) || (i == 3)) puts("bad 2.2");
+ s .= "1";
+ break;
+ case 2:
+ puts("bad 2.3");
+ break;
+ case 3:
+ unless (i == 0) puts("bad 2.4");
+ s .= "3";
+ break;
+ case 4:
+ unless (i == 2) puts("bad 2.5");
+ s .= "4";
+ break;
+ }
+ }
+ unless (s eq "3141") puts("bad 2.9");
+
+ /* Test checking for undef. */
+
+ s = undef;
+ i = 0;
+ switch (s) {
+ case undef:
+ ++i;
+ break;
+ default:
+ puts("bad 2.11");
+ break;
+ }
+ unless (i == 1) puts("bad 2.12");
+
+ s = "";
+ i = 0;
+ switch (s) {
+ case undef:
+ puts("bad 2.13");
+ break;
+ default:
+ ++i;
+ break;
+ }
+ unless (i == 1) puts("bad 2.14");
+
+ s = s1 = undef;
+ i = 0;
+ switch (s) {
+ case s1:
+ puts("bad 2.15");
+ break;
+ case undef:
+ ++i;
+ case "fall through to this one":
+ ++i;
+ break;
+ default:
+ puts("bad 2.16");
+ break;
+ }
+ unless (i == 2) puts("bad 2.17");
+
+ s = s1 = undef;
+ i = 0;
+ switch (s) {
+ case undef:
+ ++i;
+ break;
+ case s1:
+ puts("bad 2.18");
+ break;
+ default:
+ puts("bad 2.19");
+ break;
+ }
+ unless (i == 1) puts("bad 2.20");
+
+ s = undef;
+ s1 = "";
+ i = 0;
+ switch (s) {
+ case s1:
+ puts("bad 2.21");
+ break;
+ case undef:
+ ++i;
+ break;
+ default:
+ puts("bad 2.22");
+ break;
+ }
+ unless (i == 1) puts("bad 2.23");
+
+ /* Test case fall through. */
+ s = "";
+ switch (1) {
+ case 1+zero:
+ s .= "1";
+ case 2:
+ s .= "2";
+ break;
+ case 3:
+ s .= "3";
+ }
+ unless (s eq "12") puts("bad 3.1");
+
+ /* Test multiple cases per leg. */
+ s = "";
+ for (i = 0; i < 6; ++i) {
+ switch (i) {
+ case 0+zero:
+ s .= "0";
+ break;
+ case 1:
+ case 2:
+ s .= (string)i;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ s .= (string)i;
+ break;
+ }
+ }
+ unless (s eq "012345") puts("bad 4.1");
+
+ /* Test default case in the end, beginning, and middle of the cases. */
+
+ s = "";
+ switch (3) {
+ case 0+zero:
+ puts("bad 5.1");
+ break;
+ default:
+ s .= "d";
+ break;
+ }
+ unless (s eq "d") puts("bad 5.2");
+
+ s = "";
+ switch (3) {
+ default:
+ s .= "d";
+ break;
+ case 0+zero:
+ puts("bad 5.3");
+ break;
+ }
+ unless (s eq "d") puts("bad 5.4");
+
+ s = "";
+ switch (3) {
+ case 1+zero:
+ puts("bad 5.5");
+ break;
+ default:
+ s .= "d";
+ break;
+ case 0:
+ puts("bad 5.6");
+ break;
+ }
+ unless (s eq "d") puts("bad 5.7");
+
+ /* Test falling thru to and from the default case. */
+
+ s = "";
+ switch (3) {
+ case 3+zero:
+ s .= "3";
+ default:
+ s .= "d";
+ break;
+ }
+ unless (s eq "3d") puts("bad 6.1");
+
+ s = "";
+ switch (3) {
+ default:
+ s .= "d";
+ case 0+zero:
+ s .= "0";
+ break;
+ }
+ unless (s eq "d0") puts("bad 6.2");
+
+ s = "";
+ switch (3) {
+ case 0:
+ s .= "0";
+ break;
+ default:
+ s .= "d";
+ case 1+zero:
+ s .= "1";
+ break;
+ }
+ unless (s eq "d1") puts("bad 6.3");
+
+ s = "";
+ switch (3) {
+ default:
+ s .= "d";
+ case 1+zero:
+ s .= "1";
+ case 0:
+ s .= "0";
+ }
+ unless (s eq "d10") puts("bad 6.4");
+
+ s = "";
+ switch (3) {
+ case 1+zero:
+ s .= "1";
+ default:
+ s .= "d";
+ case 0:
+ s .= "0";
+ }
+ unless (s eq "d0") puts("bad 6.5");
+
+ /* Test empty case bodies. */
+
+ s = "";
+ for (i = 0; i < 4; ++i) {
+ switch (i) {
+ case 0+zero:
+ case 1:
+ case 3:
+ s .= (string)i;
+ break;
+ case 2:
+ default:
+ }
+ }
+ unless (s eq "013") puts("bad 7.2");
+
+ s = "";
+ switch (2) {
+ case 2+zero:
+ default:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.3");
+
+ s = "";
+ switch (0) {
+ case 2+zero:
+ default:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.4");
+
+ s = "";
+ switch (2) {
+ default:
+ case 2+zero:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.5");
+
+ s = "";
+ switch (0) {
+ default:
+ case 2+zero:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.6");
+
+ s = "";
+ switch (2) {
+ case 2+zero:
+ default:
+ case 1:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.7");
+
+ s = "";
+ switch (1) {
+ case 2+zero:
+ default:
+ case 1:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.8");
+
+ s = "";
+ switch (0) {
+ case 2+zero:
+ default:
+ case 1:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.9");
+
+ /* Test various whitespace around regexp, and regexp variations. */
+ s = "";
+ m = "nn";
+ mm = "oo";
+ mvar = "pp";
+ foreach (s1 in {"aa","bb","cc","dd","ee","ff","gg","hh","ii",
+ "jj","kk","ll","mm","nn","oo","pp"}) {
+ switch (s1) {
+ // the next line has a tab after the "case"
+ case /aa/: s .= "1"; break;
+ case m|bb|: s .= "2"; break;
+ case m|Cc|i: s .= "3"; break;
+ case m#dd#: s .= "4"; break;
+ case m#eE#i: s .= "5"; break;
+ case m)ff): s .= "6"; break;
+ case m)Gg)i: s .= "7"; break;
+ case m,hh,: s .= "8"; break;
+ case m,Ii,i: s .= "9"; break;
+ case m!jj!: s .= "a"; break;
+ case m!Kk!i: s .= "b"; break;
+ case m"ll": s .= "c"; break;
+ case m"Mm"i: s .= "d"; break;
+ // the next ones aren't regexps
+ case m: s .= "e"; break; // variable m
+ case mm: s .= "f"; break; // variable mm
+ case mvar: s .= "g"; break; // variable mvar
+ }
+ }
+ unless (s eq "123456789abcdefg") puts("bad 8.1");
+
+ /* Test interpolations in regexp's. */
+ s = "";
+ s1 = "ab";
+ s2 = "ef";
+ s3 = "g";
+ s4 = "i";
+ s5 = "jkl";
+ for (i = 0; i < length(sa); ++i) {
+ switch (sa[i]) {
+ case /${s1}c/:
+ s .= "a";
+ break;
+ case /d${s2}/:
+ s .= "d";
+ break;
+ case /${s3}h${s4}/:
+ s .= "g";
+ break;
+ case /${s5}/i:
+ s .= "j";
+ break;
+ }
+ }
+ unless (s eq "adgj") puts("bad 9.1");
+
+ /* Test $1 $2 etc available in cases. */
+ switch ("This is a test") {
+ case /(test)/:
+ unless ($1 eq "test") puts("bad 10.1");
+ break;
+ }
+ switch ("This is a test") {
+ case /(a) (test)/:
+ unless ($1 eq "a") puts("bad 10.2");
+ unless ($2 eq "test") puts("bad 10.3");
+ break;
+ }
+
+ /* Test labeled statements in cases. */
+
+ i = 0;
+ switch (1) {
+ case 1+zero:
+ lab1: if (i++) break;
+ goto lab1;
+ }
+ unless (i == 2) puts("bad 11.1");
+
+ i = 0;
+ switch (0) {
+ case 1+zero:
+ lab2: if (i++) break;
+ goto lab2;
+ default:
+ lab3: if (i++) break;
+ goto lab3;
+ }
+ unless (i == 2) puts("bad 11.2");
+
+ /*
+ * Test goto out of the switch to check that the run-time
+ * stack remains balanced. This used to crash due to a bug.
+ * However, it's difficult to see the regression as a crash in
+ * a release build. If we have the loop below iterate only a few
+ * times, the Tcl bytecode engine seems to happily scribble
+ * memory but on some platforms it is in a region where
+ * it does not cause a crash. I'm hesitant to have the loop
+ * iterate too many times since Larry already doesn't like how
+ * long the L tests take. But it can easily be seen in a Tcl
+ * debug build.
+ */
+
+ for (i = 1; i < 1000; ++i) {
+ switch (i) {
+ case i:
+ goto sw_1_1_next;
+ }
+ sw_1_1_next:
+ }
+
+ /*
+ * Test id: at end of case expression. At one point this used
+ * to cause a syntax error.
+ */
+
+ i = 0;
+ switch (0) {
+ case i:
+ ++i;
+ break;
+ default:
+ puts("bad 12.1");
+ break;
+ }
+ unless (i == 1) puts("bad 12.2");
+
+ i = 0;
+ switch (0) {
+ case 1+i-1-i:
+ ++i;
+ break;
+ default:
+ puts("bad 12.3");
+ break;
+ }
+ unless (i == 1) puts("bad 12.4");
+
+ /*
+ * Test that the right comparison bytecode is generated
+ * (string vs numeric).
+ */
+ i = 0;
+ switch ("0") {
+ case "00":
+ puts("bad 13.1");
+ break;
+ case /0/:
+ default:
+ ++i;
+ break;
+ }
+ unless (i == 1) puts("bad 13.2");
+
+ /*
+ * Check that integer switch expressions and the case values
+ * are properly canonicalized.
+ */
+
+ s = "";
+ for (i = 0; i <= 3; ++i) {
+ switch (i) {
+ case 0:
+ s .= "0";
+ break;
+ case 0x1:
+ s .= "1";
+ break;
+ case 0o2:
+ s .= "2";
+ break;
+ case 000000003:
+ s .= "3";
+ break;
+ case 99+0:
+ default:
+ puts("bad 13.3");
+ break;
+ }
+ }
+ unless (s eq "0123") puts("bad 13.4");
+
+ s = "";
+ for (i = 100000000000000000000; i <= 100000000000000000003; ++i) {
+ switch (i) {
+ case 100000000000000000000:
+ s .= "0";
+ break;
+ case 0x56bc75e2d63100001:
+ s .= "1";
+ break;
+ case 0o12657072742654304000002:
+ s .= "2";
+ break;
+ case 0000000000000100000000000000000003:
+ s .= "3";
+ break;
+ case 99+0:
+ default:
+ puts("bad 13.5");
+ break;
+ }
+ }
+ unless (s eq "0123") puts("bad 13.6");
+
+ s = "";
+ a = (poly)"100000000000000000000";
+ b = (poly)"0x56bc75e2d63100001"; // this is a+1
+ c = (poly)"0o12657072742654304000002"; // this is a+2
+ d = (poly)"100000000000000000003"; // this is a+3
+ for (i = 100000000000000000000; i <= 100000000000000000003; ++i) {
+ switch (i) {
+ case a:
+ s .= "0";
+ break;
+ case b:
+ s .= "1";
+ break;
+ case c:
+ s .= "2";
+ break;
+ case d:
+ s .= "3";
+ break;
+ default:
+ puts("bad 13.7");
+ break;
+ }
+ }
+ unless (s eq "0123") puts("bad 13.8");
+
+ s = "";
+ i = (poly)"0x1"; // don't use (int) since that canonicalizes
+ switch (i) {
+ case 1:
+ s .= "1";
+ break;
+ case 99+0:
+ default:
+ puts("bad 13.9");
+ break;
+ }
+ unless (s eq "1") puts("bad 13.10");
+
+ /* Test switching on a widget type. */
+
+ w = "2";
+ s = "";
+ switch (w) {
+ case "1":
+ puts("bad 14.1");
+ break;
+ case /2/:
+ s .= "1";
+ break;
+ default:
+ puts("bad 14.2");
+ break;
+ }
+ unless (s eq "1") puts("bad 14.3");
+}
+switch_1_1();
+} -output {}
+
+test switch-1.2 {check switch statement, jump-table code} -body {
+#lang L --line=1
+/*
+ * This test exercises the case of constant case expressions in switch
+ * statements, for which the compiler generates a jump table. This is
+ * basically the above test edited to have only constant case values.
+ */
+void switch_1_2()
+{
+ int i;
+ int ia[] = { 3, 1, 4, 1 };
+ string s;
+ string sa[] = { "abc", "def", "ghi", "JkL", "00" };
+ widget w;
+
+ /* Test string matching. */
+ s = "";
+ for (i = 0; i < length(sa); ++i) {
+ switch (sa[i]) {
+ case "abc":
+ unless (i == 0) puts("bad 1.1");
+ s .= "a";
+ break;
+ case "def":
+ unless (i == 1) puts("bad 1.2");
+ s .= "d";
+ break;
+ case "ghi":
+ unless (i == 2) puts("bad 1.3");
+ s .= "g";
+ break;
+ case "jkl":
+ puts("bad 1.4");
+ break;
+ case "JkL":
+ unless (i == 3) puts("bad 1.5");
+ s .= "j";
+ break;
+ case "bad":
+ puts("bad 1.6");
+ break;
+ case "also bad":
+ puts("bad 1.7");
+ break;
+ case "0": // should not match "00"
+ puts("bad 1.8");
+ break;
+ }
+ }
+ unless (s eq "adgj") {puts("bad 1.9"); puts(s); }
+
+ /*
+ * Test matching on ints. The leading zeros check that the
+ * compiler isn't doing a pure string match.
+ */
+ s = "";
+ for (i = 0; i < length(ia); ++i) {
+ switch (ia[i]) {
+ case 0:
+ puts("bad 2.1");
+ break;
+ case 01:
+ unless ((i == 1) || (i == 3)) puts("bad 2.2");
+ s .= "1";
+ break;
+ case 2:
+ puts("bad 2.3");
+ break;
+ case 003:
+ unless (i == 0) puts("bad 2.4");
+ s .= "3";
+ break;
+ case 4:
+ unless (i == 2) puts("bad 2.5");
+ s .= "4";
+ break;
+ }
+ }
+ unless (s eq "3141") puts("bad 2.9");
+
+ /* Test case fall through. */
+ s = "";
+ switch (1) {
+ case 1:
+ s .= "1";
+ case 2:
+ s .= "2";
+ break;
+ case 3:
+ s .= "3";
+ }
+ unless (s eq "12") puts("bad 3.1");
+
+ /* Test multiple cases per leg. */
+ s = "";
+ for (i = 0; i < 6; ++i) {
+ switch (i) {
+ case 0:
+ s .= "0";
+ break;
+ case 1:
+ case 2:
+ s .= (string)i;
+ break;
+ case 3:
+ case 4:
+ case 5:
+ s .= (string)i;
+ break;
+ }
+ }
+ unless (s eq "012345") puts("bad 4.1");
+
+ /* Test default case in the end, beginning, and middle of the cases. */
+
+ s = "";
+ switch (3) {
+ case 0:
+ puts("bad 5.1");
+ break;
+ default:
+ s .= "d";
+ break;
+ }
+ unless (s eq "d") puts("bad 5.2");
+
+ s = "";
+ switch (3) {
+ default:
+ s .= "d";
+ break;
+ case 0:
+ puts("bad 5.3");
+ break;
+ }
+ unless (s eq "d") puts("bad 5.4");
+
+ s = "";
+ switch (3) {
+ case 1:
+ puts("bad 5.5");
+ break;
+ default:
+ s .= "d";
+ break;
+ case 0:
+ puts("bad 5.6");
+ break;
+ }
+ unless (s eq "d") puts("bad 5.7");
+
+ /* Test lone default clause. */
+ s = "";
+ switch (3) {
+ default:
+ s .= "d";
+ }
+ unless (s eq "d") puts("bad 5.8");
+
+ /* Test falling thru to and from the default case. */
+
+ s = "";
+ switch (3) {
+ case 3:
+ s .= "3";
+ default:
+ s .= "d";
+ break;
+ }
+ unless (s eq "3d") puts("bad 6.1");
+
+ s = "";
+ switch (3) {
+ default:
+ s .= "d";
+ case 0:
+ s .= "0";
+ break;
+ }
+ unless (s eq "d0") puts("bad 6.2");
+
+ s = "";
+ switch (3) {
+ case 0:
+ s .= "0";
+ break;
+ default:
+ s .= "d";
+ case 1:
+ s .= "1";
+ break;
+ }
+ unless (s eq "d1") puts("bad 6.3");
+
+ s = "";
+ switch (3) {
+ default:
+ s .= "d";
+ case 1:
+ s .= "1";
+ case 0:
+ s .= "0";
+ }
+ unless (s eq "d10") puts("bad 6.4");
+
+ s = "";
+ switch (3) {
+ case 1:
+ s .= "1";
+ default:
+ s .= "d";
+ case 0:
+ s .= "0";
+ }
+ unless (s eq "d0") puts("bad 6.5");
+
+ /* Test empty case bodies. */
+
+ s = "";
+ for (i = 0; i < 4; ++i) {
+ switch (i) {
+ case 0:
+ case 1:
+ case 3:
+ s .= (string)i;
+ break;
+ case 2:
+ default:
+ }
+ }
+ unless (s eq "013") puts("bad 7.2");
+
+ s = "";
+ switch (2) {
+ case 2:
+ default:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.3");
+
+ s = "";
+ switch (0) {
+ case 2:
+ default:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.4");
+
+ s = "";
+ switch (2) {
+ default:
+ case 2:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.5");
+
+ s = "";
+ switch (0) {
+ default:
+ case 2:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.6");
+
+ s = "";
+ switch (2) {
+ case 2:
+ default:
+ case 1:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.7");
+
+ s = "";
+ switch (1) {
+ case 2:
+ default:
+ case 1:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.8");
+
+ s = "";
+ switch (0) {
+ case 2:
+ default:
+ case 1:
+ s .= "x";
+ break;
+ }
+ unless (s eq "x") puts("bad 7.9");
+
+ /* Test labeled statements in cases. */
+
+ i = 0;
+ switch (1) {
+ case 1:
+ lab1: if (i++) break;
+ goto lab1;
+ }
+ unless (i == 2) puts("bad 11.1");
+
+ i = 0;
+ switch (0) {
+ case 1:
+ lab2: if (i++) break;
+ goto lab2;
+ default:
+ lab3: if (i++) break;
+ goto lab3;
+ }
+ unless (i == 2) puts("bad 11.2");
+
+ /*
+ * Test that the right comparison bytecode is generated
+ * (string vs numeric).
+ */
+
+ i = 0;
+ switch ("0") {
+ case "00":
+ puts("bad 13.1");
+ break;
+ default:
+ ++i;
+ break;
+ }
+ unless (i == 1) puts("bad 13.2");
+
+ /*
+ * Check that integer switch expressions and the case values
+ * are properly canonicalized.
+ */
+
+ s = "";
+ for (i = 0; i <= 3; ++i) {
+ switch (i) {
+ case 0:
+ s .= "0";
+ break;
+ case 0x1:
+ s .= "1";
+ break;
+ case 0o2:
+ s .= "2";
+ break;
+ case 000000003:
+ s .= "3";
+ break;
+ default:
+ puts("bad 13.3");
+ break;
+ }
+ }
+ unless (s eq "0123") puts("bad 13.4");
+
+ s = "";
+ for (i = 100000000000000000000; i <= 100000000000000000003; ++i) {
+ switch (i) {
+ case 100000000000000000000:
+ s .= "0";
+ break;
+ case 0x56bc75e2d63100001:
+ s .= "1";
+ break;
+ case 0o12657072742654304000002:
+ s .= "2";
+ break;
+ case 0000000000000100000000000000000003:
+ s .= "3";
+ break;
+ default:
+ puts("bad 13.5");
+ break;
+ }
+ }
+ unless (s eq "0123") puts("bad 13.6");
+
+ s = "";
+ i = (poly)"0x1"; // don't use (int) since that canonicalizes
+ switch (i) {
+ case 1:
+ s .= "1";
+ break;
+ default:
+ puts("bad 13.7");
+ break;
+ }
+ unless (s eq "1") puts("bad 13.8");
+
+ /* Test switching on a widget type. */
+
+ w = "2";
+ s = "";
+ switch (w) {
+ case "1":
+ puts("bad 14.1");
+ break;
+ case "2":
+ s .= "1";
+ break;
+ default:
+ puts("bad 14.2");
+ break;
+ }
+ unless (s eq "1") puts("bad 14.3");
+}
+switch_1_2();
+} -output {}
+
+test switch-2 {test multiple-default-clause error in switch stmt} -body {
+#lang L --line=1
+void switch_2()
+{
+ switch (0) {
+ default:
+ break;
+ default:
+ break;
+ }
+ switch (0) {
+ default:
+ break;
+ default:
+ break;
+ default:
+ break;
+ }
+ switch (0) {
+ default:
+ default:
+ break;
+ }
+ switch (0) {
+ default:
+ default:
+ }
+ switch (0) {
+ default:
+ case 0:
+ break;
+ default:
+ }
+}
+} -returnCodes error -match regexp -result {.*6: L Error: multiple default cases in switch statement
+.*12: L Error: multiple default cases in switch statement
+.*14: L Error: multiple default cases in switch statement
+.*19: L Error: multiple default cases in switch statement
+.*24: L Error: multiple default cases in switch statement
+.*30: L Error: multiple default cases in switch statement
+}
+
+test switch-3.0 {test case m() function call} -setup {
+ makeFile {
+ /*
+ * Put this in its own file to avoid polluting
+ * the global name space with a function m().
+ */
+ string m(...args)
+ {
+ string ret = "", s;
+
+ foreach (s in args) ret .= s;
+ return (ret);
+ }
+ void main()
+ {
+ string s, t;
+
+ s = "";
+ foreach (t in {"","abc","def","ghi"}) {
+ /* Here m() is a function call not a regexp. */
+ switch (t) {
+ case m(): s .= "1"; break;
+ case m("abc"): s .= "2"; break;
+ case m("de","f"): s .= "3"; break;
+ case m("g","h","i"): s .= "4"; break;
+ }
+ }
+ unless (s == "1234") puts("bad 1: ${s}");
+ }
+ } switch-3.0.l
+} -body {
+#lang L
+void switch_3_0()
+{
+ int ret;
+ string tclsh = interpreter();
+ string out, err;
+
+ ret = system({tclsh, "switch-3.0.l"}, undef, &out, &err);
+ unless (ret == 0) puts("bad 1.1");
+ if (out) puts("bad 1.2: ${out}");
+ if (err) puts("bad 1.3: ${err}");
+}
+switch_3_0();
+} -output {}
+
+test switch-3.1 {test type errors in switch stmt} -body {
+#lang L --line=1
+void switch_3_1()
+{
+ switch (0) {
+ case /regexp/: // type err
+ }
+ switch ("string") {
+ case 0: // type err
+ }
+}
+} -returnCodes error -match regexp -result {.*4: L Error: case type incompatible with switch expression
+.*7: L Error: case type incompatible with switch expression
+}
+
+test switch-3.2 {test other errors in switch stmt} -body {
+#lang L --line=1
+void switch_3_2()
+{
+ switch ("string") {
+ case /re/g: // bad regexp modifier
+ case /re/ig: // bad regexp modifier
+ }
+}
+} -returnCodes error -match regexp -result {.*4: L Error: illegal regular expression modifier
+.*5: L Error: illegal regular expression modifier
+}
+
+test switch-3.3 {test duplicate case values in switch stmt} -body {
+#lang L --line=1
+void switch_3_3()
+{
+ switch ((poly)0) {
+ case 0:
+ case 0:
+ case 1:
+ case 1:
+ case 1:
+ case "s":
+ case "s":
+ }
+}
+} -returnCodes error -match regexp -result {.*5: L Error: duplicate case value
+.*7: L Error: duplicate case value
+.*8: L Error: duplicate case value
+.*10: L Error: duplicate case value
+}
+
+test switch-4 {test illegal types in switch stmt} -body {
+#lang L --line=1
+void switch_4_v() {}
+class switch_4_c {}
+void switch_4()
+{
+ int arr[];
+ string hsh{int};
+ switch_4_c obj;
+ struct { int i,j; } st;
+
+ /* These are all errors - only int, string, and poly are legal. */
+
+ /* constant case expressions */
+ switch (0.0) {
+ case 0:
+ }
+ switch(arr) {
+ case 0:
+ }
+ switch(hsh) {
+ case 0:
+ }
+ switch(obj) {
+ case 0:
+ }
+ switch(st) {
+ case 0:
+ }
+ switch(switch_4_v()) {
+ case 0:
+ }
+
+ /* non-constant case expressions */
+ switch (0.0) {
+ case 1+2:
+ }
+ switch(arr) {
+ case 1+2:
+ }
+ switch(hsh) {
+ case 1+2:
+ }
+ switch(obj) {
+ case 1+2:
+ }
+ switch(st) {
+ case 1+2:
+ }
+ switch(switch_4_v()) {
+ case 1+2:
+ }
+}
+} -returnCodes error -match regexp -result {.*13: L Error: switch expression must be int or string
+.*16: L Error: switch expression must be int or string
+.*19: L Error: switch expression must be int or string
+.*22: L Error: switch expression must be int or string
+.*25: L Error: switch expression must be int or string
+.*28: L Error: switch expression must be int or string
+.*33: L Error: switch expression must be int or string
+.*36: L Error: switch expression must be int or string
+.*39: L Error: switch expression must be int or string
+.*42: L Error: switch expression must be int or string
+.*45: L Error: switch expression must be int or string
+.*48: L Error: switch expression must be int or string
+}
+
+test switch-5 {test break as a label in switch stmt} -body {
+#lang L --line=1
+void switch_5()
+{
+ /*
+ * Check that break: is an error. This used to be allowed
+ * and was the source of a very hard-to-find bug.
+ */
+ switch (1) {
+ case 1:
+ break:
+ case 2:
+ break;
+ }
+
+ /* It's illegal anywhere, not just in a switch. */
+ break:
+}
+switch_5();
+} -returnCodes error -match regexp -result {.*9: L Error: break is not a legal label
+.*15: L Error: break is not a legal label
+}
+
+test struct-1.0 {structs} -body {
+#lang L --line=1
+struct struct_1_0_point {
+ int x, y;
+ string label;
+};
+
+void struct_1_0() {
+ struct struct_1_0_point p1, p2;
+
+ p1.x = 1;
+ p1.y = 2;
+ p1.label = "this is a label";
+ puts("p1 is:");
+ puts(p1);
+ puts(format("p1.x is %d, p1.y is %d, and p1.label is %s", p1.x, p1.y, p1.label));
+ p2 = p1;
+ p2.label = "this is another label";
+ puts("p1 is:");
+ puts(p1);
+ puts("p2 is:");
+ puts(p2);
+}
+#lang tcl
+struct_1_0
+} -output "p1 is:
+1 2 {this is a label}
+p1.x is 1, p1.y is 2, and p1.label is this is a label
+p1 is:
+1 2 {this is a label}
+p2 is:
+1 2 {this is another label}
+"
+
+test struct-1.1 {struct allocation and arrays of structs} -body {
+#lang L --line=1
+struct struct_1_1_point {
+ int x, y;
+ string label;
+};
+
+void struct_1_1() {
+ int i = 0;
+ struct struct_1_1_point s[10];
+
+ while(i < 10) {
+ s[i].y = i;
+ s[i].x = 42 + i;
+ s[i].label = format("%d cows", 10 - i);
+ i++;
+ }
+ for (i=0; i<10; i++) {
+ puts(s[i]);
+ }
+}
+#lang tcl
+struct_1_1
+} -output "42 0 {10 cows}
+43 1 {9 cows}
+44 2 {8 cows}
+45 3 {7 cows}
+46 4 {6 cows}
+47 5 {5 cows}
+48 6 {4 cows}
+49 7 {3 cows}
+50 8 {2 cows}
+51 9 {1 cows}
+"
+
+test struct-1.2 {arrays of structs containing arrays} -body {
+#lang L --line=1
+struct struct_1_2_point {
+ int x, y;
+ string label;
+ int z[4];
+};
+
+void struct_1_2() {
+ int i = 0;
+ struct struct_1_2_point s[10];
+
+ while(i < 10) {
+ s[i].y = i;
+ s[i].x = 42 + i;
+ s[i].label = format("%d cows", 10 - i);
+ s[i].z[i%4] = i;
+ i++;
+ }
+ for (i=0; i<10; i++) {
+ puts(s[i]);
+ }
+}
+#lang tcl
+struct_1_2
+} -output "42 0 {10 cows} 0
+43 1 {9 cows} {{} 1}
+44 2 {8 cows} {{} {} 2}
+45 3 {7 cows} {{} {} {} 3}
+46 4 {6 cows} 4
+47 5 {5 cows} {{} 5}
+48 6 {4 cows} {{} {} 6}
+49 7 {3 cows} {{} {} {} 7}
+50 8 {2 cows} 8
+51 9 {1 cows} {{} 9}
+"
+
+test struct-1.3 {increment and decrement on struct fields} -body {
+#lang L --line=1
+struct foo {
+ int i;
+};
+
+void struct_1_3() {
+ struct foo v;
+
+ v.i = 0;
+ for (v.i=0; v.i<5; v.i++);
+ puts(v);
+
+ puts("pre:");
+ puts(v.i);
+ ++v.i;
+ puts(v.i);
+ puts(++v.i);
+ --v.i;
+ puts(v.i);
+ puts(--v.i);
+
+ puts("post:");
+ puts(v.i);
+ v.i++;
+ puts(v.i);
+ puts(v.i++);
+ puts(v.i);
+ v.i--;
+ puts(v.i);
+ puts(v.i--);
+ puts(v.i);
+}
+#lang tcl
+struct_1_3
+} -output "5\npre:\n5\n6\n7\n6\n5\npost:\n5\n6\n6\n7\n6\n6\n5\n"
+
+test struct-1.4 {check struct type declarations} -body {
+#lang L --line=1
+struct struct_1_4_1 {
+ int i;
+ int j;
+};
+struct struct_1_4_2;
+struct struct_1_4_3 {
+ int i;
+ int j;
+ struct struct_1_4_2 st;
+};
+struct struct_1_4_2 {
+ string s;
+};
+void struct_1_4()
+{
+ struct struct_1_4_1 st1 = { 2, 3 };
+ struct struct_1_4_2 st2 = { "s2" };
+ struct struct_1_4_3 st3 = { 4, 5, { "s3" } };
+ /* This redeclaration hides the global one. */
+ struct struct_1_4_2 { int k,l; } st4 = { 6, 7 };
+
+ unless ((st1.i == 2) && (st1.j == 3)) puts("bad 1");
+ unless (st2.s eq "s2") puts("bad 2");
+ unless ((st3.i == 4) && (st3.j == 5) && (st3.st.s eq "s3")) {
+ puts("bad 3");
+ }
+ unless ((st4.k == 6) && (st4.l == 7)) puts("bad 4");
+
+ if (1) {
+ /* This redeclaration hides the global one in this scope. */
+ struct struct_1_4_1 { string t,u; } st5 = { "t", "u" };
+ unless ((st5.t eq "t") && (st5.u eq "u")) puts("bad 5");
+ }
+ if (1) {
+ /* This should reference the global one. */
+ struct struct_1_4_1 st6 = { 8, 9 };
+ unless ((st6.i == 8) && (st6.j == 9)) puts("bad 7");
+ }
+}
+#lang tcl
+struct_1_4
+} -output {}
+
+test struct-1.5 {check multiple struct type declarations} -body {
+#lang L --line=1
+struct struct_1_5_1 { int i,j; };
+struct struct_1_5_1 { int i,j; };
+struct struct_1_5_2 { int i,j; };
+void struct_1_5_1()
+{
+ struct struct_1_5_2 { string s; } st1;
+ struct struct_1_5_2 { string s; } st2;
+}
+} -returnCodes error -match regexp -result {.*2: L Error: multiple declaration of struct struct_1_5_1.*7: L Error: multiple declaration of struct struct_1_5_2
+}
+
+test struct-1.6 {check struct member errors} -body {
+#lang L --line=1
+void struct_1_6()
+{
+ struct struct_1_6 { string s; } st;
+ st.x = 1; // err -- x is not a member
+}
+} -returnCodes error -match regexp -result {.*4: L Error: struct field x not found
+}
+
+test hash-1.0 {basic hashtable support} -body {
+#lang L --line=1
+void hash_1_0() {
+ hash foo;
+ foo{"key"} = "value";
+ puts(foo{"key"});
+}
+#lang tcl
+hash_1_0
+} -output "value\n"
+
+test hash-1.1 {array of hashtables} -body {
+#lang L --line=1
+void hash_1_1() {
+ hash foo[10];
+ foo[5]{"key"} = "value";
+ foo[4]{"key"} = "";
+ puts(foo[5]{"key"});
+ puts(foo[4]{"key"});
+}
+#lang tcl
+hash_1_1
+} -output "value\n\n"
+
+test hash-1.2 {increment and decrement on hash elements} -body {
+#lang L --line=1 -poly
+void hash_1_2() {
+ hash foo;
+
+ foo{"three"} = 0;
+ for (foo{"three"}=0; foo{"three"}<5; foo{"three"}++);
+ puts(foo);
+
+ puts("pre:");
+ puts(foo{"three"});
+ ++foo{"three"};
+ puts(foo{"three"});
+ puts(++foo{"three"});
+ --foo{"three"};
+ puts(foo{"three"});
+ puts(--foo{"three"});
+
+ puts("post:");
+ puts(foo{"three"});
+ foo{"three"}++;
+ puts(foo{"three"});
+ puts(foo{"three"}++);
+ puts(foo{"three"});
+ foo{"three"}--;
+ puts(foo{"three"});
+ puts(foo{"three"}--);
+ puts(foo{"three"});
+ puts(foo);
+}
+#lang tcl
+hash_1_2
+} -output "three 5\npre:\n5\n6\n7\n6\n5\npost:\n5\n6\n6\n7\n6\n6\n5\nthree 5\n"
+
+# test hash-1.3 removed
+
+test hash-1.4 {basic hash element types} -body {
+#lang L --line=1
+struct sh14 {
+ int x;
+ int y;
+};
+void
+hash_1_4()
+{
+ int ki, vi;
+ string ks, vs;
+ float kf, vf;
+ poly kp, vp;
+ struct sh14 vst;
+ int ihi{int};
+ int ihs{string};
+ int ihf{float};
+ int ihp{poly};
+ string shi{int};
+ string shs{string};
+ string shf{float};
+ string shp{poly};
+ float fhi{int};
+ float fhs{string};
+ float fhf{float};
+ float fhp{poly};
+ poly phi{int};
+ poly phs{string};
+ poly phf{float};
+ poly php{poly};
+ struct sh14 sthi{int};
+ struct sh14 sths{string};
+ struct sh14 sthf{float};
+ struct sh14 sthp{poly};
+
+ printf("start\n");
+
+ ihi{0} = 100;
+ ihi{1} = 101;
+ ihi{2} = 102;
+ foreach (ki=>vi in ihi) {
+ printf("ihi has %d=>%d\n", ki, vi);
+ }
+
+ ihs{"zero"} = 100;
+ ihs{"one"} = 101;
+ ihs{"two"} = 102;
+ foreach (ks=>vi in ihs) {
+ printf("ihs has %s=>%d\n", ks, vi);
+ }
+
+ ihf{1.1} = 100;
+ ihf{2.2} = 101;
+ ihf{3.3} = 102;
+ foreach (kf=>vi in ihf) {
+ printf("ihf has %3.1f=>%d\n", kf, vi);
+ }
+
+ ihp{0} = 100;
+ ihp{"two"} = 101;
+ ihp{3.3} = 102;
+ foreach (kp=>vi in ihp) {
+ printf("ihp has %s=>%d\n", kp, vi);
+ }
+
+ shi{0} = "zero";
+ shi{1} = "one";
+ shi{2} = "two";
+ foreach (ki=>vs in shi) {
+ printf("shi has %d=>%s\n", ki, vs);
+ }
+
+ shs{"zero"} = "zero0";
+ shs{"one"} = "one1";
+ shs{"two"} = "two2";
+ foreach (ks=>vs in shs) {
+ printf("shs has %s=>%s\n", ks, vs);
+ }
+
+ shf{1.1} = "one.one";
+ shf{2.2} = "two.two";
+ shf{3.3} = "three.three";
+ foreach (kf=>vs in shf) {
+ printf("shf has %3.1f=>%s\n", kf, vs);
+ }
+
+ shp{0} = "zero";
+ shp{1.1} = "one.one";
+ shp{"two"} = "two2";
+ foreach (kp=>vs in shp) {
+ printf("shp has %s=>%s\n", kp, vs);
+ }
+
+ fhi{0} = 1.1;
+ fhi{1} = 2.2;
+ fhi{2} = 3.3;
+ foreach (ki=>vf in fhi) {
+ printf("fhi has %d=>%3.1f\n", ki, vf);
+ }
+
+ fhs{"zero"} = 1.1;
+ fhs{"one"} = 2.2;
+ fhs{"two"} = 3.3;
+ foreach (ks=>vf in fhs) {
+ printf("fhs has %s=>%3.1f\n", ks, vf);
+ }
+
+ fhf{1.1} = 11.1;
+ fhf{2.2} = 22.2;
+ fhf{3.3} = 33.3;
+ foreach (kf=>vf in fhf) {
+ printf("fhf has %3.1f=>%3.1f\n", kf, vf);
+ }
+
+ fhp{0} = 1.1;
+ fhp{1.1} = 2.2;
+ fhp{"two"} = 3.3;
+ foreach (kp=>vf in fhp) {
+ printf("fhp has %s=>%3.1f\n", kp, vf);
+ }
+
+ phi{0} = 1;
+ phi{1} = "two";
+ phi{2} = 3.3;
+ foreach (ki=>vp in phi) {
+ printf("phi has %d=>%s\n", ki, vp);
+ }
+
+ phs{"zero"} = 1;
+ phs{"one"} = "two";
+ phs{"two"} = 3.3;
+ foreach (ks=>vp in phs) {
+ printf("phs has %s=>%s\n", ks, vp);
+ }
+
+ phf{1.1} = 1;
+ phf{2.2} = "two";
+ phf{3.3} = 33.33;
+ foreach (kf=>vp in phf) {
+ printf("phf has %3.1f=>%s\n", kf, vp);
+ }
+
+ php{"one"} = 1;
+ php{1.1} = "two";
+ php{2} = 3.3;
+ foreach (kp=>vp in php) {
+ printf("php has %s=>%s\n", kp, vp);
+ }
+
+ sthi{0}.x = 100;
+ sthi{0}.y = 101;
+ sthi{1}.x = 200;
+ sthi{1}.y = 201;
+ sthi{2}.x = 300;
+ sthi{2}.y = 301;
+ foreach (ki=>vst in sthi) {
+ printf("sthi has %d=>(%d,%d)\n", ki, vst.x, vst.y);
+ }
+
+ sths{"zero"}.x = 100;
+ sths{"zero"}.y = 101;
+ sths{"one"}.x = 200;
+ sths{"one"}.y = 201;
+ sths{"two"}.x = 300;
+ sths{"two"}.y = 301;
+ foreach (ks=>vst in sths) {
+ printf("sths has %s=>(%d,%d)\n", ks, vst.x, vst.y);
+ }
+
+ sthf{1.1}.x = 100;
+ sthf{1.1}.y = 101;
+ sthf{2.2}.x = 200;
+ sthf{2.2}.y = 201;
+ sthf{3.3}.x = 300;
+ sthf{3.3}.y = 301;
+ foreach (kf=>vst in sthf) {
+ printf("sthf has %3.1f=>(%d,%d)\n", kf, vst.x, vst.y);
+ }
+
+ sthp{0}.x = 100;
+ sthp{0}.y = 101;
+ sthp{1.1}.x = 200;
+ sthp{1.1}.y = 201;
+ sthp{"two"}.x = 300;
+ sthp{"two"}.y = 301;
+ foreach (kp=>vst in sthp) {
+ printf("sthp has %s=>(%d,%d)\n", kp, vst.x, vst.y);
+ }
+
+ printf("end\n");
+}
+#lang tcl
+hash_1_4
+} -output "start
+ihi has 0=>100
+ihi has 1=>101
+ihi has 2=>102
+ihs has zero=>100
+ihs has one=>101
+ihs has two=>102
+ihf has 1.1=>100
+ihf has 2.2=>101
+ihf has 3.3=>102
+ihp has 0=>100
+ihp has two=>101
+ihp has 3.3=>102
+shi has 0=>zero
+shi has 1=>one
+shi has 2=>two
+shs has zero=>zero0
+shs has one=>one1
+shs has two=>two2
+shf has 1.1=>one.one
+shf has 2.2=>two.two
+shf has 3.3=>three.three
+shp has 0=>zero
+shp has 1.1=>one.one
+shp has two=>two2
+fhi has 0=>1.1
+fhi has 1=>2.2
+fhi has 2=>3.3
+fhs has zero=>1.1
+fhs has one=>2.2
+fhs has two=>3.3
+fhf has 1.1=>11.1
+fhf has 2.2=>22.2
+fhf has 3.3=>33.3
+fhp has 0=>1.1
+fhp has 1.1=>2.2
+fhp has two=>3.3
+phi has 0=>1
+phi has 1=>two
+phi has 2=>3.3
+phs has zero=>1
+phs has one=>two
+phs has two=>3.3
+phf has 1.1=>1
+phf has 2.2=>two
+phf has 3.3=>33.33
+php has one=>1
+php has 1.1=>two
+php has 2=>3.3
+sthi has 0=>(100,101)
+sthi has 1=>(200,201)
+sthi has 2=>(300,301)
+sths has zero=>(100,101)
+sths has one=>(200,201)
+sths has two=>(300,301)
+sthf has 1.1=>(100,101)
+sthf has 2.2=>(200,201)
+sthf has 3.3=>(300,301)
+sthp has 0=>(100,101)
+sthp has 1.1=>(200,201)
+sthp has two=>(300,301)
+end
+"
+
+test hash-1.5 {hashes of hashes and arrays} -body {
+#lang L --line=1
+void
+hash_1_5()
+{
+ int k1, k2;
+ string vs;
+ string hai[3]{int};
+ string hia{int}[3];
+ string hii{int}{int};
+ string hi{int};
+
+ printf("start\n");
+
+ // Array of hashes.
+ hai[0]{1} = "01";
+ hai[0]{6} = "06";
+ hai[0]{5} = "05";
+ hai[1]{2} = "12";
+ hai[1]{3} = "13";
+ hai[1]{0} = "10";
+ hai[2]{0} = "20";
+ hai[2]{1} = "21";
+ hai[2]{2} = "22";
+ foreach (hi in hai) {
+ foreach (k1 in sort(keys(hi))) {
+ printf("hai has %d=>%s\n", k1, hi{k1});
+ }
+ }
+
+ // Hash of arrays.
+ hia{1}[0] = "10";
+ hia{1}[1] = "11";
+ hia{1}[2] = "12";
+ hia{0}[0] = "00";
+ hia{0}[1] = "01";
+ hia{0}[2] = "02";
+ hia{2}[0] = "20";
+ hia{2}[1] = "21";
+ hia{2}[2] = "22";
+ foreach (k1 in sort(keys(hia))) {
+ foreach (vs in hia{k1}) {
+ printf("hia{%d} has %s\n", k1, vs);
+ }
+ }
+
+ // Hash of hashes.
+ hii{0}{2} = "02";
+ hii{1}{0} = "10";
+ hii{0}{0} = "00";
+ hii{2}{1} = "21";
+ hii{1}{2} = "12";
+ hii{1}{1} = "11";
+ hii{0}{1} = "01";
+ hii{2}{0} = "20";
+ hii{2}{2} = "22";
+ foreach (k1 in sort(keys(hii))) {
+ foreach (k2 in sort(keys(hii{k1}))) {
+ printf("hii{%d}{%d} has %s\n", k1, k2, hii{k1}{k2});
+ }
+ }
+
+ printf("end\n");
+}
+#lang tcl
+hash_1_5
+} -output "start
+hai has 1=>01
+hai has 5=>05
+hai has 6=>06
+hai has 0=>10
+hai has 2=>12
+hai has 3=>13
+hai has 0=>20
+hai has 1=>21
+hai has 2=>22
+hia{0} has 00
+hia{0} has 01
+hia{0} has 02
+hia{1} has 10
+hia{1} has 11
+hia{1} has 12
+hia{2} has 20
+hia{2} has 21
+hia{2} has 22
+hii{0}{0} has 00
+hii{0}{1} has 01
+hii{0}{2} has 02
+hii{1}{0} has 10
+hii{1}{1} has 11
+hii{1}{2} has 12
+hii{2}{0} has 20
+hii{2}{1} has 21
+hii{2}{2} has 22
+end
+"
+
+test deep-1.1 {deep dive 1} -body {
+#lang L --line=1
+struct xy {
+ string x;
+ string y;
+};
+struct sd11 {
+ string a;
+ string b;
+ struct xy h{int};
+};
+
+void
+deep_1_1()
+{
+ int k1, k2;
+ struct sd11 s;
+ struct xy xy;
+ struct sd11 h{int};
+
+ printf("start\n");
+
+ /*
+ * Test a hash that has a struct that has another hash.
+ */
+
+ h{0}.a = "h{0}.a";
+ h{0}.b = "h{0}.b";
+ h{0}.h{0}.x = "h{0}.h{0}.x";
+ h{0}.h{0}.y = "h{0}.h{0}.y";
+ h{1}.a = "h{1}.a";
+ h{1}.b = "h{1}.b";
+ h{1}.h{0}.x = "h{1}.h{0}.x";
+ h{1}.h{0}.y = "h{1}.h{0}.y";
+ h{1}.h{2}.x = "h{1}.h{2}.x";
+ h{1}.h{2}.y = "h{1}.h{2}.y";
+
+ foreach (k1=>s in h) {
+ printf("h{%d}.a = %s\n", k1, s.a);
+ printf("h{%d}.b = %s\n", k1, s.b);
+ foreach (k2=>xy in s.h) {
+ printf("h{%d}.h{%d}.x = %s\n", k1, k2, xy.x);
+ printf("h{%d}.h{%d}.y = %s\n", k1, k2, xy.y);
+ }
+ }
+
+ printf("end\n");
+}
+#lang tcl
+deep_1_1
+} -output "start
+h{0}.a = h{0}.a
+h{0}.b = h{0}.b
+h{0}.h{0}.x = h{0}.h{0}.x
+h{0}.h{0}.y = h{0}.h{0}.y
+h{1}.a = h{1}.a
+h{1}.b = h{1}.b
+h{1}.h{0}.x = h{1}.h{0}.x
+h{1}.h{0}.y = h{1}.h{0}.y
+h{1}.h{2}.x = h{1}.h{2}.x
+h{1}.h{2}.y = h{1}.h{2}.y
+end
+"
+
+test deep-1.2 {deep dive with consecutive hash indices} -body {
+#lang L --line=1
+void
+deep_1_2()
+{
+ int k1, k2, k3, k4;
+ string v;
+ string h{int};
+ string hh{int}{int};
+ string hhh{int}{int}{int};
+ string hhhh{int}{int}{int}{int};
+
+ printf("start\n");
+
+ /*
+ * Test various cases with consecutive hash indices.
+ */
+
+ hh{0}{0} = "00";
+ hh{0}{1} = "01";
+ hh{1}{0} = "10";
+ foreach (k1=>h in hh) {
+ foreach (k2=>v in h) {
+ unless (hh{k1}{k2} eq h{k2}) {
+ printf("bad 1\n");
+ }
+ printf("hh{%d}{%d} has %s\n", k1, k2, hh{k1}{k2});
+ }
+ }
+
+ hhh{0}{0}{0} = "000";
+ hhh{0}{0}{1} = "001";
+ hhh{0}{1}{0} = "010";
+ hhh{1}{0}{0} = "100";
+ foreach (k1=>hh in hhh) {
+ foreach (k2=>h in hh) {
+ foreach (k3=>v in h) {
+ unless (hhh{k1}{k2}{k3} eq hh{k2}{k3}) {
+ printf("bad 2\n");
+ }
+ unless (hh{k2}{k3} eq h{k3}) {
+ printf("bad 3\n");
+ }
+ printf("hhh{%d}{%d}{%d} has %s\n", k1, k2, k3,
+ hhh{k1}{k2}{k3});
+ }
+ }
+ }
+
+ hhhh{0}{0}{0}{0} = "0000";
+ hhhh{0}{0}{0}{1} = "0001";
+ hhhh{0}{0}{1}{0} = "0010";
+ hhhh{0}{1}{0}{0} = "0100";
+ hhhh{1}{0}{0}{0} = "1000";
+ foreach (k1=>hhh in hhhh) {
+ foreach (k2=>hh in hhh) {
+ foreach (k3=>h in hh) {
+ foreach (k4=>v in h) {
+ unless (hhhh{k1}{k2}{k3}{k4} eq
+ hhh{k2}{k3}{k4}) {
+ printf("bad 4\n");
+ }
+ unless (hhh{k2}{k3}{k4} eq hh{k3}{k4}) {
+ printf("bad 5\n");
+ }
+ unless (hh{k3}{k4} eq h{k4}) {
+ printf("bad 6\n");
+ }
+ printf("hhhh{%d}{%d}{%d}{%d} has %s\n",
+ k1, k2, k3, k4,
+ hhhh{k1}{k2}{k3}{k4});
+ }
+ }
+ }
+ }
+
+ printf("end\n");
+}
+#lang tcl
+deep_1_2
+} -output "start
+hh{0}{0} has 00
+hh{0}{1} has 01
+hh{1}{0} has 10
+hhh{0}{0}{0} has 000
+hhh{0}{0}{1} has 001
+hhh{0}{1}{0} has 010
+hhh{1}{0}{0} has 100
+hhhh{0}{0}{0}{0} has 0000
+hhhh{0}{0}{0}{1} has 0001
+hhhh{0}{0}{1}{0} has 0010
+hhhh{0}{1}{0}{0} has 0100
+hhhh{1}{0}{0}{0} has 1000
+end
+"
+
+test deep-1.3 {deep dive with consecutive array indices} -body {
+#lang L --line=1
+void
+deep_1_3()
+{
+ string v;
+ string a[3];
+ string aa[2][2];
+ string aaa[2][2][2];
+ string aaaa[2][2][2][2];
+
+ printf("start\n");
+
+ /*
+ * Test various cases with consecutive array indices.
+ */
+
+ a[0] = "0";
+ a[1] = "1";
+ a[2] = "2";
+ foreach (v in a) {
+ printf("a has '%s'\n", v);
+ }
+
+ aa[0][0] = "00";
+ aa[0][1] = "01";
+ aa[0][2] = "02";
+ aa[1][0] = "10";
+ foreach (a in aa) {
+ foreach (v in a) {
+ printf("aa has '%s'\n", v);
+ }
+ }
+
+ aaa[0][0][0] = "000";
+ aaa[0][0][1] = "001";
+ aaa[0][1][0] = "010";
+ aaa[0][1][1] = "011";
+ aaa[1][0][0] = "100";
+ foreach (aa in aaa) {
+ foreach (a in aa) {
+ foreach (v in a) {
+ printf("aaa has '%s'\n", v);
+ }
+ }
+ }
+
+ aaaa[0][0][0][0] = "0000";
+ aaaa[0][0][0][1] = "0001";
+ aaaa[0][0][1][0] = "0010";
+ aaaa[0][1][0][0] = "0100";
+ aaaa[1][0][0][0] = "1000";
+ foreach (aaa in aaaa) {
+ foreach (aa in aaa) {
+ foreach (a in aa) {
+ foreach (v in a) {
+ printf("aaaa has '%s'\n", v);
+ }
+ }
+ }
+ }
+
+ printf("end\n");
+}
+#lang tcl
+deep_1_3
+} -output "start
+a has '0'
+a has '1'
+a has '2'
+aa has '00'
+aa has '01'
+aa has '02'
+aa has '10'
+aaa has '000'
+aaa has '001'
+aaa has '010'
+aaa has '011'
+aaa has '100'
+aaaa has '0000'
+aaaa has '0001'
+aaaa has '0010'
+aaaa has '0100'
+aaaa has '1000'
+end
+"
+
+test deep-1.4 {deep dive with alternating hash and array indices} -body {
+#lang L --line=1
+void
+deep_1_4()
+{
+ /*
+ * Note that, because of the array auto-extend semantics, if
+ * you write to a[i] but there are values before index i not
+ * yet written, those get automatically set to an undefined
+ * value, which the foreach's will iterate through. When used
+ * as a string, the undefined value shows up as "". (Tcl
+ * doesn't let you use it as an integer, which is why the
+ * hashes are string hashes in these tests.)
+ */
+
+ int i, j, ki, k1, k2;
+ string vs;
+ string a[3];
+ string aa[3][3];
+ string h{int};
+ string hh{int}{int};
+ string ah[3]{int};
+ string ha{int}[3];
+ string aah[3][3]{int};
+ string aha[3]{int}[3];
+ string ahh[3]{int}{int};
+ string haa{int}[3][3];
+ string hah{int}[3]{int};
+ string hha{int}{int}[3];
+
+ printf("start\n");
+
+ ah[0]{0} = "ah[0]{0}";
+ ah[2]{0} = "ah[2]{0}";
+ ah[2]{1} = "ah[2]{1}";
+ i = 0;
+ foreach (h in ah) {
+ foreach (ki=>vs in h) {
+ unless (ah[i]{ki} eq vs) printf("bad 1\n");
+ printf("ah[%d]{%d} = '%s'\n", i, ki, vs);
+ }
+ ++i;
+ }
+
+ ha{0}[0] = "ha{0}[0]";
+ ha{0}[1] = "ha{0}[1]";
+ ha{1}[1] = "ha{1}[1]";
+ foreach (ki=>a in ha) {
+ i = 0;
+ foreach (vs in a) {
+ unless (ha{ki}[i] eq vs) printf("bad 2\n");
+ printf("ha{%d}[%d] = '%s'\n", ki, i, vs);
+ ++i;
+ }
+ }
+
+ aah[0][0]{0} = "aah[0][0]{0}";
+ aah[0][1]{1} = "aah[0][1]{1}";
+ aah[1][0]{2} = "aah[1][0]{2}";
+ aah[1][0]{3} = "aah[1][0]{3}";
+ i = 0;
+ foreach (ah in aah) {
+ j = 0;
+ foreach (h in ah) {
+ foreach (ki=>vs in h) {
+ unless (aah[i][j]{ki} eq vs) printf("bad 3\n");
+ unless (ah[j]{ki} eq vs) printf("bad 4\n");
+ unless (h{ki} eq vs) printf("bad 5\n");
+ printf("aah[%d][%d]{%d} = '%s'\n", i, j, ki,
+ aah[i][j]{ki});
+ }
+ ++j;
+ }
+ ++i;
+ }
+
+ aha[0]{0}[0] = "aha[0]{0}[0]";
+ aha[0]{1}[1] = "aha[0]{1}[1]";
+ aha[1]{2}[0] = "aha[1]{2}[0]";
+ aha[0]{3}[2] = "aha[0]{3}[2]";
+ i = 0;
+ foreach (ha in aha) {
+ foreach (ki=>a in ha) {
+ j = 0;
+ foreach (vs in a) {
+ unless (aha[i]{ki}[j] eq vs) printf("bad 6\n");
+ unless (ha{ki}[j] eq vs) printf("bad 7\n");
+ unless (a[j] eq vs) printf("bad 7\n");
+ printf("aha[%d]{%d}[%d] = '%s'\n", i, ki, j,
+ aha[i]{ki}[j]);
+ ++j;
+ }
+ }
+ ++i;
+ }
+
+ ahh[0]{0}{1} = "ahh[0]{0}{1}";
+ ahh[0]{2}{3} = "ahh[0]{2}{3}";
+ ahh[1]{4}{5} = "ahh[1]{4}{5}";
+ ahh[2]{6}{7} = "ahh[2]{6}{7}";
+ i = 0;
+ foreach (hh in ahh) {
+ foreach (k1=>h in hh) {
+ foreach (k2=>vs in h) {
+ unless (ahh[i]{k1}{k2} eq vs) printf("bad 7\n");
+ unless (hh{k1}{k2} eq vs) printf("bad 8\n");
+ unless (h{k2} eq vs) printf("bad 9\n");
+ printf("ahh[%d]{%d}{%d} = '%s'\n", i, k1, k2,
+ ahh[i]{k1}{k2});
+ }
+ }
+ ++i;
+ }
+
+ haa{0}[0][0] = "haa{0}[0][0]";
+ haa{0}[1][0] = "haa{0}[1][0]";
+ haa{1}[0][0] = "haa{1}[0][0]";
+ haa{2}[0][1] = "haa{2}[0][1]";
+ foreach (ki=>aa in haa) {
+ i = 0;
+ foreach (a in aa) {
+ j = 0;
+ foreach (vs in a) {
+ unless (haa{ki}[i][j] eq vs) printf("bad 10\n");
+ unless (aa[i][j] eq vs) printf("bad 11\n");
+ unless (a[j] eq vs) printf("bad 12\n");
+ printf("haa{%d}[%d][%d] = '%s'\n", ki, i, j,
+ haa{ki}[i][j]);
+ ++j;
+ }
+ ++i;
+ }
+ }
+
+ hha{0}{1}[0] = "hha{0}{1}[0]";
+ hha{2}{3}[0] = "hha{2}{3}[0]";
+ hha{4}{5}[1] = "hha{4}{5}[1]";
+ hha{6}{7}[2] = "hha{6}{7}[2]";
+ foreach (k1=>ha in hha) {
+ foreach (k2=>a in ha) {
+ i = 0;
+ foreach (vs in a) {
+ unless (hha{k1}{k2}[i] eq vs) printf("bad13\n");
+ unless (ha{k2}[i] eq vs) printf("bad 14n");
+ unless (a[i] eq vs) printf("bad 15\n");
+ printf("hha{%d}{%d}[%d] = '%s'\n", k1, k2, i,
+ hha{k1}{k2}[i]);
+ ++i;
+ }
+ }
+ }
+
+ hah{0}[0]{0} = "hah{0}[0]{0}";
+ hah{1}[0]{2} = "hah{1}[0]{2}";
+ hah{3}[1]{4} = "hah{3}[1]{4}";
+ hah{5}[2]{6} = "hah{5}[2]{6}";
+ foreach (k1=>ah in hah) {
+ i = 0;
+ foreach (h in ah) {
+ foreach (k2=>vs in h) {
+ unless (hah{k1}[i]{k2} eq vs) printf("bad16\n");
+ unless (ah[i]{k2} eq vs) printf("bad 17\n");
+ unless (h{k2} eq vs) printf("bad 18\n");
+ printf("hah{%d}[%d]{%d} = '%s'\n", k1, i, k2,
+ hah{k1}[i]{k2});
+ }
+ ++i;
+ }
+ }
+
+ printf("end\n");
+}
+
+#lang tcl
+deep_1_4
+} -output {start
+ah[0]{0} = 'ah[0]{0}'
+ah[2]{0} = 'ah[2]{0}'
+ah[2]{1} = 'ah[2]{1}'
+ha{0}[0] = 'ha{0}[0]'
+ha{0}[1] = 'ha{0}[1]'
+ha{1}[0] = ''
+ha{1}[1] = 'ha{1}[1]'
+aah[0][0]{0} = 'aah[0][0]{0}'
+aah[0][1]{1} = 'aah[0][1]{1}'
+aah[1][0]{2} = 'aah[1][0]{2}'
+aah[1][0]{3} = 'aah[1][0]{3}'
+aha[0]{0}[0] = 'aha[0]{0}[0]'
+aha[0]{1}[0] = ''
+aha[0]{1}[1] = 'aha[0]{1}[1]'
+aha[0]{3}[0] = ''
+aha[0]{3}[1] = ''
+aha[0]{3}[2] = 'aha[0]{3}[2]'
+aha[1]{2}[0] = 'aha[1]{2}[0]'
+ahh[0]{0}{1} = 'ahh[0]{0}{1}'
+ahh[0]{2}{3} = 'ahh[0]{2}{3}'
+ahh[1]{4}{5} = 'ahh[1]{4}{5}'
+ahh[2]{6}{7} = 'ahh[2]{6}{7}'
+haa{0}[0][0] = 'haa{0}[0][0]'
+haa{0}[1][0] = 'haa{0}[1][0]'
+haa{1}[0][0] = 'haa{1}[0][0]'
+haa{2}[0][0] = ''
+haa{2}[0][1] = 'haa{2}[0][1]'
+hha{0}{1}[0] = 'hha{0}{1}[0]'
+hha{2}{3}[0] = 'hha{2}{3}[0]'
+hha{4}{5}[0] = ''
+hha{4}{5}[1] = 'hha{4}{5}[1]'
+hha{6}{7}[0] = ''
+hha{6}{7}[1] = ''
+hha{6}{7}[2] = 'hha{6}{7}[2]'
+hah{0}[0]{0} = 'hah{0}[0]{0}'
+hah{1}[0]{2} = 'hah{1}[0]{2}'
+hah{3}[1]{4} = 'hah{3}[1]{4}'
+hah{5}[2]{6} = 'hah{5}[2]{6}'
+end
+}
+
+test deep-2.1 {deep dive array auto-extend} -body {
+#lang L --line=1
+void
+deep_2_1()
+{
+ int i, j;
+ int a1[];
+ int a2[];
+ int aa1[][];
+ int aa2[][];
+
+ /*
+ * Test that arrays auto-extend properly.
+ */
+
+ a1[0] = 0;
+ a1[1] = 1;
+ a1[2] = 2;
+ unless ((a1[0] == 0) && (a1[1] == 1) && (a1[2] == 2)) {
+ puts("a1 bad 1");
+ }
+ if (defined(a1[3])) puts("a1 bad 2");
+
+ a2[1] = 1;
+ a2[3] = 3;
+ a2[6] = 6;
+ a2[10] = 10;
+ unless ((a2[1] == 1) && (a2[3] == 3) && (a2[6] == 6) && (a2[10] == 10)) {
+ puts("a2 bad 1");
+ }
+ if (defined(a2[0])) puts("a2 bad 2");
+ if (defined(a2[2])) puts("a2 bad 3");
+ if (defined(a2[4])) puts("a2 bad 4");
+ if (defined(a2[5])) puts("a2 bad 5");
+ if (defined(a2[7])) puts("a2 bad 6");
+ if (defined(a2[8])) puts("a2 bad 7");
+ if (defined(a2[9])) puts("a2 bad 8");
+ if (defined(a2[11])) puts("a2 bad 9");
+
+ /* Now check that the pad elements can be written and used. */
+ a2[0] = 0;
+ a2[2] = 2;
+ a2[4] = 4;
+ a2[5] = 5;
+ unless ((a2[0] == 0) && (a2[2] == 2)) puts("a2 bad 10");
+ unless ((a2[4] == 4) && (a2[5] == 5)) puts("a2 bad 11");
+ if (defined(a2[7])) puts("a2 bad 12");
+ if (defined(a2[8])) puts("a2 bad 13");
+ if (defined(a2[9])) puts("a2 bad 14");
+ if (defined(a2[11])) puts("a2 bad 15");
+
+ aa1[0][0] = 100;
+ aa1[0][1] = 101;
+ aa1[0][2] = 102;
+ aa1[1][0] = 110;
+ aa1[1][1] = 111;
+ aa1[2][0] = 120;
+ unless ((aa1[0][0] == 100) && (aa1[0][1] == 101) && (aa1[0][2] == 102) &&
+ (aa1[1][0] == 110) && (aa1[1][1] == 111) && (aa1[2][0] == 120)) {
+ puts("aa1 bad 1");
+ }
+ if (defined(aa1[0][3])) puts("aa1 bad 2");
+ if (defined(aa1[1][3])) puts("aa1 bad 3");
+ if (defined(aa1[2][1])) puts("aa1 bad 4");
+
+ aa2[1][1] = 111;
+ aa2[3][3] = 133;
+ aa2[6][6] = 166;
+ aa2[10][10] = 1010;
+ unless ((aa2[1][1] == 111) && (aa2[3][3] == 133) && (aa2[6][6] == 166) &&
+ (aa2[10][10] == 1010)) {
+ puts("aa2 bad 2");
+ }
+ for (i = 0; i <= 10; ++i) {
+ for (j = 0; j <= i; ++j) {
+ if ((i == 1) && (j == 1)) continue;
+ if ((i == 3) && (j == 3)) continue;
+ if ((i == 6) && (j == 6)) continue;
+ if ((i == 10) && (j == 10)) continue;
+ if (defined(aa2[i][j])) printf("aa2[%d][%d] defined\n",
+ i, j);
+ }
+ }
+}
+#lang tcl
+deep_2_1
+} -output ""
+
+test deep-2.2 {check that a negative array index is an error} -body {
+#lang L --line=1
+void
+deep_2_2()
+{
+ int a[3];
+ a[-1] = 0;
+}
+#lang tcl
+deep_2_2
+} -returnCodes error -match regexp -result {cannot write to negative array index}
+
+test deep-2.3 {check deep-dive element create/read} -body {
+#lang L --line=1
+void
+deep_2_3()
+{
+ /*
+ * This checks that an op= works on an undefined deep-dive
+ * element. A string substitute is the only one we can test;
+ * because undef isn't a valid integer, ++a[0] would cause a
+ * run-time error that you can't use "" in a + operation.
+ */
+
+ string a[];
+ string h{string};
+
+ h{"undefined"} =~ s//ShouldWork/;
+ unless (h{"undefined"} eq "ShouldWork") puts("bad 1");
+
+ a[0] =~ s//ShouldWork/;
+ unless (a[0] eq "ShouldWork") puts("bad 2");
+}
+#lang tcl
+deep_2_3
+} -output {}
+
+test deep-3.1 {check reading an undefined array index} -body {
+#lang L --line=1
+void
+deep_3_1()
+{
+ int i;
+ int a[] = {};
+
+ /*
+ * Reading an array element with an undefined index should
+ * cause a run-time error.
+ */
+ a[i];
+}
+deep_3_1();
+} -returnCodes error -match glob -result {cannot read from undefined array index}
+
+test deep-3.2 {check writing an undefined array index} -body {
+#lang L --line=1
+void
+deep_3_2()
+{
+ int i;
+ int a[] = {};
+
+ /*
+ * Writing an array element with an undefined index should
+ * cause a run-time error.
+ */
+ a[i] = 0; // run-time error
+}
+deep_3_2();
+} -returnCodes error -match glob -result {cannot write to undefined array index}
+
+test deep-3.2.2 {check reading an undefined hash index} -body {
+#lang L
+void
+deep_3_2_2()
+{
+ string idx;
+ string h{string} = {};
+
+ /*
+ * Reading a hash element with an undefined index should
+ * cause a run-time error.
+ */
+ h{idx};
+}
+deep_3_2_2();
+} -returnCodes error -match glob -result {cannot read from undefined hash index}
+
+test deep-3.2.2.1 {check back-door reading undefined hash index} -setup {
+ makeFile {
+ string s;
+ string deep_3_2_2h{string};
+
+ deep_3_2_2h{s};
+ puts("worked");
+ } deep-3.2.2.1.l
+} -body {
+#lang L --line=1
+void deep_3_2_2_1()
+{
+ /*
+ * Test the back door BK_L_ALLOW_UNDEF_HASH_INDEX=YES which
+ * allows using an undef hash index. Do this in its own tclsh
+ * instance since the env variable is read only at the first
+ * undef hash index.
+ */
+ int ret;
+ string err, out, tclsh = interpreter();
+
+ putenv("BK_L_ALLOW_UNDEF_HASH_INDEX=YES");
+ ret = system({tclsh, "deep-3.2.2.1.l"}, undef, &out, &err);
+ if (ret) puts("bad 1");
+ unless (out == "worked\n") puts("bad 2");
+ putenv("BK_L_ALLOW_UNDEF_HASH_INDEX=");
+}
+deep_3_2_2_1();
+} -output {}
+
+test deep-3.2.3 {check writing an undefined hash index} -body {
+#lang L
+void
+deep_3_2_3()
+{
+ string idx;
+ string h{string} = {};
+
+ /*
+ * Writing a hash element with an undefined index should
+ * cause a run-time error.
+ */
+ h{idx} = "bad";
+}
+deep_3_2_3();
+} -returnCodes error -match glob -result {cannot write to undefined hash index}
+
+test deep-3.2.3.1 {check back-door writing undefined array index} -setup {
+ makeFile {
+ string s;
+ string deep_3_2_3h{string};
+
+ deep_3_2_3h{s} = "should be ok now";
+ puts("worked");
+ } deep-3.2.3.1.l
+} -body {
+#lang L --line=1
+void deep_3_2_3_1()
+{
+ /*
+ * Test the back door BK_L_ALLOW_UNDEF_HASH_INDEX=YES which
+ * allows using an undef hash index. Do this in its own tclsh
+ * instance since the env variable is read only at the first
+ * undef hash index.
+ */
+ int ret;
+ string err, out, tclsh = interpreter();
+
+ putenv("BK_L_ALLOW_UNDEF_HASH_INDEX=YES");
+ ret = system({tclsh, "deep-3.2.3.1.l"}, undef, &out, &err);
+ if (ret) puts("bad 1");
+ unless (out == "worked\n") puts("bad 2");
+ putenv("BK_L_ALLOW_UNDEF_HASH_INDEX=");
+}
+deep_3_2_3_1();
+} -output {}
+
+test deep-3.3 {check reading an undefined string index} -body {
+#lang L --line=1
+void
+deep_3_3()
+{
+ int i;
+ string s = "";
+
+ /*
+ * Reading a string element with an undefined index should
+ * cause a run-time error.
+ */
+ s[i];
+}
+deep_3_3();
+} -returnCodes error -match glob -result {cannot read from undefined string index}
+
+test deep-3.3.1 {check writing an undefined string index} -body {
+#lang L
+void
+deep_3_3_1()
+{
+ int i;
+ string s;
+
+ /*
+ * Writing a string element with an undefined index should
+ * cause a run-time error.
+ */
+ s[i] = "bad";
+}
+deep_3_3_1();
+} -returnCodes error -match glob -result {cannot write to undefined string index}
+
+test deep-3.4 {check writing an undefined array index} -body {
+#lang L --line=1
+void
+deep_3_4()
+{
+ int i;
+ string s = "";
+
+ /*
+ * Writing a string element with an undefined index is
+ * illegal.
+ */
+
+ s[i] = "bad"; // run-time error
+}
+deep_3_4();
+} -returnCodes error -match regexp -result {cannot write to undefined string index}
+
+test deep-3.5 {check compile-time undefined array and hash indices} -body {
+#lang L --line=1
+void deep_3_5()
+{
+ int ia[];
+ string sa[], sh{string};
+
+ /* These should all be compile-time errors. */
+
+ ia[undef];
+ sa[undef];
+ ia[undef] = 1;
+ sa[undef] = "bad";
+ sh{undef};
+ sh{undef} = "bad";
+}
+deep_3_5();
+} -returnCodes error -match regexp -result {.*8: L Error: cannot use undef as an array/string index
+.*9: L Error: cannot use undef as an array/string index
+.*10: L Error: cannot use undef as an array/string index
+.*11: L Error: cannot use undef as an array/string index
+.*12: L Error: cannot use undef as a hash index
+.*13: L Error: cannot use undef as a hash index
+}
+
+test deep-4.0 {check hash and array indexing of a poly} -body {
+#lang L --line=1
+void deep_4_0()
+{
+ poly p;
+
+ p = {};
+ p{"key1"} = "val";
+ p{"key2"} = 123;
+ unless(p{"key1"} eq "val") puts("bad 1.1");
+ unless(p{"key2"} == 123) puts("bad 1.2");
+
+ p = {};
+ p[0] = "val";
+ p[1] = 123;
+ unless(p[0] eq "val") puts("bad 2.1");
+ unless(p[1] == 123) puts("bad 2.2");
+}
+deep_4_0();
+} -output {}
+
+test deep-5.1 {check deep-dive object sharing} -body {
+#lang L --line=1
+typedef struct block {
+ string line;
+} block;
+
+void deep_5_1()
+{
+ block b, v1, v2;
+ string h{string}, h2{string}, h3{string};
+ string a1[][], a2[][];
+
+ /*
+ * Having the rhs be a string concat creates an object with a
+ * refCount of 1.
+ */
+ b.line = "LINE1" . "1";
+ v1 = b;
+
+ /*
+ * Now change b.line. v1's copy should not change.
+ */
+ b.line = "LINE2";
+ v2 = b;
+
+ unless (v1.line eq "LINE11") puts("v1 bad: ${v1}");
+ unless (v2.line eq "LINE2") puts("v2 bad: ${v2}");
+
+ /*
+ * Do it again but with a list of a list (2d array in this case).
+ * Having the rhs be a string concat creates an object with a
+ * refCount of 1.
+ */
+
+ a1 = { { "old" . "val" } };
+ a2 = a1;
+ a1[0][0] = "newval";
+ unless (a1[0][0] == "newval") puts("a1[][] bad 1");
+ unless (a2[0][0] == "oldval") puts("a2[][] bad 2");
+
+ a1 = { { } };
+ a2 = a1;
+ a1[0][0] = "newval";
+ unless (a1[0][0] == "newval") puts("a1[][] bad 3");
+ if (a2[0][0]) puts("a2[][] bad 4");
+
+ /* Try the same thing with hashes. */
+
+ h{"idx"} = "LINE1" . "1";
+ h2 = h;
+
+ h{"idx"} = "LINE2";
+ h3 = h;
+
+ unless (h2{"idx"} eq "LINE11") puts("h2 bad: ${h2}");
+ unless (h3{"idx"} eq "LINE2") puts("h3 bad: ${h3}");
+}
+deep_5_1();
+} -output {}
+
+test regexp-1.0 {regular expression support} -body {
+#lang L --line=1
+void regexp_1_0() {
+ string s = "string";
+ puts(s =~ /ring/);
+ puts(s =~ /bob/);
+ puts(s !~ /ring/);
+ puts(s !~ /bob/);
+}
+#lang tcl
+regexp_1_0
+} -output "1\n0\n0\n1\n"
+
+test regexp-1.1 {magic submatch variables ($1, $2, ...)} -body {
+#lang L --line=1
+void regexp_1_1() {
+ string s = "Go not to the elves for counsel, for they will say both yes and no.";
+
+ if (s =~ /((Go).*(elves)).*/) {
+ puts($0);
+ puts($1);
+ puts($2);
+ puts($3);
+ }
+}
+#lang tcl
+regexp_1_1
+} -output "Go not to the elves for counsel, for they will say both yes and no.
+Go not to the elves\nGo\nelves\n"
+
+
+test regexp-1.2 {magic submatch variables with interpolation} -body {
+#lang L --line=1
+void regexp_1_2() {
+ string s = "Go not to the elves for counsel, for they will say both yes and no.";
+ string interp = "elves";
+
+ if (s =~ /((Go).*(${interp})).*/) {
+ puts($0);
+ puts($1);
+ puts($2);
+ puts($3);
+ }
+}
+#lang tcl
+regexp_1_2
+} -output "Go not to the elves for counsel, for they will say both yes and no.
+Go not to the elves\nGo\nelves\n"
+
+test regexp-1.3 {regexp substitution} -body {
+#lang L --line=1 -poly
+void regexp_1_3() {
+ string s = "string";
+ string s1[] = {"a", "b", "coochie"};
+ hash h[2];
+
+ puts(s =~ m/ring/);
+ puts(s =~ m|bob|);
+ puts("--------");
+ puts(s =~ s/ring/ling/);
+ puts(s);
+ puts("--------");
+ puts(s1[2] =~ s/c/f/);
+ puts(s1);
+ puts("--------");
+ h[0]{"a"} = "string";
+ h[1]{"m"} = "not a string";
+ puts(h);
+ h[1]{"m"} =~ s/not a/probably a/;
+ puts(h);
+}
+#lang tcl
+regexp_1_3
+} -output "1\n0\n--------\n1\nstling\n--------\n1\na b foochie\n--------\n{a string} {m {not a string}}\n{a string} {m {probably a string}}\n"
+
+test regexp-1.4 {regexp modifiers i and g} -body {
+#lang L --line=1 -poly
+void regexp_1_4() {
+ string foo = "aaa";
+ foo =~ s/a/b/;
+ puts(foo);
+ foo =~ s/a/b/g;
+ puts(foo);
+ foo =~ s/B/a/;
+ puts(foo);
+ foo =~ s/B/a/i;
+ puts(foo);
+ foo =~ s/B/a/ig;
+ puts(foo);
+ if (foo =~ /A/) {
+ puts("busted");
+ }
+ if (foo =~ /A/i) {
+ puts("works");
+ }
+}
+#lang tcl
+regexp_1_4
+} -output "baa\nbbb\nbbb\nabb\naaa\nworks\n"
+
+test regexp-1.5 {regexp quoting} -body {
+#lang L --line=1
+void
+regexp_1_5()
+{
+ string r, s;
+
+ s = "a b c d";
+ s =~ s/\s//;
+ unless (s eq "ab c d") puts("bad 1");
+
+ s = "a b c d";
+ s =~ s/\s+//g;
+ unless (s eq "abcd") puts("bad 2");
+
+ r = "\\s+";
+ s = "a b c d";
+ s =~ s/${r}//g;
+ unless (s eq "abcd") puts("bad 3");
+
+ r = "\\s+";
+ s = "a b c d";
+ s =~ s/\${r}//g;
+ unless (s eq "a b c d") puts("bad 4");
+
+ s = "$a$b";
+ s =~ s/\$//g; // should match a dollar sign
+ unless (s eq "ab") puts("bad 5");
+
+ r = "\\s+";
+ s = '${r} ${r}';
+ s =~ s/\${r}//g; // should match '${r}' literally
+ unless (s eq " ") puts("bad 6");
+
+ s = "(in parens)";
+ s =~ s/\(//;
+ unless (s eq "in parens)") puts("bad 7");
+ s =~ s/(in)//;
+ unless (s eq " parens)") puts("bad 8");
+
+ /*
+ * Check escapes in the substitution part:
+ * & \0 \1 ... \9 get substituted with the re matches
+ * \a \e \f \n \r \t get expanded to control chars
+ * \x for anything else gets expanded to "x"
+ * $0-$9 are synonyms for \0-\9
+ */
+
+ /* Check &, \0, and $0. */
+ s = "abc";
+ s =~ s/b/x&y/;
+ unless (s eq "axbyc") puts("bad 9.1");
+ s = "abc";
+ s =~ s/b/x\0y/;
+ unless (s eq "axbyc") puts("bad 9.2");
+ s = "abc";
+ s =~ s/b/x$0y/;
+ unless (s eq "axbyc") puts("bad 9.2.1");
+
+ /* Check \1 through \9. */
+ s = "123456789abc";
+ s =~ s/123456789a(b)c/123456789c\1a/;
+ unless (s eq "123456789cba") puts("bad 9.3");
+ s = "123456789abc";
+ s =~ s/12345678(9)a(b)c/123456789c\2a/;
+ unless (s eq "123456789cba") puts("bad 9.4");
+ s = "123456789abc";
+ s =~ s/1234567(8)(9)a(b)c/123456789c\3a/;
+ unless (s eq "123456789cba") puts("bad 9.5");
+ s = "123456789abc";
+ s =~ s/123456(7)(8)(9)a(b)c/123456789c\4a/;
+ unless (s eq "123456789cba") puts("bad 9.6");
+ s = "123456789abc";
+ s =~ s/12345(6)(7)(8)(9)a(b)c/123456789c\5a/;
+ unless (s eq "123456789cba") puts("bad 9.7");
+ s = "123456789abc";
+ s =~ s/1234(5)(6)(7)(8)(9)a(b)c/123456789c\6a/;
+ unless (s eq "123456789cba") puts("bad 9.8");
+ s = "123456789abc";
+ s =~ s/123(4)(5)(6)(7)(8)(9)a(b)c/123456789c\7a/;
+ unless (s eq "123456789cba") puts("bad 9.9");
+ s = "123456789abc";
+ s =~ s/12(3)(4)(5)(6)(7)(8)(9)a(b)c/123456789c\8a/;
+ unless (s eq "123456789cba") puts("bad 9.10");
+ s = "123456789abc";
+ s =~ s/1(2)(3)(4)(5)(6)(7)(8)(9)a(b)c/123456789c\9a/;
+ unless (s eq "123456789cba") puts("bad 9.11");
+
+ /* Check $1 through $9. */
+ s = "123456789abc";
+ s =~ s/123456789a(b)c/123456789c$1a/;
+ unless (s eq "123456789cba") puts("bad 9.12");
+ s = "123456789abc";
+ s =~ s/12345678(9)a(b)c/123456789c$2a/;
+ unless (s eq "123456789cba") puts("bad 9.13");
+ s = "123456789abc";
+ s =~ s/1234567(8)(9)a(b)c/123456789c$3a/;
+ unless (s eq "123456789cba") puts("bad 9.14");
+ s = "123456789abc";
+ s =~ s/123456(7)(8)(9)a(b)c/123456789c$4a/;
+ unless (s eq "123456789cba") puts("bad 9.15");
+ s = "123456789abc";
+ s =~ s/12345(6)(7)(8)(9)a(b)c/123456789c$5a/;
+ unless (s eq "123456789cba") puts("bad 9.16");
+ s = "123456789abc";
+ s =~ s/1234(5)(6)(7)(8)(9)a(b)c/123456789c$6a/;
+ unless (s eq "123456789cba") puts("bad 9.17");
+ s = "123456789abc";
+ s =~ s/123(4)(5)(6)(7)(8)(9)a(b)c/123456789c$7a/;
+ unless (s eq "123456789cba") puts("bad 9.18");
+ s = "123456789abc";
+ s =~ s/12(3)(4)(5)(6)(7)(8)(9)a(b)c/123456789c$8a/;
+ unless (s eq "123456789cba") puts("bad 9.19");
+ s = "123456789abc";
+ s =~ s/1(2)(3)(4)(5)(6)(7)(8)(9)a(b)c/123456789c$9a/;
+ unless (s eq "123456789cba") puts("bad 9.19.1");
+
+ /* Make sure $a still works, where a != [0-9]. */
+ s = "123456789abc";
+ s =~ s/1(2)(3)(4)(5)(6)(7)(8)(9)a(b)c/123456789c$aa/;
+ unless (s eq "123456789c$aa") puts("bad 9.19.2");
+
+ /* Check \a \e \f \n \r \t. */
+ s = "a\nb\n\nc\n\nd\n";
+ s =~ s/\n\n/\n/g;
+ unless (s eq "a\nb\nc\nd\n") puts("bad 9.20");
+
+ /* Check \x for x being anything else. */
+ s = "abc";
+ s =~ s/b/a\bc/;
+ unless (s eq "aabcc") puts("bad 9.30");
+ s = "abc";
+ s =~ s/b/a\&c/;
+ unless (s eq "aa&cc") puts("bad 9.31");
+
+ /*
+ * Re-do the above checks but put the escapes in an
+ * interpolated part of the substituted string. This checks
+ * that they are properly processed at run time.
+ */
+
+ /* Check & and \0. */
+ s = "abc";
+ r = "x&y";
+ s =~ s/b/${r}/;
+ unless (s eq "axbyc") puts("bad 10.1");
+ s = "abc";
+ r = "x\\0y";
+ s =~ s/b/${r}/;
+ unless (s eq "axbyc") puts("bad 10.2");
+
+ /* Check \1 through \9. */
+ s = "123456789abc";
+ r = "123456789c\\1a";
+ s =~ s/123456789a(b)c/${r}/;
+ unless (s eq "123456789cba") puts("bad 10.3");
+ s = "123456789abc";
+ r = "123456789c\\2a";
+ s =~ s/12345678(9)a(b)c/${r}/;
+ unless (s eq "123456789cba") puts("bad 10.4");
+ s = "123456789abc";
+ r = "123456789c\\3a";
+ s =~ s/1234567(8)(9)a(b)c/${r}/;
+ unless (s eq "123456789cba") puts("bad 10.5");
+ s = "123456789abc";
+ r = "123456789c\\4a";
+ s =~ s/123456(7)(8)(9)a(b)c/${r}/;
+ unless (s eq "123456789cba") puts("bad 10.6");
+ s = "123456789abc";
+ r = "123456789c\\5a";
+ s =~ s/12345(6)(7)(8)(9)a(b)c/${r}/;
+ unless (s eq "123456789cba") puts("bad 10.7");
+ s = "123456789abc";
+ r = "123456789c\\6a";
+ s =~ s/1234(5)(6)(7)(8)(9)a(b)c/${r}/;
+ unless (s eq "123456789cba") puts("bad 10.8");
+ s = "123456789abc";
+ r = "123456789c\\7a";
+ s =~ s/123(4)(5)(6)(7)(8)(9)a(b)c/${r}/;
+ unless (s eq "123456789cba") puts("bad 10.9");
+ s = "123456789abc";
+ r = "123456789c\\8a";
+ s =~ s/12(3)(4)(5)(6)(7)(8)(9)a(b)c/${r}/;
+ unless (s eq "123456789cba") puts("bad 10.10");
+ s = "123456789abc";
+ r = "123456789c\\9a";
+ s =~ s/1(2)(3)(4)(5)(6)(7)(8)(9)a(b)c/${r}/;
+ unless (s eq "123456789cba") puts("bad 10.11");
+
+ /* Check \a \e \f \n \r \t. */
+ s = "a\nb\n\nc\n\nd\n";
+ r = "\\n";
+ s =~ s/\n\n/${r}/g;
+ unless (s eq "a\nb\nc\nd\n") puts("bad 10.20");
+
+ /* Check \x for x being anything else. */
+ s = "abc";
+ r = "a\\bc";
+ s =~ s/b/${r}/;
+ unless (s eq "aabcc") puts("bad 10.30");
+ s = "abc";
+ r = "a\\&c";
+ s =~ s/b/${r}/;
+ unless (s eq "aa&cc") puts("bad 10.31");
+}
+#lang tcl
+regexp_1_5
+} -output ""
+
+test regexp-1.6 {regexp capture variables in interpolated regexp} -body {
+#lang L --line=1
+void regexp_1_6()
+{
+ string r1 = "(1)";
+ string r2 = "(1)(2)(3)(4)(5)(6)(7)(8)(9)";
+
+ unless ("x1y" =~ /x${r1}y/) puts("bad 1.1");
+ unless ($0 eq "x1y") puts("bad 1.2");
+ unless ($1 eq "1") puts("bad 1.3");
+
+ unless ("x123456789y" =~ /x${r2}y/) puts("bad 2.1");
+ unless ($0 eq "x123456789y") puts("bad 2.2");
+ unless ($1 eq "1") puts("bad 2.3");
+ unless ($2 eq "2") puts("bad 2.4");
+ unless ($3 eq "3") puts("bad 2.5");
+ unless ($4 eq "4") puts("bad 2.6");
+ unless ($5 eq "5") puts("bad 2.7");
+ unless ($6 eq "6") puts("bad 2.8");
+ unless ($7 eq "7") puts("bad 2.9");
+ unless ($8 eq "8") puts("bad 2.10");
+ unless ($9 eq "9") puts("bad 2.11");
+}
+regexp_1_6();
+} -output {}
+
+test regexp-1.7 {check number of regexp capture variables available} -body {
+#lang L --line=1
+void regexp_1_7()
+{
+ /*
+ * This is more of a performance check. Ensure that in a
+ * regexp with no interpolations that no unneeded capture
+ * variables are allocated.
+ */
+
+ puts($1); // error -- no regexp seen yet, so $1 is not yet declared
+
+ "x" =~ /(x)/; // declares $1
+ puts($2); // error
+
+ "x" =~ /(x)(y)/; // declares $1 and $2
+ puts($3); // error
+}
+} -returnCodes error -match regexp -result {.*9: L Error: undeclared variable: \$1
+.*12: L Error: undeclared variable: \$2
+.*15: L Error: undeclared variable: \$3
+}
+
+test regexp-1.8 {check matching of different regexp kinds} -body {
+#lang L --line=1
+/*
+ * The compiler generates four different kinds of code for regexp
+ * matching. This test checks each kind:
+ * re is a string constant - INST_STR_EQ
+ * re is a glob (/l modifier) - INST_STR_MATCH
+ * re has no captures - INST_REGEXP
+ * re has captures - ::regexp cmd
+ */
+int regexp_1_8_streq() { return("abc" =~ /^abc$/); }
+int regexp_1_8_strmatch() { return("abc" =~ /abc/l); }
+int regexp_1_8_simple_re() { return("abc" =~ /a*bc/); }
+int regexp_1_8_complex_re() { return("abc" =~ /a*(b)c/); }
+int regexp_1_8_complex_re2() { return("abc" =~ /^${""}abc$/); }
+int regexp_1_8_complex_re3() { return("abc" =~ /^abc${""}$/); }
+int regexp_1_8_complex_re4() { return("abc" =~ /^ab${""}c$/); }
+void regexp_1_8()
+{
+ string dis;
+
+ unless (regexp_1_8_streq()) puts("bad 1.1");
+ unless (regexp_1_8_strmatch()) puts("bad 1.2");
+ unless (regexp_1_8_simple_re()) puts("bad 1.3");
+ unless (regexp_1_8_complex_re()) puts("bad 1.4");
+ unless (regexp_1_8_complex_re2()) puts("bad 1.5");
+ unless (regexp_1_8_complex_re3()) puts("bad 1.6");
+ unless (regexp_1_8_complex_re4()) puts("bad 1.7");
+
+ /*
+ * Check the disassembly of the regexp matches to verify that
+ * they are compiled as expected.
+ */
+ dis = ::tcl::unsupported::disassemble("proc", "regexp_1_8_streq");
+ unless (dis =~ /streq/) puts("bad 2.1");
+ dis = ::tcl::unsupported::disassemble("proc", "regexp_1_8_strmatch");
+ unless (dis =~ /strmatch/) puts("bad 2.2");
+ dis = ::tcl::unsupported::disassemble("proc", "regexp_1_8_simple_re");
+ unless (dis =~ / regexp/) puts("bad 2.3");
+ dis = ::tcl::unsupported::disassemble("proc", "regexp_1_8_complex_re");
+ unless (dis =~ /::regexp/) puts("bad 2.4");
+ dis = ::tcl::unsupported::disassemble("proc", "regexp_1_8_complex_re2");
+ unless (dis =~ /::regexp/) puts("bad 2.5");
+ dis = ::tcl::unsupported::disassemble("proc", "regexp_1_8_complex_re3");
+ unless (dis =~ /::regexp/) puts("bad 2.6");
+ dis = ::tcl::unsupported::disassemble("proc", "regexp_1_8_complex_re4");
+ unless (dis =~ /::regexp/) puts("bad 2.7");
+}
+regexp_1_8();
+} -output {}
+
+test regexp-1.9 {check alternate regexp syntax} -body {
+#lang L
+void regexp_1_9()
+{
+ string s;
+
+ unless ("Hello World" =~ m!World!) puts("bad 1.1");
+ unless ("Hello World" =~ m!world!i) puts("bad 1.2");
+
+ unless ("Hello World" =~ m,World,) puts("bad 1.3");
+ unless ("Hello World" =~ m,world,i) puts("bad 1.4");
+
+ unless ("Hello World" =~ m/World/) puts("bad 1.5");
+ unless ("Hello World" =~ m/world/i) puts("bad 1.6");
+
+ unless ("/usr/bin/perl" =~ m"/perl") puts("bad 1.7");
+ unless ("/usr/bin/perl" =~ m"/Perl"i) puts("bad 1.8");
+
+ /*
+ * The following delims are special cases and must be matched
+ * as shown. Using the start delim as the end delim is an
+ * error here, unlike all the other allowable delims. This is
+ * for Perl compatibility.
+ */
+
+ unless ("Hello World" =~ m{World}) puts("bad 2.1");
+ unless ("Hello World" =~ m{world}i) puts("bad 2.2");
+
+ /* Test alternate syntax like s{regexp}{replace}. */
+
+ s = "xyzzy";
+ s =~ s{xy}{zz};
+ unless (s == "zzzzy") puts("bad 3.1");
+
+ s = "xyzzy";
+ s =~ s{XY}{zz}i;
+ unless (s == "zzzzy") puts("bad 3.2");
+
+ s = "xyzzy";
+ s =~ s{xy}/zz/;
+ unless (s == "zzzzy") puts("bad 3.3");
+
+ s = "xyzzy";
+ s =~ s{XY}/zz/i;
+ unless (s == "zzzzy") puts("bad 3.4");
+}
+regexp_1_9();
+} -output {}
+
+test regexp-1.10 {test alternate regexp lexical and syntax errors} -setup {
+ # This is a pain to test because tcltest cannot handle
+ # the unbalanced {} () that we need in the L code.
+ # Make the .l file using makeFile so we can quote those
+ # characters and keep tcltest happy.
+ makeFile "
+ void main()
+ {
+ string s;
+
+ /*
+ * This tests when the regexp start delim is different
+ * than the end delim. The following are all errors,
+ * because the start delim is not escaped inside the
+ * regexp even though it is illegal to use it as
+ * the end delim. This rule comes from Perl.
+ */
+ s =~ m\{\{\};
+ s =~ s\{\{\}\{\};
+
+ /*
+ * Put this one last since it causes a syntax error.
+ * Although s{regexp}{replace} is legal,
+ * s/regexp//replace/ is not.
+ */
+ s =~ s/regexp//replace/;
+ }
+ " regexp-1.10.l
+} -body {
+#lang L
+void regexp_1_10()
+{
+ int ret;
+ string tclsh = interpreter();
+ string out, err[];
+
+ ret = system({tclsh, "regexp-1.10.l"}, undef, &out, &err);
+ unless (ret == 1) puts("bad 1.1");
+ if (out) puts("bad 1.2: ${out}");
+ unless (err[0] =~ /:13: L Error: regexp delimiter must be quoted/) {
+ puts("bad 1.3: ${err[0]}");
+ }
+ unless (err[1] =~ /:14: L Error: regexp delimiter must be quoted/) {
+ puts("bad 1.4: ${err[1]}");
+ }
+ unless (err[2] =~ /:21: L Error: syntax error/) {
+ puts("bad 1.5: ${err[2]}");
+ }
+}
+regexp_1_10();
+} -output {}
+
+test regexp-1.11 {test regexp submatch captures with subst operator} -body {
+#lang L --line=1
+void regexp_1_11()
+{
+ string s;
+
+ /*
+ * A single substitution.
+ */
+ s = "abcd";
+ s =~ s/a(b)(c)d/a\2\1d/;
+ unless (s == "acbd") puts("bad 1.1 '${s}'");
+ unless ($0 == "abcd") puts("bad 1.2");
+ unless ($1 == "b") puts("bad 1.3");
+ unless ($2 == "c") puts("bad 1.4");
+
+ /*
+ * Multiple substitutions. $0-$9 should reflect the last match.
+ */
+ s = "abc1abc22abc333";
+ s =~ s/a(b)(c)(\d+)/\3\2\1/g;
+ unless (s == "1cb22cb333cb") puts("bad 2.1 '${s}'");
+ unless ($0 == "abc333") puts("bad 2.2");
+ unless ($1 == "b") puts("bad 2.3");
+ unless ($2 == "c") puts("bad 2.4");
+ unless ($3 == "333") puts("bad 2.5");
+}
+regexp_1_11();
+} -output {}
+
+test regexp-1.12 {check newline matching of . in regexp} -body {
+#lang L --line=1
+void regexp_1_12()
+{
+ /*
+ * "." in a regexp should not match embedded newlines.
+ */
+
+ string s1 = "a\nb";
+ string s2 = "a\n\nb";
+
+ /*
+ * These used to compile to INST_STR_MATCH bytecodes.
+ */
+
+ // s1 & s2 are Tcl_Obj's with no type yet
+ if (s1 =~ /a.b/) puts("bad 1.1");
+ if (s2 =~ /a.*b/) puts("bad 1.2");
+
+ // make them type bytearray
+ s1 = Binary_format("a*", s1);
+ s2 = Binary_format("a*", s2);
+ if (s1 =~ /a.b/) puts("bad 1.3");
+ if (s2 =~ /a.*b/) puts("bad 1.4");
+
+ // make them type string
+ s1 = sprintf("%s", s1);
+ s2 = sprintf("%s", s2);
+ if (s1 =~ /a.b/) puts("bad 1.5");
+ if (s2 =~ /a.*b/) puts("bad 1.6");
+
+ /*
+ * These compile to INST_REGEXP bytecodes.
+ */
+
+ if (s1 =~ /a.bc?/) puts("bad 2.1");
+ if (s2 =~ /a.*bc?/) puts("bad 2.2");
+
+ /*
+ * These compile to calls to the ::regexp cmd.
+ */
+
+ if (s1 =~ /a.(b)/) puts("bad 3.1");
+ if (s2 =~ /a.*(b)/) puts("bad 3.2");
+}
+regexp_1_12();
+} -output {}
+
+test regexp-2 {test globs} -body {
+#lang L --line=1
+void regexp_2()
+{
+ unless ("x" =~ /?/l) puts("bad 1.1");
+ unless ("xy" =~ /??/l) puts("bad 1.2");
+ unless ("xy" =~ /*y/l) puts("bad 1.3"); /* this comment is for emacs */
+ unless ("xy" =~ /[x-z]y/l) puts("bad 1.4");
+}
+regexp_2();
+} -output {}
+
+test reference-1.1 {L references} -body {
+#lang L --line=1
+private int ref_11_g_private;
+int ref_11_g_public;
+struct reference_1_1_point {
+ int x, y;
+};
+private void setvar(int &var, int val)
+{
+ var = val;
+}
+class ref_11_cls {
+ public int cpub;
+ instance {
+ public int cinst;
+ }
+ constructor ref_11_cls_new()
+ {
+ setvar(&cpub, 123);
+ unless (cpub == 123) puts("bad c.1");
+ setvar(&cinst, 456);
+ unless (cinst == 456) puts("bad c.2");
+ }
+}
+void reference_1_1()
+{
+ int local;
+ ref_11_cls o;
+ struct reference_1_1_point a = { 0, 0 };
+
+ unless ((a.x == 0) && (a.y == 0)) puts("bad 1.1");
+ reference_1_1_tweak(&a);
+ unless ((a.x == 2) && (a.y == 0)) puts("bad 1.2");
+
+ setvar(&local, 222);
+ unless (local == 222) puts("bad 2.1");
+
+ o = ref_11_cls_new();
+ unless (ref_11_cls->cpub == 123) puts("bad 3.1");
+ unless (o->cinst == 456) puts("bad 3.2");
+
+ setvar(&ref_11_cls->cpub, 234);
+ unless (ref_11_cls->cpub == 234) puts("bad 3.3");
+
+ setvar(&o->cinst, 567);
+ unless (o->cinst == 567) puts("bad 3.4");
+
+ setvar(&ref_11_g_public, 1100);
+ unless (ref_11_g_public == 1100) puts("bad 4.1");
+
+ setvar(&ref_11_g_private, 1200);
+ unless (ref_11_g_private == 1200) puts("bad 4.2");
+}
+void reference_1_1_tweak(struct reference_1_1_point &foo)
+{
+ foo->x = 2;
+}
+reference_1_1();
+} -output {}
+
+test reference-1.2 {test deep-dive arguments (copy in/out)} -body {
+#lang L --line=1
+void r12set(string &s, string v) { s = v; }
+void reference_1_2()
+{
+ string a[];
+ string aa[][];
+ string aaa[][][];
+ string h{string};
+ string hh{string}{string};
+ string hhh{string}{string}{string};
+ struct {
+ string s;
+ string a[];
+ string h{string};
+ } st;
+
+ r12set(&a[0], "zero");
+ unless (a[0] eq "zero") puts("bad 1.1");
+ r12set(&a[1], "one");
+ unless ((a[0] eq "zero") && (a[1] eq "one")) puts("bad 1.2");
+ r12set(&a[0], "is1");
+ unless ((a[0] eq "is1") && (a[1] eq "one")) puts("bad 1.3");
+
+ r12set(&aa[1][2], "12");
+ unless (aa[1][2] eq "12") puts("bad 2.1");
+
+ r12set(&aaa[3][2][1], "321");
+ unless (aaa[3][2][1] eq "321") puts("bad 3.1");
+
+ r12set(&h{"zero"}, "is0");
+ unless (h{"zero"} eq "is0") puts("bad 10.1");
+
+ r12set(&hh{"zero1"}{"zero2"}, "is00");
+ unless (hh{"zero1"}{"zero2"} eq "is00") puts("bad 11.1");
+
+ r12set(&hhh{"zero3"}{"zero2"}{"zero1"}, "is000");
+ unless (hhh{"zero3"}{"zero2"}{"zero1"} eq "is000") puts("bad 12.1");
+
+ r12set(&st.s, "iss");
+ unless (st.s eq "iss") puts("bad 20.1");
+
+ r12set(&st.a[3], "a-3");
+ unless (st.a[3] eq "a-3") puts("bad 21.1");
+
+ r12set(&st.h{"two"}, "h-2");
+ unless (st.h{"two"} eq "h-2") puts("bad 22.1");
+}
+reference_1_2();
+} -output {}
+
+test reference-1.2.1 {test deep-dive copy in/out with built-in compiler functions} -body {
+#lang L --line=1
+void reference_1_2_1()
+{
+ string cmd, s[];
+ STATUS st[];
+ FILE f;
+ int pid, ret;
+
+ /*
+ * These tests pass array or hash elements as reference
+ * parameters. The compiler implements these as
+ * copy-in/copy-out parameters and these used to not work
+ * with compiler built-ins.
+ */
+
+ // check system(): out/err/STATUS args
+ cmd = <<'END'
+ perl -e 'print "test32"; print STDERR "yes1"; exit(0);'
+ END;
+ ret = system(cmd, undef, &s[0], &s[1], &st[0]);
+ unless (ret == 0) puts("bad 1.1");
+ unless (s[0] == "test32") puts("bad 1.2");
+ unless (s[1] == "yes1") puts("bad 1.3");
+ unless (st[0].argv[0] == "perl") puts("bad 1.4");
+
+ // check read(): buf arg
+ unless (Fprintf("ref-1-2-1.txt", "654321") == 0) puts("bad 2.1");
+ unless (f = fopen("ref-1-2-1.txt", "r")) puts("bad 2.2");
+ unless (read(f, &s[0]) == 6) puts("bad 2.3");
+ unless (s[0] == "654321") pust("bad 2.4");
+ fclose(f);
+ unlink("ref-1-2-1.txt");
+
+ // check spawn(): when the STATUS arg gets set
+ cmd = "not-perl -e 'exit(123);'";
+ pid = spawn(cmd, undef, undef, undef, &st[0]);
+ if (defined(pid)) puts("bad 3.1");
+ unless (st[0].argv == {"not-perl","-e","exit(123);"}) puts("bad 3.3");
+
+ // check waitpid(): STATUS arg
+ cmd = "perl -e 'exit(123);'";
+ pid = spawn(cmd);
+ unless (defined(pid)) puts("bad 4.1");
+ unless (waitpid(pid, &st[0], 0) == pid) puts("bad 4.2");
+ unless (st[0].argv == {"perl","-e","exit(123);"}) puts("bad 4.3");
+}
+reference_1_2_1();
+} -output {}
+
+test reference-1.3 {test copy in/out semantics} -body {
+#lang L --line=1
+string g_ref13[];
+void r13(string &s, string v)
+{
+ s = v;
+ g_ref13 = { "ch-one", "ch-two", "ch-three" };
+}
+void reference_1_3()
+{
+ g_ref13 = { "one", "two" };
+ r13(&g_ref13[0], "new-one");
+ unless (join("|", g_ref13) eq "new-one|ch-two|ch-three") puts("bad 1.1");
+}
+reference_1_3();
+} -output {}
+
+test reference-1.4 {test multiple reference arguments} -body {
+#lang L --line=1
+void reference_1_4_foo1(string &s1, string &s2)
+{
+ s1 = s2;
+}
+void reference_1_4_foo2(string &s1, string s2)
+{
+ s1 = s2;
+ s2 = "bad";
+}
+void reference_1_4_foo3(string &s1, string s2, string &s3)
+{
+ s1 = sprintf("%s%s", s2, s3);
+ s2 = "bad";
+}
+void reference_1_4_foo4(string &s1, string s2, string &s3)
+{
+ s1 = sprintf("%s%s", s2, s3);
+ s3 = s2;
+ s2 = "bad";
+}
+void reference_1_4_foo5(string &s1, string &s2, string &s3)
+{
+ s1 = sprintf("%s%s", s2, s3);
+ s2 = s3;
+ s3 = "x";
+}
+void reference_1_4_foo6(string &s1, string s2, string &s3, string s4)
+{
+ s1 = sprintf("%s%s", s2, s3);
+ s3 = sprintf("%s%s", s3, s4);
+ s2 = s4 = "bad";
+}
+void reference_1_4_foo7(string s1, string &s2, string s3, string s4, string &s5)
+{
+ s2 = sprintf("%s%s%s", s1, s2, s3);
+ s5 = sprintf("%s%s%s", s3, s4, s5);
+ s1 = s3 = s4 = "bad";
+}
+void reference_1_4()
+{
+ string s1, s2, s3;
+
+ s1 = "";
+ s2 = "foo1";
+ reference_1_4_foo1(&s1, &s2);
+ unless (s1 eq "foo1") puts("bad 1.1");
+ unless (s2 eq "foo1") puts("bad 1.2");
+
+ s1 = "";
+ reference_1_4_foo2(&s1, "foo2");
+ unless (s1 eq "foo2") puts("bad 2.1");
+
+ s1 = "";
+ s2 = "xxx";
+ reference_1_4_foo3(&s1, "foo3", &s2);
+ unless (s1 eq "foo3xxx") puts("bad 3.1");
+ unless (s2 eq "xxx") puts("bad 3.2");
+
+ s1 = "xx";
+ s2 = "yy";
+ reference_1_4_foo4(&s1, "foo4", &s2);
+ unless (s1 eq "foo4yy") puts("bad 4.1");
+ unless (s2 eq "foo4") puts("bad 4.2");
+
+ s1 = "zz";
+ s2 = "xx";
+ s3 = "yy";
+ reference_1_4_foo5(&s1, &s2, &s3);
+ unless (s1 eq "xxyy") puts("bad 4.1");
+ unless (s2 eq "yy") puts("bad 4.2");
+ unless (s3 eq "x") puts("bad 4.3");
+
+ s1 = "x";
+ s2 = "y";
+ reference_1_4_foo6(&s1, "foo61", &s2, "foo62");
+ unless (s1 eq "foo61y") puts("bad 5.1");
+ unless (s2 eq "yfoo62") puts("bad 5.2");
+
+ s1 = "a";
+ s2 = "b";
+ reference_1_4_foo7("foo71", &s1, "foo72", "foo73", &s2);
+ unless (s1 eq "foo71afoo72") puts("bad 6.1");
+ unless (s2 eq "foo72foo73b") puts("bad 6.2");
+}
+reference_1_4();
+} -output {}
+
+test reference-1.5 {test parameter multiple declaration errs with references} -body {
+#lang L --line=1 -nowarn
+void reference_1_5_1(string &arg1, string arg1) {}
+void reference_1_5_2(string &arg2, string &arg2) {}
+void reference_1_5_3(string arg3, string &arg3) {}
+void reference_1_5_4(string &arg4, string &arg4, string arg4) {}
+void reference_1_5_5(string &arg5, string arg5, string &arg5) {}
+} -returnCodes error -match regexp -result {.*1: L Error: multiple declaration of local arg1
+.*2: L Error: multiple declaration of local &arg2
+.*3: L Error: multiple declaration of local arg3
+.*4: L Error: multiple declaration of local &arg4
+.*4: L Error: multiple declaration of local arg4
+.*5: L Error: multiple declaration of local &arg5
+.*5: L Error: multiple declaration of local arg5
+.*5: L Error: multiple declaration of local arg5
+}
+
+test reference-1.6 {test reference parameter passed as a reference parameter} -body {
+#lang L --line=1
+string reference_1_6_g;
+void reference_1_6_1(string &arg)
+{
+ arg .= "2";
+ reference_1_6_2(&arg);
+}
+void reference_1_6_2(string &arg)
+{
+ arg .= "3";
+}
+void reference_1_6()
+{
+ string s;
+
+ s = "1";
+ reference_1_6_1(&s);
+ unless (s == "123") puts("bad 1");
+
+ reference_1_6_g = "1";
+ reference_1_6_1(&reference_1_6_g);
+ unless (reference_1_6_g == "123") puts("bad 2");
+}
+reference_1_6();
+} -output {}
+
+test pointer-1 {check L pointers} -body {
+#lang L --line=1
+string pointer_1_g_public;
+private string pointer_1_g_private;
+private string chk(_argused string opt, poly var)
+{
+ return (var);
+}
+class pointer_1_cls {
+ public string s;
+ instance {
+ public string si;
+ }
+ constructor pointer_1_cls_new()
+ {
+ string nm;
+
+ nm = chk(textvariable: &pointer_1_g_public);
+ unless (nm eq "::pointer_1_g_public") {
+ puts("bad c1.1");
+ }
+ nm = chk(textvariable: &pointer_1_g_private);
+ unless (nm =~ /::_[0-9]+%l_toplevel_pointer_1_g_private/) {
+ puts("bad c1.2");
+ puts(nm);
+ }
+ nm = chk(textvariable: &s);
+ unless (nm eq "::L::_class_pointer_1_cls::s") {
+ puts("bad c1.3");
+ }
+ nm = chk(textvariable: &si);
+ unless (nm eq "::L::_instance_pointer_1_cls1::si") {
+ puts("bad c1.4");
+ }
+ }
+}
+void pointer_1()
+{
+ string nm;
+ pointer_1_cls obj = pointer_1_cls_new();
+
+ nm = chk(textvariable: &pointer_1_g_public);
+ unless (nm eq "::pointer_1_g_public") {
+ puts("bad 1.1");
+ }
+ nm = chk(textvariable: &pointer_1_g_private);
+ unless (nm =~ /::_[0-9]+%l_toplevel_pointer_1_g_private/) {
+ puts("bad 1.2");
+ }
+ nm = chk(textvariable: &pointer_1_cls->s);
+ unless (nm eq "::L::_class_pointer_1_cls::s") {
+ puts("bad 1.3");
+ }
+ nm = chk(textvariable: &obj->si);
+ unless (nm eq "::L::_instance_pointer_1_cls1::si") {
+ puts("bad 1.4");
+ }
+}
+pointer_1();
+} -output {}
+
+test pointer-2 {check L pointer identification} -body {
+#lang L --line=1
+string pointer_2_g;
+private void chk(_argused string opt, poly arg, string varname)
+{
+ unless (arg =~ /${varname}/) puts("bad chk.1");
+}
+private string joinargs(...args)
+{
+ string ret, s;
+
+ foreach (s in args) {
+ if (defined(ret)) {
+ ret .= " " . s;
+ } else {
+ ret = s;
+ }
+ }
+ return (ret);
+}
+void pointer_2()
+{
+ string s;
+
+ /* These are L pointers. */
+ s = joinargs(textvariable: &pointer_2_g);
+ unless (s eq "-textvariable ::pointer_2_g") puts("bad 1.1");
+ s = joinargs(tvariable: &pointer_2_g);
+ unless (s eq "-tvariable ::pointer_2_g") puts("bad 1.2");
+ s = joinargs(variable: &pointer_2_g);
+ unless (s eq "-variable ::pointer_2_g") puts("bad 1.3");
+
+ /* These are reference parameters, not pointers. */
+ s = joinargs(ariable: &s);
+ unless (s eq "-ariable s") puts("bad 2.1");
+ s = joinargs(o: &s);
+ unless (s eq "-o s") puts("bad 2.2");
+
+ /* Mix of L pointers and ref parms. */
+ s = joinargs(textvariable: &pointer_2_g, &s);
+ unless (s eq "-textvariable ::pointer_2_g s") puts("bad 3.1");
+ s = joinargs(textvariable: &pointer_2_g, &s, &s);
+ unless (s eq "-textvariable ::pointer_2_g s s") puts("bad 3.2");
+ s = joinargs(&s, textvariable: &pointer_2_g);
+ unless (s eq "s -textvariable ::pointer_2_g") puts("bad 3.3");
+ s = joinargs(&s, &s, textvariable: &pointer_2_g);
+ unless (s eq "s s -textvariable ::pointer_2_g") puts("bad 3.4");
+ s = joinargs(&s, textvariable: &pointer_2_g, &s);
+ unless (s eq "s -textvariable ::pointer_2_g s") puts("bad 3.5");
+}
+pointer_2();
+} -output {}
+
+test pointer-3 {check L pointer errors} -body {
+#lang L --line=1 -nowarn
+class pointer_3_cls {}
+private void chk(_argused string opt, _argused poly arg) {}
+void pointer_3()
+{
+ string s;
+ string sa[];
+ string saa[][];
+ string h{string};
+
+ /*
+ * These should all issue errors, not crash the compiler.
+ */
+ chk(textvariable: &undeclared1);
+ chk(textvariable: &undeclared2[2]);
+ chk(textvariable: &undeclared3.s);
+ chk(textvariable: &undeclared4->s);
+ chk(textvariable: &pointer_3_cls->undeclared1);
+ chk(textvariable: &pointer_3_cls->undeclared2[3]);
+ chk(textvariable: &s);
+ chk(textvariable: &sa[1]);
+ chk(textvariable: &saa[1][2]);
+ chk(textvariable: &h{"bad"});
+ chk(textvariable: &chk);
+}
+} -returnCodes error -match regexp -result {.*13: L Error: undeclared variable: undeclared1
+.*14: L Error: undeclared variable: undeclared2
+.*15: L Error: undeclared variable: undeclared3
+.*16: L Error: undeclared variable: undeclared4
+.*17: L Error: undeclared1 is not a member of class pointer_3_cls
+.*18: L Error: undeclared2 is not a member of class pointer_3_cls
+.*19: L Error: illegal operand to &
+.*20: L Error: illegal operand to &
+.*21: L Error: illegal operand to &
+.*22: L Error: illegal operand to &
+.*23: L Error: illegal operand to &
+}
+
+test typedef-1.0 {basic typedef support} -body {
+#lang L --line=1
+typedef int typedef_1_0_foot[5];
+typedef string typedef_1_0_nike;
+typedef struct typedef_1_0_point {
+ int x;
+ int y;
+} typedef_1_0_point;
+
+void typedef_1_0() {
+ puts(typedef_1_0_aux());
+}
+
+typedef_1_0_nike typedef_1_0_aux() {
+ typedef_1_0_foot cheese;
+ typedef_1_0_nike shoe = "pegasus";
+ typedef_1_0_point p;
+
+ p.x = 1;
+ p.y = 2;
+ puts(p);
+ cheese[2] = 1;
+ cheese[3] = 2;
+ cheese[4] = 3;
+ puts(cheese[3]);
+ puts(shoe);
+ return shoe;
+}
+#lang tcl
+typedef_1_0
+} -output "1 2\n2\npegasus\npegasus\n"
+
+test typedef-1.1 {test redefining identical typedefs} -body {
+#lang L --line=1
+typedef int t1;
+typedef int t1;
+typedef int t1;
+
+typedef float t2;
+typedef float t2;
+typedef float t2;
+
+typedef string t3;
+typedef string t3;
+typedef string t3;
+
+typedef widget t4;
+typedef widget t4;
+typedef widget t4;
+
+typedef poly t5;
+typedef poly t5;
+typedef poly t5;
+
+typedef int a11_1[];
+typedef int a11_1[];
+typedef int a11_1[];
+
+typedef int a11_2[2];
+typedef int a11_2[2];
+typedef int a11_2[2];
+
+typedef int a11_3{int};
+typedef int a11_3{int};
+typedef int a11_3{int};
+
+typedef int a11_4[2][3];
+typedef int a11_4a[3];
+typedef a11_4a a11_4[2];
+
+typedef struct { int x,y; } s11_1;
+typedef struct { int x,y; } s11_1;
+typedef struct { int x,y; } s11_1;
+
+typedef int int_typedef;
+
+typedef int h11_1{int};
+typedef int h11_1{int_typedef};
+typedef int_typedef h11_1{int};
+typedef int_typedef h11_1{int_typedef};
+
+typedef int h11_2{int}{int};
+typedef int h11_2a{int};
+typedef h11_2a h11_2{int};
+} -output ""
+
+test typedef-1.2 {test redefining different typedefs} -body {
+#lang L --line=1
+typedef int t12;
+typedef float t12;
+typedef string t12;
+typedef widget t12;
+typedef poly t12; // not an error, but perhaps should be
+typedef int t12[];
+typedef int t12[2];
+typedef int t12{int};
+typedef struct { int i; } t12;
+
+typedef int a12_1[]; // not an error -- array size is ignored
+typedef int a12_1[2];
+
+typedef int a12_2[2]; // not an error -- array size is ignored
+typedef int a12_2[];
+
+typedef int a12_3[2];
+typedef string a12_3[2];
+
+typedef int h12_1{int};
+typedef int h12_1{string};
+
+typedef int h12_2{int};
+typedef string h12_2{int};
+
+typedef int h12_3{int};
+typedef string h12_3{string};
+
+typedef struct { int x; } s12_1;
+typedef struct { string x; } s12_1;
+
+typedef struct { int x; } s12_2;
+typedef struct { int x,y; } s12_2;
+
+typedef struct { int x,y; } s12_3;
+typedef struct { int x; } s12_3;
+
+typedef struct s1 { int x; } s12_4;
+typedef struct s2 { string x; } s12_4;
+
+typedef struct s3 { int x; } s12_5;
+typedef struct s4 { int x,y; } s12_5;
+
+typedef struct s5 { int x,y; } s12_6;
+typedef struct s6 { int x; } s12_6;
+} -returnCodes error -match regexp -result {.*2: L Error: Cannot redefine type t12
+.*3: L Error: Cannot redefine type t12
+.*4: L Error: Cannot redefine type t12
+.*6: L Error: Cannot redefine type t12
+.*7: L Error: Cannot redefine type t12
+.*8: L Error: Cannot redefine type t12
+.*9: L Error: Cannot redefine type t12
+.*18: L Error: Cannot redefine type a12_3
+.*21: L Error: Cannot redefine type h12_1
+.*24: L Error: Cannot redefine type h12_2
+.*27: L Error: Cannot redefine type h12_3
+.*30: L Error: Cannot redefine type s12_1
+.*33: L Error: Cannot redefine type s12_2
+.*36: L Error: Cannot redefine type s12_3
+.*39: L Error: Cannot redefine type s12_4
+.*42: L Error: Cannot redefine type s12_5
+.*45: L Error: Cannot redefine type s12_6
+}
+
+test typedef-1.3 {test some typedef cases} -body {
+#lang L --line=1
+/*
+ * This is really a regression test. These have caused errors in the past.
+ */
+typedef int int_t;
+typedef int h1_t{int_t};
+typedef int_t h2_t{int};
+typedef int_t h3_t{int_t};
+void typedef_1_3()
+{
+ int k, n;
+ h1_t h1 = { 1=>2 };
+ h2_t h2 = { 3=>4, 5=>6 };
+ h3_t h3 = { 7=>8, 9=>10, 11=>12 };
+
+ unless (h1{1} == 2) puts("bad 1");
+ n = 0;
+ foreach (k in h1) ++n;
+ unless (n == 1) puts("bad 2");
+
+ unless ((h2{3} == 4) && (h2{5} == 6)) puts("bad 3");
+ n = 0;
+ foreach (k in h2) ++n;
+ unless (n == 2) puts("bad 4");
+
+ unless ((h3{7} == 8) && (h3{9} == 10) && (h3{11} == 12)) puts("bad 4");
+ n = 0;
+ foreach (k in h3) ++n;
+ unless (n == 3) puts("bad 5");
+}
+#lang tcl
+typedef_1_3
+} -output {}
+
+test typedef-1.4 {test another typedef case} -body {
+#lang L --line=1
+/* Another regression test. This used to fail. */
+typedef struct {
+ int x;
+ int y;
+} typedef_1_4_t;
+
+typedef_1_4_t typedef_1_4_bars{string};
+
+void typedef_1_4_foo(typedef_1_4_t f)
+{
+ typedef_1_4_bars{"FOO"} = f;
+ puts("X = ${f.x}");
+}
+
+void typedef_1_4()
+{
+ typedef_1_4_t f = { 1, 2 };
+ typedef_1_4_foo(f);
+}
+#lang tcl
+typedef_1_4
+} -output {X = 1
+}
+
+
+test defined-1.0 {interesting defined form support} -body {
+#lang L --line=1
+void defined_1_0() {
+ int arr[5][2], i, j;
+ for (i = 0; defined(arr[i]); i++) {
+ for (j = 0; defined(arr[i][j]); j++) {
+ puts(format("%d, %d", i, j));
+ }
+ }
+ puts("-*-");
+ puts(defined(arr[3]));
+ puts(defined(arr[-1]));
+}
+#lang tcl
+defined_1_0
+} -output "-*-
+0
+0
+"
+
+test defined-1.1 {defined works on hashes} -body {
+#lang L --line=1
+void defined_1_1() {
+ hash foo[5];
+
+ foo[2]{"a"} = 1;
+ foo[3]{"b"} = 2;
+
+ if (defined(foo[2]{"a"})) {
+ puts("defined works");
+ }
+ if (!defined(foo[2]{"b"})) {
+ puts("defined works even better");
+ }
+}
+#lang tcl
+defined_1_1
+} -output "defined works\ndefined works even better\n"
+
+test main-1.0 {test that main gets called} -setup {
+ set fname [makeFile {
+ void main() {
+ printf("main got called\n");
+ }
+ } test-1.0.l]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fname
+} -cleanup {
+ removeFile test-1.0.l
+} -result {main got called}
+
+test main-2.1 {test main() with one parameter} -setup {
+ set fname [makeFile {
+ void main(string av[]) {
+ string s;
+ undef(av[0]); // don't print av[0]
+ foreach (s in av) printf("<${s}>");
+ }
+ } main-2.1.l]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fname arg1 arg2 arg3
+} -cleanup {
+ removeFile main-2.1.l
+} -result {<arg1><arg2><arg3>}
+
+test main-2.2 {test main() with two parameters} -setup {
+ set fname [makeFile {
+ void main(int ac, string av[]) {
+ string s;
+ printf("<${ac}>");
+ undef(av[0]); // don't print av[0]
+ foreach (s in av) printf("<${s}>");
+ }
+ } main-2.2.l]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fname arg1 arg2 arg3
+} -cleanup {
+ removeFile main-2.2.l
+} -result {<4><arg1><arg2><arg3>}
+
+test main-2.3 {test main() with three parameters} -setup {
+ set fname [makeFile {
+ putenv("MAIN23_TEST=YES");
+ void main(int ac, string av[], string env{string}) {
+ string s;
+ printf("<${ac}>");
+ undef(av[0]); // don't print av[0]
+ foreach (s in av) printf("<${s}>");
+ printf("<${env{"MAIN23_TEST"}}>");
+ }
+ } main-2.3.l]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fname arg1 arg2 arg3
+} -cleanup {
+ removeFile main-2.3.l
+} -result {<4><arg1><arg2><arg3><YES>}
+
+test main-3 {check that main() return value is tclsh exit status} -setup {
+ set fname1 [makeFile {
+ int main(string av[])
+ {
+ puts("main here");
+ return (int)av[1];
+ }
+ } main-3-int.l]
+ set fname2 [makeFile {
+ void main()
+ {
+ puts("main here");
+ }
+ } main-3-void.l]
+} -body {
+#lang L --line=1
+void main3()
+{
+ int ret;
+ string out;
+ string tclsh = eval("interpreter");
+
+ ret = system({tclsh, "main-3-int.l", 0}, undef, &out, undef);
+ unless (ret == 0) puts("1.1");
+ unless (out == "main here\n") puts("bad 1.2");
+
+ ret = system({tclsh, "main-3-int.l", 1}, undef, &out, undef);
+ unless (ret == 1) puts("bad 2.1");
+ unless (out == "main here\n") puts("bad 2.2");
+
+ ret = system({tclsh, "main-3-int.l", 123}, undef, &out, undef);
+ unless (ret == 123) puts("bad 3.1");
+ unless (out == "main here\n") puts("bad 3.2");
+
+ /* Check that a void main() gives an exit status of 0. */
+ ret = system({tclsh, "main-3-void.l", 123}, undef, &out, undef);
+ unless (ret == 0) puts("bad 4.1");
+ unless (out == "main here\n") puts("bad 4.2");
+}
+main3();
+} -output {}
+
+test main-4 {check main() type checking} -body {
+#lang L --line=1
+float main() { return (3.14159); }
+void main(float bad) {}
+void main(int ac, string bad) {}
+void main(int ac, string av[], string bad) {}
+void main(int bad1, string bad2[], string bad3{string}, string too_many) {}
+} -returnCodes error -match regexp -result {.*1: L Error: main must have int or void return type
+.*2: L Error: invalid parameter types for main\(\)
+.*3: L Error: invalid parameter types for main\(\)
+.*4: L Error: invalid parameter types for main\(\)
+.*5: L Error: too many formal parameters for main\(\)
+}
+
+test defined-1.2 {defined operator on scalars} -body {
+#lang L --line=1
+int d12_fint() { return 0; }
+float d12_ffloat() { return 0.0; }
+string d12_fstring() { return "0"; }
+void
+defined_1_2()
+{
+ int i;
+ int ii = 0;
+ string s;
+ string ss = "";
+ float f;
+ float ff = 3.14159;
+
+ if (defined(i)) puts("err 1");
+ unless (defined(ii)) puts("err 2");
+ if (defined(s)) puts("err 3");
+ unless (defined(ss)) puts("err 4");
+ if (defined(f)) puts("err 5");
+ unless (defined(ff)) puts("err 6");
+ unless (defined(0)) puts("err 7");
+ unless (defined(1)) puts("err 7");
+ unless (defined("")) puts("err 8");
+ unless (defined("x")) puts("err 9");
+ unless (defined(0.0)) puts("err 10");
+ unless (defined(1.0)) puts("err 11");
+ unless (defined(d12_fint())) puts("err 12");
+ unless (defined(d12_ffloat())) puts("err 13");
+ unless (defined(d12_fstring())) puts("err 14");
+ unless (defined(1-0)) puts("err 16");
+ unless (defined(1+2+3+4)) puts("err 17");
+}
+#lang tcl
+defined_1_2
+} -output ""
+
+test defined-1.3 {defined operator on auto-extended arrays} -body {
+#lang L --line=1
+void
+defined_1_3()
+{
+ int i;
+ int a[];
+ int a3[3] = {0, 0, 0};
+ string s[];
+ string s3[3] = {"", "", ""};
+ float f[];
+ float f3[3] = {0.0, 0.0, 0.0};
+ string h{int}[];
+
+ a[3] = 3;
+ a[5] = 5;
+ a[6] = 6;
+ a[8] = 8;
+ if (defined(a[0])) puts("err 1.1");
+ if (defined(a[1])) puts("err 1.2");
+ if (defined(a[2])) puts("err 1.3");
+ unless (defined(a[3])) puts("err 1.4");
+ if (defined(a[4])) puts("err 1.5");
+ unless (defined(a[5])) puts("err 1.6");
+ unless (defined(a[6])) puts("err 1.7");
+ if (defined(a[7])) puts("err 1.8");
+ unless (defined(a[8])) puts("err 1.9");
+ for (i = 9; i < 1000; ++i) {
+ if (defined(a[i])) printf("err 1.10 i=%d\n", i);
+ }
+
+ unless (defined(a3[0])) puts("err 2.1");
+ unless (defined(a3[1])) puts("err 2.2");
+ unless (defined(a3[2])) puts("err 2.3");
+ for (i = 3; i < 1000; ++i) {
+ if (defined(a3[i])) printf("err 2.4 i=%d\n", i);
+ }
+
+ s[3] = "3";
+ s[5] = "5";
+ s[6] = "6";
+ s[8] = "8";
+ if (defined(s[0])) puts("err 3.1");
+ if (defined(s[1])) puts("err 3.2");
+ if (defined(s[2])) puts("err 3.3");
+ unless (defined(s[3])) puts("err 3.4");
+ if (defined(s[4])) puts("err 3.5");
+ unless (defined(s[5])) puts("err 3.6");
+ unless (defined(s[6])) puts("err 3.7");
+ if (defined(s[7])) puts("err 3.8");
+ unless (defined(s[8])) puts("err 3.9");
+ for (i = 9; i < 1000; ++i) {
+ if (defined(s[i])) printf("err 3.10 i=%d\n", i);
+ }
+
+ unless (defined(s3[0])) puts("err 4.1");
+ unless (defined(s3[1])) puts("err 4.2");
+ unless (defined(s3[2])) puts("err 4.3");
+ for (i = 3; i < 1000; ++i) {
+ if (defined(s3[i])) printf("err 4.4 i=%d\n", i);
+ }
+
+ f[3] = 3.0;
+ f[5] = 5.0;
+ f[6] = 6.0;
+ f[8] = 8.0;
+ if (defined(f[0])) puts("err 5.1");
+ if (defined(f[1])) puts("err 5.2");
+ if (defined(f[2])) puts("err 5.3");
+ unless (defined(f[3])) puts("err 5.4");
+ if (defined(f[4])) puts("err 5.5");
+ unless (defined(f[5])) puts("err 5.6");
+ unless (defined(f[6])) puts("err 5.7");
+ if (defined(f[7])) puts("err 5.8");
+ unless (defined(f[8])) puts("err 5.9");
+ for (i = 9; i < 1000; ++i) {
+ if (defined(f[i])) printf("err 5.10 i=%d\n", i);
+ }
+
+ unless (defined(f3[0])) puts("err 5.1");
+ unless (defined(f3[1])) puts("err 5.2");
+ unless (defined(f3[2])) puts("err 5.3");
+ for (i = 3; i < 1000; ++i) {
+ if (defined(f3[i])) printf("err 5.4 i=%d\n", i);
+ }
+
+ h{0}[2] = "2";
+ if (defined(h{0}[0])) puts("err 6.1");
+ if (defined(h{0}[1])) puts("err 6.2");
+ unless (defined(h{0}[2])) puts("err 6.3");
+ if (defined(h{0}[3])) puts("err 6.4");
+}
+#lang tcl
+defined_1_3
+} -output ""
+
+test defined-1.4 {check propagation of undefined values} -body {
+#lang L --line=1
+int
+d14(int i)
+{
+ return (i);
+}
+void
+defined_1_4()
+{
+ int i, j;
+ int a[];
+
+ a[1] = 1; // a[0] is now undefined
+ i = a[0]; // i is now undefined
+ j = d14(i); // j is now undefined
+
+ if (defined(a[0])) puts("err 1");
+ if (defined(i)) puts("err 2");
+ if (defined(j)) puts("err 3");
+ if (defined(d14(i))) puts("err 4");
+ if (defined(d14(j))) puts("err 5");
+ if (defined(d14(d14(j)))) puts("err 6");
+ if (defined(d14(d14(d14(j))))) puts("err 7");
+}
+#lang tcl
+defined_1_4
+} -output ""
+
+test defined-1.5 {check that tcl shimmering does not make undef defined} -body {
+#lang L --line=1
+void defined_1_5()
+{
+ /*
+ * This tests that the use of the undefined "s" in the printf,
+ * or the undefined ah[0] in the foreach, does not shimmer the
+ * shared undef object to something that is defined. This was
+ * a bug in an earlier implementation of undef.
+ */
+
+ string a[], s;
+ int ah[]{int}, k, v;
+
+ s = a[0]; // s is now undef
+
+ if (defined(s)) puts("bad 1.1");
+ printf("s = '%s'\n", s);
+ if (defined(s)) puts("bad 1.2");
+ printf("s = '%s'\n", s);
+
+ if (defined(ah[0])) puts("bad 2.1");
+ foreach (k=>v in ah[0]) {}
+ if (defined(ah[0])) puts("bad 2.2");
+ if (defined(s)) puts("bad 1.3");
+}
+defined_1_5();
+} -output {s = ''
+s = ''
+}
+
+test defined-1.6 {check undef constant} -body {
+#lang L --line=1
+string defined_1_6_foo(string arg)
+{
+ if (arg) {
+ return (arg);
+ } else {
+ return (undef);
+ }
+}
+void defined_1_6()
+{
+ int i;
+ string s;
+
+ if (defined(undef)) puts("bad 0.1");
+
+ i = undef;
+ if (defined(i)) puts("bad 1.1");
+ printf("i = '%s'\n", i);
+ if (defined(i)) puts("bad 1.2");
+
+ i = 0;
+ unless (defined(i)) puts("bad 2.1");
+ printf("i = '%s'\n", i);
+ unless (defined(i)) puts("bad 2.2");
+
+ i = undef;
+ if (defined(i)) puts("bad 3.1");
+ printf("i = '%s'\n", i);
+ if (defined(i)) puts("bad 3.2");
+
+ unless (defined(defined_1_6_foo("1"))) puts("bad 4.1");
+ if (defined(defined_1_6_foo(s))) puts("bad 4.2");
+ if (defined(defined_1_6_foo(undef))) puts("bad 4.3");
+}
+defined_1_6();
+} -output {i = ''
+i = '0'
+i = ''
+}
+
+test defined-1.7 {check attempted assignment to undef} -body {
+#lang L --line=1
+void defined_1_7()
+{
+ undef = 1;
+ undef += 1;
+ ++undef;
+ undef--;
+ undef =~ s/a/b/;
+}
+} -returnCodes error -match regexp -result {.*3: L Error: invalid l-value in assignment
+.*4: L Error: invalid l-value in assignment
+.*5: L Error: invalid l-value in inc/dec
+.*6: L Error: invalid l-value in inc/dec
+.*7: L Error: invalid l-value in =~
+}
+
+test defined-1.8 {check attempted declaration of undef} -body {
+#lang L --line=1
+void undef() {}
+int undef;
+void defined_1_8()
+{
+ int undef;
+}
+} -returnCodes error -match regexp -result {.*1: L Error: cannot use undef for function name
+.*2: L Error: cannot use undef for variable name
+.*5: L Error: cannot use undef for variable name
+}
+
+test defined-1.9 {check that undef has type poly} -body {
+#lang L --line=1
+class defined_1_9_cls {}
+void defined_1_9()
+{
+ int i;
+ float f;
+ string s;
+ int a[], aa[][];
+ int h{int}, hh{int}{int};
+ struct { int i,j; } st;
+ defined_1_9_cls o;
+
+ /* None of these should be type errors. */
+
+ i = undef;
+ if (defined(i)) puts("bad 1");
+ f = undef;
+ if (defined(f)) puts("bad 2");
+ s = undef;
+ if (defined(s)) puts("bad 3");
+ a = undef;
+ if (defined(a)) puts("bad 4");
+ aa = undef;
+ if (defined(aa)) puts("bad 5");
+ h = undef;
+ if (defined(h)) puts("bad 6");
+ hh = undef;
+ if (defined(hh)) puts("bad 7");
+ st = undef;
+ if (defined(st)) puts("bad 8");
+ o = undef;
+ if (defined(o)) puts("bad 9");
+}
+defined_1_9();
+} -output {}
+
+test defined-1.10 {check undef as a reference parameter} -body {
+#lang L --line=1
+void defined_1_10_foo(int &arg) { arg = 0; }
+void defined_1_10()
+{
+ defined_1_10_foo(&undef); // err
+}
+defined_1_10();
+} -returnCodes error -match regexp -result {.*4: L Error: illegal operand to &
+}
+
+test defined-1.10.2 {check undef as a reference parameter 2} -setup {
+ set fname1 [makeFile {
+ // The docs say this causes a run-time error in foo().
+ void foo(string &p)
+ {
+ puts(p);
+ }
+ void main()
+ {
+ foo(undef);
+ }
+ } defined-1-10-2-read.l .]
+ set fname2 [makeFile {
+ // The docs say this causes a run-time error in foo().
+ void foo(string &p)
+ {
+ p = "x";
+ }
+ void main()
+ {
+ foo(undef);
+ }
+ } defined-1-10-2-write.l .]
+} -body {
+#lang L
+void defined_1_10_2()
+{
+ int ret;
+ string err[];
+ string tclsh = interpreter();
+
+ ret = system({tclsh, "defined-1-10-2-read.l"}, undef, undef, &err);
+ unless (ret) puts("bad 1");
+
+ ret = system({tclsh, "defined-1-10-2-write.l"}, undef, undef, &err);
+ unless (ret) puts("bad 2");
+}
+defined_1_10_2();
+} -output {}
+
+test defined-1.11 {check that assignment to part of an obj makes it defined} -body {
+#lang L --line=1
+void defined_1_11()
+{
+ string s;
+ string a[];
+ string aa[][];
+ string h{string};
+ string hh{string}{string};
+
+ if (defined(s)) puts("bad 1.1");
+ s[0] = "x";
+ unless (defined(s)) puts("bad 1.2");
+
+ if (defined(a)) puts("bad 2.1");
+ a[0] = "x";
+ unless (defined(a)) puts("bad 2.2");
+
+ if (defined(aa)) puts("bad 3.1");
+ a[0][0] = "x";
+ unless (defined(a)) puts("bad 3.2");
+ unless (defined(a[0])) puts("bad 3.3");
+
+ if (defined(h)) puts("bad 4.1");
+ h{"k"} = "v";
+ unless (defined(h)) puts("bad 4.2");
+
+ if (defined(hh)) puts("bad 5.1");
+ hh{"k1"}{"k2"} = "v";
+ unless (defined(hh)) puts("bad 5.2");
+ unless (defined(hh{"k1"})) puts("bad 5.3");
+}
+defined_1_11();
+} -output {}
+
+test defined-1.12 {check defined(&var)} -body {
+#lang L --line=1 -nowarn
+string def1_12_g1 = "global1";
+string def1_12_g2 = "global2";
+string def1_12_g3 = "global3";
+
+// The args are all named differently on purpose.
+string def1_12_f1(string &a1)
+{
+ return ((string)defined(&a1));
+}
+string def1_12_f2(string &a2, string &b2)
+{
+ return ((string)defined(&a2) . (string)defined(&b2));
+}
+string def1_12_f3(string &a3, string &b3, string &c3)
+{
+ return ((string)defined(&a3) . (string)defined(&b3) .
+ (string)defined(&c3));
+}
+string def1_12_ff(string &a4, string &b4)
+{
+ return (def1_12_f1(&a4) . def1_12_f1(&b4));
+}
+void defined_1_12()
+{
+ string a, b, c;
+
+ unless (def1_12_f1(&a) eq "1") puts("bad 1.1");
+ unless (def1_12_f1(undef) eq "0") puts("bad 1.2");
+
+ unless (def1_12_f2(&a, &b) eq "11") puts("bad 2.1");
+ unless (def1_12_f2(undef, &b) eq "01") puts("bad 2.2");
+ unless (def1_12_f2(&a, undef) eq "10") puts("bad 2.3");
+ unless (def1_12_f2(undef, undef) eq "00") puts("bad 2.4");
+
+ unless (def1_12_f3(&a, &b, &c) eq "111") puts("bad 3.1");
+ unless (def1_12_f3(undef, &b, &c) eq "011") puts("bad 3.2");
+ unless (def1_12_f3(&a, undef, &c) eq "101") puts("bad 3.3");
+ unless (def1_12_f3(&a, &b, undef) eq "110") puts("bad 3.4");
+ unless (def1_12_f3(undef, &b, undef) eq "010") puts("bad 3.5");
+ unless (def1_12_f3(undef, undef, &a) eq "001") puts("bad 3.6");
+ unless (def1_12_f3(&a, undef, undef) eq "100") puts("bad 3.7");
+ unless (def1_12_f3(undef, undef, undef) eq "000") puts("bad 3.8");
+
+ unless (def1_12_ff(&a, &b) eq "11") puts("bad 4.1");
+ unless (def1_12_ff(undef, &b) eq "01") puts("bad 4.2");
+ unless (def1_12_ff(&a, undef) eq "10") puts("bad 4.3");
+ unless (def1_12_ff(undef, undef) eq "00") puts("bad 4.4");
+
+ unless (def1_12_f1(&def1_12_g1) eq "1") puts("bad 5.1");
+ unless (def1_12_f2(&def1_12_g1, &def1_12_g2) eq "11") puts("bad 5.2");
+ unless (def1_12_f3(&def1_12_g1, &def1_12_g2, &def1_12_g3) eq "111") {
+ puts("bad 5.2");
+ }
+}
+defined_1_12();
+} -output {}
+
+test defined-1.13 {check errors with defined(&var)} -body {
+#lang L --line=1 -nowarn
+private string not_a_ref_parm1;
+string not_a_ref_parm2;
+class def_1_13_cls
+{
+ public string not_a_ref_parm3;
+ instance {
+ public string not_a_ref_parm4;
+ }
+}
+void defined_1_13()
+{
+ string not_a_ref_parm5;
+ def_1_13_cls obj = def_1_13_cls_new();
+
+ defined(&not_declared);
+ defined(&not_a_ref_parm1);
+ defined(&not_a_ref_parm2);
+ defined(&def_1_13_cls->not_a_ref_parm3);
+ defined(&obj->not_a_ref_parm4);
+ defined(&not_a_ref_parm5);
+ defined(&defined_1_13); // fn ptr
+ defined(&3);
+}
+defined_1_13();
+} -returnCodes error -match regexp -result {.*15: L Error:.*not a call-by-reference parm
+.*16: L Error:.*not a call-by-reference parm
+.*17: L Error:.*not a call-by-reference parm
+.*18: L Error:.*not a call-by-reference parm
+.*19: L Error:.*not a call-by-reference parm
+.*20: L Error:.*not a call-by-reference parm
+.*21: L Error:.*not a call-by-reference parm
+.*22: L Error:.*not a call-by-reference parm
+}
+
+test defined-1.14 {check that undef is false} -body {
+#lang L --line=1
+string defined_1_14fn(_argused string &s)
+{
+ if (&s) {
+ return ("def");
+ } else {
+ return ("undef");
+ }
+}
+void defined_1_14()
+{
+ int i;
+ string s;
+ string a[];
+ string h{string};
+ struct { int i; int j; } st;
+ poly p;
+
+ if (undef) puts("bad 1");
+ if (i) puts("bad 2");
+ if (s) puts("bad 3");
+ if (p) puts("bad 4.1");
+ if (a) puts("bad 4.2");
+ if (h) puts("bad 4.3");
+ if (st) puts("bad 4.4");
+ unless (defined_1_14fn(&s) eq "def") puts("bad 4.5");
+ unless (defined_1_14fn(undef) eq "undef") puts("bad 4.6");
+
+ /* Check that Tcl code does the same thing. */
+ eval('if {$i} {puts "bad 5"}');
+ eval('if {$s} {puts "bad 6"}');
+ eval('if {$p} {puts "bad 7"}');
+ eval('if {$a} {puts "bad 8"}');
+ eval('if {$h} {puts "bad 8"}');
+ eval('if {$st} {puts "bad 10"}');
+}
+defined_1_14();
+} -output {}
+
+test defined-1.15 {check that undef != anything defined} -body {
+#lang L --line=1
+void defined_1_15()
+{
+ int i;
+ string s;
+ poly p;
+
+ if (defined(i) || defined(s) || defined(p)) puts("bad");
+
+ if (i == 0) puts("bad 1.1");
+ unless (i != 0) puts("bad 1.2");
+
+ if (s eq "") puts("bad 2.1");
+ unless (s ne "") puts("bad 2.2");
+
+ if (p eq "") puts("bad 3.1");
+ unless (p ne "") puts("bad 3.2");
+
+ /*
+ * An L regexp compiles down to different opcodes depending on the
+ * complexity of the regexp, so test each.
+ */
+ if (s =~ /^$/) puts("bad 4.1"); // constant (INST_STR_EQ)
+ if (s =~ /.*/) puts("bad 4.2"); // glob (INST_STR_MATCH)
+ if (s =~ /x*/) puts("bad 4.2"); // non-glob re (INST_REGEXP)
+ if (s =~ //g) puts("bad 4.3"); // complex (::regexp cmd)
+
+ /* Check that Tcl code does the same thing. */
+ eval('if {$i == 0} {puts "bad 5.1"}');
+ eval('if {$s == ""} {puts "bad 5.2"}');
+}
+defined_1_15();
+} -output {}
+
+test defined-1.16 {check calling defined proc from Tcl code} -body {
+#lang L
+void defined_1_16()
+{
+ string d = "this is defined";
+ string u; // this is not
+
+ if (defined(u)) puts("bad 1.1");
+ eval('if [defined $u] {puts "bad 1.2"}');
+
+ unless (defined(d)) puts("bad 2.1");
+ eval('if ![defined $d] {puts "bad 2.2"}');
+}
+defined_1_16();
+} -output {}
+
+test undef-1 {check undef built-in} -body {
+#lang L --line=1
+void undef_1()
+{
+ string s;
+ string a[], a2[];
+ string h{string}, h2{string};
+
+ h = { "k1"=>"v1", "k2"=>"v2", "k3"=>"v3" };
+ h2 = h;
+ undef(h{"k1"});
+ unless (length(h) == 2) puts("bad 1.1");
+ unless ((h{"k2"} eq "v2") && (h{"k3"} eq "v3")) puts("bad 1.2");
+ undef(h{"k2"});
+ unless (length(h) == 1) puts("bad 1.3");
+ unless (h{"k3"} eq "v3") puts("bad 1.4");
+ undef(h{"k3"});
+ unless (length(h) == 0) puts("bad 1.5");
+ unless (defined(h)) puts("bad 1.6");
+
+ /* Make sure deleting from h didn't affect a copy of h. */
+ unless (length(h2) == 3) puts("bad 2.1");
+ unless ((h2{"k1"} eq "v1") && (h2{"k2"} eq "v2")) puts("bad 2.2");
+ unless (h2{"k3"} eq "v3") puts("bad 2.3");
+
+ /*
+ * Deleting a non-existent hash element is legal. Deep-dive
+ * semantics says to create the element, then it gets deleted.
+ */
+ h = {};
+ undef(h{"not_here"});
+ unless (length(h) == 0) puts("bad 3.1");
+ unless (defined(h)) puts("bad 3.2");
+
+ a = { "1", "2", "3" };
+ a2 = a;
+ undef(a[0]);
+ unless (length(a) == 2) puts("bad 4.1");
+ unless ((a[0] eq "2") && (a[1] eq "3")) puts("bad 4.2");
+ undef(a[0]);
+ unless (length(a) == 1) puts("bad 4.3");
+ unless (a[0] eq "3") puts("bad 4.4");
+ undef(a[0]);
+ unless (length(a) == 0) puts("bad 4.5");
+ unless (defined(a)) puts("bad 4.6");
+
+ /* Make sure deleting from "a" didn't affect a copy of "a". */
+ unless (length(a2) == 3) puts("bad 5.1");
+ unless ((a2[0] eq "1") && (a2[1] eq "2")) puts("bad 5.2");
+ unless (a2[2] eq "3") puts("bad 5.3");
+
+ /*
+ * Deleting a non-existent array element is legal. Deep-dive
+ * semantics says to create the element (AND all before it),
+ * then it gets deleted but all the elements before it remain.
+ */
+ a = {};
+ undef(a[3]);
+ unless (length(a) == 3) puts("bad 6.1");
+ unless (defined(a)) puts("bad 6.2");
+ if (defined(a[0]) || defined(a[1]) || defined(a[2])) puts("bad 6.3");
+
+ s = "0123456789";
+ undef(s[0]);
+ unless (s eq "123456789") puts("bad 10.1");
+ undef(s[1]);
+ unless (s eq "13456789") puts("bad 10.2");
+ undef(s[7]);
+ unless (s eq "1345678") puts("bad 10.3");
+
+ /* undef(var) is like var=undef. */
+ s = "testing";
+ undef(s);
+ if (defined(s)) puts("bad 20.1");
+}
+undef_1();
+} -output {}
+
+test undef-2 {check undef built-in on nested arrays and hashes} -body {
+#lang L --line=1
+void undef_2()
+{
+ int a[][] = { {1,2,3}, {4,5,6}, {7,8,9} };
+ int h{int}{int} = {
+ 1 => { 10=>10, 20=>20, 30=>30 },
+ 2 => { 10=>10, 20=>20, 30=>30 },
+ 3 => { 10=>10, 20=>20, 30=>30 },
+ };
+
+ undef(h{2});
+ unless (length(h) == 2) puts("bad 1.1");
+
+ undef(h{1}{20});
+ unless (length(h{1}) == 2) puts("bad 2.1");
+ unless ((h{1}{10} == 10) && (h{1}{30} == 30)) puts("bad 2.2");
+ undef(h{1}{10});
+ unless (length(h{1}) == 1) puts("bad 2.3");
+ unless (h{1}{30} == 30) puts("bad 2.4");
+ undef(h{1}{30});
+ unless (length(h{1}) == 0) puts("bad 2.5");
+
+ unless (length(h) == 2) puts("bad 3.1");
+ undef(h{1});
+ unless (length(h) == 1) puts("bad 3.3");
+ unless (length(h{3}) == 3) puts("bad 3.4");
+
+ undef(a[1]);
+ unless (length(a) == 2) puts("bad 4.1");
+ unless (length(a[0]) == 3) puts("bad 4.2");
+ unless (length(a[1]) == 3) puts("bad 4.3");
+ unless ((a[0][0] == 1) && (a[0][1] == 2)) puts("bad 4.4");
+ unless (a[0][2] == 3) puts("bad 4.5");
+
+ undef(a[1][1]);
+ unless (length(a[1]) == 2) puts("bad 5.1");
+ unless ((a[1][0] == 7) && (a[1][1] == 9)) puts("bad 5.2");
+
+ undef(a[0]);
+ unless (length(a) == 1) puts("bad 6.1");
+ unless (length(a[0]) == 2) puts("bad 6.2");
+ undef(a[0]);
+ unless (length(a) == 0) puts("bad 6.3");
+}
+undef_2();
+} -output {}
+
+test undef-3 {check undef built-in on class variables} -body {
+#lang L --line=1
+class undef_3_cls {
+ public string hcls{string};
+ public string acls[];
+ public string scls;
+ instance {
+ public string hins{string};
+ public string ains[];
+ public string sins;
+ }
+}
+void undef_3()
+{
+ undef_3_cls obj = undef_3_cls_new();
+
+ undef_3_cls->hcls = { "k1"=>"v1", "k2"=>"v2", "k3"=>"v3" };
+ undef(undef_3_cls->hcls{"k1"});
+ unless (length(undef_3_cls->hcls) == 2) puts("bad 1.1");
+ unless (undef_3_cls->hcls{"k2"} eq "v2") puts("bad 1.2");
+ unless (undef_3_cls->hcls{"k3"} eq "v3") puts("bad 1.3");
+ undef(undef_3_cls->hcls{"k2"});
+ unless (length(undef_3_cls->hcls) == 1) puts("bad 1.4");
+ unless (undef_3_cls->hcls{"k3"} eq "v3") puts("bad 1.5");
+ undef(undef_3_cls->hcls{"k3"});
+ unless (length(undef_3_cls->hcls) == 0) puts("bad 1.6");
+ unless (defined(undef_3_cls->hcls)) puts("bad 1.7");
+
+ undef_3_cls->acls = { "1", "2", "3" };
+ undef(undef_3_cls->acls[0]);
+ unless (length(undef_3_cls->acls) == 2) puts("bad 2.1");
+ unless (undef_3_cls->acls[0] eq "2") puts("bad 2.2");
+ unless (undef_3_cls->acls[1] eq "3") puts("bad 2.3");
+ undef(undef_3_cls->acls[0]);
+ unless (length(undef_3_cls->acls) == 1) puts("bad 2.4");
+ unless (undef_3_cls->acls[0] eq "3") puts("bad 2.5");
+ undef(undef_3_cls->acls[0]);
+ unless (length(undef_3_cls->acls) == 0) puts("bad 2.6");
+ unless (defined(undef_3_cls->acls)) puts("bad 2.7");
+
+ obj->hins = { "k1"=>"v1", "k2"=>"v2", "k3"=>"v3" };
+ undef(obj->hins{"k1"});
+ unless (length(obj->hins) == 2) puts("bad 3.1");
+ unless (obj->hins{"k2"} eq "v2") puts("bad 3.2");
+ unless (obj->hins{"k3"} eq "v3") puts("bad 3.3");
+ undef(obj->hins{"k2"});
+ unless (length(obj->hins) == 1) puts("bad 3.4");
+ unless (obj->hins{"k3"} eq "v3") puts("bad 3.5");
+ undef(obj->hins{"k3"});
+ unless (length(obj->hins) == 0) puts("bad 3.6");
+ unless (defined(obj->hins)) puts("bad 3.7");
+
+ obj->ains = { "1", "2", "3" };
+ undef(obj->ains[0]);
+ unless (length(obj->ains) == 2) puts("bad 4.1");
+ unless (obj->ains[0] eq "2") puts("bad 4.2");
+ unless (obj->ains[1] eq "3") puts("bad 4.3");
+ undef(obj->ains[0]);
+ unless (length(obj->ains) == 1) puts("bad 4.4");
+ unless (obj->ains[0] eq "3") puts("bad 4.5");
+ undef(obj->ains[0]);
+ unless (length(obj->ains) == 0) puts("bad 4.6");
+ unless (defined(obj->ains)) puts("bad 4.7");
+
+ undef_3_cls->scls = "testing";
+ undef(undef_3_cls->scls);
+ if (defined(undef_3_cls->scls)) puts("bad 5.1");
+
+ obj->sins = "testing";
+ undef(obj->sins);
+ if (defined(obj->sins)) puts("bad 6.1");
+}
+undef_3();
+} -output {}
+
+test undef-4 {check undef built-in errors} -body {
+#lang L --line=1
+private string[] foo() { return {"x"}; }
+void undef_4()
+{
+ string a[];
+ struct { int i,j; } st;
+
+ undef();
+ undef(a[0], a[1]);
+ undef(a[1..3]);
+ undef(foo());
+ undef(st.i);
+ undef(3);
+}
+undef_4();
+} -returnCodes error -match regexp -result {.*7: L Error: incorrect # args to undef
+.*8: L Error: incorrect # args to undef
+.*9: L Error: illegal l-value in undef\(\)
+.*10: L Error: illegal l-value in undef\(\)
+.*11: L Error: cannot undef\(\) a struct field
+.*12: L Error: illegal l-value in undef\(\)
+}
+
+test undef-5 {check that undefined list goes to defined} -body {
+#lang L --line=1
+void undef_5()
+{
+ string a[] = {"x"};
+
+ a = undef;
+ if (defined(a)) puts("bad 1.1");
+ a[END+1] = "x";
+ unless (defined(a)) puts("bad 1.2");
+
+ a = undef;
+ if (defined(a)) puts("bad 2.1");
+ push(&a, "x");
+ unless (defined(a)) puts("bad 2.2");
+
+ a = undef;
+ if (defined(a)) puts("bad 3.1");
+ a[0] = "x";
+ unless (defined(a)) puts("bad 3.2");
+
+ a = undef;
+ if (defined(a)) puts("bad 4.1");
+ a[10] = "x";
+ unless (defined(a)) puts("bad 4.2");
+
+ a = undef;
+ if (defined(a)) puts("bad 5.1");
+ push(&a, {"x","y"});
+ unless (defined(a)) puts("bad 5.2");
+}
+undef_5();
+} -output {}
+
+test undef-6 {check comparison errors against undef} -body {
+#lang L --line=1
+void undef_6()
+{
+ int i;
+ string s;
+
+ i == undef; // line 6
+ i != undef;
+ i <= undef;
+ i < undef;
+ i >= undef;
+ i > undef;
+ undef == i;
+ undef != i;
+ undef <= i;
+ undef < i;
+ undef >= i;
+ undef > i; // line 17
+
+ s eq undef; // line 19
+ s ne undef;
+ s le undef;
+ s lt undef;
+ s ge undef;
+ s gt undef;
+ undef eq s;
+ undef ne s;
+ undef le s;
+ undef lt s;
+ undef ge s;
+ undef gt s; // line 30
+
+ undef == undef; // line 32
+ undef != undef;
+ undef <= undef;
+ undef < undef;
+ undef >= undef;
+ undef > undef;
+ undef eq undef;
+ undef ne undef;
+ undef le undef;
+ undef lt undef;
+ undef ge undef;
+ undef gt undef; // line 43
+}
+} -returnCodes error -match regexp -result {.*6: L Error: undef illegal in comparison
+.*7: L Error: undef illegal in comparison
+.*8: L Error: undef illegal in comparison
+.*9: L Error: undef illegal in comparison
+.*10: L Error: undef illegal in comparison
+.*11: L Error: undef illegal in comparison
+.*12: L Error: undef illegal in comparison
+.*13: L Error: undef illegal in comparison
+.*14: L Error: undef illegal in comparison
+.*15: L Error: undef illegal in comparison
+.*16: L Error: undef illegal in comparison
+.*17: L Error: undef illegal in comparison
+.*19: L Error: undef illegal in comparison
+.*20: L Error: undef illegal in comparison
+.*21: L Error: undef illegal in comparison
+.*22: L Error: undef illegal in comparison
+.*23: L Error: undef illegal in comparison
+.*24: L Error: undef illegal in comparison
+.*25: L Error: undef illegal in comparison
+.*26: L Error: undef illegal in comparison
+.*27: L Error: undef illegal in comparison
+.*28: L Error: undef illegal in comparison
+.*29: L Error: undef illegal in comparison
+.*30: L Error: undef illegal in comparison
+.*32: L Error: undef illegal in comparison
+.*33: L Error: undef illegal in comparison
+.*34: L Error: undef illegal in comparison
+.*35: L Error: undef illegal in comparison
+.*36: L Error: undef illegal in comparison
+.*37: L Error: undef illegal in comparison
+.*38: L Error: undef illegal in comparison
+.*39: L Error: undef illegal in comparison
+.*40: L Error: undef illegal in comparison
+.*41: L Error: undef illegal in comparison
+.*42: L Error: undef illegal in comparison
+.*43: L Error: undef illegal in comparison
+}
+
+test undef-7 {check for bug with undef object ref count} -body {
+#lang L --line=1
+void undef_7()
+{
+ string a[];
+
+ /*
+ * This used to trip a bug in undef (and assert or core dump)
+ * where the undef object's ref count would be reset to 1234
+ * in Lcompile.c every time a reference to the undef object
+ * was given out. If undef propagated more than this # of
+ * times, the wheels could fall off while freeing an object
+ * that had these undefs in it.
+ */
+
+ // This creates 3000 Tcl_Obj's that point to undef, and when
+ // they are added to the array, the undef ref count is
+ // incremented as expected.
+ a[3000] = "";
+
+ // Now create one more ref to undef (when it is pushed onto
+ // the Tcl run-time stack). This used to reset the ref count
+ // back to 1234, then when the locals were freed which includes
+ // the 3000 undefs above, we used to assert or core dump.
+ undef;
+}
+undef_7();
+} -output {}
+
+test undef-8 {check for another bug with undef object ref count} -body {
+#lang L --line=1
+#pragma nowarn
+void undef_8()
+{
+ int iters = 100;
+ int a[], aft, bef, h{int}, i, j, x, y;
+ string s;
+ FILE f;
+
+ /*
+ * These check for an old bug where the undef object's ref
+ * count would continually grow until it eventually
+ * overflowed. Here we check that various operations which
+ * should create and then drop a reference to undef don't grow
+ * the ref count.
+ */
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ {x,y} = {i}; // uses INST_L_LINDEX_STK bytecode
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 1 composite assign ${bef} -> ${aft}");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ a[0] = 0; // grows array w/undef
+ undef(a);
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 2 a[] write ${bef} -> ${aft}");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ a[0]; // read of undefined array element
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 3 a[] read ${bef} -> ${aft}");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ pop(&a); // elt delete on empty array
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 5 pop(&a) ${bef} -> ${aft}");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ ((hash){i}){0}; // hash read of non-hash
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 6 not-a-hash{idx} ${bef} -> ${aft}");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ h{0}; // hash read of undef element
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 7 h{} ${bef} -> ${aft}");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ s[0]; // string index of undef string
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 8 undef_string[] ${bef} -> ${aft}");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ "s"[2]; // string index beyond end of string
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 9 string[beyond] ${bef} -> ${aft}");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ undef; // puts undef on run-time stack
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 10 undef ${bef} -> ${aft}");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ getopt({}, "", {}); // getopt returns undef
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 11 getopt ${bef} -> ${aft}");
+
+ f = fopen("tst", "w");
+ puts(f, "testing");
+ fclose(f);
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ f = fopen("tst", "r");
+ while (<f>) ; // returns undef on EOF
+ fclose(f);
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 12 <f> ${bef} -> ${aft}");
+ unlink("tst");
+
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ fgetline("bad channel"); // returns undef
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 13 fgetline ${bef} -> ${aft}");
+
+ /*
+ * This one can't be tested here unless we spawn another tclsh
+ * since it eats args from the cmd line and messes up tcltest.
+ */
+ /*
+ bef = Lrefcnt(undef);
+ for (i = 0; i < iters; ++i) {
+ <>;
+ }
+ aft = Lrefcnt(undef);
+ if (aft > bef) puts("bad 14 <> ${bef} -> ${aft}");
+ */
+
+}
+undef_8();
+} -output {}
+
+test undef-9 {test read of an undef ref parm} -body {
+#lang L
+void undef_9f(string &arg)
+{
+ puts(arg);
+}
+void undef_9()
+{
+ undef_9f(undef);
+}
+undef_9();
+} -returnCodes error -match regexp -result {undefined reference parameter read}
+
+test undef-10 {test write of an undef ref parm} -body {
+#lang L
+void undef_10f(string &arg)
+{
+ arg = "bad";
+}
+void undef_10()
+{
+ undef_10f(undef);
+}
+undef_10();
+} -returnCodes error -match regexp -result {undefined reference parameter written}
+
+test undef-11 {test read of an _optional undef ref parm} -body {
+#lang L
+void undef_11f(_optional string &arg)
+{
+ puts(arg);
+}
+void undef_11()
+{
+ undef_11f();
+}
+undef_11();
+} -returnCodes error -match regexp -result {undefined reference parameter read}
+
+test undef-12 {test write of an _optional undef ref parm} -body {
+#lang L
+void undef_12f(_optional string &arg)
+{
+ arg = "bad";
+}
+void undef_12()
+{
+ undef_12f();
+}
+undef_12();
+} -returnCodes error -match regexp -result {undefined reference parameter written}
+
+test undef-13 {test definedness tests on ref parm} -body {
+#lang L
+string undef_13f(string &arg)
+{
+ string ret;
+
+ ret = (string)defined(&arg);
+ if (defined(&arg)) ret .= (string)defined(arg);
+
+ return (ret);
+}
+string undef_13opt(_optional string &arg)
+{
+ string ret;
+
+ ret = (string)defined(&arg);
+ if (defined(&arg)) ret .= (string)defined(arg);
+
+ return (ret);
+}
+void undef_13()
+{
+ string p;
+
+ unless (undef_13f(undef) == "0") puts("bad 1.1");
+ unless (undef_13f(&p) == "10") puts("bad 1.2");
+ p = "ok";
+ unless (undef_13f(&p) == "11") puts("bad 1.3");
+
+ p = undef;
+ unless (undef_13opt() == "0") puts("bad 2.0");
+ unless (undef_13opt(undef) == "0") puts("bad 2.1");
+ unless (undef_13opt(&p) == "10") puts("bad 2.2");
+ p = "ok";
+ unless (undef_13opt(&p) == "11") puts("bad 2.3");
+}
+undef_13();
+} -output {}
+
+test undef-14 {test definedness tests on function-pointer parm} -body {
+#lang L
+/*
+ * Although function-pointer args look like ref parms because they
+ * have a &, they are not references and the rules for defined()
+ * tests are different. You cannot say defined(&arg).
+ */
+string undef_14foo() { return ("x"); }
+string undef_14f(string &arg())
+{
+ return ((string)defined(arg));
+}
+string undef_14opt(_optional string &arg())
+{
+ return ((string)defined(arg));
+}
+void undef_14()
+{
+ unless (undef_14f(undef) == "0") puts("bad 1.1");
+ unless (undef_14f(&undef_14foo) == "1") puts("bad 1.2");
+
+ unless (undef_14opt() == "0") puts("bad 2.1");
+ unless (undef_14opt(undef) == "0") puts("bad 2.2");
+ unless (undef_14opt(&undef_14foo) == "1") puts("bad 2.3");
+}
+undef_14();
+} -output {}
+
+test toplevel-1.0 {Toplevel code in L} -body {
+#lang L --line=1
+int toplevel_1_0_i = 2;
+printf("at the toplevel, i is: %d\n", toplevel_1_0_i);
+
+void toplevel_1_0(void) {
+ printf("in toplevel_1_0, i is: %d\n", toplevel_1_0_i);
+}
+#lang tcl
+toplevel_1_0
+} -output {at the toplevel, i is: 2
+in toplevel_1_0, i is: 2
+}
+
+test toplevel-1.1 {Toplevel code via the L command, sharing variables} -body {
+L { puts("Accent on helpful side of your nature. Drain the moat."); }
+proc toplevel_1_1 {} {
+ set toplevel_1_1_v 2
+ L {
+ string toplevel_1_1_v = "Sphenic numbers always have exactly "
+ "eight divisors.";
+ }
+ puts $toplevel_1_1_v
+}
+toplevel_1_1
+} -output {Accent on helpful side of your nature. Drain the moat.
+2
+}
+
+test typecheck-1.0 {L typechecking} -body {
+#lang L --line=1
+string typecheck_1_0_foo() {
+ return "string";
+}
+
+void typecheck_1_0() {
+ puts(typecheck_1_0_foo() + 22);
+}
+#lang tcl
+typecheck_1_0
+} -returnCodes {error} -match glob \
+-result "*:6: L Error: expected type int or float but got string*\n"
+
+test typecheck-1.1 {arity check} -body {
+#lang L --line=1 -nowarn
+void typecheck_1_1_foo() {}
+void typecheck_1_1_bar(int a, int b) {}
+void typecheck_1_1() {
+ typecheck_1_1_foo(1, 2, 3);
+ typecheck_1_1_bar();
+}
+#lang tcl
+} -returnCodes {error} -match glob \
+-result "*:4: L Error: too many arguments for function typecheck_1_1_foo
+*:5: L Error: not enough arguments for function typecheck_1_1_bar\n"
+
+test typecheck-1.2 {check functions returning int arrays of arrays} -body {
+#lang L --line=1
+int[]
+typecheck_1_2_int()
+{
+ int i, a[3];
+
+ for (i = 0; i < 3; ++i) {
+ a[i] = i;
+ }
+ return a;
+}
+int[][]
+typecheck_1_2_int_int()
+{
+ int i, j, a[3][4];
+
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ a[i][j] = 10*i + j;
+ }
+ }
+ return a;
+}
+int[][][]
+typecheck_1_2_int_int_int()
+{
+ int i, j, k, a[3][4][5];
+
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ for (k = 0; k < 5; ++k) {
+ a[i][j][k] = 100*i + 10*j + k;
+ }
+ }
+ }
+ return a;
+}
+void
+typecheck_1_2()
+{
+ int i, j, k;
+ int one[3];
+ int two[3][4];
+ int three[3][4][5];
+
+ one = typecheck_1_2_int();
+ two = typecheck_1_2_int_int();
+ three = typecheck_1_2_int_int_int();
+
+ for (i = 0; i < 3; ++i) {
+ unless (one[i] == i) {
+ printf("one: i=%d bad\n", i);
+ }
+ }
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ unless (two[i][j] == (10*i + j)) {
+ printf("two: i=%d j=%d bad\n", i, j);
+ }
+ }
+ }
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ for (k = 0; k < 5; ++k) {
+ unless (three[i][j][k] == (100*i + 10*j + k)) {
+ printf("three: i=%d j=%d k=%d bad\n",
+ i, j, k);
+ }
+ }
+ }
+ }
+}
+typecheck_1_2();
+} -output {}
+
+test typecheck-1.3 {check functions returning float arrays of arrays} -body {
+#lang L --line=1
+float[]
+typecheck_1_3_float()
+{
+ int i;
+ float a[3];
+
+ for (i = 0; i < 3; ++i) {
+ a[i] = i;
+ }
+ return a;
+}
+float[][]
+typecheck_1_3_float_float()
+{
+ int i, j;
+ float a[3][4];
+
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ a[i][j] = 10.0*i + j;
+ }
+ }
+ return a;
+}
+float[][][]
+typecheck_1_3_float_float_float()
+{
+ int i, j, k;
+ float a[3][4][5];
+
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ for (k = 0; k < 5; ++k) {
+ a[i][j][k] = 100.0*i + 10.0*j + k;
+ }
+ }
+ }
+ return a;
+}
+void
+typecheck_1_3()
+{
+ int i, j, k;
+ float one[3];
+ float two[3][4];
+ float three[3][4][5];
+
+ one = typecheck_1_3_float();
+ two = typecheck_1_3_float_float();
+ three = typecheck_1_3_float_float_float();
+
+ /*
+ * Although testing equality of floats is usually unwise,
+ * there should be sufficient precision in this case to make
+ * the comparisons true when they should be.
+ */
+ for (i = 0; i < 3; ++i) {
+ unless (one[i] == i) {
+ printf("one: i=%d bad\n", i);
+ }
+ }
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ unless (two[i][j] == (10.0*i + j)) {
+ printf("two: i=%d j=%d bad\n", i, j);
+ }
+ }
+ }
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ for (k = 0; k < 5; ++k) {
+ unless (three[i][j][k] == (100.0*i+10.0*j+k)) {
+ printf("three: i=%d j=%d k=%d bad\n",
+ i, j, k);
+ }
+ }
+ }
+ }
+}
+typecheck_1_3();
+} -output {}
+
+test typecheck-1.4 {check functions returning string arrays of arrays} -body {
+#lang L --line=1
+string[]
+typecheck_1_4_string()
+{
+ int i;
+ string a[3];
+
+ for (i = 0; i < 3; ++i) {
+ a[i] = "${i}";
+ }
+ return a;
+}
+string[][]
+typecheck_1_4_string_string()
+{
+ int i, j;
+ string a[3][4];
+
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ a[i][j] = "${i}:${j}";
+ }
+ }
+ return a;
+}
+string[][][]
+typecheck_1_4_string_string_string()
+{
+ int i, j, k;
+ string a[3][4][5];
+
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ for (k = 0; k < 5; ++k) {
+ a[i][j][k] = "${i}:${j}:${k}";
+ }
+ }
+ }
+ return a;
+}
+void
+typecheck_1_4()
+{
+ int i, j, k;
+ string one[3];
+ string two[3][4];
+ string three[3][4][5];
+
+ one = typecheck_1_4_string();
+ two = typecheck_1_4_string_string();
+ three = typecheck_1_4_string_string_string();
+
+ for (i = 0; i < 3; ++i) {
+ unless (one[i] eq "${i}") {
+ printf("one: i=%d bad\n", i);
+ }
+ }
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ unless (two[i][j] eq "${i}:${j}") {
+ printf("two: i=%d j=%d bad\n", i, j);
+ }
+ }
+ }
+ for (i = 0; i < 3; ++i) {
+ for (j = 0; j < 4; ++j) {
+ for (k = 0; k < 5; ++k) {
+ unless (three[i][j][k] eq "${i}:${j}:${k}") {
+ printf("three: i=%d j=%d k=%d bad\n",
+ i, j, k);
+ }
+ }
+ }
+ }
+}
+typecheck_1_4();
+} -output {}
+
+test typecheck-1.5 {check functions returning void arrays are illegal} -body {
+#lang L --line=1
+void[] typecheck_1_5() { return; }
+} -returnCodes error -match regexp -result {.*1: L Error: type void illegal.*
+}
+
+test typecheck-2.1 {check int-to-float casts and coercions} -body {
+#lang L --line=1
+float
+typecheck_2_1_return_float(float f)
+{
+ return f;
+}
+
+float
+typecheck_2_1_sum_three_floats(float f1, float f2, float f3)
+{
+ return f1 + f2 + f3;
+}
+
+void
+typecheck_2_1()
+{
+ /*
+ * Exact comparisons with floats must be done with care. Keep
+ * the precision of the numbers low so there is sufficient
+ * precision for the variable comparisons to be true when
+ * intended.
+ */
+
+ /* Test initializers and all comparison ops that allow floats. */
+
+ int i1 = 1964;
+ int i2 = 0;
+ float f1 = i1;
+ float f2 = 0.0;
+
+ unless (f1 == 1964) puts("BAD 1.1.1");
+ unless (1964 == f1) puts("BAD 1.1.2");
+ unless (f1 == 1964.0) puts("BAD 1.1.3");
+ unless (1964.0 == f1) puts("BAD 1.1.4");
+ unless (f1 == (float)1964) puts("BAD 1.1.5");
+ unless ((float)1964 == f1) puts("BAD 1.1.6");
+ unless (f1 == (float)i1) puts("BAD 1.1.7");
+ unless ((float)i1 == f1) puts("BAD 1.1.8");
+ unless (f1 == i1) puts("BAD 1.1.9");
+ unless (i1 == f1) puts("BAD 1.1.10");
+
+ unless (f1 >= 1964) puts("BAD 1.2.1");
+ unless (1964 >= f1) puts("BAD 1.2.2");
+ unless (f1 >= 1964.0) puts("BAD 1.2.3");
+ unless (1964.0 >= f1) puts("BAD 1.2.4");
+ unless (f1 >= (float)1964) puts("BAD 1.2.5");
+ unless ((float)1964 >= f1) puts("BAD 1.2.6");
+ unless (f1 >= (float)i1) puts("BAD 1.2.7");
+ unless ((float)i1 >= f1) puts("BAD 1.2.8");
+ unless (f1 >= i1) puts("BAD 1.2.9");
+ unless (i1 >= f1) puts("BAD 1.2.10");
+
+ unless (f1 <= 1964) puts("BAD 1.3.1");
+ unless (1964 <= f1) puts("BAD 1.3.2");
+ unless (f1 <= 1964.0) puts("BAD 1.3.3");
+ unless (1964.0 <= f1) puts("BAD 1.3.4");
+ unless (f1 <= (float)1964) puts("BAD 1.3.5");
+ unless ((float)1964 <= f1) puts("BAD 1.3.6");
+ unless (f1 <= (float)i1) puts("BAD 1.3.7");
+ unless ((float)i1 <= f1) puts("BAD 1.3.8");
+ unless (f1 <= i1) puts("BAD 1.3.9");
+ unless (i1 <= f1) puts("BAD 1.3.10");
+
+ unless (f1 != 1999) puts("BAD 1.4.1");
+ unless (1999 != f1) puts("BAD 1.4.2");
+ unless (f1 != 1999.0) puts("BAD 1.4.3");
+ unless (1999.0 != f1) puts("BAD 1.4.4");
+ unless (f1 != (float)1999) puts("BAD 1.4.5");
+ unless ((float)1999 != f1) puts("BAD 1.4.6");
+ unless (f1 != (float)i2) puts("BAD 1.4.7");
+ unless ((float)i2 != f1) puts("BAD 1.4.8");
+ unless (f1 != i2) puts("BAD 1.4.9");
+ unless (i2 != f1) puts("BAD 1.4.10");
+
+ /* Test assignments and all binary ops that allow floats. */
+
+ i2 = 1965;
+ f2 = i2;
+ unless (f2 == 1965.0) puts("BAD 2.1");
+
+ f2 = f2 + 1;
+ unless (f2 == 1966.0) puts("BAD 2.2");
+
+ f2 = f2 - 2;
+ unless (f2 == 1964.0) puts("BAD 2.3");
+
+ f2 = f2 / 2;
+ unless (f2 == 982.0) puts("BAD 2.4");
+
+ f2 = f2 * 2;
+ unless (f2 == 1964.0) puts("BAD 2.5");
+
+ f2 = i2;
+ f2 = 1 + f2;
+ unless (f2 == 1966.0) puts("BAD 3.1");
+
+ f2 = -2 + f2;
+ unless (f2 == 1964.0) puts("BAD 3.2");
+
+ f2 = f2 / 2;
+ unless (f2 == 982.0) puts("BAD 3.3");
+
+ f2 = 2;
+ f2 = 2 / f2;
+ unless (f2 == 1.0) puts("BAD 3.4");
+
+ i2 = 1965;
+ f2 = i2;
+ f2 += 1;
+ unless (f2 == 1966.0) puts("BAD 4.1");
+
+ f2 -= 2;
+ unless (f2 == 1964.0) puts("BAD 4.2");
+
+ f2 /= 2;
+ unless (f2 == 982.0) puts("BAD 4.3");
+
+ f2 *= 2;
+ unless (f2 == 1964.0) puts("BAD 4.4");
+
+ /* Test that int actuals coerce to a float when the formal is a float. */
+
+ f2 = typecheck_2_1_return_float(1);
+ unless (f2 == 1.0) puts("BAD 5.1");
+
+ i2 = 3;
+ f2 = typecheck_2_1_return_float(i2);
+ unless (f2 == 3.0) puts("BAD 5.2");
+
+ f2 = typecheck_2_1_sum_three_floats(1, 2, 3);
+ unless (f2 = 6.0) puts("BAD 5.3");
+
+ i1 = 1;
+ i2 = 3;
+ f2 = typecheck_2_1_sum_three_floats(i1, i2, 3);
+ unless (f2 = 6.0) puts("BAD 5.4");
+}
+typecheck_2_1();
+} -output ""
+
+test typecheck-3.1 {void illegal in if-stmt conditional} -body {
+#lang L --line=1
+void typecheck_3_1_v() { return; }
+void
+typecheck_3_1()
+{
+ if (typecheck_3_1_v()) return;
+}
+} -returnCodes error -match regexp -result {void type illegal in predicate}
+
+test typecheck-3.2 {void illegal in unless-stmt conditional} -body {
+#lang L --line=1
+void typecheck_3_2_v() { return; }
+void
+typecheck_3_2()
+{
+ unless (typecheck_3_2_v()) return;
+}
+} -returnCodes error -match regexp -result {void type illegal in predicate}
+
+test typecheck-3.3 {void illegal in while-loop conditional} -body {
+#lang L --line=1
+void typecheck_3_3_v() { return; }
+void
+typecheck_3_3()
+{
+ while (typecheck_3_3_v()) return;
+}
+} -returnCodes error -match regexp -result {void type illegal in predicate}
+
+test typecheck-3.4 {void illegal in do-loop conditional} -body {
+#lang L --line=1
+void typecheck_3_4_v() { return; }
+void
+typecheck_3_4()
+{
+ do {
+ return;
+ } while(typecheck_3_4_v());
+}
+} -returnCodes error -match regexp -result {void type illegal in predicate}
+
+test typecheck-3.5 {void illegal in for-loop conditional} -body {
+#lang L --line=1
+void typecheck_3_5_v() { return; }
+void
+typecheck_3_5()
+{
+ for (1; typecheck_3_5_v(); 1) return;
+}
+} -returnCodes error -match regexp -result {void type illegal in predicate}
+
+test typecheck-3.6 {void illegal in abbreviated-for-loop conditional} -body {
+#lang L --line=1
+void typecheck_3_6_v() { return; }
+void
+typecheck_3_6()
+{
+ for (1; typecheck_3_6_v();) return;
+}
+} -returnCodes error -match regexp -result {void type illegal in predicate}
+
+test typecheck-3.10 {void illegal in binary operators} -body {
+#lang L --line=1
+void t310v() { return; }
+void
+typecheck_3_10()
+{
+ int i;
+
+ if (t310v() && 0) return;
+ if (0 && t310v()) return;
+ if (t310v() || 0) return;
+ if (0 || t310v()) return;
+ if (t310v() =~ /bad/) return;
+ if (t310v() eq "") return;
+ if ("" eq t310v()) return;
+ if (t310v() ne "") return;
+ if ("" ne t310v()) return;
+ if (t310v() gt "") return;
+ if ("" gt t310v()) return;
+ if (t310v() ge "") return;
+ if ("" ge t310v()) return;
+ if (t310v() lt "") return;
+ if ("" lt t310v()) return;
+ if (t310v() le "") return;
+ if ("" le t310v()) return;
+ if (t310v() == 0) return;
+ if (0 == t310v()) return;
+ if (t310v() != 0) return;
+ if (0 != t310v()) return;
+ if (t310v() > 0) return;
+ if (0 > t310v()) return;
+ if (t310v() >= 0) return;
+ if (0 >= t310v()) return;
+ if (t310v() < 0) return;
+ if (0 < t310v()) return;
+ if (t310v() <= 0) return;
+ if (0 <= t310v()) return;
+ i = t310v() + 1;
+ i = 1 + t310v();
+ i = t310v() - 1;
+ i = 1 - t310v();
+ i = t310v() * 1;
+ i = 1 * t310v();
+ i = t310v() / 1;
+ i = 1 / t310v();
+ i = t310v() % 1;
+ i = 1 % t310v();
+ i = t310v() & 1;
+ i = 1 & t310v();
+ i = t310v() | 1;
+ i = 1 | t310v();
+ i = t310v() ^ 1;
+ i = 1 ^ t310v();
+ i = t310v() << 1;
+ i = 1 << t310v();
+ i = t310v() >> 1;
+ i = 1 >> t310v();
+}
+} -returnCodes error -match regexp -result {.*7: L Error: void type illegal in predicate
+.*8: L Error: void type illegal in predicate
+.*9: L Error: void type illegal in predicate
+.*10: L Error: void type illegal in predicate
+.*11: L Error: expected type.*but got void in =~
+.*12: L Error: expected type.*but got void in string comparison
+.*13: L Error: expected type.*but got void in string comparison
+.*14: L Error: expected type.*but got void in string comparison
+.*15: L Error: expected type.*but got void in string comparison
+.*16: L Error: expected type.*but got void in string comparison
+.*17: L Error: expected type.*but got void in string comparison
+.*18: L Error: expected type.*but got void in string comparison
+.*19: L Error: expected type.*but got void in string comparison
+.*20: L Error: expected type.*but got void in string comparison
+.*21: L Error: expected type.*but got void in string comparison
+.*22: L Error: expected type.*but got void in string comparison
+.*23: L Error: expected type.*but got void in string comparison
+.*24: L Error: type void illegal
+.*25: L Error: type void illegal
+.*26: L Error: type void illegal
+.*27: L Error: type void illegal
+.*28: L Error: type void illegal
+.*29: L Error: type void illegal
+.*30: L Error: type void illegal
+.*31: L Error: type void illegal
+.*32: L Error: type void illegal
+.*33: L Error: type void illegal
+.*34: L Error: type void illegal
+.*35: L Error: type void illegal
+.*36: L Error: expected type.*but got void in arithmetic operator
+.*37: L Error: expected type.*but got void in arithmetic operator
+.*38: L Error: expected type.*but got void in arithmetic operator
+.*39: L Error: expected type.*but got void in arithmetic operator
+.*40: L Error: expected type.*but got void in arithmetic operator
+.*41: L Error: expected type.*but got void in arithmetic operator
+.*42: L Error: expected type.*but got void in arithmetic operator
+.*43: L Error: expected type.*but got void in arithmetic operator
+.*44: L Error: expected type.*but got void in arithmetic operator
+.*45: L Error: expected type.*but got void in arithmetic operator
+.*46: L Error: expected type.*but got void in arithmetic operator
+.*47: L Error: expected type.*but got void in arithmetic operator
+.*48: L Error: expected type.*but got void in arithmetic operator
+.*49: L Error: expected type.*but got void in arithmetic operator
+.*50: L Error: expected type.*but got void in arithmetic operator
+.*51: L Error: expected type.*but got void in arithmetic operator
+.*52: L Error: expected type.*but got void in arithmetic operator
+.*53: L Error: expected type.*but got void in arithmetic operator
+.*54: L Error: expected type.*but got void in arithmetic operator
+.*55: L Error: expected type.*but got void in arithmetic operator
+}
+
+test typecheck-3.10.2 {void illegal in binary operators 2} -body {
+#lang L --line=1
+void t310_2v() { return; }
+void
+typecheck_3_10_2()
+{
+ int i;
+
+ /*
+ * Similar to typecheck-3.10 but testing void as both lhs and
+ * rhs. The earlier test was getting too big which makes it
+ * hard to update for changes in error messages or error
+ * checking in the compiler.
+ */
+
+ if (t310_2v() && t310_2v()) return;
+ if (t310_2v() || t310_2v()) return;
+ if (t310_2v() =~ /bad/) return;
+ if (t310_2v() eq t310_2v()) return;
+ if (t310_2v() ne t310_2v()) return;
+ if (t310_2v() gt t310_2v()) return;
+ if (t310_2v() ge t310_2v()) return;
+ if (t310_2v() lt t310_2v()) return;
+ if (t310_2v() le t310_2v()) return;
+ if (t310_2v() == t310_2v()) return;
+ if (t310_2v() != t310_2v()) return;
+ if (t310_2v() > t310_2v()) return;
+ if (t310_2v() >= t310_2v()) return;
+ if (t310_2v() < t310_2v()) return;
+ if (t310_2v() <= t310_2v()) return;
+ i = t310_2v() + t310_2v();
+ i = t310_2v() - t310_2v();
+ i = t310_2v() * t310_2v();
+ i = t310_2v() / t310_2v();
+ i = t310_2v() % t310_2v();
+ i = t310_2v() & t310_2v();
+ i = t310_2v() | t310_2v();
+ i = t310_2v() ^ t310_2v();
+ i = t310_2v() << t310_2v();
+ i = t310_2v() >> t310_2v();
+}
+} -returnCodes error -match regexp -result {.*14: L Error: void type illegal in predicate
+.*15: L Error: void type illegal in predicate
+.*16: L Error: expected type.*but got void in =~
+.*17: L Error: expected type.*but got void in string comparison
+.*18: L Error: expected type.*but got void in string comparison
+.*19: L Error: expected type.*but got void in string comparison
+.*20: L Error: expected type.*but got void in string comparison
+.*21: L Error: expected type.*but got void in string comparison
+.*22: L Error: expected type.*but got void in string comparison
+.*23: L Error: type void illegal
+.*24: L Error: type void illegal
+.*25: L Error: type void illegal
+.*26: L Error: type void illegal
+.*27: L Error: type void illegal
+.*28: L Error: type void illegal
+.*29: L Error: expected type.*but got void in arithmetic operator
+.*30: L Error: expected type.*but got void in arithmetic operator
+.*31: L Error: expected type.*but got void in arithmetic operator
+.*32: L Error: expected type.*but got void in arithmetic operator
+.*33: L Error: expected type.*but got void in arithmetic operator
+.*34: L Error: expected type.*but got void in arithmetic operator
+.*35: L Error: expected type.*but got void in arithmetic operator
+.*36: L Error: expected type.*but got void in arithmetic operator
+.*37: L Error: expected type.*but got void in arithmetic operator
+.*38: L Error: expected type.*but got void in arithmetic operator
+}
+
+test typecheck-3.11 {void illegal in casts and unary operators} -body {
+#lang L --line=1
+void t311v() { return; }
+void
+typecheck_3_11()
+{
+ int i;
+ float f;
+ string s;
+ hash h;
+
+ i = (int)t311v();
+ f = (float)t311v();
+ s = (string)t311v();
+ h = (hash)t311v();
+ i = !t311v();
+ i = ~t311v();
+ i = +t311v();
+ i = -t311v();
+}
+} -returnCodes error -match regexp -result {.*10: L Error: type void illegal
+.*11: L Error: type void illegal
+.*12: L Error: type void illegal
+.*13: L Error: type void illegal
+.*14: L Error: void type illegal in predicate
+.*15: L Error: expected type int.*
+.*16: L Error: expected type int or float.*
+.*17: L Error: expected type int or float.*
+}
+
+test typecheck-3.12 {void illegal in assignments} -body {
+#lang L --line=1
+void t312v() { return; }
+int takes_int(int i) { return i; }
+void
+typecheck_3_12()
+{
+ int i;
+
+ i = t312v();
+ i += t312v();
+ i -= t312v();
+ i /= t312v();
+ i *= t312v();
+ i %= t312v();
+ i &= t312v();
+ i |= t312v();
+ i ^= t312v();
+ i >>= t312v();
+ i <<= t312v();
+ takes_int(t312v());
+}
+} -returnCodes error -match regexp -result {.*8: L Error: type void illegal
+.*9: L Error: type void illegal
+.*10: L Error: type void illegal
+.*11: L Error: type void illegal
+.*12: L Error: type void illegal
+.*13: L Error: type void illegal
+.*14: L Error: type void illegal
+.*15: L Error: type void illegal
+.*16: L Error: type void illegal
+.*17: L Error: type void illegal
+.*18: L Error: type void illegal
+.*19: L Error: parameter 1 has incompatible type
+}
+
+test typecheck-3.13 {void illegal as foreach expr} -body {
+#lang L --line=1 -nowarn
+void t313v() { return; }
+void
+typecheck_3_13()
+{
+ int k;
+
+ foreach (k in t313v()) { }
+}
+} -returnCodes error -match regexp -result {.*foreach expression must be array, hash, or string}
+
+test typecheck-4.1 {type errors in foreach} -body {
+#lang L --line=1
+void
+typecheck_4_1()
+{
+ int vi;
+ float vf;
+ string vs;
+ int ai[2] = { 22, 23 };
+ string as[2] = { "b", "c" };
+ float af[2] = { 2.1, 2.2 };
+ hash h = { 1=>2, 2=>3 };
+
+ foreach (vi in as) {}
+ foreach (vi in af) {}
+ foreach (vs in ai) {}
+ foreach (vs in af) {}
+ foreach (vf in as) {}
+ foreach (vi,vi in h) {}
+}
+} -returnCodes error -match regexp -result {.*12: L Error: loop index type incompatible with array element type
+.*13: L Error: loop index type incompatible with array element type
+.*14: L Error: loop index type incompatible with array element type
+.*15: L Error: loop index type incompatible with array element type
+.*16: L Error: loop index type incompatible with array element type
+.*17: L Error: multiple variables illegal in foreach over hash
+}
+
+test typecheck-4.2 {type errors in foreach with multiple variables} -body {
+#lang L --line=1
+void
+typecheck_4_2()
+{
+ int i1,i2,i3;
+ float f1,f2,f3;
+ string s1,s2,s3;
+ int ai[3] = { 22, 23, 24 };
+ string as[3] = { "b", "c", "d" };
+ float af[3] = { 2.1, 2.2, 2.3 };
+
+ foreach (i1,s2,s3 in as) {}
+ foreach (s1,i2,s3 in as) {}
+ foreach (s1,s2,i3 in as) {}
+ foreach (s1,i2,i3 in ai) {}
+ foreach (i1,s2,i3 in ai) {}
+ foreach (i1,i2,s3 in ai) {}
+ foreach (s1,f2,f3 in af) {}
+ foreach (f1,s2,f3 in af) {}
+ foreach (f1,f2,s3 in af) {}
+
+ /* Make sure that multiple type errors get caught. */
+ foreach (i1,i2,s3 in as) {}
+ foreach (i1,i2,i3 in as) {}
+}
+} -returnCodes error -match regexp -result {.*11: L Error: loop index type incompatible with array element type
+.*12: L Error: loop index type incompatible with array element type
+.*13: L Error: loop index type incompatible with array element type
+.*14: L Error: loop index type incompatible with array element type
+.*15: L Error: loop index type incompatible with array element type
+.*16: L Error: loop index type incompatible with array element type
+.*17: L Error: loop index type incompatible with array element type
+.*18: L Error: loop index type incompatible with array element type
+.*19: L Error: loop index type incompatible with array element type
+.*22: L Error: loop index type incompatible with array element type
+.*22: L Error: loop index type incompatible with array element type
+.*23: L Error: loop index type incompatible with array element type
+.*23: L Error: loop index type incompatible with array element type
+.*23: L Error: loop index type incompatible with array element type
+}
+
+test typecheck-4.4 {scalars as condition expressions} -body {
+#lang L --line=1
+void
+typecheck_4_4()
+{
+ /* These are all legal. */
+
+ int i = 0;
+ float f = 0.0;
+ string s1, s2 = "defined";
+ widget w;
+ poly p = "0";
+
+ if (i) puts("bad 1");
+ if (f) puts("bad 2"); // Exact comparisons w/floats don't always work
+
+ /* Strings as conditionals get checked for defined. */
+ if (s1) puts("bad 3");
+ unless (s2) puts("bad 4");
+
+ /* !condition should work too. */
+ unless (!s1) puts("bad 4.1");
+ if (!s2) puts("bad 4.2");
+ if (s1 || !s2) puts("bad 4.3");
+
+ if (w) puts("bad 5");
+ if (p) puts("bad 6");
+}
+typecheck_4_4();
+} -output {}
+
+test typecheck-5.1 {type errors in hash elements} -body {
+#lang L --line=1
+struct st51 {
+ int x;
+ int y;
+};
+void
+typecheck_5_1()
+{
+ int a[3], i;
+ string s;
+ float f;
+ poly p;
+ struct st51 st = {0,0};
+
+ int ihi{int};
+ int ihs{string};
+ int ihf{float};
+
+ string shi{int};
+ string shs{string};
+ string shf{float};
+
+ float fhi{int};
+ float fhs{string};
+ float fhf{float};
+
+ poly phi{int};
+ poly phs{string};
+ poly phf{float};
+
+ ihi{1.1} = 0; // These want an index of type int.
+ ihi{"s"} = 0;
+ ihi{st} = 0;
+ ihi{a} = 0;
+ ihi{shi} = 0;
+ shi{1.1} = "s";
+ shi{"s"} = "s";
+ shi{st} = "s";
+ shi{a} = "s";
+ shi{shi} = "s";
+ fhi{1.1} = 0.0;
+ fhi{"s"} = 0.0;
+ fhi{st} = 0.0;
+ fhi{a} = 0.0;
+ fhi{shi} = 0.0;
+ phi{1.1} = 0.0;
+ phi{"s"} = 0.0;
+ phi{st} = 0.0;
+ phi{a} = 0.0;
+ phi{shi} = 0.0;
+ i = ihi{1.1};
+ i = ihi{"s"};
+ i = ihi{st};
+ i = ihi{a};
+ i = ihi{shi};
+ s = shi{1.1};
+ s = shi{"s"};
+ s = shi{st};
+ s = shi{a};
+ s = shi{shi};
+ f = fhi{1.1};
+ f = fhi{"s"};
+ f = fhi{st};
+ f = fhi{a};
+ f = fhi{shi};
+ p = phi{1.1};
+ p = phi{"s"};
+ p = phi{st};
+ p = phi{a};
+ p = phi{shi};
+ ihs{1.1} = 0; // These want an index of type string.
+ ihs{0} = 0;
+ ihs{st} = 0;
+ ihs{a} = 0;
+ ihs{shi} = 0;
+ shs{1.1} = "s";
+ shs{0} = "s";
+ shs{st} = "s";
+ shs{a} = "s";
+ shs{shi} = "s";
+ fhs{1.1} = 0.0;
+ fhs{0} = 0.0;
+ fhs{st} = 0.0;
+ fhs{a} = 0.0;
+ fhs{shi} = 0.0;
+ phs{1.1} = 0.0;
+ phs{0} = 0.0;
+ phs{st} = 0.0;
+ phs{a} = 0.0;
+ phs{shi} = 0.0;
+ i = ihs{1.1};
+ i = ihs{0};
+ i = ihs{st};
+ i = ihs{a};
+ i = ihs{shi};
+ s = shs{1.1};
+ s = shs{0};
+ s = shs{st};
+ s = shs{a};
+ s = shs{shi};
+ f = fhs{1.1};
+ f = fhs{0};
+ f = fhs{st};
+ f = fhs{a};
+ f = fhs{shi};
+ p = phs{1.1};
+ p = phs{0};
+ p = phs{st};
+ p = phs{a};
+ p = phs{shi};
+ ihf{"s"} = 0; // These want an index of type float (but int is OK).
+ ihf{st} = 0;
+ ihf{a} = 0;
+ ihf{shi} = 0;
+ shf{"s"} = "s";
+ shf{st} = "s";
+ shf{a} = "s";
+ shf{shi} = "s";
+ fhf{"s"} = 0.0;
+ fhf{st} = 0.0;
+ fhf{a} = 0.0;
+ fhf{shi} = 0.0;
+ phf{"s"} = 0.0;
+ phf{st} = 0.0;
+ phf{a} = 0.0;
+ phf{shi} = 0.0;
+ i = ihf{"s"};
+ i = ihf{st};
+ i = ihf{a};
+ i = ihf{shi};
+ s = shf{"s"};
+ s = shf{st};
+ s = shf{a};
+ s = shf{shi};
+ f = fhf{"s"};
+ f = fhf{st};
+ f = fhf{a};
+ f = fhf{shi};
+ p = phf{"s"};
+ p = phf{st};
+ p = phf{a};
+ p = phf{shi};
+}
+#lang tcl
+typecheck_5_1
+} -returnCodes error -match regexp -result {.*30: L Error: expected type int but got float in hash index
+.*31: L Error: expected type int but got string in hash index
+.*32: L Error: expected type int but got struct in hash index
+.*33: L Error: expected type int but got array in hash index
+.*34: L Error: expected type int but got hash in hash index
+.*35: L Error: expected type int but got float in hash index
+.*36: L Error: expected type int but got string in hash index
+.*37: L Error: expected type int but got struct in hash index
+.*38: L Error: expected type int but got array in hash index
+.*39: L Error: expected type int but got hash in hash index
+.*40: L Error: expected type int but got float in hash index
+.*41: L Error: expected type int but got string in hash index
+.*42: L Error: expected type int but got struct in hash index
+.*43: L Error: expected type int but got array in hash index
+.*44: L Error: expected type int but got hash in hash index
+.*45: L Error: expected type int but got float in hash index
+.*46: L Error: expected type int but got string in hash index
+.*47: L Error: expected type int but got struct in hash index
+.*48: L Error: expected type int but got array in hash index
+.*49: L Error: expected type int but got hash in hash index
+.*50: L Error: expected type int but got float in hash index
+.*51: L Error: expected type int but got string in hash index
+.*52: L Error: expected type int but got struct in hash index
+.*53: L Error: expected type int but got array in hash index
+.*54: L Error: expected type int but got hash in hash index
+.*55: L Error: expected type int but got float in hash index
+.*56: L Error: expected type int but got string in hash index
+.*57: L Error: expected type int but got struct in hash index
+.*58: L Error: expected type int but got array in hash index
+.*59: L Error: expected type int but got hash in hash index
+.*60: L Error: expected type int but got float in hash index
+.*61: L Error: expected type int but got string in hash index
+.*62: L Error: expected type int but got struct in hash index
+.*63: L Error: expected type int but got array in hash index
+.*64: L Error: expected type int but got hash in hash index
+.*65: L Error: expected type int but got float in hash index
+.*66: L Error: expected type int but got string in hash index
+.*67: L Error: expected type int but got struct in hash index
+.*68: L Error: expected type int but got array in hash index
+.*69: L Error: expected type int but got hash in hash index
+.*70: L Error: expected type string but got float in hash index
+.*71: L Error: expected type string but got int in hash index
+.*72: L Error: expected type string but got struct in hash index
+.*73: L Error: expected type string but got array in hash index
+.*74: L Error: expected type string but got hash in hash index
+.*75: L Error: expected type string but got float in hash index
+.*76: L Error: expected type string but got int in hash index
+.*77: L Error: expected type string but got struct in hash index
+.*78: L Error: expected type string but got array in hash index
+.*79: L Error: expected type string but got hash in hash index
+.*80: L Error: expected type string but got float in hash index
+.*81: L Error: expected type string but got int in hash index
+.*82: L Error: expected type string but got struct in hash index
+.*83: L Error: expected type string but got array in hash index
+.*84: L Error: expected type string but got hash in hash index
+.*85: L Error: expected type string but got float in hash index
+.*86: L Error: expected type string but got int in hash index
+.*87: L Error: expected type string but got struct in hash index
+.*88: L Error: expected type string but got array in hash index
+.*89: L Error: expected type string but got hash in hash index
+.*90: L Error: expected type string but got float in hash index
+.*91: L Error: expected type string but got int in hash index
+.*92: L Error: expected type string but got struct in hash index
+.*93: L Error: expected type string but got array in hash index
+.*94: L Error: expected type string but got hash in hash index
+.*95: L Error: expected type string but got float in hash index
+.*96: L Error: expected type string but got int in hash index
+.*97: L Error: expected type string but got struct in hash index
+.*98: L Error: expected type string but got array in hash index
+.*99: L Error: expected type string but got hash in hash index
+.*100: L Error: expected type string but got float in hash index
+.*101: L Error: expected type string but got int in hash index
+.*102: L Error: expected type string but got struct in hash index
+.*103: L Error: expected type string but got array in hash index
+.*104: L Error: expected type string but got hash in hash index
+.*105: L Error: expected type string but got float in hash index
+.*106: L Error: expected type string but got int in hash index
+.*107: L Error: expected type string but got struct in hash index
+.*108: L Error: expected type string but got array in hash index
+.*109: L Error: expected type string but got hash in hash index
+.*110: L Error: expected type float but got string in hash index
+.*111: L Error: expected type float but got struct in hash index
+.*112: L Error: expected type float but got array in hash index
+.*113: L Error: expected type float but got hash in hash index
+.*114: L Error: expected type float but got string in hash index
+.*115: L Error: expected type float but got struct in hash index
+.*116: L Error: expected type float but got array in hash index
+.*117: L Error: expected type float but got hash in hash index
+.*118: L Error: expected type float but got string in hash index
+.*119: L Error: expected type float but got struct in hash index
+.*120: L Error: expected type float but got array in hash index
+.*121: L Error: expected type float but got hash in hash index
+.*122: L Error: expected type float but got string in hash index
+.*123: L Error: expected type float but got struct in hash index
+.*124: L Error: expected type float but got array in hash index
+.*125: L Error: expected type float but got hash in hash index
+.*126: L Error: expected type float but got string in hash index
+.*127: L Error: expected type float but got struct in hash index
+.*128: L Error: expected type float but got array in hash index
+.*129: L Error: expected type float but got hash in hash index
+.*130: L Error: expected type float but got string in hash index
+.*131: L Error: expected type float but got struct in hash index
+.*132: L Error: expected type float but got array in hash index
+.*133: L Error: expected type float but got hash in hash index
+.*134: L Error: expected type float but got string in hash index
+.*135: L Error: expected type float but got struct in hash index
+.*136: L Error: expected type float but got array in hash index
+.*137: L Error: expected type float but got hash in hash index
+.*138: L Error: expected type float but got string in hash index
+.*139: L Error: expected type float but got struct in hash index
+.*140: L Error: expected type float but got array in hash index
+.*141: L Error: expected type float but got hash in hash index
+}
+
+test typecheck-6.1 {type check errors with push built-in} -body {
+#lang L --line=1 -nowarn
+class typecheck_6_1_cls {}
+void
+typecheck_6_1()
+{
+ int a[], aa[][], i, j;
+ int h{int};
+ float f;
+ string s;
+ struct { int i,j; } st;
+ poly p;
+ widget w;
+ typecheck_6_1_cls o;
+
+ /* Errors -- first arg not a reference (&). */
+ push(a, i);
+ push(i, i);
+ push(h, i);
+ push(f, i);
+ push(s, i);
+ push(st, i);
+ push(p, i);
+ push(w, i);
+
+ /* Error -- too few arguments. */
+ push(&a);
+ push();
+
+
+ /* Error -- first arg not an array reference. */
+ push(&i, i);
+ push(&h, i);
+ push(&f, i);
+ push(&s, i);
+ push(&st, i);
+ push(&w, i);
+ push(&1, i);
+ push(&3.14159, i);
+ push(&o, i);
+}
+#lang tcl
+typecheck_6_1
+} -returnCodes {error} -match regexp -result {.*:15: L Error: first arg to push not an array reference.*
+.*:16: L Error: first arg to push not an array reference.*
+.*:17: L Error: first arg to push not an array reference.*
+.*:18: L Error: first arg to push not an array reference.*
+.*:19: L Error: first arg to push not an array reference.*
+.*:20: L Error: first arg to push not an array reference.*
+.*:21: L Error: first arg to push not an array reference.*
+.*:22: L Error: first arg to push not an array reference.*
+.*:25: L Error: too few arguments to push
+.*:26: L Error: too few arguments to push
+.*:30: L Error: first arg to push not an array reference.*
+.*:31: L Error: first arg to push not an array reference.*
+.*:32: L Error: first arg to push not an array reference.*
+.*:33: L Error: first arg to push not an array reference.*
+.*:34: L Error: first arg to push not an array reference.*
+.*:35: L Error: first arg to push not an array reference.*
+.*:36: L Error: first arg to push not an array reference.*
+.*:37: L Error: first arg to push not an array reference.*
+.*:38: L Error: first arg to push not an array reference.*
+}
+
+test typecheck-6.2 {type check errors with push built-in 2} -body {
+#lang L --line=1
+void typecheck_6_2_v() { }
+void
+typecheck_6_2()
+{
+ int ai[], i;
+ string as[], s;
+ widget aw[], w;
+ float af[], f;
+ int aa[][]; // array of array
+ int ah[]{int}, h{int}; // array of hash, and a hash
+ struct { int i,j; } ast[], st; // array of struct, and a struct
+
+ /*
+ * Check pushing incompatible type onto the array. Just check
+ * for an array of int, since we check the full type-checker
+ * elsewhere.
+ */
+
+ push(&ai, typecheck_6_2_v()); // pushing a void
+
+ push(&ai, f);
+ push(&ai, s);
+
+ push(&ai, aa);
+ push(&ai, as);
+ push(&ai, af);
+ push(&ai, h);
+ push(&ai, ah);
+ push(&ai, st);
+ push(&ai, ast);
+ push(&ai, w);
+ push(&ai, aw);
+
+ push(&aa[0], f);
+ push(&aa[0], s);
+
+
+ push(&aa[0], as);
+ push(&aa[0], af);
+ push(&aa[0], h);
+ push(&aa[0], ah);
+ push(&aa[0], st);
+ push(&aa[0], ast);
+ push(&aa[0], w);
+ push(&aa[0], aw);
+
+ push(&ai, f, s);
+ push(&ai, i, f);
+ push(&ai, i, f, s);
+}
+typecheck_6_2();
+} -returnCodes {error} -match regexp -result {.*:19: L Error: arg #2 to push has type incompatible with array
+.*:21: L Error: arg #2 to push has type incompatible with array
+.*:22: L Error: arg #2 to push has type incompatible with array
+.*:24: L Error: arg #2 to push has type incompatible with array
+.*:25: L Error: arg #2 to push has type incompatible with array
+.*:26: L Error: arg #2 to push has type incompatible with array
+.*:27: L Error: arg #2 to push has type incompatible with array
+.*:28: L Error: arg #2 to push has type incompatible with array
+.*:29: L Error: arg #2 to push has type incompatible with array
+.*:30: L Error: arg #2 to push has type incompatible with array
+.*:31: L Error: arg #2 to push has type incompatible with array
+.*:32: L Error: arg #2 to push has type incompatible with array
+.*:34: L Error: arg #2 to push has type incompatible with array
+.*:35: L Error: arg #2 to push has type incompatible with array
+.*:38: L Error: arg #2 to push has type incompatible with array
+.*:39: L Error: arg #2 to push has type incompatible with array
+.*:40: L Error: arg #2 to push has type incompatible with array
+.*:41: L Error: arg #2 to push has type incompatible with array
+.*:42: L Error: arg #2 to push has type incompatible with array
+.*:43: L Error: arg #2 to push has type incompatible with array
+.*:44: L Error: arg #2 to push has type incompatible with array
+.*:45: L Error: arg #2 to push has type incompatible with array
+.*:47: L Error: arg #2 to push has type incompatible with array
+.*:47: L Error: arg #3 to push has type incompatible with array
+.*:48: L Error: arg #3 to push has type incompatible with array
+.*:49: L Error: arg #3 to push has type incompatible with array
+.*:49: L Error: arg #4 to push has type incompatible with array
+}
+
+test typecheck-6.3 {type check push built-in} -body {
+#lang L --line=1
+void
+typecheck_6_3()
+{
+ int ai[], i;
+ string as[], s;
+ widget aw[], w;
+ float af[], f;
+ poly ap[], p;
+ int aa[][], a[]; // array of array, and an array
+ int ah[]{int}, h{int}; // array of hash, and a hash
+ struct { int i,j; } ast[], st; // array of struct, and a struct
+
+ /* All legal. */
+
+ push(&ai, 0);
+ push(&ai, i);
+
+ push(&as, "s");
+ push(&as, s);
+
+ push(&af, 3.14);
+ push(&af, f);
+ push(&af, 0); // legal to push ints onto a float array
+ push(&af, i);
+
+ push(&ap, 0);
+ push(&ap, 3.14);
+ push(&ap, "s");
+ push(&ap, i);
+ push(&ap, s);
+ push(&ap, w);
+ push(&ap, f);
+ push(&ap, p);
+ push(&ap, ai);
+ push(&ap, as);
+ push(&ap, af);
+ push(&ap, ap);
+ push(&ap, aw);
+ push(&ap, ast);
+ push(&ap, h);
+ push(&ap, st);
+
+ push(&aw, w);
+ push(&aw, (widget)"w");
+ push(&aw, s); // legal to push strings onto a widget array
+ push(&aw, "w");
+
+ push(&ah, h);
+
+ push(&aa, a);
+
+ push(&ast, st);
+}
+#lang tcl
+typecheck_6_3
+} -output {}
+
+test typecheck-7.1 {test type checking of reference parameters} -body {
+#lang L --line=1 -nowarn
+void typecheck_7_1_foo(int &a) {}
+void typecheck_7_1()
+{
+ int a;
+
+ typecheck_7_1_foo(a); // incorrect arg type
+}
+typecheck_7_1();
+} -returnCodes error -match regexp -result {.*6: L Error: parameter 1 has incompatible type
+}
+
+test typecheck-8.1 {widget and string type compatibility} -body {
+#lang L --line=1
+void typecheck_8_1()
+{
+ poly p = "p";
+ string s = "s";
+ widget w = "w";
+
+ p = s;
+ unless (p eq "s") puts("bad 1");
+ p = w;
+ unless (p eq "w") puts("bad 2");
+ p = p;
+ unless (p eq "w") puts("bad 3");
+ p = "p";
+ s = p;
+ unless (s eq "p") puts("bad 4");
+ s = s;
+ unless (s eq "p") puts("bad 5");
+ s = w;
+ unless (s eq "w") puts("bad 6");
+ s = "s";
+ w = p;
+ unless (w eq "p") puts("bad 7");
+ w = s;
+ unless (w eq "s") puts("bad 8");
+ w = w;
+ unless (w eq "s") puts("bad 9");
+ w = "w";
+
+ unless (p ne s) puts("bad 10");
+ unless (s ne p) puts("bad 11");
+ unless (p ne w) puts("bad 12");
+ unless (w ne p) puts("bad 13");
+ unless (s ne w) puts("bad 14");
+ unless (w ne s) puts("bad 15");
+ unless (p eq p) puts("bad 16");
+ unless (s eq s) puts("bad 17");
+ unless (w eq w) puts("bad 18");
+}
+#lang tcl
+typecheck_8_1
+} -output {}
+
+test typecheck-9.1 {illegal types in function prototype declarations} -body {
+#lang L --line=1
+void typecheck_9_1_1(void, void);
+void typecheck_9_1_2(void, void, void);
+void typecheck_9_1_3(int, void);
+void typecheck_9_1_4(void, int);
+void typecheck_9_1_5(void[]);
+void typecheck_9_1_6(void[][]);
+void typecheck_9_1_7(void{int});
+void typecheck_9_1_8(void{int}[]);
+void typecheck_9_1_9(void[]{int});
+void typecheck_9_1_10(void &bad);
+void typecheck_9_1_11(int{void});
+void{int} typecheck_9_1_12();
+void[] typecheck_9_1_13();
+int{void} typecheck_9_1_14();
+} -returnCodes error -match regexp -result {.*1: L Error: type void illegal
+.*1: L Error: type void illegal
+.*2: L Error: type void illegal
+.*2: L Error: type void illegal
+.*2: L Error: type void illegal
+.*3: L Error: type void illegal
+.*4: L Error: type void illegal
+.*5: L Error: type void illegal
+.*6: L Error: type void illegal
+.*7: L Error: type void illegal
+.*8: L Error: type void illegal
+.*9: L Error: type void illegal
+.*10: L Error: type void illegal in declaration of 'bad'
+.*11: L Error: type void illegal
+.*12: L Error: type void illegal in declaration of 'typecheck_9_1_12'
+.*13: L Error: type void illegal in declaration of 'typecheck_9_1_13'
+.*14: L Error: type void illegal in declaration of 'typecheck_9_1_14'
+}
+
+test typecheck-9.2 {illegal types in function pointer args} -body {
+#lang L --line=1
+void typecheck_9_2_1(void &bad(void, void));
+void typecheck_9_2_2(void &bad(void, void, void));
+void typecheck_9_2_3(void &bad(int, void));
+void typecheck_9_2_4(void &bad(void, int));
+void typecheck_9_2_5(void &bad(void[]));
+void typecheck_9_2_6(void &bad(void[][]));
+void typecheck_9_2_7(void &bad(void{int}));
+void typecheck_9_2_8(void &bad(void{int}[]));
+void typecheck_9_2_9(void &bad(void[]{int}));
+void typecheck_9_2_10(void &bad(void &bad));
+void typecheck_9_2_11(void &bad(int{void}));
+void typecheck_9_2_12(void{int} &bad());
+void typecheck_9_2_13(void[] &bad());
+void typecheck_9_2_14(int{void} &bad());
+} -returnCodes error -match regexp -result {.*1: L Error: type void illegal
+.*1: L Error: type void illegal
+.*2: L Error: type void illegal
+.*2: L Error: type void illegal
+.*2: L Error: type void illegal
+.*3: L Error: type void illegal
+.*4: L Error: type void illegal
+.*5: L Error: type void illegal
+.*6: L Error: type void illegal
+.*7: L Error: type void illegal
+.*8: L Error: type void illegal
+.*9: L Error: type void illegal
+.*10: L Error: type void illegal in declaration of 'bad'
+.*11: L Error: type void illegal
+.*12: L Error: type void illegal in declaration of 'bad'
+.*13: L Error: type void illegal in declaration of 'bad'
+.*14: L Error: type void illegal in declaration of 'bad'
+}
+
+test typecheck-9.3 {illegal types in variable declarations 1} -body {
+#lang L --line=1
+void typecheck_9_3()
+{
+ void bad1;
+ void bad2[];
+ void bad3[][];
+ void bad4{int};
+ void bad5{int}{int};
+ void bad6[]{int};
+ void bad7{int}[];
+ int bad8{void};
+ int bad9[]{void}{int};
+ int &bad10;
+ int &bad11[];
+ int &bad12{int};
+ int &bad13(void);
+ int &bad14(int);
+ int &bad15(int arg);
+}
+} -returnCodes error -match regexp -result {.*3: L Error:.*bad1.*
+.*4: L Error:.*bad2.*
+.*5: L Error:.*bad3.*
+.*6: L Error:.*bad4.*
+.*7: L Error:.*bad5.*
+.*8: L Error:.*bad6.*
+.*9: L Error:.*bad7.*
+.*10: L Error:.*bad8.*
+.*11: L Error:.*bad9.*
+.*12: L Error:.*bad10.*
+.*13: L Error:.*bad11.*
+.*14: L Error:.*bad12.*
+.*15: L Error:.*bad13.*
+.*16: L Error:.*bad14.*
+.*17: L Error:.*bad15.*
+}
+
+test typecheck-9.3.1 {illegal types in variable declarations 2} -body {
+#lang L --line=1
+void typecheck_9_3_1()
+{
+ void bad1, bad2[], bad3[][], bad4{int}, bad5{int}{int};
+ void bad6[]{int}, bad7{int}[], bad8{void}, bad9[]{void}{int};
+ int &bad10, &bad11[], &bad12{int}, &bad13(void);
+ int &bad14(int), &bad15(int arg);
+}
+} -returnCodes error -match regexp -result {.*3: L Error:.*bad1.*
+.*3: L Error:.*bad2.*
+.*3: L Error:.*bad3.*
+.*3: L Error:.*bad4.*
+.*3: L Error:.*bad5.*
+.*4: L Error:.*bad6.*
+.*4: L Error:.*bad7.*
+.*4: L Error:.*bad8.*
+.*4: L Error:.*bad9.*
+.*5: L Error:.*bad10.*
+.*5: L Error:.*bad11.*
+.*5: L Error:.*bad12.*
+.*5: L Error:.*bad13.*
+.*6: L Error:.*bad14.*
+.*6: L Error:.*bad15.*
+}
+
+test typecheck-9.3.2 {illegal types in variable declarations 3} -body {
+#lang L --line=1
+typedef void &t932();
+void typecheck_9_3_2()
+{
+ t932 bad1;
+ t932 bad2[];
+ t932 bad3[][];
+ t932 bad4{int};
+ t932 bad5{int}{int};
+ t932 bad6[]{int};
+ t932 bad7{int}[];
+ t932 bad8{void};
+ t932 bad9[]{void}{int};
+ t932 &bad10;
+ t932 &bad11[];
+ t932 &bad12{int};
+ t932 &bad13(void);
+ t932 &bad14(int);
+ t932 &bad15(int arg);
+}
+} -returnCodes error -match regexp -result {.*4: L Error:.*bad1.*
+.*5: L Error:.*bad2.*
+.*6: L Error:.*bad3.*
+.*7: L Error:.*bad4.*
+.*8: L Error:.*bad5.*
+.*9: L Error:.*bad6.*
+.*10: L Error:.*bad7.*
+.*11: L Error:.*bad8.*
+.*12: L Error:.*bad9.*
+.*13: L Error:.*bad10.*
+.*14: L Error:.*bad11.*
+.*15: L Error:.*bad12.*
+.*16: L Error:.*bad13.*
+.*17: L Error:.*bad14.*
+.*18: L Error:.*bad15.*
+}
+
+test typecheck-9.4 {illegal types in struct declarations 1} -body {
+#lang L --line=1
+struct {
+ void bad1;
+ void bad2[];
+ void bad3[][];
+ void bad4{int};
+ void bad5{int}{int};
+ void bad6[]{int};
+ void bad7{int}[];
+ int bad8{void};
+ int bad9[]{void}{int};
+ int &bad10;
+ int &bad11[];
+ int &bad12{int};
+ int &bad13(void);
+ int &bad14(int);
+ int &bad15(int arg);
+};
+} -returnCodes error -match regexp -result {.*2: L Error:.*bad1.*
+.*3: L Error:.*bad2.*
+.*4: L Error:.*bad3.*
+.*5: L Error:.*bad4.*
+.*6: L Error:.*bad5.*
+.*7: L Error:.*bad6.*
+.*8: L Error:.*bad7.*
+.*9: L Error:.*bad8.*
+.*10: L Error:.*bad9.*
+.*11: L Error:.*bad10.*
+.*12: L Error:.*bad11.*
+.*13: L Error:.*bad12.*
+.*14: L Error:.*bad13.*
+.*15: L Error:.*bad14.*
+.*16: L Error:.*bad15.*
+}
+
+test typecheck-9.4.1 {illegal types in struct declarations 2} -body {
+#lang L --line=1
+struct {
+ void bad1, bad2[], bad3[][], bad4{int}, bad5{int}{int};
+ void bad6[]{int}, bad7{int}[], bad8{void};
+ int bad9[]{void}{int}, &bad10, &bad11[];
+ int &bad12{int}, &bad13(void), &bad14(int), &bad15(int arg);
+};
+} -returnCodes error -match regexp -result {.*2: L Error:.*bad1.*
+.*2: L Error:.*bad2.*
+.*2: L Error:.*bad3.*
+.*2: L Error:.*bad4.*
+.*2: L Error:.*bad5.*
+.*3: L Error:.*bad6.*
+.*3: L Error:.*bad7.*
+.*3: L Error:.*bad8.*
+.*4: L Error:.*bad9.*
+.*4: L Error:.*bad10.*
+.*4: L Error:.*bad11.*
+.*5: L Error:.*bad12.*
+.*5: L Error:.*bad13.*
+.*5: L Error:.*bad14.*
+.*5: L Error:.*bad15.*
+}
+
+test typecheck-9.4.2 {illegal types in struct declarations 3} -body {
+#lang L --line=1
+typedef void &t942();
+struct {
+ t942 bad1;
+ t942 bad2[];
+ t942 bad3[][];
+ t942 bad4{int};
+ t942 bad5{int}{int};
+ t942 bad6[]{int};
+ t942 bad7{int}[];
+ t942 bad8{void};
+ t942 bad9[]{void}{int};
+ t942 &bad10;
+ t942 &bad11[];
+ t942 &bad12{int};
+ t942 &bad13(void);
+ t942 &bad14(int);
+ t942 &bad15(int arg);
+};
+} -returnCodes error -match regexp -result {.*3: L Error:.*bad1.*
+.*4: L Error:.*bad2.*
+.*5: L Error:.*bad3.*
+.*6: L Error:.*bad4.*
+.*7: L Error:.*bad5.*
+.*8: L Error:.*bad6.*
+.*9: L Error:.*bad7.*
+.*10: L Error:.*bad8.*
+.*11: L Error:.*bad9.*
+.*12: L Error:.*bad10.*
+.*13: L Error:.*bad11.*
+.*14: L Error:.*bad12.*
+.*15: L Error:.*bad13.*
+.*16: L Error:.*bad14.*
+.*17: L Error:.*bad15.*
+}
+
+test typecheck-9.4.3 {call-by-name type errors} -body {
+#lang L --line=1 -nowarn
+typedef int arr_t[];
+typedef int hash_t{int};
+typedef struct { int i,j; } struc_t;
+void t943(int &i, string &s, float &f, arr_t &a, hash_t &h, struc_t &st) {}
+
+void typecheck_9_4_3()
+{
+ int i;
+ string s;
+ float f;
+ arr_t a;
+ hash_t h;
+ struc_t st;
+
+ t943( i, &s, &f, &a, &h, &st);
+ t943(&i, s, &f, &a, &h, &st);
+ t943(&i, &s, f, &a, &h, &st);
+ t943(&i, &s, &f, a, &h, &st);
+ t943(&i, &s, &f, &a, h, &st);
+ t943(&i, &s, &f, &a, &h, st);
+ t943( i, s, f, a, h, st);
+}
+} -returnCodes error -match regexp -result {.*15: L Error: parameter 1 has incompatible type
+.*16: L Error: parameter 2 has incompatible type
+.*17: L Error: parameter 3 has incompatible type
+.*18: L Error: parameter 4 has incompatible type
+.*19: L Error: parameter 5 has incompatible type
+.*20: L Error: parameter 6 has incompatible type
+.*21: L Error: parameter 1 has incompatible type
+.*21: L Error: parameter 2 has incompatible type
+.*21: L Error: parameter 3 has incompatible type
+.*21: L Error: parameter 4 has incompatible type
+.*21: L Error: parameter 5 has incompatible type
+.*21: L Error: parameter 6 has incompatible type
+}
+
+test typecheck-10.1 {check type errors in op=} -body {
+#lang L --line=1
+void typecheck_10_1()
+{
+ int i1, i2;
+ string s1;
+
+
+ i1 += s1;
+ i1 -= s1;
+ i1 *= s1;
+ i1 /= s1;
+
+ i1 %= s1;
+ s1 %= i1;
+ i1 &= s1;
+ s1 &= i1;
+ i1 |= s1;
+ s1 |= i1;
+ i1 ^= s1;
+ s1 ^= i1;
+ i1 <<= s1;
+ s1 <<= i1;
+ i1 >>= s1;
+ s1 >>= i1;
+
+ i1 .= i2;
+ i1 .= s1;
+ s1 .= i1;
+}
+} -returnCodes error -match regexp -result {.*7: L Error: assignment of incompatible types
+.*8: L Error: assignment of incompatible types
+.*9: L Error: assignment of incompatible types
+.*10: L Error: assignment of incompatible types
+.*12: L Error: assignment of incompatible types
+.*13: L Error: assignment of incompatible types
+.*14: L Error: assignment of incompatible types
+.*15: L Error: assignment of incompatible types
+.*16: L Error: assignment of incompatible types
+.*17: L Error: assignment of incompatible types
+.*18: L Error: assignment of incompatible types
+.*19: L Error: assignment of incompatible types
+.*20: L Error: assignment of incompatible types
+.*21: L Error: assignment of incompatible types
+.*22: L Error: assignment of incompatible types
+.*23: L Error: assignment of incompatible types
+.*25: L Error: expected type string or widget but got int in .=
+.*26: L Error: assignment of incompatible types
+.*27: L Error: assignment of incompatible types
+}
+
+test typecheck-10.2 {check type errors in comparison operators} -body {
+#lang L --line=1
+void typecheck_10_2()
+{
+ int i;
+ string s;
+
+ s == i; // line 6
+ i == s;
+
+ s != i;
+ i != s; // line 10
+
+ s <= i;
+ i <= s;
+
+ s >= i; // line 15
+ i >= s;
+
+ s < i;
+ i < s;
+ // line 20
+ s > i;
+ i > s;
+
+
+ i eq s; // line 25
+ s eq i;
+ i eq i;
+ i ne s;
+ s ne i;
+ i ne i; // line 30
+ i le s;
+ s le i;
+ i le i;
+ i ge s;
+ s ge i; // line 35
+ i ge i;
+ i lt s;
+ s lt i;
+ i lt i;
+ i gt s; // line 40
+ s gt i;
+ i gt i; // line 42
+}
+} -returnCodes error -match regexp -result {.*6: L Error: incompatible types in comparison
+.*7: L Error: incompatible types in comparison
+.*9: L Error: incompatible types in comparison
+.*10: L Error: incompatible types in comparison
+.*12: L Error: incompatible types in comparison
+.*15: L Error: incompatible types in comparison
+.*16: L Error: incompatible types in comparison
+.*18: L Error: incompatible types in comparison
+.*19: L Error: incompatible types in comparison
+.*21: L Error: incompatible types in comparison
+.*22: L Error: incompatible types in comparison
+.*25: L Error: expected type string or widget but got int in string comparison
+.*26: L Error: expected type string or widget but got int in string comparison
+.*27: L Error: expected type string or widget but got int in string comparison
+.*28: L Error: expected type string or widget but got int in string comparison
+.*29: L Error: expected type string or widget but got int in string comparison
+.*30: L Error: expected type string or widget but got int in string comparison
+.*31: L Error: expected type string or widget but got int in string comparison
+.*32: L Error: expected type string or widget but got int in string comparison
+.*34: L Error: expected type string or widget but got int in string comparison
+.*35: L Error: expected type string or widget but got int in string comparison
+.*36: L Error: expected type string or widget but got int in string comparison
+.*37: L Error: expected type string or widget but got int in string comparison
+.*38: L Error: expected type string or widget but got int in string comparison
+.*39: L Error: expected type string or widget but got int in string comparison
+.*40: L Error: expected type string or widget but got int in string comparison
+.*41: L Error: expected type string or widget but got int in string comparison
+.*42: L Error: expected type string or widget but got int in string comparison
+}
+
+test typecheck-10.3 {check type names in type-error messages} -body {
+#lang L --line=1
+class typecheck_10_3_cls {}
+void typecheck_10_3()
+{
+ int x;
+ typecheck_10_3_cls obj;
+
+ 1 eq "string";
+ 1.0 eq "string";
+ "string" == 1;
+ (widget)"s" == 1;
+ (void)"s" == 1;
+ (int{int})"s" == 1;
+ (struct {int i;})"s" == 1;
+ (int[])"s" == 1;
+ {1,2,3} == 1;
+ &x == 1;
+ obj == 1;
+}
+} -returnCodes error -match regexp -result {.*7: L Error: expected type string or widget but got int in string comparison
+.*8: L Error: expected type string or widget but got float in string comparison
+.*9: L Error: incompatible types in comparison
+.*10: L Error: incompatible types in comparison
+.*11: L Error: type void illegal
+.*12: L Error: incompatible types in comparison
+.*13: L Error: incompatible types in comparison
+.*14: L Error: incompatible types in comparison
+.*15: L Error: incompatible types in comparison
+.*16: L Error: incompatible types in comparison
+.*17: L Error: incompatible types in comparison
+}
+
+test typecheck-11.1 {check FMT errors} -body {
+#lang L --line=1
+void typeck_11_1_foo0(_argused FMT fmt, _argused ...args) {}
+void typeck_11_1_foo1(_argused int a, _argused FMT fmt, _argused ...args) {}
+void typecheck_11_1()
+{
+ typeck_11_1_foo0("%s");
+ typeck_11_1_foo0("%s %s");
+ typeck_11_1_foo0("%s %s", "bad");
+ typeck_11_1_foo0("%%s %s");
+
+ typeck_11_1_foo1(1, "%s");
+ typeck_11_1_foo1(1, "%s %s");
+ typeck_11_1_foo1(1, "%s %s", "bad");
+ typeck_11_1_foo1(1, "%%s %s");
+
+ // With some unicode.
+ typeck_11_1_foo0("זו ה%sשפה שלנו");
+ typeck_11_1_foo0("%s זו ה%%sשפה שלנו");
+
+ typeck_11_1_foo0(1); // format arg not a string
+}
+typecheck_11_1();
+} -returnCodes error -match regexp -result {.*5: L Warning: bad format specifier
+.*6: L Warning: bad format specifier
+.*7: L Warning: bad format specifier
+.*8: L Warning: bad format specifier
+.*10: L Warning: bad format specifier
+.*11: L Warning: bad format specifier
+.*12: L Warning: bad format specifier
+.*13: L Warning: bad format specifier
+.*16: L Warning: bad format specifier
+.*17: L Warning: bad format specifier
+.*19: L Error: parameter 1 has incompatible type
+}
+
+test typecheck-11.2 {check FMT errors 2} -body {
+#lang L --line=1
+void typeck_11_2_foo0(_argused FMT fmt, _argused int bad) {}
+void typeck_11_2_foo1(_argused FMT fmt) {}
+} -returnCodes error -match regexp -result {.*1: L Error: rest argument must follow FMT
+.*2: L Error: rest argument must follow FMT
+}
+
+test typecheck-11.3 {check FMT cases where compile-time checks cannot be done} -body {
+#lang L --line=1
+void typeck_11_3_foo0(_argused FMT fmt, _argused ...args) {}
+void typecheck_11_3()
+{
+ string fmt = "%s";
+
+ typeck_11_3_foo0("${fmt}", "bad", "but", "no", "error");
+ typeck_11_3_foo0(fmt, "bad", "but", "no", "error");
+}
+typecheck_11_3();
+} -output {}
+
+test typecheck-11.4 {check that unicode does not confuse FMT checking} -body {
+#lang L --line=1
+void typecheck_11_4()
+{
+ string s;
+
+ s = sprintf("זו ה%sשפה שלנו %s", "is", "meaningless");
+ unless (s == "זו הisשפה שלנו meaningless") puts("bad 1");
+}
+typecheck_11_4();
+} -output {}
+
+test typecheck-11.5 {check more legal FMT cases} -body {
+#lang L
+void typecheck_11_5()
+{
+ string a[] = { "1", "2", "3" };
+
+ /*
+ * These are legal cases where the number of %'s in the format
+ * arg doesn't equal the number of subsequent args.
+ */
+
+ unless (sprintf("%1$d %1$x", 16) == "16 10") puts("bad 1");
+ unless (sprintf("%*s", 6, "123") == " 123") puts("bad 2");
+ unless (sprintf("%.*s", 3, "1234567890") == "123") puts("bad 3");
+ unless (sprintf("%*.*s", 3, 5, "1234567890") == "12345") puts("bad 4");
+ unless (sprintf("%%s") == "%s") puts("bad 5");
+
+ /*
+ * Here, the number of actuals isn't known at comile time so
+ * no check should be done and therefore no compile-time error
+ * should occur.
+ */
+
+ unless (sprintf("%s %s %s", (expand)a) == "1 2 3") puts("bad 10");
+}
+typecheck_11_5();
+} -output {}
+
+test fnptr-1 {function pointers 1} -body {
+#lang L --line=1
+typedef string &fnptr1_t(int);
+
+string fnptr1_doit(int x)
+{
+ return ("doit got ${x}");
+}
+string fnptr1_foo(string &f(int))
+{
+ return (f(33));
+}
+string fnptr1_foo2(fnptr1_t f)
+{
+ return (f(44));
+}
+void fnptr_1()
+{
+ unless (fnptr1_foo(&fnptr1_doit) eq "doit got 33") puts("bad 1");
+ unless (fnptr1_foo2(&fnptr1_doit) eq "doit got 44") puts("bad 2");
+}
+#lang tcl
+fnptr_1
+} -output {}
+
+test fnptr-2 {function pointers 2} -body {
+#lang L --line=1
+typedef int &fnptr2_t(poly,poly);
+
+/* Integer comparison. */
+int icmp(int a, int b)
+{
+ if (a < b) {
+ return -1;
+ } else if (a > b) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+/* Unary comparison. */
+int ucmp(string a, string b)
+{
+ int al = strlen(a);
+ int bl = strlen(b);
+
+ if (al < bl) {
+ return -1;
+ } else if (al > bl) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+string fnptr2_sort(poly[] a, fnptr2_t compar)
+{
+ int i, swapped;
+
+ do {
+ swapped = 0;
+ for (i = 0; i < length(a)-1; ++i) {
+ if (compar(a[i], a[i+1]) > 0) {
+ poly t = a[i];
+ a[i] = a[i+1];
+ a[i+1] = t;
+ swapped = 1;
+ }
+ }
+ } while (swapped);
+
+ return ((string)a);
+}
+
+void fnptr_2()
+{
+ unless (fnptr2_sort((int[])"3 1 4 1 5 9", &icmp) eq "1 1 3 4 5 9") {
+ puts("bad 1");
+ }
+ unless (fnptr2_sort((string[])"111 1 1 11 111111111 11111", &ucmp) eq
+ "1 1 11 111 11111 111111111") {
+ puts("bad 2");
+ }
+}
+#lang tcl
+fnptr_2
+} -output {}
+
+test fnptr-3 {function pointer type errors} -body {
+#lang L --line=1 -nowarn
+typedef void &fp3_v_v_t(void);
+typedef void &fp3_v_i_t(int);
+typedef int &fp3_i_v_t(void);
+typedef int &fp3_i_i_t(int);
+typedef void &fp3_v_is_t(int, string);
+
+void fp3_v_v(void) {}
+void fp3_v_i(int i) {}
+int fp3_i_v(void) { return (0); }
+int fp3_i_i(int i) { return (i); }
+void fp3_v_is(int i, string s) {}
+
+void fp3f_vv (fp3_v_v_t f) { f(); }
+void fp3f_vi (fp3_v_i_t f) { f(1); }
+void fp3f_iv (fp3_i_v_t f) { f(); }
+void fp3f_ii (fp3_i_i_t f) { f(1); }
+void fp3f_vis(fp3_v_is_t f) { f(1,"s"); }
+
+void fnptr_3()
+{
+ fp3f_vv(1);
+ fp3f_vv(1.1);
+ fp3f_vv((int[])"1 2 3");
+ fp3f_vv((hash)"1 2 3 4");
+ fp3f_vv((struct { int i,j; })"1 2");
+
+ /* Try all the various error combinations, given the above types. */
+
+ fp3f_vv(fp3_v_v);
+ fp3f_vv(&fp3_v_i);
+ fp3f_vv(&fp3_i_v);
+ fp3f_vv(&fp3_i_i);
+ fp3f_vv(&fp3_v_is);
+
+ fp3f_vi(fp3_v_i);
+ fp3f_vi(&fp3_v_v);
+ fp3f_vi(&fp3_i_v);
+ fp3f_vi(&fp3_i_i);
+ fp3f_vi(&fp3_v_is);
+
+ fp3f_iv(fp3_i_v);
+ fp3f_iv(&fp3_v_v);
+ fp3f_iv(&fp3_v_i);
+ fp3f_iv(&fp3_i_i);
+ fp3f_iv(&fp3_v_is);
+
+ fp3f_ii(fp3_i_i);
+ fp3f_ii(&fp3_v_v);
+ fp3f_ii(&fp3_v_i);
+ fp3f_ii(&fp3_i_v);
+ fp3f_ii(&fp3_v_is);
+
+ fp3f_vis(fp3_v_is);
+ fp3f_vis(&fp3_v_v);
+ fp3f_vis(&fp3_v_i);
+ fp3f_vis(&fp3_i_v);
+ fp3f_vis(&fp3_i_i);
+}
+} -returnCodes error -match regexp -result {.*21: L Error: parameter 1.*
+.*22: L Error: parameter 1.*
+.*23: L Error: parameter 1.*
+.*24: L Error: parameter 1.*
+.*25: L Error: parameter 1.*
+.*30: L Error: parameter 1.*
+.*31: L Error: parameter 1.*
+.*32: L Error: parameter 1.*
+.*33: L Error: parameter 1.*
+.*36: L Error: parameter 1.*
+.*37: L Error: parameter 1.*
+.*38: L Error: parameter 1.*
+.*39: L Error: parameter 1.*
+.*42: L Error: parameter 1.*
+.*43: L Error: parameter 1.*
+.*44: L Error: parameter 1.*
+.*45: L Error: parameter 1.*
+.*48: L Error: parameter 1.*
+.*49: L Error: parameter 1.*
+.*50: L Error: parameter 1.*
+.*51: L Error: parameter 1.*
+.*54: L Error: parameter 1.*
+.*55: L Error: parameter 1.*
+.*56: L Error: parameter 1.*
+.*57: L Error: parameter 1.*
+}
+
+test assign-1 {check assignment statement value and type} -body {
+#lang L --line=1
+void
+assign_1()
+{
+ /*
+ * Check type and value of "lhs = rhs". Rhs should be
+ * evaluated before lhs. The type of (lhs = rhs) should be
+ * the type of lhs and have the value of lhs.
+ */
+
+ int i, j, k;
+ float f, g;
+ string s1, s2;
+ int a1[], a2[], a3[];
+ int h1{int}, h2{int}, h3{int};
+
+ i = (j = 13);
+ unless ((i == 13) && (j == 13)) puts("bad 1");
+
+ i = (j = (k = 14));
+ unless ((i == 14) && (j == 14) && (k == 14)) puts("bad 2");
+
+ i = j = k = 14; // = should be right associative
+ unless ((i == 14) && (j == 14) && (k == 14)) puts("bad 2.1");
+
+ /* Note: exact comparisons against floats don't always work. */
+ f = (g = (i = 1));
+ unless ((f == 1.0) && (g == 1.0)) puts("bad 3");
+
+ s1 = (s2 = "ok");
+ unless ((s1 eq "ok") && (s2 eq "ok")) puts("bad 4");
+
+ a1[0] = 3;
+ a3 = (a2 = a1);
+ unless ((a1[0] == 3) && !defined(a1[1])) puts("bad 5.1");
+ unless ((a2[0] == 3) && !defined(a2[1])) puts("bad 5.2");
+ unless ((a3[0] == 3) && !defined(a3[1])) puts("bad 5.3");
+
+ h1{1} = 4;
+ h3 = (h2 = h1);
+ unless ((h1{1} == 4) && (h2{1} == 4) && (h3{1} == 4)) puts("bad 6.1");
+ foreach (i in h1) unless (i == 1) puts("bad 6.2");
+ foreach (i in h2) unless (i == 1) puts("bad 6.3");
+ foreach (i in h3) unless (i == 1) puts("bad 6.4");
+
+ /* Check that rhs is evaluated *before* lhs. */
+
+ i = 0;
+ a1[i] = (i = 2);
+ unless (a1[2] == 2) puts("bad 7");
+
+ i = 3;
+ a1[3] = 1;
+ a1[4] = 2;
+ a1[i] = ++i;
+ unless ((a1[3] == 1) && (a1[4] == 4)) puts("bad 8");
+
+ i = 3;
+ a1[3] = 1;
+ a1[4] = 2;
+ a1[i] = i++;
+ unless ((a1[3] == 1) && (a1[4] == 3)) puts("bad 9");
+
+ i = 3;
+ a1[3] = 1;
+ a1[4] = 2;
+ a1[i] += ++i;
+ unless ((a1[3] == 1) && (a1[4] == 6)) puts("bad 10");
+
+ i = 3;
+ a1[3] = 1;
+ a1[4] = 2;
+ a1[i] += i++;
+ unless ((a1[3] == 1) && (a1[4] == 5)) puts("bad 11");
+}
+#lang tcl
+assign_1
+} -output {}
+
+test backtrace-1.0 {backtracing in L} -setup {
+ set fname [makeFile {
+void foo()
+{
+ puts("foo", "bar");
+}
+
+void bar()
+{
+ foo();
+}
+
+int
+main()
+{
+ bar();
+}
+
+ } backtrace-1.0.l]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $fname
+} -cleanup {
+ removeFile backtrace-1.0.l
+} -returnCodes {error} -match regexp -result {.*line 4.*line 9.*line 15}
+
+test pattern-1.0 {L pattern functions} -body {
+#lang L --line=1
+string Pattern1_()
+{
+ // This is NOT a pattern function (because the _ is trailing).
+ return("Pattern1_");
+}
+string Pattern1_foo(int a, int b)
+{
+ return("Pattern1_foo ${a} ${b}");
+}
+string Pattern1_*(...args)
+{
+ poly p;
+ string ret = "Pattern1_* ${$1}";
+ foreach (p in args) ret .= " ${p}";
+ return (ret);
+}
+string pattern2(...args)
+{
+ poly p;
+ string ret = "pattern2";
+ foreach (p in args) ret .= " ${p}";
+ return (ret);
+}
+string p1_0_widget(...args)
+{
+ poly p;
+ string ret = "p1_0_widget";
+ foreach (p in args) ret .= " ${p}";
+ return (ret);
+}
+void pattern_1_0()
+{
+ string s;
+ widget w = "p1_0_widget";
+
+ s = Pattern1_foo(1, 2); // calls Pattern1_foo(1, 2)
+ unless (s eq "Pattern1_foo 1 2") puts("bad 1.1");
+
+ s = Pattern1_bar(); // calls Pattern1_*("bar")
+ unless (s eq "Pattern1_* bar") puts("bad 2.1");
+ s = Pattern1_bar(3); // calls Pattern1_*("bar", 3)
+ unless (s eq "Pattern1_* bar 3") puts("bad 2.2");
+ s = Pattern1_bar(3, 4); // calls Pattern1_*("bar", 3, 4)
+ unless (s eq "Pattern1_* bar 3 4") puts("bad 2.3");
+ s = Pattern1_foo123(1, 2); // calls Pattern1_*("foo123", 1, 2)
+ unless (s eq "Pattern1_* foo123 1 2") puts("bad 2.4");
+ s = Pattern1_foo_(1, 2); // calls Pattern1_*("foo_", 1, 2)
+ unless (s eq "Pattern1_* foo_ 1 2") puts("bad 2.5");
+
+ s = Pattern1_Bar(); // calls Pattern1_*("bar")
+ unless (s eq "Pattern1_* bar") puts("bad 3.1");
+ s = Pattern1_Bar(3); // calls Pattern1_*("bar", 3)
+ unless (s eq "Pattern1_* bar 3") puts("bad 3.2");
+ s = Pattern1_Bar(3, 4); // calls Pattern1_*("bar", 3, 4)
+ unless (s eq "Pattern1_* bar 3 4") puts("bad 3.3");
+
+ s = Pattern1_barBaz();
+ unless (s eq "Pattern1_* bar baz") puts("bad 4.1");
+ s = Pattern1_barBaz(3);
+ unless (s eq "Pattern1_* bar baz 3") puts("bad 4.2");
+ s = Pattern1_barBaz(3, 4);
+ unless (s eq "Pattern1_* bar baz 3 4") puts("bad 4.3");
+
+ s = Pattern1_barBazBlech();
+ unless (s eq "Pattern1_* bar baz blech") puts("bad 5.1");
+ s = Pattern1_barBazBlech(3);
+ unless (s eq "Pattern1_* bar baz blech 3") puts("bad 5.2");
+ s = Pattern1_barBazBlech(3, 4);
+ unless (s eq "Pattern1_* bar baz blech 3 4") puts("bad 5.3");
+
+ s = Pattern2_bar(); // calls pattern2("bar")
+ unless (s eq "pattern2 bar") puts("bad 6.1");
+ s = Pattern2_bar(5); // calls pattern2("bar", 5)
+ unless (s eq "pattern2 bar 5") puts("bad 6.2");
+ s = Pattern2_bar(5, 6); // calls pattern2("bar", 5, 6)
+ unless (s eq "pattern2 bar 5 6") puts("bad 6.3");
+
+ s = Pattern2_Bar();
+ unless (s eq "pattern2 bar") puts("bad 7.1");
+ s = Pattern2_Bar(5);
+ unless (s eq "pattern2 bar 5") puts("bad 7.2");
+ s = Pattern2_Bar(5, 6);
+ unless (s eq "pattern2 bar 5 6") puts("bad 7.3");
+
+ s = Pattern2_barBaz();
+ unless (s eq "pattern2 bar baz") puts("bad 8.1");
+ s = Pattern2_barBaz(5);
+ unless (s eq "pattern2 bar baz 5") puts("bad 8.2");
+ s = Pattern2_barBaz(5, 6);
+ unless (s eq "pattern2 bar baz 5 6") puts("bad 8.3");
+
+ s = Pattern2_barBazBlech();
+ unless (s eq "pattern2 bar baz blech") puts("bad 9.1");
+ s = Pattern2_barBazBlech(5);
+ unless (s eq "pattern2 bar baz blech 5") puts("bad 9.2");
+ s = Pattern2_barBazBlech(5, 6);
+ unless (s eq "pattern2 bar baz blech 5 6") puts("bad 9.3");
+
+ s = Pattern1_(); // calls Pattern1_()
+ unless (s eq "Pattern1_") puts("bad 10.1");
+
+ s = Pattern2_bar(w); // calls p1_0_widget("bar")
+ unless (s eq "p1_0_widget bar") puts("bad 20.1");
+ s = Pattern2_bar(w, 1); // calls p1_0_widget("bar", 1)
+ unless (s eq "p1_0_widget bar 1") puts("bad 20.2");
+ s = Pattern2_bar(w, 1, 2); // calls p1_0_widget("bar", 1, 2)
+ unless (s eq "p1_0_widget bar 1 2") puts("bad 20.3");
+
+ s = Pattern2_Bar(w);
+ unless (s eq "p1_0_widget bar") puts("bad 21.1");
+ s = Pattern2_Bar(w, 1);
+ unless (s eq "p1_0_widget bar 1") puts("bad 21.2");
+ s = Pattern2_Bar(w, 1, 2);
+ unless (s eq "p1_0_widget bar 1 2") puts("bad 21.3");
+
+ s = Pattern2_barBaz(w);
+ unless (s eq "p1_0_widget bar baz") puts("bad 22.1");
+ s = Pattern2_barBaz(w, 1);
+ unless (s eq "p1_0_widget bar baz 1") puts("bad 22.2");
+ s = Pattern2_barBaz(w, 1, 2);
+ unless (s eq "p1_0_widget bar baz 1 2") puts("bad 22.3");
+
+ s = Pattern2_barBazBlech(w);
+ unless (s eq "p1_0_widget bar baz blech") puts("bad 23.1");
+ s = Pattern2_barBazBlech(w, 1);
+ unless (s eq "p1_0_widget bar baz blech 1") puts("bad 23.2");
+ s = Pattern2_barBazBlech(w, 1, 2);
+ unless (s eq "p1_0_widget bar baz blech 1 2") puts("bad 23.3");
+}
+pattern_1_0();
+} -output {}
+
+test pattern-1.2 {check pattern function argument type checking} -body {
+#lang L --line=1 -nowarn
+void Pattern120_*() {}
+void Pattern121_*(int a) {}
+void Pattern122_*(int a, int b) {}
+void pattern_1_2()
+{
+ Pattern120_foo(1);
+ Pattern121_foo();
+ Pattern121_foo(1,2);
+ Pattern122_foo();
+ Pattern122_foo(1);
+ Pattern122_foo(1,2,3);
+}
+pattern_1_2();
+} -returnCodes {error} -match regexp -result {.*6: L Error: too many arguments for function Pattern120_foo
+.*7: L Error: not enough arguments for function Pattern121_foo
+.*8: L Error: too many arguments for function Pattern121_foo
+.*9: L Error: not enough arguments for function Pattern122_foo
+.*10: L Error: not enough arguments for function Pattern122_foo
+.*11: L Error: too many arguments for function Pattern122_foo
+}
+
+test pattern-1.3 {check pattern function call with (expand) args} -body {
+#lang L --line=1
+string pattern13(...args)
+{
+ poly p;
+ string ret = "pattern13";
+ foreach (p in args) ret .= " ${p}";
+ return (ret);
+}
+void pattern_1_3()
+{
+ int i;
+ string got, want;
+ string args[], args2[];
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_foo((expand)args);
+ want = "pattern13 foo";
+ if (length(args)) want .= " " . join(" ", args);
+ unless (got eq want) {
+ printf("bad 1.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_foo((expand)args, "a");
+ want = "pattern13 foo";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a";
+ unless (got eq want) {
+ printf("bad 2.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_foo((expand)args, "a", "b");
+ want = "pattern13 foo";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a b";
+ unless (got eq want) {
+ printf("bad 3.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_foo((expand)args, "a", "b", "c");
+ want = "pattern13 foo";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a b c";
+ unless (got eq want) {
+ printf("bad 4.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBar((expand)args);
+ want = "pattern13 foo bar";
+ if (length(args)) want .= " " . join(" ", args);
+ unless (got eq want) {
+ printf("bad 5.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBar((expand)args, "a");
+ want = "pattern13 foo bar";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a";
+ unless (got eq want) {
+ printf("bad 6.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBar((expand)args, "a", "b");
+ want = "pattern13 foo bar";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a b";
+ unless (got eq want) {
+ printf("bad 7.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBar((expand)args, "a", "b", "c");
+ want = "pattern13 foo bar";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a b c";
+ unless (got eq want) {
+ printf("bad 8.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBarBaz((expand)args);
+ want = "pattern13 foo bar baz";
+ if (length(args)) want .= " " . join(" ", args);
+ unless (got eq want) {
+ printf("bad 9.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBarBaz((expand)args, "a");
+ want = "pattern13 foo bar baz";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a";
+ unless (got eq want) {
+ printf("bad 10.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBarBaz((expand)args, "a", "b");
+ want = "pattern13 foo bar baz";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a b";
+ unless (got eq want) {
+ printf("bad 11.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBarBaz((expand)args, "a", "b", "c");
+ want = "pattern13 foo bar baz";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a b c";
+ unless (got eq want) {
+ printf("bad 12.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ args2 = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_foo((expand)args, (expand)args2, "a");
+ want = "pattern13 foo";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a";
+ unless (got eq want) {
+ printf("bad 20.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ args2 = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_foo((expand)args, (expand)args2, "a");
+ want = "pattern13 foo";
+ if (length(args)) want .= " " . join(" ", args);
+ if (length(args2)) want .= " " . join(" ", args2);
+ want .= " a";
+ unless (got eq want) {
+ printf("bad 20.2 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ args2[END+1] = (string)(i*100);
+ }
+
+ args = {};
+ args2 = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_foo((expand)args, "a", (expand)args2);
+ want = "pattern13 foo";
+ if (length(args)) want .= " " . join(" ", args);
+ want .= " a";
+ if (length(args2)) want .= " " . join(" ", args2);
+ unless (got eq want) {
+ printf("bad 20.3 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ args2[END+1] = (string)(i*100);
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_foo("a", (expand)args);
+ want = "pattern13 foo a";
+ if (length(args)) want .= " " . join(" ", args);
+ unless (got eq want) {
+ printf("bad 21.1 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_foo("a", "b", (expand)args);
+ want = "pattern13 foo a b";
+ if (length(args)) want .= " " . join(" ", args);
+ unless (got eq want) {
+ printf("bad 21.2 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBar("a", (expand)args);
+ want = "pattern13 foo bar a";
+ if (length(args)) want .= " " . join(" ", args);
+ unless (got eq want) {
+ printf("bad 21.3 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+
+ args = {};
+ for (i = 0; i < 10; ++i) {
+ got = Pattern13_fooBar("a", "b", (expand)args);
+ want = "pattern13 foo bar a b";
+ if (length(args)) want .= " " . join(" ", args);
+ unless (got eq want) {
+ printf("bad 21.4 got '%s' want '%s'\n", got, want);
+ }
+ args[END+1] = (string)i;
+ }
+}
+pattern_1_3();
+} -output {}
+
+test include-1.0 {include files} -setup {
+ set fname [makeFile {
+ ++include_1_0;
+ unless (basename(__FILE__) eq "foo-1.0.l") puts("bad 1");
+ unless (__LINE__ == 4) puts("bad 2");
+ } foo-1.0.l [file dirname [info script]]]
+} -body {
+#lang L --line=1
+int include_1_0 = 0;
+puts(include_1_0);
+#include "foo-1.0.l"
+puts(include_1_0);
+// Check variations in spacing and punctation.
+// The compiler should include foo-1.0.l only once.
+#include"foo-1.0.l"
+#include "foo-1.0.l"
+#include "foo-1.0.l"
+#include "foo-1.0.l"
+#include"foo-1.0.l"
+puts(include_1_0);
+} -cleanup {
+ removeFile $fname
+} -output {0
+1
+1
+}
+
+test include-1.1 {nested include files} -setup {
+#
+# The code for these files isn't indented because L recognizes
+# include() only when it starts at the beginning of the line.
+#
+ set fname1 [makeFile {#include "foo-1.1-2.l"
+unless (basename(__FILE__) eq "foo-1.1-1.l") puts("bad 1.1");
+unless (__LINE__ == 3) puts("bad 1.2 ${__LINE__}");
+} foo-1.1-1.l [file dirname [info script]]]
+ set fname2 [makeFile {unless (__LINE__ == 1) puts("bad 2.1");
+int include_1_1a = 3;
+unless (basename(__FILE__) eq "foo-1.1-2.l") puts("bad 2.2");
+unless (__LINE__ == 4) puts("bad 2.3");
+#include "foo-1.1-3.l"
+unless (basename(__FILE__) eq "foo-1.1-2.l") puts("bad 2.4");
+unless (__LINE__ == 7) puts("bad 2.5 ${__LINE__}");
+} foo-1.1-2.l .]
+ set fname3 [makeFile {
+int include_1_1b = 4;
+unless (basename(__FILE__) eq "foo-1.1-3.l") puts("bad 3.1");
+unless (__LINE__ == 4) puts("bad 3.2");
+} foo-1.1-3.l .]
+} -body {
+#lang L --line=1
+#include "foo-1.1-1.l"
+unless (include_1_1a == 3) puts("bad 10.1");
+unless (include_1_1b == 4) puts("bad 10.2");
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+} -output {}
+
+test include-1.2 {malformed includes} -body {
+#lang L --line=1
+#include "
+#include <
+#include ""
+#include <>
+} -returnCodes {error} -match regexp -result {.*1: L Error: malformed #include
+.*2: L Error: malformed #include
+.*3: L Error: malformed #include
+.*4: L Error: malformed #include
+}
+
+test include-1.3 {test line number tracking with include files} -setup {
+ set fname1 [makeFile {int include_1_3a = "bad1";
+#include "foo-1.3-2.l"} foo-1.3-1.l [file dirname [info script]]]
+ set fname2 [makeFile {int include_1_3b = "bad2";
+#include "foo-1.3-3.l"
+int include_1_3c = "bad3";} foo-1.3-2.l .]
+ set fname3 [makeFile {int include_1_3d = "bad4";} foo-1.3-3.l .]
+} -body {
+#lang L --line=1
+int include_1_3 = "bad0";
+#include "foo-1.3-1.l"
+int include_1_3last = "badn";
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+} -returnCodes {error} -match regexp -result {.*1: L Error: assignment of incompatible types
+.*foo-1.3-1.l:1: L Error: assignment of incompatible types
+.*foo-1.3-2.l:1: L Error: assignment of incompatible types
+.*foo-1.3-3.l:1: L Error: assignment of incompatible types
+.*foo-1.3-2.l:3: L Error: assignment of incompatible types
+.*3: L Error: assignment of incompatible types
+}
+
+test include-1.4 {test missing include file} -body {
+#lang L --line=1
+#include "does-not-exist.l"
+} -returnCodes {error} -match regexp -result {.*1: L Error: cannot find include file does-not-exist.l
+}
+
+# Create files with the same names in $BIN/mydir, $BIN/include, and in
+# the cwd of the L script, and ensure that the one specified by an
+# absolute path (to mydir) gets included, where $BIN is where the
+# running tclsh lives.
+test include-1.5 {test include "/abs/path" search path} -setup {
+ set mydir [makeDirectory mydir [file dirname [interpreter]]]
+ set incdir [makeDirectory include [file dirname [interpreter]]]
+ set fname1 [makeFile {puts("good");} f-1.5-1.l $mydir]
+ set fname2 [makeFile {puts("bad");} f-1.5-1.l $incdir]
+ set fname3 [makeFile {puts("bad");} f-1.5-1.l .]
+ set script [makeFile "#include \"$mydir/f-1.5-1.l\"" f-1.5-scr.l .]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $script
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+ removeFile $script
+ removeDirectory $mydir
+ removeDirectory $incdir
+} -result {good}
+
+# Create files with the same names in $BIN/include and in
+# the cwd of the L script, and ensure that #include "file.l" includes
+# the one in the cwd, where $BIN is where the running tclsh lives.
+test include-1.6 {test include "file" search path} -setup {
+ set incdir [makeDirectory include [file dirname [interpreter]]]
+ set fname1 [makeFile {puts("bad");} f-1.6-1.l $incdir]
+ set fname2 [makeFile {puts("good");} f-1.6-1.l .]
+ set script [makeFile "#include \"f-1.6-1.l\"" f-1.6-scr.l .]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $script
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $script
+ removeDirectory $incdir
+} -result {good}
+
+# Create files with the same names in $BIN/include and in
+# the cwd of the L script, and ensure that #include <file.l> includes
+# the one in $BIN, where $BIN is where the running tclsh lives.
+test include-1.7 {test include <file> search path 1} -setup {
+ set incdir [makeDirectory include [file dirname [interpreter]]]
+ set fname1 [makeFile {puts("good");} f-1.7-1.l $incdir]
+ set fname2 [makeFile {puts("bad");} f-1.7-1.l .]
+ set script [makeFile "#include <f-1.7-1.l>" f-1.7-scr.l .]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $script
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $script
+ removeDirectory $incdir
+} -result {good}
+
+# Ensure that #include <file.l> finds file.l in $BIN/include,
+# where $BIN is where the running tclsh lives.
+test include-1.8 {test include <file> search path 1} -setup {
+ set incdir [makeDirectory include [file dirname [interpreter]]]
+ set fname1 [makeFile {puts("good");} f-1.8-1.l $incdir]
+ set script [makeFile "#include <f-1.8-1.l>" f-1.8-scr.l .]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] $script
+} -cleanup {
+ removeFile $fname1
+ removeFile $script
+ removeDirectory $incdir
+} -result {good}
+
+test include-2.1 {nested include files almost nested too deeply} -setup {
+ set fname1 [makeFile {#include "f-1.2.l"} f-1.1.l [file dirname [info script]]]
+ set fname2 [makeFile {#include "f-1.3.l"} f-1.2.l .]
+ set fname3 [makeFile {#include "f-1.4.l"} f-1.3.l .]
+ set fname4 [makeFile {#include "f-1.5.l"} f-1.4.l .]
+ set fname5 [makeFile {#include "f-1.6.l"} f-1.5.l .]
+ set fname6 [makeFile {#include "f-1.7.l"} f-1.6.l .]
+ set fname7 [makeFile {#include "f-1.8.l"} f-1.7.l .]
+ set fname8 [makeFile {#include "f-1.9.l"} f-1.8.l .]
+ set fname9 [makeFile {#include "f-1.10.l"} f-1.9.l .]
+ set fname10 [makeFile {#include "f-1.11.l"} f-1.10.l .]
+ set fname11 [makeFile {printf("ok");} f-1.11.l .]
+} -body {
+#lang L --line=1
+#include "f-1.1.l"
+} -output {ok}
+
+test include-2.2 {nested include files nested too deeply} -setup {
+ set fname1 [makeFile {#include "f-2.2.l"} f-2.1.l [file dirname [info script]]]
+ set fname2 [makeFile {#include "f-2.3.l"} f-2.2.l .]
+ set fname3 [makeFile {#include "f-2.4.l"} f-2.3.l .]
+ set fname4 [makeFile {#include "f-2.5.l"} f-2.4.l .]
+ set fname5 [makeFile {#include "f-2.6.l"} f-2.5.l .]
+ set fname6 [makeFile {#include "f-2.7.l"} f-2.6.l .]
+ set fname7 [makeFile {#include "f-2.8.l"} f-2.7.l .]
+ set fname8 [makeFile {#include "f-2.9.l"} f-2.8.l .]
+ set fname9 [makeFile {#include "f-2.10.l"} f-2.9.l .]
+ set fname10 [makeFile {#include "f-2.11.l"} f-2.10.l .]
+ set fname11 [makeFile {#include "f-2.12.l"} f-2.11.l .]
+ set fname12 [makeFile {printf("ok");} f-2.12.l .]
+} -body {
+#lang L --line=1
+#include "f-2.1.l"
+} -returnCodes {error} -match regexp -result {f-2.11.l:1: L Error: include file nesting too deep -- aborting
+}
+
+# This test creates two slave interps that declare global symbols
+# with the same names as those declared in the master interp.
+# If the L global state is properly kept per-interp, there
+# should be no multiple-declaration errors.
+
+test interp-1 {test per-interp global state} -body {
+#lang L --line=1
+int interp_1_g;
+void interp_1_foo() {}
+
+#lang tcl
+interp create interp_1_1
+interp eval interp_1_1 {
+#lang L --line=1
+int interp_1_g;
+void interp_1_foo() {}
+}
+interp create interp_1_2
+interp eval interp_1_2 {
+#lang L --line=1
+int interp_1_g;
+void interp_1_foo() {}
+}
+interp delete interp_1_2
+interp delete interp_1_1
+} -output {}
+
+test split-1.0 {test split function} -body {
+#lang L --line=1
+void
+split_1_0()
+{
+ int m;
+ string s;
+ string r[];
+ widget w;
+
+ /* These are all white space. */
+ string allspace[] = {
+ "",
+ " ",
+ " ",
+ " ",
+ " ",
+ "\n",
+ "\t",
+ "\n\n" };
+
+ foreach (s in allspace) {
+ r = split(s);
+ if (defined(r[0])) printf("bad 1: '%s'\n", s);
+ }
+
+ /*
+ * A split followed by a join should give the string back.
+ */
+
+ s = "This is not a test. This is really not a test.";
+ r = split(s);
+ unless (s eq join(" ", r)) puts("bad 2.1");
+
+ s = "This:is:not:a:test.:This:is:really:not:a:test.";
+ r = split(/:/, s);
+ unless (s eq join(":", r)) puts("bad 2.3");
+
+ s = ":This:is:not:a:test.:This:is:really:not:a:test.";
+ r = split(/:/, s);
+ unless (s eq join(":", r)) puts("bad 2.4");
+
+ /*
+ * A split with no regexp should split on white space but
+ * return no null field for any initial white space.
+ * A split on / / can return initial null fields however.
+ */
+
+ r = split(" has one");
+ unless ((r[0] eq "has") && (r[1] eq "one")) puts("bad 3.1");
+ unless (length(r) == 2) puts("bad 3.2");
+
+ r = split(/ /, "has none");
+ unless ((r[0] eq "has") && (r[1] eq "none")) puts("bad 3.3");
+ unless (length(r) == 2) puts("bad 3.4");
+
+ r = split(/ /, " has one");
+ unless ((r[0] eq "") && (r[1] eq "has") &&
+ (r[2] eq "one")) puts("bad 3.5");
+ unless (length(r) == 3) puts("bad 3.6");
+
+ /* Trailing white space never produces a null field. */
+
+ r = split("trail ");
+ unless (r[0] eq "trail") puts("bad 4.1");
+ unless (length(r) == 1) puts("bad 4.2");
+
+ r = split(/ /, "trail ");
+ unless (r[0] eq "trail") puts("bad 4.3");
+ unless (length(r) == 1) puts("bad 4.4");
+
+ r = split(/ /, "trail ");
+ unless (r[0] eq "trail") puts("bad 4.5");
+ unless (length(r) == 1) puts("bad 4.6");
+
+ /*
+ * If all result fields are null, they are considered to be
+ * trailing and should not be returned.
+ */
+
+ r = split(/x/, "xxx");
+ unless (length(r) == 0) puts("bad 4.7");
+
+ r = split(/x/, "xxx");
+ unless (length(r) == 0) puts("bad 4.8");
+
+ r = split(/xx/, "xxxxxx");
+ unless (length(r) == 0) puts("bad 4.9");
+
+ r = split(/xx/, "xxxxxx");
+ unless (length(r) == 0) puts("bad 4.10");
+
+ r = split(/two/, "twotwotwo");
+ unless (length(r) == 0) puts("bad 4.11");
+
+ r = split(/two/, "twotwotwo");
+ unless (length(r) == 0) puts("bad 4.12");
+
+ /* Check split on a regexp. */
+
+ r = split(/[abc]/, "XaXbXcX");
+ unless ((r[0] eq "X") && (r[1] eq "X") && (r[2] eq "X") &&
+ (r[3] eq "X")) {
+ puts("bad 5.3");
+ }
+ unless (length(r) == 4) puts("bad 5.4");
+
+ r = split(/[abc]/, "XaaXbXcX");
+ unless ((r[0] eq "X") && (r[1] eq "") && (r[2] eq "X") &&
+ (r[3] eq "X") && (r[4] eq "X")) {
+ puts("bad 5.5");
+ }
+ unless (length(r) == 5) puts("bad 5.6");
+
+ r = split(/xx/, "xxxyxx");
+ unless ((r[0] eq "") && (r[1] eq "xy")) {
+ puts("bad 5.11");
+ }
+ unless (length(r) == 2) puts("bad 5.12");
+
+ /* A match at the end never produces a trailing null field. */
+
+ r = split(/d/, "abcd");
+ unless (r[0] eq "abc") puts("bad 5.15");
+ unless (length(r) == 1) puts("bad 5.16");
+
+ r = split(/def/, "abcdef");
+ unless (r[0] eq "abc") puts("bad 5.17");
+ unless (length(r) == 1) puts("bad 5.18");
+
+ /* A match on the first char always produces a null field. */
+
+ r = split(/a/, "abcd");
+ unless ((r[0] eq "") && (r[1] eq "bcd")) puts("bad 5.19");
+ unless (length(r) == 2) puts("bad 5.20");
+
+ /* Test interpolated regexp. */
+
+ s = "abc";
+ r = split(/[${s}]/, "XaXbXcX");
+ unless ((r[0] eq "X") && (r[1] eq "X") && (r[2] eq "X") &&
+ (r[3] eq "X")) {
+ puts("bad 6.1");
+ }
+ unless (length(r) == 4) puts("bad 6.2");
+
+ /* Test limits, regexp match. */
+
+ r = split(/ /, "1 2 3 4", 4);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3") &&
+ (r[3] eq "4")) {
+ puts("bad 7.17");
+ }
+ unless (length(r) == 4) puts("bad 7.18");
+
+ r = split(/ /, "1 2 3 4", 3);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3 4")) {
+ puts("bad 7.19");
+ }
+ unless (length(r) == 3) puts("bad 7.20");
+
+ r = split(/ /, "1 2 3 4", 2);
+ unless ((r[0] eq "1") && (r[1] eq "2 3 4")) puts("bad 7.21");
+ unless (length(r) == 2) puts("bad 7.22");
+
+ r = split(/ /, "1 2 3 4", 1);
+ unless (r[0] eq "1 2 3 4") puts("bad 7.23");
+ unless (length(r) == 1) puts("bad 7.24");
+
+ r = split(/ /, "1 2 3 4", 0);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3") &&
+ (r[3] eq "4")) {
+ puts("bad 7.25");
+ }
+ unless (length(r) == 4) puts("bad 7.26");
+
+ r = split(/ /, "1 2 3 4", -1);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3") &&
+ (r[3] eq "4")) {
+ puts("bad 7.27");
+ }
+ unless (length(r) == 4) puts("bad 7.28");
+
+ /* Test limits, multi-char match. */
+
+ r = split(/aa/, "1aa2aa3aa4", 5);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3") &&
+ (r[3] eq "4")) {
+ puts("bad 7.30");
+ }
+ unless (length(r) == 4) puts("bad 7.31");
+
+ r = split(/aa/, "1aa2aa3aa4", 4);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3") &&
+ (r[3] eq "4")) {
+ puts("bad 7.32");
+ }
+ unless (length(r) == 4) puts("bad 7.33");
+
+ r = split(/aa/, "1aa2aa3aa4", 3);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3aa4")) {
+ puts("bad 7.34");
+ }
+ unless (length(r) == 3) puts("bad 7.35");
+
+ r = split(/aa/, "1aa2aa3aa4", 2);
+ unless ((r[0] eq "1") && (r[1] eq "2aa3aa4")) puts("bad 7.36");
+ unless (length(r) == 2) puts("bad 7.37");
+
+ r = split(/aa/, "1aa2aa3aa4", 1);
+ unless (r[0] eq "1aa2aa3aa4") puts("bad 7.38");
+ unless (length(r) == 1) puts("bad 7.39");
+
+ r = split(/aa/, "1aa2aa3aa4", 0);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3") &&
+ (r[3] eq "4")) {
+ puts("bad 7.40");
+ }
+ unless (length(r) == 4) puts("bad 7.41");
+
+ r = split(/aa/, "1aa2aa3aa4", -1);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3") &&
+ (r[3] eq "4")) {
+ puts("bad 7.42");
+ }
+ unless (length(r) == 4) puts("bad 7.43");
+
+ /* Test that an escape of the regexp delimeter works. */
+
+ r = split(/\//, "/this/is/a/pathname");
+ unless ((r[0] eq "") && (r[1] eq "this") && (r[2] eq "is") &&
+ (r[3] eq "a") && (r[4] eq "pathname")) {
+ puts("bad 8.1");
+ }
+ unless (length(r) == 5) puts("bad 8.2");
+
+ /* Ensure third arg is not parsed as a regexp. */
+
+ m = 3;
+ r = split(/ /, "1 2 3 4", m);
+ unless ((r[0] eq "1") && (r[1] eq "2") && (r[2] eq "3 4")) {
+ puts("bad 9.7");
+ }
+ unless (length(r) == 3) puts("bad 9.8");
+
+ /* Split on a multi-character delimeter. */
+
+ r = split(/two/, "onetwothreetwofourtwo");
+ unless ((r[0] eq "one") && (r[1] eq "three") && (r[2] eq "four")) {
+ puts("bad 10.7");
+ }
+ unless (length(r) == 3) puts("bad 10.8");
+
+ r = split(/two/, "twoonetwo");
+ unless ((r[0] eq "") && (r[1] eq "one")) {
+ puts("bad 10.9");
+ }
+ unless (length(r) == 2) puts("bad 10.10");
+
+ r = split(/two/, "nomatches");
+ unless (r[0] eq "nomatches") {
+ puts("bad 10.11");
+ }
+ unless (length(r) == 1) puts("bad 10.12");
+
+ /* Split on an empty regexp. */
+
+ r = split(//, "abc");
+ unless ((r[0] eq "a") && (r[1] eq "b") && (r[2] eq "c")) {
+ puts("bad 12.1");
+ }
+ unless (length(r) == 3) puts("bad 12.2");
+
+ /* Split on a widget should work. */
+
+ w = "axbxc";
+ r = split(/x/, w);
+ unless ((r[0] eq "a") && (r[1] eq "b") && (r[2] eq "c")) {
+ puts("bad 13.1");
+ }
+ unless (length(r) == 3) puts("bad 13.2");
+
+ /*
+ * Check splitting on a regexp w/trimming leading null fields
+ * from the result.
+ */
+
+ r = split(/ /t, " A B");
+ unless ((r[0] eq "A") && (r[1] eq "B")) puts("bad 14.1");
+ unless (length(r) == 2) puts("bad 14.2");
+
+ r = split(/ /t, " A B");
+ unless ((r[0] eq "A") && (r[1] eq "B")) puts("bad 14.3");
+ unless (length(r) == 2) puts("bad 14.4");
+
+ r = split(/ /t, " A B ");
+ unless ((r[0] eq "A") && (r[1] eq "") && (r[2] eq "B")) puts("bad 14.5");
+ unless (length(r) == 3) puts("bad 14.6");
+}
+split_1_0();
+} -output {}
+
+test split-1.1 {test split regexp alternate delim syntax} -body {
+#lang L
+void split_1_1()
+{
+ string m, mm, mvar, r[], re;
+
+ r = split(m|\n|, "l1\nl2\nl3\n");
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 1.1");
+
+ r = split(m:\n:, "l1\nl2\nl3\n");
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 1.2");
+
+ r = split(m,\n,, "l1\nl2\nl3\n");
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 1.3");
+
+ r = split(m"\n", "l1\nl2\nl3\n");
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 1.3.1");
+
+ r = split(m!\n!, "l1\nl2\nl3\n");
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 1.3.2");
+
+ /* Test some interpolations inside the regexp. */
+
+ re = '\n';
+ r = split(m|${re}|, "l1\nl2\nl3\n");
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 1.4");
+
+ re = '\n';
+ r = split(m$${re}$, "l1\nl2\nl3\n");
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 1.5");
+
+ re = '\n';
+ r = split(m{${re}}, "l1\nl2\nl3\n");
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 1.6");
+
+ re = "y";
+ r = split(m|x${re}|, "axybxyc");
+ unless (eq(r, {"a","b","c"})) puts("bad 1.8");
+
+ re = "x";
+ r = split(m|${re}y|, "axybxyc");
+ unless (eq(r, {"a","b","c"})) puts("bad 1.9");
+
+ re = "y";
+ r = split(m|x${re}z|, "axyzbxyzc");
+ unless (eq(r, {"a","b","c"})) puts("bad 1.10");
+
+ /* Test regexp modifiers. */
+
+ r = split(m|x|, "xaxbXcXdx");
+ unless (eq(r, {"","a","bXcXd"})) puts("bad 2.1 ${r}");
+
+ r = split(m|x|t, "xaxbXcXdx");
+ unless (eq(r, {"a","bXcXd"})) puts("bad 2.2 ${r}");
+
+ r = split(m|x|i, "xaxbXcXdx");
+ unless (eq(r, {"","a","b","c","d"})) puts("bad 2.3 ${r}");
+
+ r = split(m|x|it, "xaxbXcXdx");
+ unless (eq(r, {"a","b","c","d"})) puts("bad 2.4 ${r}");
+
+ r = split(m|x|ti, "xaxbXcXdx");
+ unless (eq(r, {"a","b","c","d"})) puts("bad 2.5 ${r}");
+
+ /*
+ * Test splitting on a variable named "m" or whose name begins
+ * with "m".
+ */
+
+ m = "l1\nl2\nl3\n";
+ r = split(m);
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 3.1");
+
+ mm = "l1\nl2\nl3\n";
+ r = split(mm);
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 3.2");
+
+ mvar = "l1\nl2\nl3\n";
+ r = split(mvar);
+ unless (eq(r, {"l1","l2","l3"})) puts("bad 3.3");
+}
+split_1_1();
+} -output {}
+
+test split-2 {test split errors} -body {
+#lang L --line=1
+void split_2()
+{
+ split(/re/g, "bad");
+ split(/re/ig, "bad");
+}
+} -returnCodes error -match regexp -result {.*3: L Error: illegal regular expression modifier
+.*4: L Error: illegal regular expression modifier
+}
+
+test split-3 {test split errors 2} -body {
+#lang L --line=1
+void split_3()
+{
+ /*
+ * This is a syntax error because the grammar special-cases
+ * split() because the 1st arg can be a regexp or a string,
+ * and does not allow no args.
+ */
+ split();
+}
+} -returnCodes error -match regexp -result {.*8: L Error: syntax error, unexpected \)
+}
+
+test split-4 {test split errors 3} -body {
+#lang L --line=1
+void split_4()
+{
+ split(/delim/, "str", 0, 0);
+ split(0);
+ split(/delim/, "str", "bad");
+ split("bad delim", "str");
+ split("bad delim", "str", 0);
+}
+} -returnCodes error -match regexp -result {.*3: L Error: too many args to split
+.*4: L Error: expression to split must be string
+.*5: L Error: third arg to split must be integer
+.*6: L Error: split delimiter must be a regular expression
+.*7: L Error: split delimiter must be a regular expression
+}
+
+test split-5 {test split errors 4 -- bad regexp} -body {
+#lang L --line=1
+void split_5()
+{
+ split(/+/, "str");
+}
+split_5();
+} -returnCodes error -result {couldn't compile pcre pattern: nothing to repeat}
+#'
+
+test split-8 {test m() as arg to split} -setup {
+ makeFile {
+ /*
+ * Put this in its own file to avoid polluting
+ * the global name space with a function m().
+ */
+ string m(...args)
+ {
+ string ret = "", s;
+
+ foreach (s in args) ret .= s;
+ return (ret);
+ }
+ void main()
+ {
+ string s[];
+
+ s = split(m());
+ if (length(s)) puts("bad 1");
+
+ s = split(m("x"));
+ unless (eq(s, {"x"})) puts("bad 2");
+
+ s = split(m("x"," ","y"));
+ unless (eq(s, {"x","y"})) puts("bad 3");
+ }
+ } split-8.l
+} -body {
+#lang L
+void split_8()
+{
+ int ret;
+ string tclsh = interpreter();
+ string out, err;
+
+ ret = system({tclsh, "split-8.l"}, undef, &out, &err);
+ unless (ret == 0) puts("bad 1.1");
+ if (out) puts("bad 1.2: ${out}");
+ if (err) puts("bad 1.3: ${err}");
+}
+split_8();
+} -output {}
+
+test consts-1.0 {test constants function} -body {
+#lang L --line=1
+void
+constants_1_0()
+{
+ int i;
+ float f;
+
+ /*
+ * Adding 0 to these forces Tcl to shimmer them to a numeric type.
+ */
+
+ i = 0 + 0;
+ unless ((tcl)i eq "0") puts("bad 1.1");
+ i = 00 + 0;
+ unless ((tcl)i eq "0") puts("bad 1.2");
+ i = 000 + 0;
+ unless ((tcl)i eq "0") puts("bad 1.3");
+ i = 1234 + 0;
+ unless ((tcl)i eq "1234") puts("bad 1.4");
+ i = 01235 + 0;
+ unless ((tcl)i eq "1235") puts("bad 1.5");
+ i = 001236 + 0;
+ unless ((tcl)i eq "1236") puts("bad 1.6");
+ i = 10000000000 + 0; // >32 bits
+ unless ((tcl)i eq "10000000000") puts("bad 1.7");
+ i = 36893488147419103232 + 0; // >64 bits
+ unless ((tcl)i eq "36893488147419103232") puts("bad 1.8");
+ i = 314159265358979323846264338327950288 + 1; // even bigger
+ unless ((tcl)i eq "314159265358979323846264338327950289") {
+ puts("bad 1.9");
+ }
+ i = 111111111111111111111111111111 + 222222222222222222222222222222;
+ unless ((tcl)i eq "333333333333333333333333333333") {
+ puts("bad 1.10");
+ }
+
+ i = 0xdeadbeef + 0;
+ unless ((tcl)i eq "3735928559") puts("bad 2.1");
+ i = 0xdeadbeefbadb0bad + 0; // 64 bits
+ unless ((tcl)i eq "16045690984232324013") puts("bad 2.2");
+ i = 0xdeadbeefbadb0badb0 + 0; // >64 bits
+ unless ((tcl)i eq "4107696891963474947504") puts("bad 2.3");
+
+ i = 0o755 + 0;
+ unless ((tcl)i eq "493") puts("bad 3.1");
+ i = 0o0756 + 0;
+ unless ((tcl)i eq "494") puts("bad 3.2");
+
+ f = 1234.5678 + 0.0;
+ unless (sprintf("%.4f", f) eq "1234.5678") puts("bad 4.1");
+}
+constants_1_0();
+} -output {}
+
+# These tests check the L compiler's mapping between the source-file
+# offsets of each "command" and the tcl bytecodes generated for it.
+# Generally speaking, a command is a statement or expression, although
+# some statements don't generate a mapping per-se (like "if"
+# statements). This is tested by generating a bytecode disassembly
+# and checking that the text of the commands were identified properly
+# in various syntactic contexts. This seems like the only way to get
+# at the mappings easily for testing.
+
+test src-mappings-1 {test bytecode <-> source-file-offset mappings 1} -body {
+#lang L --line=1 -nowarn
+struct sm1 {
+ int i;
+};
+void
+src_mappings_1()
+{
+ /*
+ * This test checks the mappings for declarations.
+ * Note: avoid tabs in the source to make the test regexp clearer.
+ */
+
+ int i1;
+ int i2 = 2;
+ int i3, i4;
+ int i5, i6 = 6, i7;
+ string s1;
+ string s2 = "str2";
+ string s3, s4;
+ string s5, s6 = "str6", s7;
+ float f1;
+ float f2 = 2.0;
+ float f3, f4;
+ float f5, f6 = 6.0, f7;
+ /* The hash ones test typedef names (hash is a typedef). */
+ hash h1;
+ hash h2 = {2=>2};
+ hash h3, h4;
+ hash h5, h6 = {6=>6}, h7;
+ struct sm1 st1;
+ struct sm1 st2 = {2};
+ struct sm1 st3, st4;
+ struct sm1 st5, st6 = {6}, st7;
+ poly p1;
+ poly p2 = 2;
+ poly p3, p4;
+ poly p5, p6 = 6, p7;
+ widget w1;
+ widget w2 = "w2";
+ widget w3, w4;
+ widget w5, w6 = "w6", w7;
+ int ai1[];
+ int ai2[2];
+ int ai3[] = {3};
+ int ai4[], ai5[5];
+ int ai6[], ai7[] = {7}, ai8[];
+ string as1[];
+ string as2[2];
+ string as3[] = {"3"};
+ string as4[], as5[5];
+ string as6[], as7[] = {"7"}, as8[];
+ float af1[];
+ float af2[2];
+ float af3[] = {3.0};
+ float af4[], af5[5];
+ float af6[], af7[] = {7.0}, af8[];
+ hash ah1[];
+ hash ah2[2];
+ hash ah3[], ah4[4], ah5[];
+ struct s ast1[];
+ struct s ast2[2];
+ struct s ast3[], ast4[4], ast5[];
+
+ puts(::tcl::unsupported::disassemble("proc", "src_mappings_1"));
+ return;
+}
+#lang tcl
+src_mappings_1
+} -match regexp -output {.*Command \d+: "i1"
+.*Command \d+: "i2 = 2"
+.*Command \d+: "i3"
+.*Command \d+: "i4"
+.*Command \d+: "i5"
+.*Command \d+: "i6 = 6"
+.*Command \d+: "i7"
+.*Command \d+: "s1"
+.*Command \d+: "s2 = \\"str2\\""
+.*Command \d+: "s3"
+.*Command \d+: "s4"
+.*Command \d+: "s5"
+.*Command \d+: "s6 = \\"str6\\""
+.*Command \d+: "s7"
+.*Command \d+: "f1"
+.*Command \d+: "f2 = 2.0"
+.*Command \d+: "f3"
+.*Command \d+: "f4"
+.*Command \d+: "f5"
+.*Command \d+: "f6 = 6.0"
+.*Command \d+: "f7"
+.*Command \d+: "h1"
+.*Command \d+: "h2 = \{2=>2\}"
+.*Command \d+: "h3"
+.*Command \d+: "h4"
+.*Command \d+: "h5"
+.*Command \d+: "h6 = \{6=>6\}"
+.*Command \d+: "h7"
+.*Command \d+: "st1"
+.*Command \d+: "st2 = \{2\}"
+.*Command \d+: "st3"
+.*Command \d+: "st4"
+.*Command \d+: "st5"
+.*Command \d+: "st6 = \{6\}"
+.*Command \d+: "st7"
+.*Command \d+: "p1"
+.*Command \d+: "p2 = 2"
+.*Command \d+: "p3"
+.*Command \d+: "p4"
+.*Command \d+: "p5"
+.*Command \d+: "p6 = 6"
+.*Command \d+: "p7"
+.*Command \d+: "w1"
+.*Command \d+: "w2 = \\"w2\\""
+.*Command \d+: "w3"
+.*Command \d+: "w4"
+.*Command \d+: "w5"
+.*Command \d+: "w6 = \\"w6\\""
+.*Command \d+: "w7"
+.*Command \d+: "ai1\[\]"
+.*Command \d+: "ai2\[2\]"
+.*Command \d+: "ai3\[\] = \{3\}"
+.*Command \d+: "ai4\[\]"
+.*Command \d+: "ai5\[5\]"
+.*Command \d+: "ai6\[\]"
+.*Command \d+: "ai7\[\] = \{7\}"
+.*Command \d+: "ai8\[\]"
+.*Command \d+: "as1\[\]"
+.*Command \d+: "as2\[2\]"
+.*Command \d+: "as3\[\] = \{\\"3\\"\}"
+.*Command \d+: "as4\[\]"
+.*Command \d+: "as5\[5\]"
+.*Command \d+: "as6\[\]"
+.*Command \d+: "as7\[\] = \{\\"7\\"\}"
+.*Command \d+: "as8\[\]"
+.*Command \d+: "af1\[\]"
+.*Command \d+: "af2\[2\]"
+.*Command \d+: "af3\[\] = \{3.0\}"
+.*Command \d+: "af4\[\]"
+.*Command \d+: "af5\[5\]"
+.*Command \d+: "af6\[\]"
+.*Command \d+: "af7\[\] = \{7.0\}"
+.*Command \d+: "af8\[\]"
+.*Command \d+: "ah1\[\]"
+.*Command \d+: "ah2\[2\]"
+.*Command \d+: "ah3\[\]"
+.*Command \d+: "ah4\[4\]"
+.*Command \d+: "ah5\[\]"
+.*Command \d+: "ast1\[\]"
+.*Command \d+: "ast2\[2\]"
+.*Command \d+: "ast3\[\]"
+.*Command \d+: "ast4\[4\]"
+.*Command \d+: "ast5\[\]"
+}
+
+test src-mappings-2 {test bytecode <-> source-file-offset mappings 2} -body {
+#lang L --line=1 -nowarn
+int f0() { return (0); }
+int f1(int i) { return (1); }
+int f2(int i, int j) { return (2); }
+int f3(string opt, int i) {}
+void
+src_mappings_2()
+{
+ /*
+ * This test checks the mappings for expressions.
+ * Note: avoid tabs in the source to make the test regexp clearer.
+ */
+
+ int i, j;
+ int i1 = 1+2;
+ int i2 = i1+2*3;
+ int i3, i4, i5;
+ string s, t;
+ float f;
+ int ai[];
+ int aii[][];
+ int ah{int};
+ int ahh{int}{int};
+
+ puts(::tcl::unsupported::disassemble("proc", "src_mappings_2"));
+ return;
+
+ /* Check assignments. */
+ i1 = 1;
+ f = 3.14;
+ s = "str";
+
+ /* Check array and hash subscripts. */
+ i = ai[i1 - i2 - i3];
+ i = aii[i1][i2];
+ i = ah{i3 - i4};
+ i = ahh{i3}{i4 - i5};
+
+ /* Check that each sub-expression has a mapping. */
+ i3 = 3;
+ i4 = 4 + 3;
+ i5 = i3 + i4 * i5 - 5;
+
+ /* Check parameters. */
+ f0();
+ f1(i1);
+ f2(i1, i2);
+ f2(i1, i2 + f1(2));
+ f3(opt: i3); // try this b/c at one point we were injecting an extra :
+
+ /* Check that each binary and unary operator gets a mapping. */
+ (tcl)i;
+ (string)i;
+ (widget)i;
+ (float)i;
+ !i;
+ ~i;
+ +i;
+ -i;
+ &i;
+ defined(i);
+ i = j;
+ i += j;
+ i -= j;
+ i *= j;
+ i /= j;
+ i %= j;
+ i &= j;
+ i |= j;
+ i <<= j;
+ i >>= j;
+ i && j;
+ i || j;
+ s eq t;
+ s ne t;
+ s gt t;
+ s ge t;
+ s lt t;
+ s le t;
+ i == j;
+ i != j;
+ i > j;
+ i >= j;
+ i < j;
+ i <= j;
+ i + j;
+ i - j;
+ i * j;
+ i / j;
+ i % j;
+ i & j;
+ i | j;
+ i ^ j;
+ i << j;
+ i >> j;
+ s =~ /x/;
+ s =~ /x/i;
+ s =~ /x/g;
+ s =~ /x/ig;
+ s =~ m|x|;
+ s =~ m|x|i;
+ s =~ m|x|g;
+ s =~ m|x|ig;
+ s =~ s/x/y/;
+ s =~ s/x/y/i;
+ s =~ s/x/y/g;
+ s =~ s/x/y/ig;
+
+ /* Check ?: operator. */
+ i = (i>j)?(i-1):(j-1);
+
+ /* Check interpolated strings. */
+ s = "abc${t}";
+ s = "${t}xyz";
+ s = "abc${t}xyz";
+ s = "abc${"${t}"}xyz";
+}
+#lang tcl
+src_mappings_2
+} -match regexp -output {.*Command \d+: "1\+2"
+.*Command \d+: "i1 = 1\+2"
+.*Command \d+: "i1\+2\*3"
+.*Command \d+: "i2 = i1\+2\*3"
+.*Command \d+: "2\*3"
+.*Command \d+: "i1 = 1"
+.*Command \d+: "f = 3.14"
+.*Command \d+: "s = \\"str\\""
+.*Command \d+: "ai\[i1 - i2 - i3\]"
+.*Command \d+: "i = ai\[i1 - i2 - i3\]"
+.*Command \d+: "i1 - i2"
+.*Command \d+: "i1 - i2 - i3"
+.*Command \d+: "aii\[i1\]\[i2\]"
+.*Command \d+: "i = aii\[i1\]\[i2\]"
+.*Command \d+: "ah\{i3 - i4\}"
+.*Command \d+: "i = ah\{i3 - i4\}"
+.*Command \d+: "i3 - i4"
+.*Command \d+: "ahh\{i3\}\{i4 - i5\}"
+.*Command \d+: "i = ahh\{i3\}\{i4 - i5\}"
+.*Command \d+: "i4 - i5"
+.*Command \d+: "i3 = 3"
+.*Command \d+: "4 \+ 3"
+.*Command \d+: "i4 = 4 \+ 3"
+.*Command \d+: "i3 \+ i4 \* i5"
+.*Command \d+: "i3 \+ i4 \* i5 - 5"
+.*Command \d+: "i5 = i3 \+ i4 \* i5 - 5"
+.*Command \d+: "i4 \* i5"
+.*Command \d+: "f0\(\)"
+.*Command \d+: "f1\(i1\)"
+.*Command \d+: "f2\(i1, i2\)"
+.*Command \d+: "f2\(i1, i2 \+ f1\(2\)\)"
+.*Command \d+: "i2 \+ f1\(2\)"
+.*Command \d+: "f1\(2\)"
+.*Command \d+: "f3\(opt: i3\)"
+.*Command \d+: "\(tcl\)i"
+.*Command \d+: "\(string\)i"
+.*Command \d+: "\(widget\)i"
+.*Command \d+: "\(float\)i"
+.*Command \d+: "!i"
+.*Command \d+: "~i"
+.*Command \d+: "\+i"
+.*Command \d+: "-i"
+.*Command \d+: "&i"
+.*Command \d+: "defined\(i\)"
+.*Command \d+: "i = j"
+.*Command \d+: "i \+= j"
+.*Command \d+: "i -= j"
+.*Command \d+: "i \*= j"
+.*Command \d+: "i /= j"
+.*Command \d+: "i %= j"
+.*Command \d+: "i <<= j"
+.*Command \d+: "i >>= j"
+.*Command \d+: "i && j"
+.*Command \d+: "i \|\| j"
+.*Command \d+: "s eq t"
+.*Command \d+: "s ne t"
+.*Command \d+: "s gt t"
+.*Command \d+: "s ge t"
+.*Command \d+: "s lt t"
+.*Command \d+: "s le t"
+.*Command \d+: "i == j"
+.*Command \d+: "i != j"
+.*Command \d+: "i > j"
+.*Command \d+: "i >= j"
+.*Command \d+: "i < j"
+.*Command \d+: "i <= j"
+.*Command \d+: "i \+ j"
+.*Command \d+: "i - j"
+.*Command \d+: "i \* j"
+.*Command \d+: "i / j"
+.*Command \d+: "i % j"
+.*Command \d+: "i & j"
+.*Command \d+: "i \| j"
+.*Command \d+: "i \^ j"
+.*Command \d+: "i << j"
+.*Command \d+: "i >> j"
+.*Command \d+: "s =~ /x/"
+.*Command \d+: "s =~ /x/i"
+.*Command \d+: "s =~ /x/g"
+.*Command \d+: "s =~ /x/ig"
+.*Command \d+: "s =~ m\|x\|"
+.*Command \d+: "s =~ m\|x\|i"
+.*Command \d+: "s =~ m\|x\|g"
+.*Command \d+: "s =~ m\|x\|ig"
+.*Command \d+: "s =~ s/x/y/"
+.*Command \d+: "s =~ s/x/y/i"
+.*Command \d+: "s =~ s/x/y/g"
+.*Command \d+: "s =~ s/x/y/ig"
+.*Command \d+: "\(i>j\)\?\(i-1\):\(j-1\)"
+.*Command \d+: "\(i-1\)"
+.*Command \d+: "\(j-1\)"
+.*Command \d+: "\\"abc\$\{t\}\\""
+.*Command \d+: "s = \\"abc\$\{t\}\\""
+.*Command \d+: "\\"\$\{t\}xyz\\""
+.*Command \d+: "s = \\"\$\{t\}xyz\\""
+.*Command \d+: "\\"abc\$\{t\}xyz\\""
+.*Command \d+: "s = \\"abc\$\{t\}xyz\\""
+.*Command \d+: "\\"abc\$\{\\"\$\{t\}\\"\}xyz\\""
+.*Command \d+: "s = \\"abc\$\{\\"\$\{t\}\\"\}xyz\\""
+.*Command \d+: "\\"\$\{t\}\\""
+}
+
+test src-mappings-3 {test bytecode <-> source-file-offset mappings 3} -body {
+#lang L --line=1 -nowarn
+int
+f()
+{
+ return (0);
+}
+void
+fv()
+{
+ return;
+}
+int{int}
+fh()
+{
+ int h{int};
+ return (h);
+}
+int[]
+fa()
+{
+ int a[5];
+ return (a);
+}
+int
+src_mappings_3()
+{
+ /*
+ * This test checks the mappings for statements.
+ */
+
+ int i, j, k, v;
+ int a[5];
+ int h{int};
+
+ /* Disassemble fv() to get its "return" stmt w/no arg. */
+ puts(::tcl::unsupported::disassemble("proc", "fv"));
+ puts(::tcl::unsupported::disassemble("proc", "src_mappings_3"));
+ return(0);
+
+ while (0) f();
+ do f(); while (0);
+ for (i = 0; i < 10;) f();
+ for (i = 0; i < 10; ++i) f();
+ foreach (k => v in fh()) f();
+ foreach (i,j in fa()) f();
+ switch (0) {
+ case i: ++i; break;
+ default: break;
+ }
+ push (&a, f());
+ /* Check break and continue. */
+ do {
+ break;
+ continue;
+ } while (0);
+ goto L1;
+ L1:
+}
+#lang tcl
+src_mappings_3
+} -match regexp -output {.*Command \d+: "return"
+.*Command \d+: "return\(0\)"
+.*Command \d+: "while \(0\) f\(\);"
+.*Command \d+: "f\(\)"
+.*Command \d+: "do f\(\); while \(0\);"
+.*Command \d+: "i = 0"
+.*Command \d+: "for \(i = 0; i < 10;\) f\(\);"
+.*Command \d+: "i < 10"
+.*Command \d+: "f\(\)"
+.*Command \d+: "i = 0"
+.*Command \d+: "for \(i = 0; i < 10; \+\+i\) f\(\);"
+.*Command \d+: "i < 10"
+.*Command \d+: "f\(\)"
+.*Command \d+: "\+\+i"
+.*Command \d+: "fh\(\)"
+.*Command \d+: "foreach \(k => v in fh\(\)\) f\(\);"
+.*Command \d+: "f\(\)"
+.*Command \d+: "fa\(\)"
+.*Command \d+: "foreach \(i,j in fa\(\)\) f\(\);"
+.*Command \d+: "f\(\)"
+.*Command \d+: "switch \(0\) \{\\n\\t\\tcase i: \+\+i; break;\\n\\t\\tdefault: break;\\n\\t\}"
+.*Command \d+: "i"
+.*Command \d+: "default:"
+.*Command \d+: "push \(&a, f\(\)\)"
+.*Command \d+: "break"
+.*Command \d+: "continue"
+.*Command \d+: "goto L1;"
+}
+
+test src-mappings-4 {test bytecode <-> source-file-offset mappings with includes} -setup {
+ set fname1 [makeFile {
+void src_mappings_4_foo1()
+{
+ int v1 = 123;
+ while (0) {
+ puts(v1);
+ }
+}
+#include "foo-sm4-2.l"
+} foo-sm4-1.l [file dirname [info script]]]
+ set fname2 [makeFile {
+void src_mappings_4_foo2()
+{
+ int i, j;
+ i = j+1;
+}
+} foo-sm4-2.l .]
+} -body {
+#lang L --line=1
+#include "foo-sm4-1.l"
+void src_mappings_4()
+{
+ /*
+ * We don't need much for this test. If the source offsets are
+ * mis-aligned, it can be seen with even just one command.
+ */
+
+ int k, l;
+
+ puts("--foo1--");
+ puts(::tcl::unsupported::disassemble("proc", "src_mappings_4_foo1"));
+ puts("--foo2--");
+ puts(::tcl::unsupported::disassemble("proc", "src_mappings_4_foo2"));
+ puts("--main--");
+ puts(::tcl::unsupported::disassemble("proc", "src_mappings_4"));
+ return;
+
+ k = l+2;
+}
+src_mappings_4();
+} -match regexp -output {--foo1--
+.*Command \d+: "v1 = 123"
+.*Command \d+: "puts\(v1\)"
+.*--foo2--
+.*Command \d+: "i = j\+1"
+.*--main--
+.*Command \d+: "return"
+.*Command \d+: "k = l\+2"
+}
+
+test src-mappings-5 {test bytecode <-> source-file-offset mappings w/here docs} -body {
+#lang L --line=1 -nowarn
+void src_mappings_5()
+{
+ string s1 = <<END
+str1
+END
+ string s2 = <<'END'
+str2
+END
+
+ puts(::tcl::unsupported::disassemble("proc", "src_mappings_5"));
+}
+src_mappings_5();
+} -match regexp -output {.*Command \d+: "s1 = <<END\\nstr1\\nEND"
+.*Command \d+: "s2 = <<'END'\\nstr2\\nEND"
+}
+
+test src-mappings-6 {test bytecode <-> source-file-offset mapping for variable} -body {
+#lang L --line=1
+void src_mappings_6()
+{
+ string s = "";
+
+ if (s) s = "1";
+
+ puts(::tcl::unsupported::disassemble("proc", "src_mappings_6"));
+}
+src_mappings_6();
+} -match regexp -output {.*Command \d+: "s"
+}
+
+test function-1.0 {check function call rules} -body {
+#lang L --line=1
+void function_1_0_foo() { puts("foo"); }
+void function_1_0_f() { puts("f"); }
+void
+function_1_0()
+{
+ function_1_0_foo();
+ function_1_0_f();
+
+ /*
+ * Calling an undeclared function is not an error, we just get
+ * no arg type checking, so passing anything should be allowed.
+ */
+ if (0) {
+ string s, p;
+
+ not_defined1();
+ not_defined1(s);
+ not_defined1(s, p);
+ not_defined2(1, 2, 3, 4);
+ }
+}
+#lang tcl
+function_1_0
+} -output {foo
+f
+}
+
+test function-1.1 {check function call rules error cases} -body {
+#lang L --line=1
+int function_1_1_f1;
+int function_1_1_f1() { return (0); } // err -- already declared as variable
+int function_1_1_f2() { return (0); }
+int function_1_1_f2; // err -- already declared as function
+int function_1_1_f3() { return (0); }
+int function_1_1_f3() { return (0); } // err -- multiply declared function
+void
+function_1_1()
+{
+ int i;
+ float f;
+ int a[];
+ int h{int};
+ struct { int i,j; } st;
+
+ /* All illegal because the var isn't a string or poly. */
+ i();
+ f();
+ a();
+ h();
+ st();
+}
+#lang tcl
+function_1_1
+} -returnCodes {error} -match regexp -result {.*1: L Error: multiple declaration of global function_1_1_f1
+.*4: L Error: multiple declaration of global function_1_1_f2
+.*6: L Error: function function_1_1_f3 already declared
+.*:17: L Error: 'i' is declared but not as a function
+.*:18: L Error: 'f' is declared but not as a function
+.*:19: L Error: 'a' is declared but not as a function
+.*:20: L Error: 'h' is declared but not as a function
+.*:21: L Error: 'st' is declared but not as a function
+}
+
+test function-1.2 {check function prototypes} -body {
+#lang L --line=1 -nowarn
+int function_1_2_f1();
+int function_1_2_f1() { return (1); }
+
+int function_1_2_f2();
+int function_1_2_f2();
+int function_1_2_f2();
+int function_1_2_f2();
+int function_1_2_f2() { return (1); }
+
+int function_1_2_f3() { return (1); }
+int function_1_2_f3();
+
+string function_1_2_f4(int a, string b, float c, int d[], hash e);
+string function_1_2_f4(int a, string b, float c, int d[], hash e){ return (b); }
+
+string function_1_2_f5(int a, string b, float c, int d[], hash e){ return (b); }
+string function_1_2_f5(int a, string b, float c, int d[], hash e);
+
+void
+function_1_2()
+{
+ int a;
+ string s;
+ float c;
+ int d[];
+ hash e;
+
+ s = function_1_2_f4(a, "f4", c, d, e);
+ unless (s eq "f4") puts("bad 1");
+
+ s = function_1_2_f5(a, "f5", c, d, e);
+ unless (s eq "f5") puts("bad 2");
+
+ unless (function_1_2_f10(12) == 12) puts("bad 3");
+ unless (function_1_2_f11(13) == 13) puts("bad 4");
+ unless (function_1_2_f12(14) == 14) puts("bad 5");
+
+ /*
+ * These check that the right parameter-passing mode is
+ * in the calls to the functions declared later.
+ */
+
+ d = {1,2,3,4};
+ unless (function_1_2_sum_ref(&d) == 10) puts("bad 6.1");
+ unless (length(d) == 3) puts("bad 6.2");
+ unless ((d[0] == 9) && (d[1] == 10) && (d[2] == 11)) puts("bad 6.3");
+
+ d = {1,2,3,4};
+ unless (function_1_2_sum_cow(d) == 10) puts("bad 7.1");
+ unless (length(d) == 4) puts("bad 7.2");
+ unless ((d[0] == 1) && (d[1] == 2)) puts("bad 7.3");
+ unless ((d[2] == 3) && (d[3] == 4)) puts("bad 7.4");
+}
+function_1_2();
+int function_1_2_f10(int a) { return (a); }
+int function_1_2_f11(int a) { return (a); }
+int function_1_2_f11(int a);
+int function_1_2_f12(int a);
+int function_1_2_f12(int a) { return (a); }
+int function_1_2_sum_ref(int &a[])
+{
+ int i, sum = 0;
+
+ foreach (i in a) sum += i;
+ a = {9,10,11};
+ return (sum);
+}
+int function_1_2_sum_cow(int a[])
+{
+ int i, sum = 0;
+
+ foreach (i in a) sum += i;
+ a = {9,10,11};
+ return (sum);
+}
+} -output {}
+
+test function-1.3 {check function prototypes 2} -body {
+#lang L --line=1
+void
+function_1_3()
+{
+ /* Call some libl functions correctly. There should be no type errs. */
+
+ unless (streq("testing", "testing")) puts("bad 1");
+ unless (strlen("three") == 5) puts("bad 2");
+ unless (strneq("test", "testing", 4)) puts("bad 3");
+}
+#lang tcl
+function_1_3
+} -output {}
+
+test function-1.3.2 {check function prototypes 3} -body {
+#lang L --line=1
+/*
+ * Check that a void formal-parameter list is treated exactly like no
+ * parameters.
+ */
+void function_1_3_2_f1();
+void function_1_3_2_f2();
+void function_1_3_2_f3(void);
+void function_1_3_2_f4(void);
+void
+function_1_3_2()
+{
+ function_1_3_2_f1();
+ function_1_3_2_f2();
+ function_1_3_2_f3();
+ function_1_3_2_f4();
+}
+function_1_3_2();
+void function_1_3_2_f1() { puts("f1"); }
+void function_1_3_2_f2(void) { puts("f2"); }
+void function_1_3_2_f3() { puts("f3"); }
+void function_1_3_2_f4(void) { puts("f4"); }
+} -output {f1
+f2
+f3
+f4
+}
+
+test function-1.4 {check function prototype errors} -body {
+#lang L --line=1
+void
+function_1_4()
+{
+ /* Call a libl function with incorrect args. */
+
+ streq();
+ streq("a");
+ streq("a", 2);
+ streq("a", "b", 2);
+}
+} -returnCodes {error} -match regexp -result {.*6: L Error: not enough arguments for function streq
+.*7: L Error: not enough arguments for function streq
+.*8: L Error: parameter 2 has incompatible type
+.*9: L Error: too many arguments for function streq
+}
+
+test function-1.5 {check function prototype errors 2} -body {
+#lang L --line=1
+void function_1_5_f1();
+int function_1_5_f1() { return (0); }
+
+int function_1_5_f2() { return (0); }
+void function_1_5_f2();
+
+void function_1_5_f3(int a);
+void function_1_5_f3() { }
+
+void function_1_5_f4() { }
+void function_1_5_f4(int a);
+
+int function_1_5_f5(int a);
+void function_1_5_f5() { }
+
+void function_1_5_f6() { }
+int function_1_5_f6(int a);
+
+string function_1_5_f7(int a, string b, float c, int d[]);
+string function_1_5_f7(int a, string b, float c, int d[], hash e){ return (b); }
+
+string function_1_5_f8(string b, float c, int d[], hash e);
+string function_1_5_f8(int a, string b, float c, int d[], hash e){ return (b); }
+
+string function_1_5_f9(string b, float c, int d[], hash e);
+string function_1_5_f9(string b, ...rest){ return (b); }
+} -returnCodes {error} -match regexp -result {.*2: L Error: does not match other declaration of function_1_5_f1
+.*5: L Error: does not match other declaration of function_1_5_f2
+.*8: L Error: does not match other declaration of function_1_5_f3
+.*11: L Error: does not match other declaration of function_1_5_f4
+.*14: L Error: does not match other declaration of function_1_5_f5
+.*17: L Error: does not match other declaration of function_1_5_f6
+.*20: L Error: does not match other declaration of function_1_5_f7
+.*23: L Error: does not match other declaration of function_1_5_f8
+.*26: L Error: does not match other declaration of function_1_5_f9
+}
+
+test function-1.6 {check function prototype errors 3} -body {
+#lang L --line=1
+void function_1_6()
+{
+ /*
+ * Check that type checking is done to calls of functions
+ * declared later.
+ */
+
+ function_1_6_v(1);
+ function_1_6_i();
+ function_1_6_i("bad");
+}
+void function_1_6_v() {}
+void function_1_6_i(int i) { i = 0; }
+} -returnCodes {error} -match regexp -result {.*8: L Error: too many arguments for function function_1_6_v
+.*9: L Error: not enough arguments for function function_1_6_i
+.*10: L Error: parameter 1 has incompatible type
+}
+
+test function-2 {check call to undefined function warnings} -setup {
+ set file [makeFile {
+ void fn2_nobody();
+ void Fn2_*();
+ void main()
+ {
+ undeclared_call1();
+ undeclared_call2();
+ undeclared_call3();
+ fn2_nobody();
+ Undeclared1_too();
+ Undeclared2_hasargs(1,2,3);
+ Fn2_star();
+ }
+ } function2.l .]
+} -constraints {
+ exec
+} -body {
+ exec [interpreter] --warn-undefined-fns $file
+} -returnCodes {error} -match regexp -result {L Warning: function undeclared_call1 not defined
+L Warning: function undeclared_call2 not defined
+L Warning: function undeclared_call3 not defined
+L Warning: function fn2_nobody not defined
+L Warning: function undeclared1 not defined
+L Warning: function undeclared2 not defined
+L Warning: function Fn2_\* not defined
+}
+
+test function-2.1 {check _optional formal-parameter attribute} -body {
+#lang L --line=1
+string fn21_foo1(_optional string arg1)
+{
+ if (arg1) {
+ return (arg1);
+ } else {
+ return ("<undef>");
+ }
+}
+string fn21_foo2(string arg1, _optional string arg2)
+{
+ if (arg2) {
+ return (arg1 . arg2);
+ } else {
+ return (arg1 . "<undef>");
+ }
+}
+string fn21_foo3(string arg1, string arg2, _optional string arg3)
+{
+ if (arg3) {
+ return (arg1 . arg2 . arg3);
+ } else {
+ return (arg1 . arg2 . "<undef>");
+ }
+}
+void function_2_1()
+{
+ unless (fn21_foo1() eq "<undef>") puts("bad 1.1");
+ unless (fn21_foo1("one") eq "one") puts("bad 1.2");
+
+ unless (fn21_foo2("one") eq "one<undef>") puts("bad 2.1");
+ unless (fn21_foo2("one", "two") eq "onetwo") puts("bad 2.2");
+
+ unless (fn21_foo3("1","2") eq "12<undef>") puts("bad 3.1");
+ unless (fn21_foo3("1","2","3") eq "123") puts("bad 3.2");
+}
+function_2_1();
+} -output {}
+
+test function-2.2 {check _optional formal-parameter attribute errors} -body {
+#lang L --line=1 -nowarn
+void fn22_err1(_optional string arg1, _optional string arg2) {}
+void fn22_err2(_optional string arg1, string arg2) {}
+void fn22_err3(string arg0, _optional string arg1, string arg2) {}
+void fn22_err4(...args, _optional string arg1) {}
+void fn22_err5(_optional string arg1, ...args) {}
+} -returnCodes {error} -match regexp -result {.*1: L Error: _optional parameter must be last
+.*2: L Error: _optional parameter must be last
+.*3: L Error: _optional parameter must be last
+.*4: L Error: Rest parameter must be last
+.*5: L Error: _optional parameter must be last
+}
+
+test function-3 {check _attribute error} -body {
+#lang L --line=1
+void function3() _attribute (bad) {}
+} -returnCodes {error} -match regexp -result {.*1: L Error: illegal attribute 'bad'
+}
+
+test function-4 {check formal-parameter attribute inconsistency checking} -body {
+#lang L --line=1
+// Check with and without names for the formals in the proto.
+string function4a(string s);
+string function4a(_optional string s)
+{
+ return (s);
+}
+string function4b(_optional string s);
+string function4b(string s)
+{
+ return (s);
+}
+string function4c(string);
+string function4c(_optional string s)
+{
+ return (s);
+}
+string function4d(_optional string);
+string function4d(string s)
+{
+ return (s);
+}
+string function4e(string);
+string function4e(_mustbetype string s)
+{
+ return (s);
+}
+string function4f(_mustbetype string);
+string function4f(string s)
+{
+ return (s);
+}
+string function4g(_mustbetype string);
+string function4g(_optional string s)
+{
+ return (s);
+}
+} -returnCodes {error} -match regexp -result {.*3: L Error: does not match other declaration of function4a
+.*8: L Error: does not match other declaration of function4b
+.*13: L Error: does not match other declaration of function4c
+.*18: L Error: does not match other declaration of function4d
+.*23: L Error: does not match other declaration of function4e
+.*28: L Error: does not match other declaration of function4f
+.*33: L Error: does not match other declaration of function4g
+}
+
+test initializers-1 {check variable initializer error cases} -body {
+#lang L --line=1
+extern int g = 0;
+void initializers_1() {
+ /*
+ * Externs in local scopes are illegal as well as extern
+ * initializers, so this is error on two counts.
+ */
+ extern int l = 0;
+}
+} -returnCodes {error} -match regexp -result {.*1: L Error: extern initializers illegal
+.*7: L Error: extern.*
+}
+
+test initializers-2 {check variable initializers} -body {
+#lang L --line=1
+struct initializers_2_s1 {
+ int i;
+ int j, k;
+ string s;
+ string as[];
+ string hs{int};
+};
+struct initializers_2_s2 {
+ int i, j;
+};
+typedef struct initializers_2_s2 h_of_s2{int};
+
+void initializers_2()
+{
+ /*
+ * In addition to the initializers themselves, check various
+ * number of initializers per declaration.
+ */
+ int i;
+ int i1 = 11;
+ int i2 = 0, i3 = 33;
+ int i4 = 0, i5 = 55, i6 = 0;
+ int i7 = 0, i8 = 88, i9 = 99, i10 = 111;
+ string s = "s";
+ float f = 3.1, f2 = 3;
+ string ai[] = { "a", "b", "c" };
+ string hs{int} = { 1=>"one", 2=>"two", 3=>"three" };
+ struct initializers_2_s1 st = {
+ 1,
+ 2, 3,
+ "s",
+ { "x", "y", "z" },
+ { 3=>"t", 6=>"s" }, // note the trailing comma (legal)
+ };
+ string aempty[] = {};
+ h_of_s2 h2 = { 1 => {2,3}, 2 => {4,5} };
+
+ unless (i1 == 11) puts("bad 1");
+ unless (!i2 && !i4 && !i6 && !i7) puts("bad 2");
+ unless (i3 == 33) puts("bad 3");
+ unless (i5 == 55) puts("bad 4");
+ unless (i8 == 88) puts("bad 5");
+ unless (i9 == 99) puts("bad 6");
+ unless (i10 == 111) puts("bad 7");
+ unless (s eq "s") puts("bad 8");
+ unless (f == 3.1) puts("bad 9");
+ unless (f2 == 3) puts("bad 9.1");
+ unless ((ai[0] eq "a") && (ai[1] eq "b")) puts("bad 10");
+ unless ((ai[2] eq "c") && !defined(ai[3])) puts("bad 11");
+ i = 0;
+ foreach (s in ai) ++i;
+ unless (i == 3) puts("bad 12");
+ unless ((hs{1} eq "one") && (hs{2} eq "two")) puts("bad 13");
+ unless ((hs{3} eq "three")) puts("bad 14");
+ i = 0;
+ foreach (i1 in hs) ++i;
+ unless (i == 3) puts("bad 15");
+
+ unless ((st.i == 1) && (st.j == 2) && (st.k == 3)) puts("bad 16");
+ unless ((st.s eq "s") && (st.as[0] eq "x")) puts("bad 17");
+ unless ((st.as[1] eq "y") && (st.as[2] eq "z")) puts("bad 18");
+ i = 0;
+ foreach (s in st.as) ++i;
+ unless (i == 3) puts("bad 19");
+ unless ((st.hs{3} eq "t") && (st.hs{6} eq "s")) puts("bad 20");
+ i = 0;
+ foreach (i1 in st.hs) ++i;
+ unless (i == 2) puts("bad 21");
+
+ if (defined(aempty[0])) puts("bad 30");
+ unless ((h2{1}.i == 2) && (h2{1}.j == 3)) puts("bad 31");
+ unless ((h2{2}.i == 4) && (h2{2}.j == 5)) puts("bad 32");
+}
+#lang tcl
+initializers_2
+} -output {}
+
+test initializers-3 {check variable initializer type errors} -body {
+#lang L --line=1 -nowarn
+struct initializers_3_s1 {
+ int i;
+ int j, k;
+ string s;
+ string as[];
+ string hs{int};
+};
+
+void initializers_3()
+{
+ int i1 = 1.0;
+ int i2, i3 = "s";
+ int i4, i5 = {3}, i6;
+ string s = 3.1;
+ float f = "3.1";
+ string ai[] = {"a", 2, "c"};
+
+ struct initializers_2_s1 st = {
+ 1,
+ 2, // err -- omitted initializer for "k"
+ "s",
+ { "x", "y", "z" },
+ { 3=>"t", 6=>"s" }
+ };
+ string hs2{int} = { 1=>"one", 3 };
+}
+} -returnCodes {error} -match regexp -result {.*11: L Error: assignment of incompatible types
+.*12: L Error: assignment of incompatible types
+.*13: L Error: assignment of incompatible types
+.*14: L Error: assignment of incompatible types
+.*15: L Error: assignment of incompatible types
+.*16: L Error: assignment of incompatible types
+.*18: L Error: assignment of incompatible types
+.*25: L Error: cannot mix hash and non-hash elements
+}
+
+test initializers-4 {check expressions in variable initializers} -body {
+#lang L --line=1
+int init_4_g = 33;
+void initializers_4()
+{
+ /*
+ * Initializers are full-blown expressions, so they can contain
+ * variables etc.
+ */
+ int e1 = 11;
+ int e2 = e1*2;
+ int a[] = { init_4_g, init_4_g*2, e1, e2, 3 };
+
+ unless ((e1 == 11) && (e2 == 22)) puts("bad 1");
+ unless ((a[0] == 33) && (a[1] == 66) && (a[2] == 11) &&
+ (a[3] == 22) && (a[4] == 3)) puts("bad 2");
+ if (defined(a[5])) puts("bad 3");
+}
+#lang tcl
+initializers_4
+} -output {}
+
+test initializers-5 {check order of variable initializers} -body {
+#lang L --line=1
+void initializers_5()
+{
+ /*
+ * This checks the variable initializers are compiled
+ * top-to-bottom and left-to-right.
+ */
+ int i1 = 2, i2 = i1 * 7, i3 = i1 + i2;
+ int i4 = i3 * 10;
+
+ unless (i1 == 2) puts("bad 1");
+ unless (i2 == 14) puts("bad 2");
+ unless (i3 == 16) puts("bad 3");
+ unless (i4 == 160) puts("bad 4");
+}
+initializers_5();
+} -output {}
+
+test initializers-6 {check blank initial values} -body {
+#lang L --line=1
+void initializers_6()
+{
+ int i;
+ float f;
+ string s;
+ poly p;
+ string as[];
+ string hs{string};
+ struct s1 {
+ int i;
+ float f;
+ string s;
+ string sa[];
+ string hs{string};
+ } st;
+
+ if (defined(i)) puts("bad 1");
+ if (defined(f)) puts("bad 2");
+ if (defined(s)) puts("bad 3");
+ if (defined(p)) puts("bad 4");
+ if (defined(as)) puts("bad 5");
+ if (defined(hs)) puts("bad 6");
+ if (defined(st)) puts("bad 7");
+}
+initializers_6();
+} -output {}
+
+test composite-1 {check composite values in expressions 1} -body {
+#lang L --line=1
+struct composite_1_s1 {
+ int i;
+ int j, k;
+ string s;
+ string as[];
+ string hs{int};
+};
+int composite_1_g = 33;
+void composite_1()
+{
+ /*
+ * These are taken from the initializer-* tests above but
+ * are used in the rhs of expressions instead of in initializers.
+ */
+
+ int i, i1;
+ int e1 = 11;
+ int e2 = e1*2;
+ string s;
+ int a[];
+ string ai[];
+ string hs{int};
+ struct composite_1_s1 st;
+ string aempty[];
+ h_of_s2 h2;
+
+ a = { composite_1_g, composite_1_g*2, e1, e2, 3 };
+
+ unless ((e1 == 11) && (e2 == 22)) puts("bad 1");
+ unless ((a[0] == 33) && (a[1] == 66) && (a[2] == 11) &&
+ (a[3] == 22) && (a[4] == 3)) puts("bad 2");
+ if (defined(a[5])) puts("bad 3");
+
+ ai = { "a", "b", "c" };
+ hs = { 1=>"one", 2=>"two", 3=>"three" };
+ st = {
+ 1,
+ 2, 3,
+ "s",
+ { "x", "y", "z" },
+ { 3=>"t", 6=>"s" }, // note the trailing comma (legal)
+ };
+ aempty = {};
+ h2 = { 1 => {2,3}, 2 => {4,5} };
+
+ unless ((ai[0] eq "a") && (ai[1] eq "b")) puts("bad 10");
+ unless ((ai[2] eq "c") && !defined(ai[3])) puts("bad 11");
+ i = 0;
+ foreach (s in ai) ++i;
+ unless (i == 3) puts("bad 12");
+ unless ((hs{1} eq "one") && (hs{2} eq "two")) puts("bad 13");
+ unless ((hs{3} eq "three")) puts("bad 14");
+ i = 0;
+ foreach (i1 in hs) ++i;
+ unless (i == 3) puts("bad 15");
+
+ unless ((st.i == 1) && (st.j == 2) && (st.k == 3)) puts("bad 16");
+ unless ((st.s eq "s") && (st.as[0] eq "x")) puts("bad 17");
+ unless ((st.as[1] eq "y") && (st.as[2] eq "z")) puts("bad 18");
+ i = 0;
+ foreach (s in st.as) ++i;
+ unless (i == 3) puts("bad 19");
+ unless ((st.hs{3} eq "t") && (st.hs{6} eq "s")) puts("bad 20");
+ i = 0;
+ foreach (i1 in st.hs) ++i;
+ unless (i == 2) puts("bad 21");
+
+ if (defined(aempty[0])) puts("bad 30");
+ unless ((h2{1}.i == 2) && (h2{1}.j == 3)) puts("bad 31");
+ unless ((h2{2}.i == 4) && (h2{2}.j == 5)) puts("bad 32");
+}
+#lang tcl
+composite_1
+} -output {}
+
+test composite-2 {check composite values in expressions 2} -body {
+#lang L --line=1
+string composite_2_join(string[] a)
+{
+ string s;
+ string ret = "";
+
+ foreach (s in a) ret = sprintf("%s%s", ret, s);
+ return (ret);
+}
+void composite_2()
+{
+ /*
+ * Try more operations with composite values.
+ */
+
+ int i;
+
+ unless (composite_2_join({"a","b","c"}) eq "abc") puts("bad 1");
+
+ for (i = 0; i < 5; ++i) {
+ unless ({0,1,2,3,4}[i] == i) printf("bad 2 %d\n", i);
+ }
+ if (defined({0,1,2,3,4}[5])) puts("bad 3");
+
+ unless ({1=>"one", 2=>"two", 3=>"three"}{1} eq "one") puts("bad 4");
+ unless ({1=>"one", 2=>"two", 3=>"three"}{2} eq "two") puts("bad 5");
+ unless ({1=>"one", 2=>"two", 3=>"three"}{3} eq "three") puts("bad 6");
+
+ unless (((struct { int i,j,k; }){1,2,3}).i == 1) puts("bad 10");
+ unless (((struct { int i,j,k; }){1,2,3}).j == 2) puts("bad 11");
+ unless (((struct { int i,j,k; }){1,2,3}).k == 3) puts("bad 12");
+
+ unless ({{1,2},{3,4},{4,5}}[1][0] == 3) puts("bad 20");
+}
+#lang tcl
+composite_2
+} -output {}
+
+test composite-2.2 {check hash of array of composite constants} -body {
+#lang L --line=1
+void composite_2_2()
+{
+ /*
+ * This checks that lists used as array constants need not all
+ * have the same number of elements to satisfy the type
+ * checker.
+ */
+
+ string h{string}[] = {
+ "k1" => { "1" },
+ "k2" => { "1", "2", "3" },
+ "k3" => { "1", "2" }
+ };
+
+ unless (length(h) == 3) puts("bad 1.1");
+ unless (length(h{"k1"}) == 1) puts("bad 1.2");
+ unless (length(h{"k2"}) == 3) puts("bad 1.3");
+ unless (length(h{"k3"}) == 2) puts("bad 1.4");
+ unless (join(" ", h{"k1"}) eq "1") puts("bad 1.5");
+ unless (join(" ", h{"k2"}) eq "1 2 3") puts("bad 1.6");
+ unless (join(" ", h{"k3"}) eq "1 2") puts("bad 1.7");
+}
+composite_2_2();
+} -output {}
+
+test composite-2.3 {check list type compatibility in assignment} -body {
+#lang L --line=1
+void composite_2_3()
+{
+ float af[];
+
+ /*
+ * This verifies that the type checker gets the compatibility
+ * test right when checking an array against a list type. The
+ * opposite, when you try to assign a list of ints and floats
+ * to an int array, is an error and is checked in a test
+ * below.
+ */
+ af = { 1.1, 2.2 };
+ af = { 1, 2.2 };
+ af = { 1.1, 2 };
+ af = { 1, 2 };
+}
+composite_2_3();
+} -output {}
+
+test composite-3 {check type errors with composite values} -body {
+#lang L --line=1 -nowarn
+void composite_3_as(string[] a) {}
+void composite_3_ai(int[] a) {}
+void composite_3_his(int{string} a) {}
+void composite_3_hsi(string{int} a) {}
+void composite_3_hss(string{string} a) {}
+void composite_3_hii(int{int} a) {}
+
+void composite_3()
+{
+ int i[];
+
+ composite_3_as({1,2,3});
+ composite_3_ai({"a","b","c"});
+ composite_3_his({1,2,3});
+ composite_3_his({1=>2,3=>4});
+ composite_3_hsi({1=>2,3=>4});
+ composite_3_hss({1=>2,3=>4});
+ composite_3_hii({"1"=>2,"3"=>4});
+
+ i = { 1.1 };
+ i = { 1, 2.2 };
+}
+} -returnCodes {error} -match regexp -result {.*12: L Error:.*incompatible type.*
+.*13: L Error:.*incompatible type.*
+.*14: L Error:.*incompatible type.*
+.*15: L Error:.*incompatible type.*
+.*16: L Error:.*incompatible type.*
+.*17: L Error:.*incompatible type.*
+.*18: L Error:.*incompatible type.*
+.*20: L Error:.*incompatible type.*
+.*21: L Error:.*incompatible type.*
+}
+
+test composite-4 {check composite l-values} -body {
+#lang L --line=1
+class composite_4
+{
+ public string c;
+ instance {
+ public string i;
+ }
+}
+void composite_4_main()
+{
+ string a, b, c;
+ string sa[];
+ composite_4 o1, o2, o3;
+
+ a = "bad";
+ { a } = { "one" };
+ unless (a eq "one") puts("bad 1.1");
+
+ a = b = "bad";
+ { a, b } = { "one", "two" };
+ unless ((a eq "one") && (b eq "two")) puts("bad 2.1");
+
+ a = b = c = "bad";
+ { a, b, c } = { "one", "two", "three" };
+ unless ((a eq "one") && (b eq "two") && (c eq "three")) puts("bad 3.1");
+
+ a = "bad";
+ { a } = {};
+ if (defined(a)) puts("bad 4.1");
+
+ a = b = "bad";
+ { a, b } = {};
+ if (defined(a) || defined(b)) puts("bad 5.1");
+
+ a = b = c = "bad";
+ { a, b, c } = {};
+ if (defined(a) || defined(b) || defined(c)) puts("bad 6.1");
+
+ a = b = c = "bad";
+ { a, b, c } = { "one" };
+ unless (a eq "one") puts("bad 7.1");
+ if (defined(b) || defined(c)) puts("bad 7.2");
+
+ a = b = c = "bad";
+ { a, b, c } = { "one", "two" };
+ unless ((a eq "one") && (b eq "two")) puts("bad 8.1");
+ if (defined(c)) puts("bad 8.2");
+
+ a = "bad";
+ { a } = { "one", "two" };
+ unless (a eq "one") puts("bad 9.1");
+
+ a = "bad";
+ { a } = { "one", "two", "three" };
+ unless (a eq "one") puts("bad 10.1");
+
+ a = b = "bad";
+ { a, b } = { "one", "two", "three" };
+ unless ((a eq "one") && (b eq "two")) puts("bad 11.1");
+
+ a = "bad";
+ { a, undef } = { "one", "two" };
+ unless (a eq "one") puts("bad 12.1");
+
+ a = "bad";
+ { a, undef } = { "one" };
+ unless (a eq "one") puts("bad 13.1");
+
+ a = "bad";
+ { a, undef, undef } = { "one" };
+ unless (a eq "one") puts("bad 14.1");
+
+ a = "bad";
+ { undef, a } = { "one", "two" };
+ unless (a eq "two") puts("bad 15.1");
+
+ a = "bad";
+ { undef, a } = { "one", "two", "three" };
+ unless (a eq "two") puts("bad 16.1");
+
+ a = "bad";
+ { undef, a, undef } = { "one", "two", "three" };
+ unless (a eq "two") puts("bad 17.1");
+
+ { undef } = {};
+ { undef, undef } = {};
+ { undef, undef, undef } = {};
+ { undef } = { undef };
+
+ { sa[0] } = { "one" };
+ unless (sa[0] eq "one") puts("bad 18.1");
+
+ { sa[0], sa[1] } = { "one", "two" };
+ unless ((sa[0] eq "one") && (sa[1] eq "two")) puts("bad 19.1");
+
+ { sa[0], sa[1], sa[3] } = { "one", "two", "four" };
+ unless ((sa[0] eq "one") && (sa[1] eq "two") && (sa[3] eq "four")) {
+ puts("bad 20.1");
+ }
+ if (defined(sa[2])) puts("bad 20.2");
+
+ o1 = composite_4_new();
+ o2 = composite_4_new();
+ o3 = composite_4_new();
+ { o1->i, o2->i, o3->i } = { "one", "two", "three" };
+ unless (o1->i eq "one") puts("bad 21.1");
+ unless (o2->i eq "two") puts("bad 21.2");
+ unless (o3->i eq "three") puts("bad 21.3");
+ { composite_4->c } = { "cvar" };
+ unless (composite_4->c eq "cvar") puts("bad 21.4");
+ composite_4_delete(o1);
+ composite_4_delete(o2);
+ composite_4_delete(o3);
+
+ a = b = "bad";
+ { a, b } = (poly){ "one", "two" };
+ unless ((a eq "one") && (b eq "two")) puts("bad 22.1");
+ a = b = "bad";
+ { a, b } = (poly){ "one", "two", "three" };
+ unless ((a eq "one") && (b eq "two")) puts("bad 22.2");
+ a = b = "bad";
+ { a } = (poly){ "one", "two", "three" };
+ unless ((a eq "one") && (b eq "bad")) puts("bad 22.3");
+}
+composite_4_main();
+} -output {}
+
+test composite-4.1 {check composite l-values with non-constant rhs} -body {
+#lang L --line=1
+void composite_4_1()
+{
+ int ai[], i, j, k;
+ string as[], a, b, c;
+ poly ap[];
+ struct {
+ int i;
+ int j;
+ string s;
+ string t;
+ } st;
+
+ as = { "a", "b", "c" };
+ { a, b, c } = as;
+ unless ((a eq "a") && (b eq "b") && (c eq "c")) puts("bad 1.1");
+
+ ai = { 1, 2, 3 };
+ { i, j, k } = ai;
+ unless ((i == 1) && (j == 2) && (k == 3)) puts("bad 2.1");
+
+ st = { 5, 6, "x", "y" };
+ { i, j, a, b } = st;
+ unless ((i == 5) && (j == 6) && (a eq "x") && (b eq "y")) {
+ puts("bad 3.1");
+ }
+
+ { a, b } = split("one two three");
+ unless ((a eq "one") && (b eq "two")) puts("bad 4.1");
+
+ as = { "a" };
+ { a, b, c } = as;
+ unless ((a eq "a") && !defined(b) && !defined(c)) puts("bad 5.1");
+
+ ap = { 5, 6, "x", "y" };
+ { i, j, a, b } = ap;
+ unless ((i == 5) && (j == 6) && (a eq "x") && (b eq "y")) {
+ puts("bad 6.1");
+ }
+ ap = { "5", "6", 1, 2 };
+ { i, j, a, b } = ap; // poly array, so no type checking
+ unless ((i == 5) && (j == 6) && (a eq "1") && (b eq "2")) {
+ puts("bad 6.2");
+ }
+
+ /* These are not type errors. */
+ i = j = 0;
+ { a, i, j } = { "s" };
+ if (defined(i) || defined(j)) puts("bad 10.1");
+ c = ""; i = j = 0;
+ { i, j, a, b, c, i, j } = st;
+ if (defined(c) || defined(i) || defined(j)) puts("bad 10.2");
+}
+composite_4_1();
+} -output {}
+
+test composite-5 {check composite l-value errors} -body {
+#lang L --line=1 -nowarn
+int composite_5_f() { return (0); }
+void composite_5()
+{
+ int a, b;
+ string s;
+
+ { a, b } += 1;
+ { a, b } -= 1;
+ { a, b } *= 1;
+ { a, b } /= 1;
+ { a, b } %= 1;
+ { a, b } &= 1;
+ { a, b } |= 1;
+ { a, b } ^= 1;
+ { a, b } >>= 1;
+ { a, b } <<= 1;
+ { a, b } =~ /bad/;
+ { s } =~ s/bad/bad/;
+
+ { a, b } = 0;
+
+ { 1 } = { 1 };
+ { composite_5_f() } = { 1 };
+}
+} -returnCodes {error} -match regexp -result {.*7: L Error: arithmetic assignment illegal
+.*8: L Error: arithmetic assignment illegal
+.*9: L Error: arithmetic assignment illegal
+.*10: L Error: arithmetic assignment illegal
+.*11: L Error: arithmetic assignment illegal
+.*12: L Error: arithmetic assignment illegal
+.*13: L Error: arithmetic assignment illegal
+.*14: L Error: arithmetic assignment illegal
+.*15: L Error: arithmetic assignment illegal
+.*16: L Error: arithmetic assignment illegal
+.*17: L Error: expected type string or widget but got list in =~
+.*18: L Error: invalid l-value in =~
+.*20: L Error: right-hand side incompatible with composite assign
+.*22: L Error: invalid l-value in assignment
+.*23: L Error: invalid l-value in assignment
+}
+
+test composite-6 {test composite l-value type errors} -body {
+#lang L --line=1
+void composite_6()
+{
+ string as[], a, b;
+ int ai[], i, j;
+ struct {
+ int i;
+ string s;
+ } st;
+
+ { a, i } = as;
+ { i, a } = ai;
+ { i, i } = as;
+
+ { a, b } = { "a", 1 };
+ { a, b } = { 1, "a" };
+
+ { a, i } = st;
+ { i, j } = st;
+
+ { a, b } = { "bad" => "bad" };
+}
+} -returnCodes {error} -match regexp -result {.*10: L Error: assignment of incompatible types
+.*11: L Error: assignment of incompatible types
+.*12: L Error: assignment of incompatible types
+.*14: L Error: assignment of incompatible types
+.*15: L Error: assignment of incompatible types
+.*17: L Error: assignment of incompatible types
+.*18: L Error: assignment of incompatible types
+.*20: L Error: right-hand side incompatible with composite assign
+}
+
+test lvalue-1 {check indexing hash/struct/array expressions} -body {
+#lang L --line=1
+void lvalue_1()
+{
+ /*
+ * This checks deep-dive of an expression rather than a
+ * variable. Set up expressions that have array/struct/hash
+ * values and then index into them.
+ */
+ string a1[] = { "1", "2", "3" };
+ string a2[];
+
+ unless (split("a x c")[0] eq "a") puts("bad 1");
+ unless (split("y b c")[1] eq "b") puts("bad 2");
+ unless (split("z b c")[2] eq "c") puts("bad 3");
+
+ if (defined(a2[0])) puts("bad 4");
+ unless ((a2 = a1)[0] eq "1") puts("bad 5");
+ unless ((a2 = a1)[1] eq "2") puts("bad 6");
+ unless ((a2 = a1)[2] eq "3") puts("bad 7");
+ unless ((a2[0] eq "1") && (a2[1] eq "2") && (a2[2] eq "3")) {
+ puts("bad 8");
+ }
+ if (defined(a2[3])) puts("bad 9");
+
+ unless ((1 ? a1 : a2)[0] eq "1") puts("bad 10");
+ unless ((1 ? a1 : a2)[1] eq "2") puts("bad 11");
+ unless ((1 ? a1 : a2)[2] eq "3") puts("bad 12");
+}
+#lang tcl
+lvalue_1
+} -output {}
+
+test lvalue-2 {illegal l-value in deep-dive assignments} -body {
+#lang L --line=1
+int[] lvalue_2_ints()
+{
+ int a[] = { 1, 2, 3 };
+ return (a);
+}
+void lvalue_2()
+{
+ int a1[], a2[];
+ string s1[], s2[];
+
+ lvalue_2_ints()[0] = 0;
+ lvalue_2_ints()[0] += 1;
+ ++lvalue_2_ints()[0];
+ lvalue_2_ints()[0]--;
+ split("a","b","c")[0] =~ s/a/b/;
+
+ (a2 = a1)[0] = 0;
+ (a2 = a1)[0] += 1;
+ ++(a2 = a1)[0];
+ (a2 = a1)[0]--;
+ (s2 = s1)[0] =~ s/bad/yes-its-still-bad/;
+}
+#lang tcl
+lvalue_2
+} -returnCodes {error} -match regexp -result {.*11: L Error: invalid l-value in assignment
+.*12: L Error: invalid l-value in assignment
+.*13: L Error: invalid l-value in inc/dec
+.*14: L Error: invalid l-value in inc/dec
+.*15: L Error: invalid l-value in =~
+.*17: L Error: invalid l-value in assignment
+.*18: L Error: invalid l-value in assignment
+.*19: L Error: invalid l-value in inc/dec
+.*20: L Error: invalid l-value in inc/dec
+.*21: L Error: invalid l-value in =~
+}
+
+test lvalue-3 {invalid l-value in inc/dec operators} -body {
+#lang L --line=1
+void lvalue_3()
+{
+ int i = 0;
+
+ i----;
+ i++++;
+ (i++)++;
+ (i++)--;
+ (i--)++;
+ (i--)--;
+ ++++i;
+ ----i;
+ ++(++i);
+ ++(--i);
+ --(++i);
+ --(--i);
+ --(i--);
+ --(i++);
+ ++(i--);
+ ++(i++);
+ (--i)--;
+ (--i)++;
+ (++i)--;
+ (++i)++;
+}
+#lang tcl
+lvalue_3
+} -returnCodes {error} -match regexp -result {.*5: L Error: invalid l-value in inc/dec
+.*6: L Error: invalid l-value in inc/dec
+.*7: L Error: invalid l-value in inc/dec
+.*8: L Error: invalid l-value in inc/dec
+.*9: L Error: invalid l-value in inc/dec
+.*10: L Error: invalid l-value in inc/dec
+.*11: L Error: invalid l-value in inc/dec
+.*12: L Error: invalid l-value in inc/dec
+.*13: L Error: invalid l-value in inc/dec
+.*14: L Error: invalid l-value in inc/dec
+.*15: L Error: invalid l-value in inc/dec
+.*16: L Error: invalid l-value in inc/dec
+.*17: L Error: invalid l-value in inc/dec
+.*18: L Error: invalid l-value in inc/dec
+.*19: L Error: invalid l-value in inc/dec
+.*20: L Error: invalid l-value in inc/dec
+.*21: L Error: invalid l-value in inc/dec
+.*22: L Error: invalid l-value in inc/dec
+.*23: L Error: invalid l-value in inc/dec
+.*24: L Error: invalid l-value in inc/dec
+}
+
+test lvalue-4 {invalid l-value in assignments} -body {
+#lang L --line=1
+int lvalue_4_foo() { return (1); }
+void lvalue_4()
+{
+ int i;
+
+ lvalue_4_foo() = i;
+ lvalue_4_foo() += i;
+ lvalue_4_foo() -= i;
+ lvalue_4_foo() *= i;
+ lvalue_4_foo() /= i;
+ lvalue_4_foo() %= i;
+ lvalue_4_foo() &= i;
+ lvalue_4_foo() |= i;
+ lvalue_4_foo() ^= i;
+ lvalue_4_foo() >>= i;
+ lvalue_4_foo() <<= i;
+ lvalue_4_foo() =~ s/bad/dab/;
+}
+#lang tcl
+lvalue_4
+} -returnCodes {error} -match regexp -result {.*6: L Error: invalid l-value in assignment
+.*7: L Error: invalid l-value in assignment
+.*8: L Error: invalid l-value in assignment
+.*9: L Error: invalid l-value in assignment
+.*10: L Error: invalid l-value in assignment
+.*11: L Error: invalid l-value in assignment
+.*12: L Error: invalid l-value in assignment
+.*13: L Error: invalid l-value in assignment
+.*14: L Error: invalid l-value in assignment
+.*15: L Error: invalid l-value in assignment
+.*16: L Error: invalid l-value in assignment
+.*17: L Error: invalid l-value in =~
+}
+
+test lvalue-5 {invalid l-value in & operator} -body {
+#lang L --line=1 -nowarn
+int lvalue_5_foo() { return (1); }
+void lvalue_5_bar(int &i) {}
+void lvalue_5()
+{
+ int a[], aa[][];
+
+ lvalue_5_bar(&lvalue_5_foo());
+ lvalue_5_bar(&1);
+ &1;
+ &1.1;
+ &"s";
+ &{1,2,3};
+ &{1=>1};
+ &(1+2);
+}
+#lang tcl
+lvalue_5
+} -returnCodes {error} -match regexp -result {.*7: L Error: illegal operand to &
+.*8: L Error: illegal operand to &
+.*9: L Error: illegal operand to &
+.*10: L Error: illegal operand to &
+.*11: L Error: illegal operand to &
+.*12: L Error: illegal operand to &
+.*13: L Error: illegal operand to &
+.*14: L Error: illegal operand to &
+}
+
+test builtin-1 {check keys built-in} -body {
+#lang L --line=1
+int[]
+builtin_1_isort(int a[])
+{
+ int sorted[] = sort(a);
+ return (sorted);
+}
+string[]
+builtin_1_ssort(string a[])
+{
+ string sorted[] = sort(a);
+ return (sorted);
+}
+void builtin_1()
+{
+ int hi{int};
+ int hs{string};
+ int hp{poly};
+ int ki[];
+ string ks[];
+ poly kp[];
+
+ hi = { 3=>3, 1=>1, 4=>4, 5=>5, 9=>9 };
+ ki = keys(hi);
+ ki = builtin_1_isort(ki);
+ unless ((ki[0] == 1) && (ki[1] == 3) && (ki[2] == 4)) puts("bad 1.1");
+ unless ((ki[3] == 5) && (ki[4] == 9)) puts("bad 1.2");
+ if (defined(ki[5])) puts("bad 1.3");
+
+ hs = { "3"=>3, "1"=>1, "4"=>4, "5"=>5, "9"=>9 };
+ ks = keys(hs);
+ ks = builtin_1_ssort(ks);
+ unless ((ks[0] eq "1") && (ks[1] eq "3")) puts("bad 2.1");
+ unless ((ks[2] eq "4") && (ks[3] eq "5")) puts("bad 2.2");
+ unless (ks[4] eq "9") puts("bad 2.3");
+ if (defined(ks[5])) puts("bad 2.4");
+
+ hp{"3"} = 3;
+ hp{1} = 1;
+ hp{"4"} = 4;
+ hp{5} = 5;
+ hp{"9"} = 9;
+ kp = keys(hp);
+ kp = builtin_1_ssort(kp);
+ unless ((kp[0] eq "1") && (kp[1] eq "3")) puts("bad 3.1");
+ unless ((kp[2] eq "4") && (kp[3] eq "5")) puts("bad 3.2");
+ unless (kp[4] eq "9") puts("bad 3.3");
+ if (defined(kp[5])) puts("bad 3.4");
+}
+builtin_1();
+} -output {}
+
+test builtin-2 {check errors with keys built-in} -body {
+#lang L --line=1
+void builtin_2()
+{
+ int h{int};
+ int k[];
+
+ k = keys();
+ k = keys(k);
+ k = keys(h, h);
+ /*
+ * These test that the compiler does not assert due to keys()
+ * not getting a type even though the call has an error.
+ */
+ keys() + 1;
+ keys(k) + 1;
+}
+} -returnCodes {error} -match regexp -result {.*6: L Error: incorrect # args to keys
+.*7: L Error: arg to keys is not a hash
+.*8: L Error: incorrect # args to keys
+}
+
+test builtin-3 {check length built-in} -body {
+#lang L --line=1
+void builtin_3()
+{
+ int a[] = {1,2,3,4};
+ int h{int} = {1=>1,2=>2,3=>3};
+ poly p = {1,2,3,4,5,6};
+ widget w = "12345";
+
+ unless (length("abcde") == 5) puts("bad 1");
+ unless (length(a) == 4) puts("bad 2");
+ unless (length(p) == 6) puts("bad 4");
+ unless (length(h) == 3) puts("bad 5");
+ unless (length(w) == 5) puts("bad 6");
+
+ /*
+ * length() of anything undef should return 0.
+ */
+ unless (length((string)undef) == 0) puts("bad 10.1");
+ unless (length((string[])undef) == 0) puts("bad 10.2");
+ unless (length((string{string})undef) == 0) puts("bad 10.3");
+ unless (length((poly)undef) == 0) puts("bad 10.4");
+}
+builtin_3();
+} -output {}
+
+test builtin-4 {check errors with length built-in} -body {
+#lang L --line=1
+void builtin_4_f() {}
+void builtin_4()
+{
+ length();
+ length(1,2);
+ length(3.14159);
+ length(builtin_4_f());
+ /*
+ * This tests that the compiler does not assert due to length()
+ * not getting a type even though the call has an error.
+ */
+ length() + 1;
+}
+} -returnCodes {error} -match regexp -result {.*4: L Error: incorrect # args to length
+.*5: L Error: incorrect # args to length
+.*6: L Error: arg to length has illegal type
+.*7: L Error: arg to length has illegal type
+}
+
+test builtin-5 {check sort built-in} -body {
+#lang L --line=1
+int builtin_5_compar(string a, string b)
+{
+ int la = length(a);
+ int lb = length(b);
+
+ if (la < lb) {
+ return (-1);
+ } else if (la > lb) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+void builtin_5()
+{
+ int ui[] = {3, 1, 4, 1, 5, 9, 2};
+ int si[];
+ string us[] = {"u","n","s","o","r","t","e","d"};
+ string ss[];
+ float uf[] = {3.1, 1.0, 9.2, -1.0, 5.5};
+ float sf[];
+ string uc[] = {"1", "22222", "333", "44", "5555"};
+ string sc[];
+
+ ss = sort(us);
+ unless ((ss[0] eq "d") && (ss[1] eq "e")) puts("bad 1.1");
+ unless ((ss[2] eq "n") && (ss[3] eq "o")) puts("bad 1.2");
+ unless ((ss[4] eq "r") && (ss[5] eq "s")) puts("bad 1.3");
+ unless ((ss[6] eq "t") && (ss[7] eq "u")) puts("bad 1.4");
+
+ si = sort(ui);
+ unless ((si[0] == 1) && (si[1] == 1) && (si[2] == 2)) puts("bad 2.1");
+ unless ((si[3] == 3) && (si[4] == 4) && (si[5] == 5)) puts("bad 2.2");
+ unless (si[6] == 9) puts("bad 2.3");
+
+ /*
+ * Exact comparisons with floats don't always work, so if this
+ * test fails, suspect that first.
+ */
+ sf = sort(uf);
+ unless ((sf[0] == -1.0) && (sf[1] == 1.0)) puts("bad 3.1");
+ unless ((sf[2] == 3.1) && (sf[3] == 5.5)) puts("bad 3.2");
+ unless (sf[4] == 9.2) puts("bad 3.3");
+
+ ss = sort(decreasing:, us);
+ unless ((ss[7] eq "d") && (ss[6] eq "e")) puts("bad 4.1");
+ unless ((ss[5] eq "n") && (ss[4] eq "o")) puts("bad 4.2");
+ unless ((ss[3] eq "r") && (ss[2] eq "s")) puts("bad 4.3");
+ unless ((ss[1] eq "t") && (ss[0] eq "u")) puts("bad 4.4");
+
+ sc = sort(command: &builtin_5_compar, uc);
+ unless ((sc[0] eq "1") && (sc[1] eq "44")) puts("bad 5.1");
+ unless ((sc[2] eq "333") && (sc[3] eq "5555")) puts("bad 5.2");
+ unless (sc[4] eq "22222") puts("bad 5.3");
+}
+builtin_5();
+} -output {}
+
+test builtin-6 {check sort built-in errors} -body {
+#lang L --line=1
+int builtin_6_compar(string a, string b) { return (0); }
+void builtin_6()
+{
+ string s;
+
+ sort();
+ sort(1);
+ /*
+ * These test that the compiler does not assert due to sort()
+ * not getting a type even though the call has an error.
+ */
+ sort() + 1;
+ sort(1) + 1;
+
+ sort(command: builtin_6_compar, {});
+ sort(command: &s, {});
+ sort(command:, {});
+ sort(command:);
+}
+} -returnCodes {error} -match regexp -result {.*6: L Error: incorrect # args to sort
+.*7: L Error: last arg to sort not an array or list
+.*12: L Error: incorrect # args to sort
+.*13: L Error: last arg to sort not an array or list
+.*15: L Error: \'command:\' arg to sort must be \&function
+.*16: L Error: \'command:\' arg to sort must be \&function
+.*17: L Error: \'command:\' arg to sort must be \&function
+.*18: L Error: last arg to sort not an array or list
+}
+
+test builtin-7 {check join built-in} -body {
+#lang L --line=1
+void builtin_7()
+{
+ int ai[] = {1,2,3};
+ string as[] = {"a","b","c"};
+ string s = "x";
+ poly p = "p";
+ widget w = "w";
+
+ unless (join(" ", as) eq "a b c") puts("bad 1");
+ unless (join(s, as) eq "axbxc") puts("bad 2");
+ unless (join("xyz", as) eq "axyzbxyzc") puts("bad 3");
+ unless (join(p, as) eq "apbpc") puts("bad 4");
+ unless (join(p,p) eq "p") puts("bad 5");
+ unless (join(" ", ai) eq "1 2 3") puts("bad 6");
+ unless (join(w, ai) eq "1w2w3") puts("bad 7");
+}
+builtin_7();
+} -output {}
+
+test builtin-8 {check join built-in errors} -body {
+#lang L --line=1
+void builtin_8()
+{
+ int ai[];
+
+ join();
+ join(ai,"s1","s2");
+ join(ai, ai);
+ join(1);
+ join(1.1);
+ join("s");
+ join("s", 1);
+ /*
+ * These test that the compiler does not assert due to join()
+ * not getting a type even though the call has an error.
+ */
+ join() + 1;
+ join(ai, ai) + 1;
+ join("s", 1) + 1;
+}
+} -returnCodes {error} -match regexp -result {.*5: L Error: incorrect # args to join
+.*6: L Error: incorrect # args to join
+.*7: L Error: first arg to join not a string
+.*8: L Error: incorrect # args to join
+.*9: L Error: incorrect # args to join
+.*10: L Error: incorrect # args to join
+.*11: L Error: second arg to join not an array or list
+}
+
+test builtin-9 {check re-declaration of built-ins} -body {
+#lang L --line=1
+void abs() {}
+void assert() {}
+void die() {}
+void join() {}
+void keys() {}
+void length() {}
+void pop() {}
+void push() {}
+void rename() {}
+void sort() {}
+void undef() {}
+void warn() {}
+} -returnCodes {error} -match regexp -result {.*1: L Error: function 'abs' conflicts with built-in
+.*2: L Error: function 'assert' conflicts with built-in
+.*3: L Error: function 'die' conflicts with built-in
+.*4: L Error: function 'join' conflicts with built-in
+.*5: L Error: function 'keys' conflicts with built-in
+.*6: L Error: function 'length' conflicts with built-in
+.*7: L Error: function 'pop' conflicts with built-in
+.*8: L Error: function 'push' conflicts with built-in
+.*9: L Error: function 'rename' conflicts with built-in
+.*10: L Error: function 'sort' conflicts with built-in
+.*11: L Error: function 'undef' conflicts with built-in
+.*12: L Error: function 'warn' conflicts with built-in
+}
+
+test builtin-10 {check built-ins stack integrity} -body {
+#lang L --line=1
+void builtin_10()
+{
+ /*
+ * This checks that an ignored return value doesn't leave the
+ * stack unbalanced (which would cause a crash).
+ */
+
+ int a[], i;
+ int n = 100;
+ int h{int} = { 1=>1, 2=>2 };
+
+ for (i = 0; i < n; ++i) {
+ push(&a, i);
+ abs(1);
+ assert(1);
+ join(" ", {"a","b"});
+ keys(h);
+ length(h);
+ pop(&a);
+ push(&a, i);
+ sort({3,2,1});
+ split("x y z");
+ undef(h{0});
+ }
+ unless (length(a) == n) puts("bad 1");
+}
+builtin_10();
+} -output {}
+
+test builtin-11 {check push onto class and instance variables} -body {
+#lang L --line=1
+class builtin_11
+{
+ public int apubl[];
+ instance {
+ public int ainst[];
+ }
+}
+void builtin_11_main()
+{
+ builtin_11 o = builtin_11_new();
+
+ push(&builtin_11->apubl, 1);
+ push(&builtin_11->apubl, 2);
+ push(&builtin_11->apubl, 3);
+ unless (length(builtin_11->apubl) == 3) puts("bad 1.1");
+ unless (builtin_11->apubl[0] == 1) puts("bad 1.2");
+ unless (builtin_11->apubl[1] == 2) puts("bad 1.3");
+ unless (builtin_11->apubl[2] == 3) puts("bad 1.4");
+
+ push(&o->ainst, 1);
+ push(&o->ainst, 2);
+ push(&o->ainst, 3);
+ unless (length(o->ainst) == 3) puts("bad 2.1");
+ unless (o->ainst[0] == 1) puts("bad 2.2");
+ unless (o->ainst[1] == 2) puts("bad 2.3");
+ unless (o->ainst[2] == 3) puts("bad 2.4");
+
+ builtin_11_delete(o);
+}
+builtin_11_main();
+} -output {}
+
+test builtin-11.2 {check push and pop built-in} -body {
+#lang L --line=1
+void builtin_11_2()
+{
+ string aa[][], s;
+ string ha{string}[];
+ struct {
+ string a[];
+ string aaaa[][][][];
+ } st;
+
+ aa = undef;
+ push(&aa[0], "a");
+ unless ((tcl)aa[0] eq "a") puts("bad 1.1");
+ unless (defined(aa[0])) puts("bad 1.2");
+ push(&aa[0], "b");
+ unless ((tcl)aa[0] eq "a b") puts("bad 1.3");
+ push(&aa[0], "c");
+ unless ((tcl)aa[0] eq "a b c") puts("bad 1.4");
+ s = pop(&aa[0]);
+ unless (defined(s) && (s eq "c")) puts("bad 1.5");
+ s = pop(&aa[0]);
+ unless (s eq "b") puts("bad 1.6");
+ s = pop(&aa[0]);
+ unless (s eq "a") puts("bad 1.7");
+ s = pop(&aa[0]);
+ if (defined(s)) puts("bad 1.8");
+ s = pop(&aa[0]);
+ if (defined(s)) puts("bad 1.9");
+
+ aa[0] = {"x","y"};
+ push(&aa[0], "a");
+ unless ((tcl)aa[0] eq "x y a") puts("bad 2.1");
+ push(&aa[0], "b");
+ unless ((tcl)aa[0] eq "x y a b") puts("bad 2.2");
+ s = pop(&aa[0]);
+ unless (defined(s) && (s eq "b")) puts("bad 2.3");
+ s = pop(&aa[0]);
+ unless (s eq "a") puts("bad 2.4");
+ s = pop(&aa[0]);
+ unless (s eq "y") puts("bad 2.5");
+ s = pop(&aa[0]);
+ unless (s eq "x") puts("bad 2.6");
+ s = pop(&aa[0]);
+ if (defined(s)) puts("bad 2.7");
+ s = pop(&aa[0]);
+ if (defined(s)) puts("bad 2.8");
+
+ ha = undef;
+ push(&ha{"new"}, "a");
+ unless ((tcl)ha{"new"} eq "a") puts("bad 5.1");
+ unless (defined(ha{"new"})) puts("bad 5.2");
+ push(&ha{"new"}, "b");
+ unless ((tcl)ha{"new"} eq "a b") puts("bad 5.3");
+ push(&ha{"new"}, "c");
+ unless ((tcl)ha{"new"} eq "a b c") puts("bad 5.4");
+ s = pop(&ha{"new"});
+ unless (defined(s) && (s eq "c")) puts("bad 5.5");
+ s = pop(&ha{"new"});
+ unless (s eq "b") puts("bad 5.6");
+ s = pop(&ha{"new"});
+ unless (s eq "a") puts("bad 5.7");
+ s = pop(&ha{"new"});
+ if (defined(s)) puts("bad 5.8");
+ s = pop(&ha{"new"});
+ if (defined(s)) puts("bad 5.9");
+
+ ha{"new"} = {"p","q"};
+ push(&ha{"new"}, "a");
+ unless ((tcl)ha{"new"} eq "p q a") puts("bad 6.1");
+ push(&ha{"new"}, "b");
+ unless ((tcl)ha{"new"} eq "p q a b") puts("bad 6.2");
+ s = pop(&ha{"new"});
+ unless (defined(s) && (s eq "b")) puts("bad 6.3");
+ s = pop(&ha{"new"});
+ unless (s eq "a") puts("bad 6.4");
+ s = pop(&ha{"new"});
+ unless (s eq "q") puts("bad 6.5");
+ s = pop(&ha{"new"});
+ unless (s eq "p") puts("bad 6.6");
+ s = pop(&ha{"new"});
+ if (defined(s)) puts("bad 6.7");
+ s = pop(&ha{"new"});
+ if (defined(s)) puts("bad 6.8");
+
+ st.a = undef;
+ push(&st.a, "a");
+ unless ((tcl)st.a eq "a") puts("bad 10.1");
+ unless (defined(st.a)) puts("bad 10.2");
+ push(&st.a, "b");
+ unless ((tcl)st.a eq "a b") puts("bad 10.3");
+ push(&st.a, "c");
+ unless ((tcl)st.a eq "a b c") puts("bad 10.4");
+ s = pop(&st.a);
+ unless (defined(s) && (s eq "c")) puts("bad 10.5");
+ s = pop(&st.a);
+ unless (s eq "b") puts("bad 10.6");
+ s = pop(&st.a);
+ unless (s eq "a") puts("bad 10.7");
+ s = pop(&st.a);
+ if (defined(s)) puts("bad 10.8");
+ s = pop(&st.a);
+ if (defined(s)) puts("bad 10.9");
+
+ st.a = {"r","s"};
+ push(&st.a, "a");
+ unless ((tcl)st.a eq "r s a") puts("bad 11.1");
+ push(&st.a, "b");
+ unless ((tcl)st.a eq "r s a b") puts("bad 11.2");
+ s = pop(&st.a);
+ unless (defined(s) && (s eq "b")) puts("bad 11.3");
+ s = pop(&st.a);
+ unless (s eq "a") puts("bad 11.4");
+ s = pop(&st.a);
+ unless (s eq "s") puts("bad 11.5");
+ s = pop(&st.a);
+ unless (s eq "r") puts("bad 11.6");
+ s = pop(&st.a);
+ if (defined(s)) puts("bad 11.7");
+ s = pop(&st.a);
+ if (defined(s)) puts("bad 11.8");
+
+ push(&st.aaaa[0][1][2], "a");
+ unless ((tcl)st.aaaa[0][1][2] eq "a") puts("bad 15.1");
+ unless (defined(st.aaaa[0][1][2])) puts("bad 15.2");
+ push(&st.aaaa[0][1][2], "b");
+ unless ((tcl)st.aaaa[0][1][2] eq "a b") puts("bad 15.2");
+ push(&st.aaaa[0][1][2], "c");
+ unless ((tcl)st.aaaa[0][1][2] eq "a b c") puts("bad 15.3");
+ s = pop(&st.aaaa[0][1][2]);
+ unless (defined(s) && (s eq "c")) puts("bad 15.4");
+ s = pop(&st.aaaa[0][1][2]);
+ unless (s eq "b") puts("bad 15.5");
+ s = pop(&st.aaaa[0][1][2]);
+ unless (s eq "a") puts("bad 15.6");
+ s = pop(&st.aaaa[0][1][2]);
+ if (defined(s)) puts("bad 15.7");
+ s = pop(&st.aaaa[0][1][2]);
+ if (defined(s)) puts("bad 15.8");
+}
+builtin_11_2();
+} -output {}
+
+test builtin-11.3 {check push built-in with multiple args} -body {
+#lang L --line=1
+void builtin_11_3()
+{
+ int i;
+ string a[], aa[][];
+
+ push(&a, "a");
+ unless (join("",a) eq "a") puts("bad 1.1");
+ unless (length(a) == 1) puts("bad 1.2");
+
+ push(&a, "b", "c");
+ unless (join("",a) eq "abc") puts("bad 2.1");
+ unless (length(a) == 3) puts("bad 2.2");
+
+ push(&a, "d", "e", "f");
+ unless (join("",a) eq "abcdef") puts("bad 3.1");
+ unless (length(a) == 6) puts("bad 3.2");
+
+ /* Check that the first arg is evaluated exactly once. */
+ undef(a);
+ i = 0;
+ push(&aa[i++], "a", "b", "c");
+ unless ((i == 1) && eq(aa[0],{"a","b","c"})) puts("bad 4.1");
+ unless (length(aa) == 1) puts("bad 4.2");
+ if (aa[1]) puts("bad 4.3");
+}
+builtin_11_3();
+} -output {}
+
+test builtin-11.4 {check push built-in with list args} -body {
+#lang L --line=1
+void builtin_11_4()
+{
+ int a[], aa[][], aaa[][][];
+ struct {
+ int a[];
+ } st;
+ string sa[], saa[][];
+
+ /* Check pushing to a plain variable. */
+
+ push(&a, 1);
+ unless (eq(a,{1})) puts("bad 1.1");
+
+ push(&a, {2});
+ unless (eq(a,{1,2})) puts("bad 1.2");
+
+ push(&a, {3,4});
+ unless (eq(a,{1,2,3,4})) puts("bad 1.3");
+
+ push(&a, {5,6,7});
+ unless (eq(a,{1,2,3,4,5,6,7})) puts("bad 1.4");
+
+ push(&a, 8, {9,10});
+ unless (eq(a,{1,2,3,4,5,6,7,8,9,10})) puts("bad 1.5");
+
+ push(&a, {11,12}, 13);
+ unless (eq(a,{1,2,3,4,5,6,7,8,9,10,11,12,13})) puts("bad 1.6");
+
+ push(&a, 14, {15}, 16, {17,18});
+ unless (eq(a,{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18})) {
+ puts("bad 1.7");
+ }
+
+ /* Check pushing to a struct member (deep dive). */
+
+ push(&st.a, 1);
+ unless (eq(st.a,{1})) puts("bad 2.1");
+
+ push(&st.a, {2});
+ unless (eq(st.a,{1,2})) puts("bad 2.2");
+
+ push(&st.a, {3,4});
+ unless (eq(st.a,{1,2,3,4})) puts("bad 2.3");
+
+ push(&st.a, {5,6,7});
+ unless (eq(st.a,{1,2,3,4,5,6,7})) puts("bad 2.4");
+
+ push(&st.a, 8, {9,10});
+ unless (eq(st.a,{1,2,3,4,5,6,7,8,9,10})) puts("bad 2.5");
+
+ push(&st.a, {11,12}, 13);
+ unless (eq(st.a,{1,2,3,4,5,6,7,8,9,10,11,12,13})) puts("bad 2.6");
+
+ push(&st.a, 14, {15}, 16, {17,18});
+ unless (eq(st.a,{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18})) {
+ puts("bad 2.7");
+ }
+
+ /*
+ * If you push to a type[], you can push a type or a type[],
+ * and you can mix and match in one push. Check that these
+ * are done correctly.
+ */
+
+ push(&aa, {1,1}); // should push a single element {1,1}
+ unless (length(aa) == 1) puts("bad 3.0");
+ unless (eq(aa, { {1,1} })) puts("bad 3.1");
+ push(&aa, {2,2});
+ unless (eq(aa, { {1,1}, {2,2} })) puts("bad 3.2");
+ push(&aa, { {3,3} }); // should push {3,3}
+ unless (eq(aa, { {1,1}, {2,2}, {3,3} })) puts("bad 3.3");
+ push(&aa, { {4,4},{5,5} }); // should push {4,4} and {5,5}
+ unless (eq(aa, { {1,1}, {2,2}, {3,3}, {4,4}, {5,5} })) puts("bad 3.4");
+ undef(aa);
+ push(&aa, {1,1}, {{2,2}}, {{3,3},{4,4}}, {5,5});
+ unless (eq(aa, { {1,1}, {2,2}, {3,3}, {4,4}, {5,5} })) puts("bad 3.5");
+
+ push(&aaa[0], {1,1}); // should push a single element {1,1}
+ unless (length(aaa[0]) == 1) puts("bad 3.10");
+ unless (eq(aaa[0], { {1,1} })) puts("bad 3.11");
+ push(&aaa[0], {2,2});
+ unless (eq(aaa[0], { {1,1}, {2,2} })) puts("bad 3.12");
+ push(&aaa[0], { {3,3} }); // should push {3,3}
+ unless (eq(aaa[0], { {1,1}, {2,2}, {3,3} })) puts("bad 3.13");
+ push(&aaa[0], { {4,4},{5,5} }); // should push {4,4} and {5,5}
+ unless (eq(aaa[0], { {1,1}, {2,2}, {3,3}, {4,4}, {5,5} })) {
+ puts("bad 3.14");
+ }
+ undef(aaa[0]);
+ push(&aaa[0], {1,1}, {{2,2}}, {{3,3},{4,4}}, {5,5});
+ unless (eq(aaa[0], { {1,1}, {2,2}, {3,3}, {4,4}, {5,5} })) {
+ puts("bad 3.15");
+ }
+
+ /*
+ * Check that things are appended as list elements and not via
+ * string concat.
+ */
+
+ undef(sa);
+ push(&sa, "a b");
+ unless (length(sa) == 1) puts("bad 4.1");
+ unless (sa[0] == "a b") puts("bad 4.2");
+ undef(sa);
+ push(&sa, {"a b"});
+ unless (length(sa) == 1) puts("bad 4.3");
+ unless (sa[0] == "a b") puts("bad 4.4");
+
+ undef(saa[0]);
+ push(&saa[0], "a b");
+ unless (length(saa[0]) == 1) puts("bad 5.1");
+ unless (saa[0][0] == "a b") puts("bad 5.2");
+ undef(saa[0]);
+ push(&saa[0], {"a b"});
+ unless (length(saa[0]) == 1) puts("bad 5.3");
+ unless (saa[0][0] == "a b") puts("bad 5.4");
+}
+builtin_11_4();
+} -output {}
+
+test builtin-11.5 {check insert built-in} -body {
+#lang L --line=1
+void builtin_11_5()
+{
+ int a[], i;
+ struct {
+ int a[];
+ } st;
+
+ /* Check inserting into a plain variable, scalar args. */
+
+ a = {};
+ insert(&a, 0, 1);
+ unless (eq(a, {1})) puts("bad 1.1");
+ insert(&a, 0, 2);
+ unless (eq(a, {2,1})) puts("bad 1.2");
+ insert(&a, 0, 3, 4);
+ unless (eq(a, {3,4,2,1})) puts("bad 1.3");
+ insert(&a, 0, 5, 6, 7);
+ unless (eq(a, {5,6,7,3,4,2,1})) puts("bad 1.4");
+
+ /* Check inserting into a struct member (deep dive), scalar args. */
+
+ st.a = {};
+ insert(&st.a, 0, 1);
+ unless (eq(st.a, {1})) puts("bad 2.1");
+ insert(&st.a, 1, 2);
+ unless (eq(st.a, {1,2})) puts("bad 2.2");
+ insert(&st.a, 1, 3, 4);
+ unless (eq(st.a, {1,3,4,2})) puts("bad 2.3");
+ insert(&st.a, 0, 5, 6, 7);
+ unless (eq(st.a, {5,6,7,1,3,4,2})) puts("bad 2.4");
+ insert(&st.a, 2, 8);
+ unless (eq(st.a, {5,6,8,7,1,3,4,2})) puts("bad 2.5");
+ insert(&st.a, 0, 9);
+ unless (eq(st.a, {9,5,6,8,7,1,3,4,2})) puts("bad 2.6");
+
+ /* Check inserting into a plain variable, scalar and list args. */
+
+ a = {};
+ insert(&a, 0, 1);
+ unless (eq(a, {1})) puts("bad 3.1");
+ insert(&a, 0, {2});
+ unless (eq(a, {2,1})) puts("bad 3.2");
+ insert(&a, 0, 3, {4,5});
+ unless (eq(a, {3,4,5,2,1})) puts("bad 3.3");
+ insert(&a, 0, {5,6,7}, 8, {9,10});
+ unless (eq(a, {5,6,7,8,9,10,3,4,5,2,1})) puts("bad 3.4 ${a}");
+
+ /* Check with a struct member (deep dive), scalar and list args. */
+
+ st.a = {};
+ insert(&st.a, 0, 1);
+ unless (eq(st.a, {1})) puts("bad 4.1");
+ insert(&st.a, 0, {2});
+ unless (eq(st.a, {2,1})) puts("bad 4.2");
+ insert(&st.a, 0, 3, {4,5});
+ unless (eq(st.a, {3,4,5,2,1})) puts("bad 4.3");
+ insert(&st.a, 0, {5,6,7}, 8, {9,10});
+ unless (eq(st.a, {5,6,7,8,9,10,3,4,5,2,1})) puts("bad 4.4 ${a}");
+
+ /* Check with an expression as the index arg. */
+
+ a = {};
+ i = 0;
+ insert(&a, i, 1);
+ unless (eq(a, {1})) puts("bad 5.1");
+ insert(&a, i, 2);
+ unless (eq(a, {2,1})) puts("bad 5.2");
+ insert(&a, i+1, 3);
+ unless (eq(a, {2,3,1})) puts("bad 5.3");
+ insert(&a, --i, 5); // try a side effect in the index arg
+ unless (eq(a, {2,3,1,5})) puts("bad 5.4");
+ insert(&a, i+1, 6);
+ unless (eq(a, {6,2,3,1,5})) puts("bad 5.5");
+}
+builtin_11_5();
+} -output {}
+
+test builtin-11.6 {check unshift built-in} -body {
+#lang L --line=1
+void builtin_11_6()
+{
+ int a[];
+ struct {
+ int a[];
+ } st;
+
+ /* Check unshifting into a plain variable, scalar args. */
+
+ a = {};
+ unshift(&a, 0);
+ unless (eq(a, {0})) puts("bad 1.1");
+ unshift(&a, 1);
+ unless (eq(a, {1,0})) puts("bad 1.2");
+ unshift(&a, 2, 3);
+ unless (eq(a, {2,3,1,0})) puts("bad 1.3");
+ unshift(&a, 4, 5, 6);
+ unless (eq(a, {4,5,62,3,1,0})) puts("bad 1.4");
+
+ /* Check unshifting into a struct member (deep dive), scalar args. */
+
+ st.a = {};
+ unshift(&st.a, 1);
+ unless (eq(st.a, {1})) puts("bad 2.1");
+ unshift(&st.a, 2);
+ unless (eq(st.a, {2,1})) puts("bad 2.2");
+ unshift(&st.a, 3, 4);
+ unless (eq(st.a, {3,4,2,1})) puts("bad 2.3");
+ unshift(&st.a, 5, 6, 7);
+ unless (eq(st.a, {5,6,7,3,4,2,1})) puts("bad 2.4");
+ unshift(&st.a, 8);
+ unless (eq(st.a, {8,5,6,7,3,4,2,1})) puts("bad 2.5");
+ unshift(&st.a, 9);
+ unless (eq(st.a, {9,8,6,7,8,3,4,2,1})) puts("bad 2.6");
+
+ /* Check unshifting into a plain variable, scalar and list args. */
+
+ a = {};
+ unshift(&a, 1);
+ unless (eq(a, {1})) puts("bad 3.1");
+ unshift(&a, {2});
+ unless (eq(a, {2,1})) puts("bad 3.2");
+ unshift(&a, 3, {4,5});
+ unless (eq(a, {3,4,5,2,1})) puts("bad 3.3");
+ unshift(&a, {5,6,7}, 8, {9,10});
+ unless (eq(a, {5,6,7,8,9,10,3,4,5,2,1})) puts("bad 3.4 ${a}");
+
+ /* Check with a struct member (deep dive), scalar and list args. */
+
+ st.a = {};
+ unshift(&st.a, 1);
+ unless (eq(st.a, {1})) puts("bad 4.1");
+ unshift(&st.a, {2});
+ unless (eq(st.a, {2,1})) puts("bad 4.2");
+ unshift(&st.a, 3, {4,5});
+ unless (eq(st.a, {3,4,5,2,1})) puts("bad 4.3");
+ unshift(&st.a, {5,6,7}, 8, {9,10});
+ unless (eq(st.a, {5,6,7,8,9,10,3,4,5,2,1})) puts("bad 4.4 ${a}");
+}
+} -output {}
+
+
+test builtin-11.7 {check shift built-in} -body {
+#lang L --line=1
+void builtin_11_7()
+{
+ int a[];
+ struct {
+ int a[];
+ } st;
+
+ a = { 1,2,3,4,5 };
+ unless (shift(&a) == 1) puts("bad 1.1");
+ unless (eq(a, {2,3,4,5})) puts("bad 1.2");
+ unless (shift(&a) == 2) puts("bad 1.3");
+ unless (eq(a, {3,4,5})) puts("bad 1.4");
+ unless (shift(&a) == 3) puts("bad 1.5");
+ unless (eq(a, {4,5})) puts("bad 1.6");
+ unless (shift(&a) == 4) puts("bad 1.7");
+ unless (eq(a, {5})) puts("bad 1.8");
+ unless (shift(&a) == 5) puts("bad 1.9");
+ unless (eq(a, {})) puts("bad 1.10");
+ unless (defined(a)) puts("bad 1.11");
+ if (defined(shift(&a))) puts("bad 1.12");
+ unless (eq(a, {})) puts("bad 1.13");
+ unless (defined(a)) puts("bad 1.14");
+
+ st.a = { 1,2,3,4,5 };
+ unless (shift(&st.a) == 1) puts("bad 2.1");
+ unless (eq(st.a, {2,3,4,5})) puts("bad 2.2");
+ unless (shift(&st.a) == 2) puts("bad 2.3");
+ unless (eq(st.a, {3,4,5})) puts("bad 2.4");
+ unless (shift(&st.a) == 3) puts("bad 2.5");
+ unless (eq(st.a, {4,5})) puts("bad 2.6");
+ unless (shift(&st.a) == 4) puts("bad 2.7");
+ unless (eq(st.a, {5})) puts("bad 2.8");
+ unless (shift(&st.a) == 5) puts("bad 2.9");
+ unless (eq(st.a, {})) puts("bad 2.10");
+ unless (defined(st.a)) puts("bad 2.11");
+ if (defined(shift(&st.a))) puts("bad 2.12");
+ unless (eq(st.a, {})) puts("bad 2.13");
+ unless (defined(st.a)) puts("bad 2.14");
+}
+builtin_11_7();
+} -output {}
+
+test builtin-14 {check errors in push and pop built-ins} -body {
+#lang L --line=1
+int[] builtin_14_array() { return {1,2,3}; }
+void builtin_14()
+{
+ int i;
+ string s;
+
+ /* The first arg has array type, but it's not an l-value. */
+ push(&(builtin_14_array()), 0);
+ pop(&(builtin_14_array()));
+
+ pop(&3) + 1; // not an array reference
+ pop(&i) + 1; // not an array reference
+ pop(&s) + 1; // not an array reference
+ pop() + 1; // bad # args
+ pop(1,2) + 1; // bad # args
+ /*
+ * We add 1 above to test that the compiler does not assert
+ * due to pop() not getting a type even though there is an
+ * error.
+ */
+}
+} -returnCodes {error} -match regexp -result {.*8: L Error: invalid l-value in push
+.*9: L Error: invalid l-value in pop
+.*11: L Error: arg to pop not an array reference.*
+.*12: L Error: arg to pop not an array reference.*
+.*13: L Error: arg to pop not an array reference.*
+.*14: L Error: incorrect # arguments to pop
+.*15: L Error: incorrect # arguments to pop
+}
+
+test builtin-14.2 {check errors in insert built-in} -body {
+#lang L --line=1
+int[] builtin_14_2_array() { return {1,2,3}; }
+void builtin_14_2()
+{
+ int i, a[];
+ string s;
+
+ /* The first arg has array type, but it's not an l-value. */
+ insert(&(builtin_14_2_array()), 0, 0);
+
+ insert(&3, 0, 0) + 1; // 1st arg not an array reference
+ insert(&i, 0, 0) + 1; // 1st arg not an array reference
+ insert(&s, 0, 0) + 1; // 1st arg not an array reference
+ insert(&a, "s", 0) + 1; // 2nd arg not an int
+ insert(&a, 1.0, 0) + 1; // 2nd arg not an int
+ insert(&a, a, 0) + 1; // 2nd arg not an int
+ insert(&a, &i, 0) + 1; // 2nd arg not an int
+ insert() + 1; // too few args
+ insert(&a, 0) + 1; // too few args
+ /*
+ * We add 1 above to test that the compiler does not assert
+ * due to insert() not getting a type even though there is an
+ * error.
+ */
+}
+} -returnCodes {error} -match regexp -result {.*8: L Error: invalid l-value in insert
+.*10: L Error: first arg to insert not an array reference.*
+.*11: L Error: first arg to insert not an array reference.*
+.*12: L Error: first arg to insert not an array reference.*
+.*13: L Error: second arg to insert not an int
+.*14: L Error: second arg to insert not an int
+.*15: L Error: second arg to insert not an int
+.*16: L Error: second arg to insert not an int
+.*17: L Error: too few arguments to insert
+.*18: L Error: too few arguments to insert
+}
+
+test builtin-14_3 {check errors in unshift built-in} -body {
+#lang L --line=1
+int[] builtin_14_3_array() { return {1,2,3}; }
+void builtin_14_3()
+{
+ int i, a[];
+ string s;
+
+ /* The first arg has array type, but it's not an l-value. */
+ unshift(&(builtin_14_3_array()), 0);
+
+ unshift(&3, 0) + 1; // 1st arg not an array reference
+ unshift(&i, 0) + 1; // 1st arg not an array reference
+ unshift(&s, 0) + 1; // 1st arg not an array reference
+ unshift(&a, "s") + 1; // 2nd arg not an int
+ unshift(&a, 1.0) + 1; // 2nd arg not an int
+ unshift(&a, &i) + 1; // 2nd arg not an int
+ unshift() + 1; // too few args
+ /*
+ * We add 1 above to test that the compiler does not assert
+ * due to pop() not getting a type even though there is an
+ * error.
+ */
+}
+} -returnCodes {error} -match regexp -result {.*8: L Error: invalid l-value in unshift
+.*10: L Error: first arg to unshift not an array reference.*
+.*11: L Error: first arg to unshift not an array reference.*
+.*12: L Error: first arg to unshift not an array reference.*
+.*13: L Error: arg #2 to unshift has type incompatible with array
+.*14: L Error: arg #2 to unshift has type incompatible with array
+.*15: L Error: arg #2 to unshift has type incompatible with array
+.*16: L Error: too few arguments to unshift
+}
+
+test builtin-14_4 {check errors in shift built-in} -body {
+#lang L --line=1
+int[] builtin_14_4_array() { return {1,2,3}; }
+void builtin_14_4()
+{
+ int i;
+ string s;
+
+ /* The first arg has array type, but it's not an l-value. */
+ shift(&(builtin_14_array()));
+
+ shift(&3) + 1; // not an array reference
+ shift(&i) + 1; // not an array reference
+ shift(&s) + 1; // not an array reference
+ shift() + 1; // bad # args
+ shift(1,2) + 1; // bad # args
+ /*
+ * We add 1 above to test that the compiler does not assert
+ * due to pop() not getting a type even though there is an
+ * error.
+ */
+}
+} -returnCodes {error} -match regexp -result {.*8: L Error: invalid l-value in shift
+.*10: L Error: arg to shift not an array reference.*
+.*11: L Error: arg to shift not an array reference.*
+.*12: L Error: arg to shift not an array reference.*
+.*13: L Error: incorrect # arguments to shift
+.*14: L Error: incorrect # arguments to shift
+}
+
+test builtin-15 {check abs built-in} -body {
+#lang L --line=1
+void builtin_15()
+{
+ poly p;
+
+ unless (abs(1) == 1) puts("bad 1.1");
+ unless (abs(0) == 0) puts("bad 1.2");
+ unless (abs(-1) == 1) puts("bad 1.3");
+
+ unless (abs(1.1) == 1.1) puts("bad 2.1");
+ unless (abs(0.0) == 0.0) puts("bad 2.2");
+ unless (abs(-1.1) == 1.1) puts("bad 2.3");
+
+ p = -1;
+ unless (abs(p) == 1) puts("bad 3.1");
+ p = -1.1;
+ unless (abs(p) == 1.1) puts("bad 3.2");
+}
+builtin_15();
+} -output {}
+
+test builtin-16 {check abs built-in errors} -body {
+#lang L --line=1
+void builtin_16()
+{
+ abs();
+ abs(1, 1);
+ abs(1.1, 1.1);
+ abs("bad");
+ /*
+ * This tests that the compiler does not assert due to abs()
+ * not getting a type even though the call has an error.
+ */
+ abs() + 1;
+}
+} -returnCodes {error} -match regexp -result {.*3: L Error: incorrect # args to abs
+.*4: L Error: incorrect # args to abs
+.*5: L Error: incorrect # args to abs
+.*6: L Error: must pass int or float to abs
+}
+
+test builtin-17 {check typeof built-in} -body {
+#lang L --line=1
+class builtin_17_cls {}
+typedef int builtin_17_type1;
+typedef builtin_17_type1 builtin_17_type2;
+void builtin_17()
+{
+ int i;
+ string s;
+ poly p;
+ widget w;
+ int a[];
+ string h{string};
+ struct { int i; } str;
+ builtin_17_type1 v1;
+ builtin_17_type2 v2;
+ builtin_17_cls c;
+
+ unless (typeof(i) eq "int") puts("bad 1");
+ unless (typeof(s) eq "string") puts("bad 2");
+ unless (typeof(p) eq "poly") puts("bad 3");
+ unless (typeof(w) eq "widget") puts("bad 4");
+ unless (typeof(a) eq "array") puts("bad 5");
+ unless (typeof(h) eq "hash") puts("bad 6");
+ unless (typeof(str) eq "struct") puts("bad 7");
+ unless (typeof(c) eq "builtin_17_cls") puts("bad 8");
+ unless (typeof(v1) eq "builtin_17_type1") puts("bad 9");
+ unless (typeof(v2) eq "builtin_17_type2") puts("bad 10");
+ unless (typeof(builtin_17) eq "function") puts("bad 11");
+}
+builtin_17();
+} -output {}
+
+test builtin-18 {check typeof built-in errors} -body {
+#lang L --line=1 -nowarn
+void builtin_18()
+{
+ int i = 0;
+
+ typeof("bad");
+ typeof(i+0);
+ typeof((string)i);
+}
+} -returnCodes {error} -match regexp -result {.*5: L Error: argument to typeof\(\) not a variable
+.*6: L Error: argument to typeof\(\) not a variable
+.*7: L Error: argument to typeof\(\) not a variable
+}
+
+test builtin-19.1 {check min/max built-ins} -body {
+#lang L --line=1
+void builtin_19_1()
+{
+ unless (min(-1, 1) == -1) puts("bad 1");
+ unless (min(2, 1) == 1) puts("bad 2");
+
+ unless (min(-1.0, 1.0) == -1.0) puts("bad 3");
+ unless (min(2.0, 1.0) == 1.0) puts("bad 4");
+}
+builtin_19_1();
+} -output {}
+
+test builtin-19.2 {check min/max built-in errors} -body {
+#lang L --line=1
+void builtin_19_2()
+{
+ min();
+ min(1);
+ min(1,2,3);
+ max();
+ max(1);
+ max(1,2,3);
+ min("bad","bad");
+ max("bad","bad");
+}
+} -returnCodes {error} -match regexp -result {.*3: L Error: incorrect # args to min
+.*4: L Error: incorrect # args to min
+.*5: L Error: incorrect # args to min
+.*6: L Error: incorrect # args to max
+.*7: L Error: incorrect # args to max
+.*8: L Error: incorrect # args to max
+.*9: L Error: expected type int or float but got string in min/max
+.*10: L Error: expected type int or float but got string in min/max
+}
+
+test builtin-20 {check (expand) operator in built-ins} -body {
+#lang L --line=1
+void builtin_20()
+{
+ string res[];
+ string sa[] = { "123", "3", "987" };
+ string opts[] = { "-decreasing", "-integer" };
+
+ res = sort((expand)opts, sa);
+ unless (eq(res, {"3","123","987"})) puts("bad 1.1");
+}
+builtin_20();
+} -returnCodes {error} -match regexp -result {.*7: L Error: \(expand\) illegal with this function
+}
+
+test line-file-1 {test __LINE__ and __FILE__} -body {
+#lang L --line=1
+void line_file_1()
+{
+ unless(basename(__FILE__) eq "l-core.test") puts("bad 1.1");
+ unless(__LINE__ == 4) puts("bad 1.2");
+ unless(__LINE__ == 5) puts("bad 1.3");
+ unless(__LINE__ == 6) puts("bad 1.4");
+ unless(__FUNC__ eq "line_file_1") puts("bad 1.5");
+}
+line_file_1();
+} -output {}
+
+test line-file-2 {test __LINE__, __FILE__, and __FUNC__ errors} -body {
+#lang L --line=1
+void line_file_2_s(string &s) { s = "bad"; }
+void line_file_2_i(int &i) { i = 1; }
+void line_file_2()
+{
+ __FILE__ = "bad";
+ __LINE__ = 1;
+ __FUNC__ = "bad";
+ line_file_2_s(&__FILE__);
+ line_file_2_i(&__LINE__);
+ line_file_2_i(&__FUNC__);
+}
+} -returnCodes {error} -match regexp -result {.*5: L Error: invalid l-value in assignment
+.*6: L Error: invalid l-value in assignment
+.*7: L Error: invalid l-value in assignment
+.*8: L Error: illegal operand to &
+.*9: L Error: illegal operand to &
+.*10: L Error: illegal operand to &
+}
+
+test line-file-3 {test __FUNC__} -body {
+#lang L --line=1
+unless (__FUNC__ =~ /\d+%l_toplevel/) puts("bad 10.1");
+void line_file_3b()
+{
+ unless (__FUNC__ eq "line_file_3b") puts("bad 1");
+}
+void line_file_3()
+{
+ unless (__FUNC__ eq "line_file_3") puts("bad 2");
+ line_file_3b();
+}
+unless (__FUNC__ =~ /\d+%l_toplevel/) puts("bad 10.2");
+line_file_3();
+} -output {}
+
+test lregex-1 {test a trivial regex} -body {
+#lang L --line=1
+int lregex_1(void) {
+ if ("x" =~ /x+/) { return(1); } else { return(0); }
+}
+#lang tcl
+lregex_1;
+} -result {1}
+
+test class-1.1 {test basic class functionality} -body {
+#lang L --line=1
+int class_1_1_inits = 0;
+int class_1_1_frees = 0;
+int class_1_1_foos = 0;
+int class_1_1_privs = 0;
+class class_1_1
+{
+ public int cvar1 = 123;
+ public int cvar2 = cvar1 * 2;
+ instance {
+ public string inst = "initial";
+ }
+ private void priv();
+ constructor class_1_1_init(string s)
+ {
+ unless (inst eq "initial") puts("bad c1");
+ inst = s;
+ ++class_1_1_inits;
+ }
+ destructor class_1_1_free(class_1_1 self)
+ {
+ ++class_1_1_frees;
+ }
+ void class_1_1_foo(class_1_1 self)
+ {
+ ++class_1_1_foos;
+ priv();
+ }
+ string class_1_1_inst(class_1_1 self)
+ {
+ return (inst);
+ }
+ int class_1_1_cvar1(class_1_1 self)
+ {
+ return (cvar1);
+ }
+ int class_1_1_cvar2(class_1_1 self)
+ {
+ return (cvar2);
+ }
+ private void priv()
+ {
+ ++class_1_1_privs;
+ }
+}
+void class_1_1_main()
+{
+ class_1_1 o = class_1_1_init("constructed");
+
+ unless (class_1_1_inst(o) eq "constructed") puts("bad 1.1");
+ unless (class_1_1_cvar1(o) == 123) puts("bad 1.2");
+ unless (class_1_1_cvar2(o) == 246) puts("bad 1.3");
+ unless (class_1_1_inits == 1) puts("bad 1.4");
+ unless (class_1_1_frees == 0) puts("bad 1.5");
+ unless (class_1_1_foos == 0) puts("bad 1.6");
+ unless (class_1_1_privs == 0) puts("bad 1.7");
+
+ class_1_1_foo(o);
+ unless (class_1_1_inits == 1) puts("bad 2.1");
+ unless (class_1_1_frees == 0) puts("bad 2.2");
+ unless (class_1_1_foos == 1) puts("bad 2.3");
+ unless (class_1_1_privs == 1) puts("bad 2.4");
+
+ class_1_1_foo(o);
+ unless (class_1_1_inits == 1) puts("bad 3.1");
+ unless (class_1_1_frees == 0) puts("bad 3.2");
+ unless (class_1_1_foos == 2) puts("bad 3.3");
+ unless (class_1_1_privs == 2) puts("bad 3.4");
+
+ unless (class_1_1_inst(o) eq "constructed") puts("bad 4.1");
+ unless (class_1_1_inits == 1) puts("bad 4.1");
+ unless (class_1_1_frees == 0) puts("bad 4.2");
+ unless (class_1_1_foos == 2) puts("bad 4.3");
+ unless (class_1_1_privs == 2) puts("bad 4.4");
+
+ class_1_1_free(o);
+ unless (class_1_1_inits == 1) puts("bad 5.1");
+ unless (class_1_1_frees == 1) puts("bad 5.2");
+ unless (class_1_1_foos == 2) puts("bad 5.3");
+ unless (class_1_1_privs == 2) puts("bad 5.4");
+}
+class_1_1_main();
+} -output {}
+
+test class-1.2 {test multiple object instances} -body {
+#lang L --line=1
+class class_1_2
+{
+ instance {
+ public int n;
+ }
+ constructor class_1_2_init(int i) { n = i; }
+ destructor class_1_2_free(class_1_2 self) {}
+ int class_1_2_inst(class_1_2 self) { return (n); }
+}
+void class_1_2_main()
+{
+ int i, j;
+ class_1_2 o[];
+
+ for (i = 0; i < 10; ++i) {
+ o[i] = class_1_2_init(i);
+ unless (class_1_2_inst(o[i]) == i) printf("bad 1 i=%d\n", i);
+ }
+ for (i = 0; i < 10; ++i) {
+ unless (class_1_2_inst(o[i]) == i) printf("bad 2 i=%d\n", i);
+ }
+ for (i = 0; i < 10; ++i) {
+ class_1_2_free(o[i]);
+ for (j = i+1; j < 10; ++j) {
+ unless (class_1_2_inst(o[j]) == j) {
+ printf("bad 3 j=%d\n", j);
+ }
+ }
+ }
+}
+class_1_2_main();
+} -output {}
+
+test class-1.3 {test class variables} -body {
+#lang L --line=1
+class class_1_3
+{
+ public string cls_var = "first";
+ constructor class_1_3_init() {}
+ destructor class_1_3_free(class_1_3 self) {}
+ void class_1_3_set(class_1_3 self, string s)
+ {
+ cls_var = s;
+ }
+ string class_1_3_get(class_1_3 self)
+ {
+ return (cls_var);
+ }
+}
+void class_1_3_main()
+{
+ int i, j;
+ class_1_3 o[];
+
+ /* As we init objects, cls_var should not change. */
+ for (i = 0; i < 10; ++i) {
+ o[i] = class_1_3_init();
+ for (j = 0; j <= i; ++j) {
+ unless (class_1_3_get(o[j]) eq "first") {
+ printf("bad 1 j=%d\n", j);
+ }
+ }
+ }
+ /* All objects should see the change to "second". */
+ class_1_3_set(o[5], "second");
+ for (j = 0; i < 10; ++i) {
+ unless (class_1_3_get(o[i]) eq "second") {
+ printf("bad 2 i=%d\n", i);
+ }
+ }
+ /* Deleting one object shouldn't mess up cls_var. */
+ class_1_3_free(o[5]);
+ for (j = 0; i < 10; ++i) {
+ if (i == 5) continue;
+ unless (class_1_3_get(o[i]) eq "second") {
+ printf("bad 2 i=%d\n", i);
+ }
+ }
+}
+class_1_3_main();
+} -output {}
+
+test class-1.4 {test no class instance variables} -body {
+#lang L --line=1
+class class_1_4
+{
+ public int cvar = 123;
+ constructor class_1_4_new()
+ {
+ unless (cvar == 123) puts ("bad c1");
+ }
+ destructor class_1_4_delete(class_1_4 self)
+ {
+ unless (cvar == 123) puts ("bad d1");
+ }
+}
+void class_1_4_main()
+{
+ class_1_4 o = class_1_4_new();
+ class_1_4_delete(o);
+}
+class_1_4_main();
+} -output {}
+
+test class-1.5 {test no class variables} -body {
+#lang L --line=1
+class class_1_5
+{
+ instance {
+ public int inst = 123;
+ }
+ constructor class_1_5_new()
+ {
+ unless (inst == 123) puts ("bad c1");
+ }
+ destructor class_1_5_delete(class_1_5 self)
+ {
+ unless (inst == 123) puts ("bad d1");
+ }
+}
+void class_1_5_main()
+{
+ class_1_5 o = class_1_5_new();
+ class_1_5_delete(o);
+}
+class_1_5_main();
+} -output {}
+
+test class-1.6 {test "->" as member variable selection} -body {
+#lang L --line=1
+class class_1_6
+{
+ public string cvar = "cvar";
+ instance {
+ public string ivar = "ivar";
+ }
+}
+void class_1_6_main()
+{
+ /* Check that -> works ("." is not allowed). */
+
+ class_1_6 o = class_1_6_new();
+
+ unless (class_1_6->cvar eq "cvar") puts("bad 1.1");
+ unless (o->ivar eq "ivar") puts("bad 2.1");
+
+ class_1_6_delete(o);
+}
+class_1_6_main();
+} -output {}
+
+test class-1.7 {test indexing errors on class instance variables} -body {
+#lang L --line=1
+class class_1_7
+{
+ public string cvar = "cvar";
+ instance {
+ public string ivar = "ivar";
+ }
+}
+void class_1_7_main()
+{
+ /* Check that any index other than -> is caught as an error. */
+
+ class_1_7 o = class_1_7_new();
+
+ o.ivar;
+ o{"bad"};
+ o[0];
+}
+} -returnCodes {error} -match regexp -result {.*14: L Error: must access object only with ->
+.*15: L Error: must access object only with ->
+.*16: L Error: must access object only with ->
+}
+
+test class-1.8 {check calling private member functions} -body {
+#lang L --line=1
+/*
+ * Check that private member functions can be called from the
+ * constructor and destructor, whether they are declared before or
+ * after the call site.
+ */
+private int cnt1 = 0;
+private int cnt2 = 0;
+class class_1_8
+{
+ private void p1() { ++cnt1; }
+ constructor class_1_8_new()
+ {
+ p1();
+ p2();
+ }
+ destructor class_1_8_delete(class_1_8 self)
+ {
+ p1();
+ p2();
+ }
+ public void class_1_8_foo(class_1_8 self)
+ {
+ p1();
+ p2();
+ }
+ private void p2() { ++cnt2; }
+}
+void class_1_8_main()
+{
+ class_1_8 o = class_1_8_new();
+ unless (cnt1 == 1) puts("bad 1.1");
+ unless (cnt2 == 1) puts("bad 1.2");
+ class_1_8_foo(o);
+ unless (cnt1 == 2) puts("bad 2.1");
+ unless (cnt2 == 2) puts("bad 2.2");
+ class_1_8_delete(o);
+ unless (cnt1 == 3) puts("bad 3.1");
+ unless (cnt2 == 3) puts("bad 3.2");
+}
+class_1_8_main();
+} -output {}
+
+test class-1.9 {check calling class member fns before they are declared} -body {
+#lang L --line=1
+/*
+ * Check the error cases to make sure that the proto is being
+ * processed before the call site even though it comes after.
+ */
+class class_1_9
+{
+ void class_1_9_f1(class_1_9 self)
+ {
+ class_1_9 o = class_1_9_new(123); // error -- too many args
+ class_1_9_f2(o, 123); // error
+ }
+ constructor class_1_9_new()
+ {
+ class_1_9_f2(self, 123); // error
+ class_1_9_free(self, 123); // error
+ }
+ destructor class_1_9_free(class_1_9 self)
+ {
+ class_1_9_f2(self, 123); // error
+ }
+ void class_1_9_f2(class_1_9 self)
+ {
+ }
+}
+} -returnCodes {error} -match regexp -result {.*14: L Error: too many arguments for function class_1_9_f2
+.*15: L Error: too many arguments for function class_1_9_free
+.*19: L Error: too many arguments for function class_1_9_f2
+.*9: L Error: too many arguments for function class_1_9_new
+.*10: L Error: too many arguments for function class_1_9_f2
+}
+
+test class-1.10 {check forward class declarations} -body {
+#lang L --line=1
+class class_1_10a
+{
+ constructor class_1_10a_new() {}
+}
+class class_1_10a; // ok -- class_1_10a already declared
+class class_1_10a; // ok -- class_1_10a already declared
+class class_1_10b; // forward declaration
+private class_1_10a obj_a;
+private class_1_10b obj_b;
+class class_1_10b
+{
+ constructor class_1_10b_new() {}
+}
+void class_1_10_main()
+{
+ obj_a = class_1_10a_new();
+ obj_b = class_1_10b_new();
+}
+class_1_10_main();
+} -output {}
+
+test class-1.11 {check forward class declaration errors} -body {
+#lang L --line=1
+class class_1_11a {}
+class class_1_11a {} // error -- already declared
+typedef int class_1_11_t;
+class class_1_11_t; // error -- not a class type
+} -returnCodes {error} -match regexp -result {.*2: L Error: redeclaration of class_1_11a
+.*4: L Error: class_1_11_t not a class type
+}
+
+test class-1.12 {check returns from class destructor} -body {
+#lang L --line=1
+/*
+ * Check that an explicit return from with the class destructor does
+ * not bypass the code to delete the namespace instance.
+ */
+class class_1_12 {
+ destructor class_1_12_delete(class_1_12 self)
+ {
+ return;
+ }
+}
+void class_1_12_main()
+{
+ string parent;
+ class_1_12 obj;
+
+ /* Creating a new object creates a new namespace under ::L. */
+ obj = class_1_12_new();
+ if (::catch("set parent [::namespace parent $obj]")) puts("bad 1");
+ unless (parent eq "::L") puts("bad 2");
+
+ /* After this delete, the namepsace should be gone. */
+ class_1_12_delete(obj);
+ unless (::catch("set parent [::namespace parent $obj]")) puts("bad 3");
+}
+class_1_12_main();
+} -output {}
+
+test class-2.1 {check missing class constructor} -body {
+#lang L --line=1
+class class_2_1
+{
+ instance {
+ public int inst = 123;
+ }
+ destructor class_2_1_delete(class_2_1 self)
+ {
+ unless (inst == 123) puts("bad 1");
+ }
+}
+void class_2_1_main()
+{
+ class_2_1 o = class_2_1_new();
+ class_2_1_delete(o);
+}
+class_2_1_main();
+} -output {}
+
+test class-2.2 {check class missing destructor} -body {
+#lang L --line=1
+class class_2_2
+{
+ instance {
+ public int inst = 123;
+ }
+ constructor class_2_2_new()
+ {
+ unless (inst == 123) puts("bad 1");
+ }
+}
+void class_2_2_main()
+{
+ class_2_2 o = class_2_2_new();
+ class_2_2_delete(o);
+}
+class_2_2_main();
+} -output {}
+
+test class-2.2.1 {check class missing constructor and destructor} -body {
+#lang L --line=1
+class class_2_2_1
+{
+ instance {
+ public int inst = 123;
+ }
+ int class_2_2_1_get(class_2_2_1 self) { return inst; }
+}
+void class_2_2_1_main()
+{
+ class_2_2_1 o = class_2_2_1_new();
+ unless (class_2_2_1_get(o) == 123) puts("bad 1");
+ class_2_2_1_delete(o);
+}
+class_2_2_1_main();
+} -output {}
+
+test class-2.3 {check multiple class constructors and destructors} -body {
+#lang L --line=1
+class class_2_3
+{
+ public int n = 0;
+ instance {
+ public int inst = n + 100;
+ }
+ constructor class_2_3_new1()
+ {
+ ++n;
+ return (self);
+ }
+ constructor class_2_3_new2(int i)
+ {
+ n += i;
+ return (self);
+ }
+ destructor class_2_3_delete1(class_2_3 self)
+ {
+ --n;
+ }
+ destructor class_2_3_delete2(class_2_3 self, int i)
+ {
+ n -= i;
+ }
+}
+void class_2_3_main()
+{
+ class_2_3 o1, o2;
+
+ o1 = class_2_3_new1();
+ unless (class_2_3->n == 1) puts("bad 1.1");
+ unless (o1->inst == 100) puts("bad 1.2");
+ o2 = class_2_3_new2(10);
+ unless (class_2_3->n == 11) puts("bad 2.1");
+ unless (o2->inst == 101) puts("bad 2.2");
+ class_2_3_delete1(o2);
+ unless (class_2_3->n == 10) puts("bad 3.1");
+ class_2_3_delete2(o1, 10);
+ unless (class_2_3->n == 0) puts("bad 4.1");
+}
+class_2_3_main();
+} -output {}
+
+test class-2.5 {check missing self argument in class destructor 1} -body {
+#lang L --line=1
+class class_2_5
+{
+ constructor class_2_5_init() {}
+ destructor class_2_5_free() {}
+}
+} -returnCodes {error} -match regexp -result {.*4: L Error: class public member function lacks 'self' as first arg
+}
+
+test class-2.6 {check missing self argument in class destructor 2} -body {
+#lang L --line=1 -nowarn
+class class_2_6
+{
+ constructor class_2_6_init() {}
+ destructor class_2_6_free(string bad) {}
+}
+} -returnCodes {error} -match regexp -result {.*4: L Error: class public member function lacks 'self' as first arg
+}
+
+test class-2.7 {check missing self argument in class destructor 3} -body {
+#lang L --line=1 -nowarn
+class class_2_7
+{
+ constructor class_2_7_init() {}
+ destructor class_2_7_free(string bad, class_2_7 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*4: L Error: class public member function lacks 'self' as first arg
+}
+
+test class-2.8 {check missing self argument in public class member fn} -body {
+#lang L --line=1 -nowarn
+class class_2_8
+{
+ constructor class_2_8_init() {}
+ destructor class_2_8_free(class_2_8 self) {}
+ void class_2_8_foo1() {}
+ void class_2_8_foo2(string bad) {}
+ void class_2_8_foo3(string bad, class_2_8 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*5: L Error: class public member function lacks 'self' as first arg
+.*6: L Error: class public member function lacks 'self' as first arg
+.*7: L Error: class public member function lacks 'self' as first arg
+}
+
+test class-2.9 {check use of self argument in class member fn} -body {
+#lang L --line=1
+class class_2_9
+{
+ constructor class_2_9_init() {}
+ destructor class_2_9_free(class_2_9 self) {}
+ void class_2_9_foo1(class_2_9 self) {}
+ void class_2_9_foo2(class_2_9 self, class_2_9 self) {}
+ void class_2_9_foo3(class_2_9 self, string self) {}
+}
+} -returnCodes {error} -match regexp -result {.*6: L Error: multiple declaration of local self
+.*7: L Error: multiple declaration of local self
+}
+
+test class-2.10 {check declaration of local named self in class} -body {
+#lang L --line=1
+class class_2_10
+{
+ constructor class_2_10_init()
+ {
+ int self;
+ }
+ destructor class_2_10_free(class_2_10 self)
+ {
+ class_2_10 self;
+ }
+ void class_2_10_foo(class_2_10 self)
+ {
+ int self;
+ }
+ private void class_2_10_priv()
+ {
+ int self;
+ }
+}
+} -returnCodes {error} -match regexp -result {.*5: L Error: multiple declaration.*
+.*9: L Error: multiple declaration.*
+.*13: L Error: multiple declaration.*
+.*17: L Error: multiple declaration.*
+}
+
+test class-2.11 {check return stmt in class destructor 1} -body {
+#lang L --line=1
+class class_2_11
+{
+ destructor class_2_11_delete(class_2_11 self)
+ {
+ return; // legal -- return type of void
+ }
+}
+void class_2_11_main()
+{
+ class_2_11 o = class_2_11_new();
+ class_2_11_delete(o);
+}
+class_2_11_main();
+} -output {}
+
+test class-2.12 {check return stmt in class destructor 2} -body {
+#lang L --line=1
+class class_2_12
+{
+ destructor class_2_12_delete(class_2_12 self)
+ {
+ return ("bad"); // err -- return type is void
+ }
+}
+} -returnCodes {error} -match regexp -result {.*5: L Error: void function cannot return value
+}
+
+test class-2.12.1 {check return stmt in class constructor 1} -body {
+#lang L --line=1
+class class_2_12_1
+{
+ instance { public int inst = 123; }
+ constructor class_2_12_1_new()
+ {
+ return (self);
+ }
+ int class_2_12_1_get(class_2_12_1 self) { return (inst); }
+}
+void class_2_12_1_main()
+{
+ class_2_12_1 o = class_2_12_1_new();
+ unless (class_2_12_1_get(o) == 123) puts("bad 1");
+ class_2_12_1_delete(o);
+}
+class_2_12_1_main();
+} -output {}
+
+test class-2.12.2 {check return stmt in class constructor 2} -body {
+#lang L --line=1
+class class_2_12_2
+{
+ constructor class_2_12_2_new()
+ {
+ return ("bad"); // err -- bad return type
+ }
+}
+} -returnCodes {error} -match regexp -result {.*5: L Error: incompatible return type
+}
+
+test class-2.13 {check name clash with class constructor 1} -body {
+#lang L --line=1
+class class_2_13
+{
+ constructor class_2_13_new() {}
+ void class_2_13_new(class_2_13 self) {} // err
+ private void class_2_13_new(class_2_13 self) {} // err
+}
+} -returnCodes {error} -match regexp -result {.*3: L Error: does not match other declaration of class_2_13_new
+.*5: L Error: function class_2_13_new already declared
+}
+
+test class-2.14 {check name clash with class constructor 2} -body {
+#lang L --line=1
+class class_2_14
+{
+ void class_2_14_new(class_2_14 self) {} // err
+ private void class_2_14_new(class_2_14 self) {} // err
+}
+} -returnCodes {error} -match regexp -result {.*1: L Error: does not match other declaration of class_2_14_new
+.*4: L Error: function class_2_14_new already declared
+}
+
+test class-2.15 {check name clash with class destructor 1} -body {
+#lang L --line=1
+class class_2_15
+{
+ destructor class_2_15_delete(class_2_15 self) {}
+ void class_2_15_delete(class_2_15 self) {} // err
+ private void class_2_15_delete(class_2_15 self) {} // err
+}
+} -returnCodes {error} -match regexp -result {.*4: L Error: function class_2_15_delete already declared
+.*5: L Error: function class_2_15_delete already declared
+}
+
+test class-2.16 {check name clash with class destructor 2} -body {
+#lang L --line=1
+class class_2_16
+{
+ void class_2_16_delete(class_2_16 self) {} // err
+ private void class_2_16_delete(class_2_16 self) {} // err
+}
+} -returnCodes {error} -match regexp -result {.*3: L Error: function class_2_16_delete already declared
+.*4: L Error: function class_2_16_delete already declared
+}
+
+test class-2.17 {check illegal self parameter in class constructor 1} -body {
+#lang L --line=1
+class class_2_17
+{
+ constructor class_2_17_new(class_2_17 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*3: L Error: 'self' parameter illegal in class constructor
+}
+
+test class-2.18 {check illegal self parameter in class constructor 2} -body {
+#lang L --line=1 -nowarn
+class class_2_18
+{
+ constructor class_2_18_new(int a, class_2_17 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*3: L Error: 'self' parameter illegal in class constructor
+}
+
+test class-2.20 {check class public member fn with arg without name} -body {
+#lang L --line=1 -nowarn
+class class_2_20
+{
+ /*
+ * This is syntactically legal and the compiler should check
+ * for this error.
+ */
+ public void class_2_20_foo(class_2_20) {}
+}
+} -returnCodes {error} -match regexp -result {.*7: L Error: class public member function lacks 'self' as first arg
+}
+
+test class-2.21 {check class member function use before declare} -body {
+#lang L --line=1
+class class_2_21
+{
+ public int class_2_21_foo(class_2_21 self, int arg)
+ {
+ return (priv(arg) + class_2_21_pub(self, arg));
+ }
+ private int priv(int arg)
+ {
+ return (arg);
+ }
+ public int class_2_21_pub(class_2_21 self, int arg)
+ {
+ return (-arg);
+ }
+}
+void class_2_21_main()
+{
+ class_2_21 o;
+
+ o = class_2_21_new();
+ unless (class_2_21_foo(o, 13) == 0) puts("bad 1");
+}
+class_2_21_main();
+} -output {}
+
+test class-2.22 {check self in private member function} -body {
+#lang L --line=1
+class class_2_22 {
+ constructor class_2_22_init() {
+ some_method(self);
+ }
+ private void some_method(class_2_22 self) {}
+ private void some_method2(int ok, class_2_22 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*5: L Error: 'self' parameter illegal in private function
+.*6: L Error: 'self' parameter illegal in private function
+}
+
+test class-3.1 {check scoping of class vars and class instance vars 1} -body {
+#lang L --line=1
+class class_3_1
+{
+ /*
+ * Class variables and instance variables should both be at
+ * class scope, so a name clash should be an error. Note that
+ * because the instance var always get compiled first, we
+ * don't check for line #'s in the error messages.
+ */
+ instance {
+ public int x;
+ }
+ public int x;
+ private int x;
+ public int x;
+ constructor class_3_1_init() {}
+ destructor class_3_1_free(class_3_1 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*: L Error: multiple declaration of x
+.*: L Error: multiple declaration of x
+.*: L Error: multiple declaration of x
+}
+
+test class-3.2 {check scoping of class vars and class instance vars 2} -body {
+#lang L --line=1
+class class_3_2
+{
+ /*
+ * Like the class_3_1 test but with multiple instance declarations.
+ * Note that because the instance var always get compiled
+ * first, we don't check for line #'s in the error messages.
+ */
+ instance {
+ public int x;
+ private int x;
+ public int x;
+ }
+ public int x;
+ constructor class_3_2_init() {}
+ destructor class_3_2_free(class_3_2 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*: L Error: multiple declaration of x
+.*: L Error: multiple declaration of x
+.*: L Error: multiple declaration of x
+}
+
+test class-3.3 {check empty class instance variable section} -body {
+#lang L --line=1
+class class_3_3
+{
+ instance {}
+}
+} -result {}
+
+test class-3.3.1 {check completely empty class declaration} -body {
+#lang L --line=1
+class class_3_3_1 {}
+void class_3_3_1_main()
+{
+ class_3_3_1 o = class_3_3_1_new();
+ class_3_3_1_delete(o);
+}
+class_3_3_1_main();
+} -output {}
+
+test class-3.4 {check scoping of class vars and class instance vars 4} -body {
+#lang L --line=1
+class class_3_4
+{
+ /*
+ * Like the class_3_3 test but with var decls in the reverse order.
+ * Note that because the instance var always get compiled first,
+ * we don't check for line #'s in the error messages.
+ */
+ public int x;
+ private int x;
+ instance {
+ public int x;
+ private int x;
+ }
+ constructor class_3_4_init() {}
+ destructor class_3_4_free(class_3_4 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*: L Error: multiple declaration of x
+.*: L Error: multiple declaration of x
+.*: L Error: multiple declaration of x
+}
+
+test class-3.5 {check scoping of class vars and class instance vars 5} -body {
+#lang L --line=1
+class class_3_5
+{
+ /*
+ * Like the class_3_2 test but with private and public function
+ * declarations of the same name as the variables. Note that
+ * because the instance var always get compiled first, we
+ * don't check for all line #'s in the error messages.
+ */
+ instance {
+ public int class_3_5_x;
+ public int class_3_5_x; // err -- multiply declared
+ }
+ public int class_3_5_x; // err -- multiply declared
+ public int class_3_5_x; // err -- multiply declared
+ private void class_3_5_x() {} // err -- already declared as a variable
+ void class_3_5_x() {} // err -- already declared as a variable
+ public void class_3_5_x() {} // err -- already declared as a variable
+ constructor class_3_5_init() {}
+ destructor class_3_5_free(class_3_5 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*: L Error: multiple declaration of class_3_5_x
+.*: L Error: multiple declaration of class_3_5_x
+.*: L Error: multiple declaration of class_3_5_x
+.*15: L Error: class_3_5_x already declared as a variable
+.*16: L Error: class_3_5_x already declared as a variable
+.*17: L Error: class_3_5_x already declared as a variable
+}
+
+test class-3.6 {check scoping of class vars and class instance vars 6} -body {
+#lang L --line=1
+class class_3_6
+{
+ /*
+ * Like the class_3_5 test but with only a public function
+ * declaration of the same name as the variables. Note that
+ * because the instance var always get compiled first, we
+ * don't check for all line #'s in the error messages.
+ */
+ instance {
+ public int class_3_6_x;
+ public int class_3_6_x; // err -- multiply declared
+ }
+ public int class_3_6_x; // err -- multiply declared
+ public int class_3_6_x; // err -- multiply declared
+ void class_3_6_x() {} // err -- already declared as a variable
+ constructor class_3_6_init() {}
+ destructor class_3_6_free(class_3_6 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*: L Error: multiple declaration of class_3_6_x
+.*: L Error: multiple declaration of class_3_6_x
+.*: L Error: multiple declaration of class_3_6_x
+.*15: L Error: class_3_6_x already declared as a variable
+}
+
+test class-3.7 {check variable visibility in class member functions} -body {
+#lang L --line=1
+/*
+ * Ensure class and instance variables are visible and work
+ * inside of all class member functions.
+ */
+class class_3_7
+{
+ public string publ_cvar = "publ_cvar";
+ private string priv_cvar = "priv_cvar";
+ instance {
+ public string publ_ivar = "publ_ivar";
+ private string priv_ivar = "priv_ivar";
+ }
+ constructor class_3_7_init()
+ {
+ unless (publ_cvar eq "publ_cvar") puts("bad c1");
+ unless (priv_cvar eq "priv_cvar") puts("bad c2");
+ unless (publ_cvar eq "publ_cvar") puts("bad c3");
+ unless (priv_ivar eq "priv_ivar") puts("bad c4");
+ }
+ destructor class_3_7_free(class_3_7 self)
+ {
+ unless (publ_cvar eq "publ_cvar") puts("bad d1");
+ unless (priv_cvar eq "priv_cvar") puts("bad d2");
+ unless (publ_ivar eq "publ_ivar") puts("bad d3");
+ unless (priv_ivar eq "priv_ivar") puts("bad d4");
+ }
+ private void priv()
+ {
+ unless (publ_cvar eq "publ_cvar") puts("bad p1");
+ unless (priv_cvar eq "priv_cvar") puts("bad p2");
+ unless (publ_ivar eq "publ_ivar") puts("bad p3");
+ unless (priv_ivar eq "priv_ivar") puts("bad p4");
+ }
+ void class_3_7_foo(class_3_7 self)
+ {
+ unless (publ_cvar eq "publ_cvar") puts("bad f1");
+ unless (priv_cvar eq "priv_cvar") puts("bad f2");
+ unless (publ_ivar eq "publ_ivar") puts("bad f3");
+ unless (priv_ivar eq "priv_ivar") puts("bad f4");
+ priv();
+ }
+}
+void class_3_7_main()
+{
+ class_3_7 o = class_3_7_init();
+ class_3_7_foo(o);
+ class_3_7_free(o);
+}
+class_3_7_main();
+} -output {}
+
+test class-3.8 {check missing public/private qualifiers on class vars} -body {
+#lang L --line=1
+class class_3_8
+{
+ int bad1, bad2;
+ int bad3;
+ instance {
+ int ibad1, ibad2;
+ int ibad3;
+ }
+}
+} -returnCodes {error} -match regexp -result {.*3: L Error: class variable bad1 not declared public or private
+.*3: L Error: class variable bad2 not declared public or private
+.*4: L Error: class variable bad3 not declared public or private
+.*6: L Error: class instance variable ibad1 not declared public or private
+.*6: L Error: class instance variable ibad2 not declared public or private
+.*7: L Error: class instance variable ibad3 not declared public or private
+}
+
+test class-3.9 {check expressions in class and instance variable intializers} -body {
+#lang L --line=1
+class class_3_9
+{
+ /*
+ * These initializers check that the declarations get compiled
+ * top-to-bottom and left-to-right.
+ */
+ private int c1 = 1;
+ private int c2 = c1 * 2, c3 = c2 + 3;
+ instance {
+ /* These get evaluated when the constructor runs. */
+ private int i1 = c1;
+ private int i2 = c2 * 2, i3 = i2 + 3;
+ }
+ constructor class_3_9_new()
+ {
+ unless (c1 == 1) puts("bad c1");
+ unless (c2 == (c1 * 2)) puts("bad c2");
+ unless (c3 == (c2 + 3)) puts("bad c3");
+ unless (i1 == c1) puts("bad c4");
+ unless (i2 == (c2 * 2)) puts("bad c5");
+ unless (i3 == (i2 + 3)) puts("bad c6");
+ }
+}
+void class_3_9_main()
+{
+ class_3_9 o = class_3_9_new();
+ class_3_9_delete(o);
+}
+class_3_9_main();
+} -output {}
+
+test class-3.10 {check dereferncing struct type name like a class name} -body {
+#lang L --line=1
+/*
+ * This used to assert: declare a typedef for a struct and then
+ * use the struct name like a class name to dereference a class
+ * variable.
+ */
+typedef struct {
+ int x;
+} class_3_10_var;
+void class_3_10_main()
+{
+ class_3_10_var->x;
+}
+class_3_10_main();
+} -returnCodes {error} -match regexp -result {.*11: L Error: can dereference only class types
+}
+
+test class-4.1 {check scoping of private names in classes} -body {
+#lang L --line=1
+/*
+ * Check that per-class variables are defined in the class scope,
+ * meaning that two classes can have the same variable names and the
+ * same names as global variables.
+ */
+int class_4_1_global_var = 100;
+int class_4_1_global_var2 = 101;
+void class_4_1_global_func() {}
+class class_4_1_1
+{
+ public int class_4_1_global_var = 411; // OK -- shadows the global
+ instance {
+ public int class_4_1_global_var2 = 811; // also OK
+ }
+
+ constructor class_4_1_1_init() {}
+ destructor class_4_1_1_free(class_4_1_1 self) {}
+ private int priv() { return (class_4_1_global_var); }
+ int class_4_1_1_get(class_4_1_1 self)
+ {
+ unless (class_4_1_global_var2 == 811) puts("bad c1");
+ return (priv());
+ }
+}
+class class_4_1_2
+{
+ public int class_4_1_global_var = 412; // OK -- shadows the global
+ instance {
+ public int class_4_1_global_var2 = 812; // also OK
+ }
+
+ constructor class_4_1_2_init() {}
+ destructor class_4_1_2_free(class_4_1_2 self) {}
+ private int priv() { return (class_4_1_global_var); }
+ int class_4_1_2_get(class_4_1_2 self)
+ {
+ unless (class_4_1_global_var2 == 812) puts("bad c2");
+ return (priv());
+ }
+}
+void class_4_1()
+{
+ class_4_1_1 o411 = class_4_1_1_init();
+ class_4_1_2 o412 = class_4_1_2_init();
+
+ unless (class_4_1_global_var == 100) puts("bad 1");
+ unless (class_4_1_1_get(o411) == 411) puts("bad 2");
+ unless (class_4_1_2_get(o412) == 412) puts("bad 3");
+ unless (class_4_1_global_var == 100) puts("bad 4");
+}
+class_4_1();
+} -output {}
+
+test class-4.2 {check typedef and struct type scoping in classes 1} -body {
+#lang L --line=1
+/*
+ * Check that typedef and struct names declared inside a class get
+ * defined at the global scope, not at the class scope. This test
+ * checks that a re-declaration of a global type name inside class
+ * scope is an error.
+ */
+typedef int class_4_2_type;
+struct class_4_2_struct {
+ int i;
+ string s;
+};
+class class_4_2
+{
+ public class_4_2_type i;
+ public struct class_4_2_struct st;
+
+ typedef string class_4_2_type; // err -- already defined
+ struct class_4_2_struct { // err -- already defined
+ int a[];
+ };
+
+ constructor class_4_2_init() {}
+ destructor class_4_2_free(class_4_2_1 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*17: L Error: Cannot redefine type class_4_2_type
+.*19: L Error: multiple declaration of struct class_4_2_struct
+}
+
+test class-4.3 {check typedef and struct type scoping in classes 2} -body {
+#lang L --line=1 -nowarn
+/*
+ * Check that typedef and struct names declared inside a class get
+ * defined at the global scope, not at the class scope. This test
+ * checks that a declaration of a global type name inside class scope
+ * is visible outside that scope.
+ */
+class class_4_3_1
+{
+ typedef string class_4_3_type;
+ struct class_4_3_struct {
+ string s;
+ };
+
+ public class_4_3_type s = "431";
+ public struct class_4_3_struct st = { "431" };
+
+ constructor class_4_3_1_init()
+ {
+ unless (s eq "431") puts("bad c1.1");
+ unless (st.s eq "431") puts("bad c1.2");
+ }
+ destructor class_4_3_1_free(class_4_3_1 self) {}
+}
+
+class_4_3_type gs = "g43";
+struct class_4_3_struct gst = { "g43" };
+
+class class_4_3_2
+{
+ public class_4_3_type s = "432";
+ public struct class_4_3_struct st = { "432" };
+
+ constructor class_4_3_2_init()
+ {
+ unless (s eq "432") puts("bad c2.1");
+ unless (st.s eq "432") puts("bad c2.2");
+ }
+ destructor class_4_3_2_free(class_4_3_2 self) {}
+}
+void class_4_3_main()
+{
+ class_4_3_1 o431 = class_4_3_1_init();
+ class_4_3_2 o432 = class_4_3_2_init();
+
+ unless (gs eq "g43") puts("bad 1");
+ unless (gst.s eq "g43") puts("bad 2");
+}
+class_4_3_main();
+} -output {}
+
+test class-5.1 {check class object type checking} -body {
+#lang L --line=1 -nowarn
+class class_5_1_1
+{
+ constructor class_5_1_1_init() {}
+ destructor class_5_1_1_free(class_5_1_1 self) {}
+ void class_5_1_1_foo(class_5_1_1 self, int a) {}
+}
+class class_5_1_2
+{
+ constructor class_5_1_2_init() {}
+ destructor class_5_1_2_free(class_5_1_2 self) {}
+ void class_5_1_2_foo(class_5_1_2 self, int a) {}
+}
+void class_5_1()
+{
+ class_5_1_1 o511;
+ class_5_1_2 o512;
+
+ /* These are all type errors (wrong class). */
+ o511 = class_5_1_2_init();
+ o512 = class_5_1_1_init();
+ class_5_1_1_foo(o512, 0);
+ class_5_1_2_foo(o511, 0);
+ class_5_1_1_free(o512);
+ class_5_1_2_free(o511);
+}
+} -returnCodes {error} -match regexp -result {.*19: L Error: assignment of incompatible types
+.*20: L Error: assignment of incompatible types
+.*21: L Error: parameter 1 has incompatible type
+.*22: L Error: parameter 1 has incompatible type
+.*23: L Error: parameter 1 has incompatible type
+.*24: L Error: parameter 1 has incompatible type
+}
+
+test class-5.2 {check wrong object type in class member fn declarations} -body {
+#lang L --line=1
+class class_5_2_1
+{
+ constructor class_5_2_1_init() {}
+ destructor class_5_2_1_free(class_5_2_1 self) {}
+}
+class class_5_2_2
+{
+ constructor class_5_2_2_init() {}
+ /* These have the wrong class as the arg type. */
+ destructor class_5_2_2_free(class_5_2_1 self) {}
+ void class_5_2_2_foo(class_5_2_1 self) {}
+}
+} -returnCodes {error} -match regexp -result {.*10: L Error: 'self' parameter must be of class type
+.*11: L Error: 'self' parameter must be of class type
+}
+
+test class-5.3 {check that class member fn args get type checked 1} -body {
+#lang L --line=1 -nowarn
+/*
+ * This test checks that class member function arguments are
+ * type checked. There should be no type errors in this example.
+ */
+typedef string myhash{int};
+class class_5_3 {
+ constructor class_5_3_init(int a, string b, myhash c) {}
+ destructor class_5_3_free(class_5_3 self) {}
+ private void priv(myhash a, int b, int c) {}
+ string class_5_3_foo(class_5_3 self, string a, int b) {
+ myhash h;
+ priv(h, 3, 4);
+ return(a);
+ }
+}
+void class_5_3_main()
+{
+ myhash h;
+ class_5_3 o = class_5_3_init(1, "str", h);
+ unless (class_5_3_foo(o, "foo", 3) eq "foo") puts("bad 1");
+}
+class_5_3_main();
+} -output {}
+
+test class-5.4 {check that class member fn args get type checked 2} -body {
+#lang L --line=1 -nowarn
+/*
+ * This test checks that class member function arguments are
+ * type checked. This example has type errors.
+ */
+typedef string myhash{int};
+class class_5_4 {
+ constructor class_5_4_init(int a, string b, myhash c) {}
+ destructor class_5_4_free(class_5_4 self) {}
+ private void priv(myhash a, int b, int c) {}
+ string class_5_4_foo(class_5_4 self, string a, int b) {
+ myhash h;
+ priv(3, h, 4); // args 1,2 backwards
+ return(b); // bad return type
+ }
+}
+void class_5_4_main()
+{
+ int i;
+ myhash h;
+ class_5_4 o = class_5_4_init(1, h, "str"); // args 2,3 backwards
+
+ i = class_5_4_foo(o, 3, "foo"); // args 2,3 backwards
+}
+class_5_4_main();
+} -returnCodes {error} -match regexp -result {.*12: L Error: parameter 1 has incompatible type
+.*12: L Error: parameter 2 has incompatible type
+.*13: L Error: incompatible return type
+.*20: L Error: parameter 2 has incompatible type
+.*20: L Error: parameter 3 has incompatible type
+.*22: L Error: parameter 2 has incompatible type
+.*22: L Error: parameter 3 has incompatible type
+.*22: L Error: assignment of incompatible types
+}
+
+test class-6.1 {check class variable access from outside class} -body {
+#lang L --line=1
+void class_6_1_str(string &s, string new)
+{
+ s = new;
+}
+void class_6_1_hash(string &h{int}, int k, string v)
+{
+ h{k} = v;
+}
+void class_6_1_arr(int &a[][], int i, int j, int v)
+{
+ a[i][j] = v;
+}
+class class_6_1
+{
+ public string s = "cvar";
+ public string h{int} = { 1=>"one", 2=>"two" };
+ public string a[] = { "zero", "one", "two" };
+ public int aa[][] = { {1,2}, {3,4} };
+}
+void class_6_1_main()
+{
+ /*
+ * This test also checks the use of complex class variables
+ * as well as class variables as reference parameters.
+ */
+
+ unless (class_6_1->s eq "cvar") puts("bad 1.1");
+ unless (class_6_1->h{1} eq "one") puts("bad 1.2");
+ unless (class_6_1->h{2} eq "two") puts("bad 1.3");
+ unless (class_6_1->a[0] eq "zero") puts("bad 1.4");
+ unless (class_6_1->a[1] eq "one") puts("bad 1.5");
+ unless (class_6_1->a[2] eq "two") puts("bad 1.6");
+ unless (class_6_1->aa[0][0] == 1) puts("bad 1.10");
+ unless (class_6_1->aa[0][1] == 2) puts("bad 1.11");
+ unless (class_6_1->aa[1][0] == 3) puts("bad 1.12");
+ unless (class_6_1->aa[1][1] == 4) puts("bad 1.13");
+
+ class_6_1->s = "new";
+ unless (class_6_1->s eq "new") puts("bad 2.1");
+
+ class_6_1->h = { 3=>"three" };
+ unless (class_6_1->h{3} eq "three") puts("bad 3.1");
+ unless (length(class_6_1->h) == 1) puts("bad 3.2");
+
+ class_6_1->a = { "just-one" };
+ unless (class_6_1->a[0] eq "just-one") puts("bad 4.1");
+ unless (length(class_6_1->a) == 1) puts("bad 4.2");
+
+ class_6_1->aa = { {5} };
+ unless (class_6_1->aa[0][0] == 5) puts("bad 5.1");
+ unless (length(class_6_1->aa) == 1) puts("bad 5.2");
+ unless (length(class_6_1->aa[0]) == 1) puts("bad 5.3");
+
+ class_6_1_str(&class_6_1->s, "new-s");
+ unless (class_6_1->s eq "new-s") puts("bad 6.1");
+
+ class_6_1->h = {};
+ class_6_1_hash(&class_6_1->h, 4, "four");
+ unless (class_6_1->h{4} eq "four") puts("bad 7.1");
+ unless (length(class_6_1->h) == 1) puts("bad 7.2");
+ if (defined(class_6_1->h{5})) puts("bad 7.3");
+
+ class_6_1->aa = {};
+ class_6_1_arr(&class_6_1->aa, 0, 0, 11);
+ class_6_1_arr(&class_6_1->aa, 0, 1, 12);
+ class_6_1_arr(&class_6_1->aa, 1, 0, 13);
+ class_6_1_arr(&class_6_1->aa, 1, 1, 14);
+ unless (class_6_1->aa[0][0] == 11) puts("bad 8.1");
+ unless (class_6_1->aa[0][1] == 12) puts("bad 8.2");
+ unless (class_6_1->aa[1][0] == 13) puts("bad 8.3");
+ unless (class_6_1->aa[1][1] == 14) puts("bad 8.4");
+ unless (length(class_6_1->aa) == 2) puts("bad 8.5");
+ unless (length(class_6_1->aa[0]) == 2) puts("bad 8.6");
+ unless (length(class_6_1->aa[1]) == 2) puts("bad 8.7");
+ if (defined(class_6_1->aa[2])) puts("bad 8.8");
+}
+class_6_1_main();
+} -output {}
+
+test class-6.2 {check class variable access errors from outside class} -body {
+#lang L --line=1 -nowarn
+class class_6_2
+{
+ private string s = "cvar";
+}
+void class_6_2_main()
+{
+ string bad = class_6_2->s; // error
+}
+} -returnCodes {error} -match regexp -result {.*7: L Error: s is not a public variable of class class_6_2
+}
+
+test class-6.3 {check class variable access from inside class} -body {
+#lang L --line=1
+class class_6_3
+{
+ public string cpubl = "publ-cvar";
+ private string cpriv = "priv-cvar";
+ constructor class_6_3_new()
+ {
+ unless (cpubl eq "publ-cvar") puts("bad c1");
+ unless (cpriv eq "priv-cvar") puts("bad c2");
+ unless (class_6_3->cpubl eq "publ-cvar") puts("bad c3");
+ unless (class_6_3->cpriv eq "priv-cvar") puts("bad c4");
+ }
+ public void class_6_3_foo(class_6_3 self)
+ {
+ unless (cpubl eq "publ-cvar") puts("bad foo.1");
+ unless (cpriv eq "priv-cvar") puts("bad foo.2");
+ unless (class_6_3->cpubl eq "publ-cvar") puts("bad foo.3");
+ unless (class_6_3->cpriv eq "priv-cvar") puts("bad foo.4");
+ }
+ destructor class_6_3_delete(class_6_3 self)
+ {
+ unless (cpubl eq "publ-cvar") puts("bad d1");
+ unless (cpriv eq "priv-cvar") puts("bad d2");
+ unless (class_6_3->cpubl eq "publ-cvar") puts("bad d3");
+ unless (class_6_3->cpriv eq "priv-cvar") puts("bad d4");
+ }
+}
+void class_6_3_main()
+{
+ class_6_3 o = class_6_3_new();
+ class_6_3_foo(o);
+ class_6_3_delete(o);
+}
+class_6_3_main();
+} -output {}
+
+test class-6.4 {check erroneous class instance var access via class name} -body {
+#lang L --line=1
+class class_6_4
+{
+ instance {
+ public string ipubl;
+ private string ipriv;
+ }
+ constructor class_6_4_new()
+ {
+ string s;
+ s = class_6_4->ipubl; // err
+ s = class_6_4->ipriv; // err
+ }
+}
+void class_6_4_main()
+{
+ string s;
+ class_6_4 o = class_6_4_new();
+
+ s = class_6_4->ipubl; // err
+ s = class_6_4->ipriv; // err
+
+ class_6_4_delete(o);
+}
+class_6_4_main();
+} -returnCodes {error} -match regexp -result {.*10: L Error: ipubl is not a class variable of class class_6_4
+.*11: L Error: ipriv is not a class variable of class class_6_4
+.*19: L Error: ipubl is not a class variable of class class_6_4
+.*20: L Error: ipriv is not a class variable of class class_6_4
+}
+
+test class-6.5 {check class instance var access from outside class} -body {
+#lang L --line=1
+class class_6_5
+{
+ instance {
+ public string ivar1;
+ public string ivar2;
+ }
+ constructor class_6_5_new(string s1, string s2)
+ {
+ ivar1 = s1;
+ ivar2 = s2;
+ }
+}
+void class_6_5_main()
+{
+ class_6_5 o1 = class_6_5_new("a", "b");
+ class_6_5 o2 = class_6_5_new("c", "d");
+ class_6_5 o3 = class_6_5_new("e", "f");
+
+ unless (o1->ivar1 eq "a") puts("bad 1");
+ unless (o1->ivar2 eq "b") puts("bad 2");
+ unless (o2->ivar1 eq "c") puts("bad 3");
+ unless (o2->ivar2 eq "d") puts("bad 4");
+ unless (o3->ivar1 eq "e") puts("bad 5");
+ unless (o3->ivar2 eq "f") puts("bad 6");
+
+ class_6_5_delete(o1);
+ class_6_5_delete(o2);
+ class_6_5_delete(o3);
+}
+class_6_5_main();
+} -output {}
+
+test class-6.6 {check class instance var access errs from outside class} -body {
+#lang L --line=1
+class class_6_6
+{
+ instance {
+ private string ivar1;
+ public string ivar2;
+ }
+}
+void class_6_6_main()
+{
+ string s;
+ class_6_6 o = class_6_6_new();
+
+ s = o->ivar1; // err
+}
+} -returnCodes {error} -match regexp -result {.*13: L Error: ivar1 is not a public variable of class class_6_6
+}
+
+test class-6.7 {check class instance var access from inside class} -body {
+#lang L --line=1
+class class_6_7
+{
+ instance {
+ public string ivar1;
+ public string ivar2;
+ }
+ constructor class_6_7_new(string s1, string s2)
+ {
+ ivar1 = s1;
+ ivar2 = s2;
+ }
+ public void class_6_7_chk(class_6_7 self, string s1, string s2)
+ {
+ unless (ivar1 eq s1) puts("bad chk.1");
+ unless (ivar2 eq s2) puts("bad chk.2");
+ unless (self->ivar1 eq s1) puts("bad chk.3");
+ unless (self->ivar2 eq s2) puts("bad chk.4");
+ }
+ private void chkother(class_6_7 other, string s1, string s2)
+ {
+ unless (other->ivar1 eq s1) puts("bad priv.chkother.1");
+ unless (other->ivar2 eq s2) puts("bad priv.chkother.2");
+ }
+ public void class_6_7_chkother(class_6_7 self, class_6_7 other,
+ string s1, string s2)
+ {
+ unless (other->ivar1 eq s1) puts("bad chkother.1");
+ unless (other->ivar2 eq s2) puts("bad chkother.2");
+ chkother(other, s1, s2);
+ }
+}
+void class_6_7_main()
+{
+ class_6_7 o1 = class_6_7_new("a", "b");
+ class_6_7 o2 = class_6_7_new("c", "d");
+ class_6_7 o3 = class_6_7_new("e", "f");
+
+ class_6_7_chk(o1, "a", "b");
+ class_6_7_chk(o2, "c", "d");
+ class_6_7_chk(o3, "e", "f");
+
+ class_6_7_chkother(o2, o1, "a", "b");
+ class_6_7_chkother(o1, o2, "c", "d");
+ class_6_7_chkother(o1, o3, "e", "f");
+
+ class_6_7_delete(o1);
+ class_6_7_delete(o2);
+ class_6_7_delete(o3);
+}
+class_6_7_main();
+} -output {}
+
+test class-6.8 {check class variable access errors} -body {
+#lang L --line=1
+class class_6_8
+{
+ public string cpubl;
+ private string cpriv;
+}
+void class_6_8_main()
+{
+ string s;
+ class_6_8 o = class_6_8_new();
+
+ s = o->cpubl; // err
+ s = o->cpriv; // err
+}
+} -returnCodes {error} -match regexp -result {.*11: L Error: cpubl is not an instance variable of class class_6_8
+.*12: L Error: cpriv is not an instance variable of class class_6_8
+}
+
+test class-7.1 {check object erroneously declared with same name as class} -body {
+#lang L --line=1 -nowarn
+class class_7_1 {}
+void class_7_1_main()
+{
+ class_7_1 class_7_1; // err
+}
+} -returnCodes {error} -match regexp -result {.*4: L Error: cannot declare object with same name as class
+}
+
+test class-8.1 {check class variables as l-values} -body {
+#lang L --line=1
+class class_8_1
+{
+ public string s;
+ public int i;
+
+ public void class_8_1_chk(class_8_1 self)
+ {
+ class_8_1->s = "abcd";
+ unless (class_8_1->s eq "abcd") puts("bad c1.1");
+
+ class_8_1->s[0] = "xyz";
+ unless (class_8_1->s eq "xyzbcd") puts("bad c1.2");
+
+ class_8_1->s[END+1] = "pdq";
+ unless (class_8_1->s eq "xyzbcdpdq") puts("bad c1.3");
+
+ unless (class_8_1->s =~ /bcd/) puts("bad c1.4");
+
+ class_8_1->s =~ s/bcd/dcb/;
+ unless (class_8_1->s eq "xyzdcbpdq") puts("bad c1.5");
+
+ class_8_1->s[0] =~ s/x/0/;
+ unless (class_8_1->s eq "0yzdcbpdq") puts("bad c1.6");
+
+ class_8_1->i = 2;
+ unless (class_8_1->i == 2) puts("bad c2.1");
+
+ class_8_1->i += 2;
+ unless (class_8_1->i == 4) puts("bad c2.2");
+
+ class_8_1->i += class_8_1->i;
+ unless (class_8_1->i == 8) puts("bad c2.3");
+ }
+}
+void class_8_1_main()
+{
+ class_8_1 o = class_8_1_new();
+
+ class_8_1_chk(o);
+
+ class_8_1->s = "abcd";
+ unless (class_8_1->s eq "abcd") puts("bad 1.1");
+
+ class_8_1->s[0] = "xyz";
+ unless (class_8_1->s eq "xyzbcd") puts("bad 1.2");
+
+ class_8_1->s[END+1] = "pdq";
+ unless (class_8_1->s eq "xyzbcdpdq") puts("bad 1.3");
+
+ unless (class_8_1->s =~ /bcd/) puts("bad 1.4");
+
+ class_8_1->s =~ s/bcd/dcb/;
+ unless (class_8_1->s eq "xyzdcbpdq") puts("bad 1.5");
+
+ class_8_1->s[0] =~ s/x/0/;
+ unless (class_8_1->s eq "0yzdcbpdq") puts("bad 1.6");
+
+ class_8_1->i = 2;
+ unless (class_8_1->i == 2) puts("bad 2.1");
+
+ class_8_1->i += 2;
+ unless (class_8_1->i == 4) puts("bad 2.2");
+
+ class_8_1->i += class_8_1->i;
+ unless (class_8_1->i == 8) puts("bad 2.3");
+
+ class_8_1_chk(o);
+}
+class_8_1_main();
+} -output {}
+
+test class-8.1.5 {check class and class instance variables used in nested scopes} -body {
+#lang L --line=1
+class class_8_1_5
+{
+ private int n = 0;
+ public int cnum = -1;
+ instance { public int num = n++; }
+ constructor class_8_1_5_new() { ++cnum; }
+}
+void class_8_1_5_main()
+{
+ /*
+ * This test checks that the compiler-generated temps used for
+ * accessing class and instance variables are allocated
+ * properly in the presence of nested scopes. There was a
+ * prior compiler bug where duplicate temps could be created.
+ */
+
+ int i, j;
+ int n = 10;
+ class_8_1_5 o1, o2, o3, o4, o[];
+
+ o1 = class_8_1_5_new();
+ unless ((o1->num == 0) && (class_8_1_5->cnum == 0)) puts("bad 1");
+ o2 = class_8_1_5_new();
+ unless ((o2->num == 1) && (class_8_1_5->cnum == 1)) puts("bad 2");
+
+ for (i = 0; i < n; ++i) {
+ o[i] = class_8_1_5_new();
+ unless (o[i]->num == (i+2)) puts("bad 3.1");
+ unless (class_8_1_5->cnum == (i+2)) puts("bad 3.2");
+ for (j = 0; j < i; ++j) {
+ unless (o[j]->num == (j+2)) puts("bad 4.1");
+ }
+ }
+ for (i = 0; i < n; ++i) {
+ unless (o[i]->num == (i+2)) puts("bad 5.1");
+ }
+ o3 = class_8_1_5_new();
+ unless (o3->num == (n+2)) puts("bad 6.1");
+ unless (class_8_1_5->cnum == (n+2)) puts("bad 6.2");
+ o4 = class_8_1_5_new();
+ unless (o4->num == (n+3)) puts("bad 7.1");
+ unless (class_8_1_5->cnum == (n+3)) puts("bad 7.2");
+}
+class_8_1_5_main();
+} -output {}
+
+test class-8.2 {check class instance variables as l-values} -body {
+#lang L --line=1
+class class_8_2
+{
+ instance {
+ public string s;
+ public int i;
+ }
+ constructor class_8_2_new()
+ {
+ self->s = "abcd";
+ unless (self->s eq "abcd") puts("bad 1.1");
+
+ self->s[0] = "xyz";
+ unless (self->s eq "xyzbcd") puts("bad 1.2");
+
+ self->s[END+1] = "pdq";
+ unless (self->s eq "xyzbcdpdq") puts("bad 1.3");
+
+ unless (self->s =~ /bcd/) puts("bad 1.4");
+
+ self->s =~ s/bcd/dcb/;
+ unless (self->s eq "xyzdcbpdq") puts("bad 1.5");
+
+ self->s[0] =~ s/x/0/;
+ unless (self->s eq "0yzdcbpdq") puts("bad 1.6");
+
+ self->i = 2;
+ unless (self->i == 2) puts("bad 2.1");
+
+ self->i += 2;
+ unless (self->i == 4) puts("bad 2.2");
+
+ self->i += self->i;
+ unless (self->i == 8) puts("bad 2.3");
+ }
+ public void class_8_2_chk(class_8_2 self, class_8_2 other)
+ {
+ other->s = "abcd";
+ unless (other->s eq "abcd") puts("bad 1.1");
+
+ other->s[0] = "xyz";
+ unless (other->s eq "xyzbcd") puts("bad 1.2");
+
+ other->s[END+1] = "pdq";
+ unless (other->s eq "xyzbcdpdq") puts("bad 1.3");
+
+ unless (other->s =~ /bcd/) puts("bad 1.4");
+
+ other->s =~ s/bcd/dcb/;
+ unless (other->s eq "xyzdcbpdq") puts("bad 1.5");
+
+ other->s[0] =~ s/x/0/;
+ unless (other->s eq "0yzdcbpdq") puts("bad 1.6");
+
+ other->i = 2;
+ unless (other->i == 2) puts("bad 2.1");
+
+ other->i += 2;
+ unless (other->i == 4) puts("bad 2.2");
+
+ other->i += other->i;
+ unless (other->i == 8) puts("bad 2.3");
+ }
+}
+void class_8_2_main()
+{
+ class_8_2 o = class_8_2_new();
+
+ class_8_2_chk(o, o);
+
+ o->s = "abcd";
+ unless (o->s eq "abcd") puts("bad 1.1");
+
+ o->s[0] = "xyz";
+ unless (o->s eq "xyzbcd") puts("bad 1.2");
+
+ o->s[END+1] = "pdq";
+ unless (o->s eq "xyzbcdpdq") puts("bad 1.3");
+
+ unless (o->s =~ /bcd/) puts("bad 1.4");
+
+ o->s =~ s/bcd/dcb/;
+ unless (o->s eq "xyzdcbpdq") puts("bad 1.5");
+
+ o->s[0] =~ s/x/0/;
+ unless (o->s eq "0yzdcbpdq") puts("bad 1.6");
+
+ o->i = 2;
+ unless (o->i == 2) puts("bad 2.1");
+
+ o->i += 2;
+ unless (o->i == 4) puts("bad 2.2");
+
+ o->i += o->i;
+ unless (o->i == 8) puts("bad 2.3");
+}
+class_8_2_main();
+} -output {}
+
+test class-8.3 {check class instance variables as reference parameters} -body {
+#lang L --line=1
+void class_8_3_str(string &s, string new)
+{
+ s = new;
+}
+void class_8_3_hash(string &h{int}, int k, string v)
+{
+ h{k} = v;
+}
+void class_8_3_arr(int &a[][], int i, int j, int v)
+{
+ a[i][j] = v;
+}
+class class_8_3
+{
+ instance {
+ public string s = "cvar";
+ public string h{int} = { 1=>"one", 2=>"two" };
+ public string a[] = { "zero", "one", "two" };
+ public int aa[][] = { {1,2}, {3,4} };
+ }
+}
+void class_8_3_main()
+{
+ /*
+ * Note that test class-6.1 checked class variables as
+ * reference parameters. This test is basically that test but
+ * it checks instance variables instead.
+ */
+
+ class_8_3 o = class_8_3_new();
+
+ unless (o->s eq "cvar") puts("bad 1.1");
+ unless (o->h{1} eq "one") puts("bad 1.2");
+ unless (o->h{2} eq "two") puts("bad 1.3");
+ unless (o->a[0] eq "zero") puts("bad 1.4");
+ unless (o->a[1] eq "one") puts("bad 1.5");
+ unless (o->a[2] eq "two") puts("bad 1.6");
+ unless (o->aa[0][0] == 1) puts("bad 1.10");
+ unless (o->aa[0][1] == 2) puts("bad 1.11");
+ unless (o->aa[1][0] == 3) puts("bad 1.12");
+ unless (o->aa[1][1] == 4) puts("bad 1.13");
+
+ o->s = "new";
+ unless (o->s eq "new") puts("bad 2.1");
+
+ o->h = { 3=>"three" };
+ unless (o->h{3} eq "three") puts("bad 3.1");
+ unless (length(o->h) == 1) puts("bad 3.2");
+
+ o->a = { "just-one" };
+ unless (o->a[0] eq "just-one") puts("bad 4.1");
+ unless (length(o->a) == 1) puts("bad 4.2");
+
+ o->aa = { {5} };
+ unless (o->aa[0][0] == 5) puts("bad 5.1");
+ unless (length(o->aa) == 1) puts("bad 5.2");
+ unless (length(o->aa[0]) == 1) puts("bad 5.3");
+
+ class_8_3_str(&o->s, "new-s");
+ unless (o->s eq "new-s") puts("bad 6.1");
+
+ o->h = {};
+ class_8_3_hash(&o->h, 4, "four");
+ unless (o->h{4} eq "four") puts("bad 7.1");
+ unless (length(o->h) == 1) puts("bad 7.2");
+ if (defined(o->h{5})) puts("bad 7.3");
+
+ o->aa = {};
+ class_8_3_arr(&o->aa, 0, 0, 11);
+ class_8_3_arr(&o->aa, 0, 1, 12);
+ class_8_3_arr(&o->aa, 1, 0, 13);
+ class_8_3_arr(&o->aa, 1, 1, 14);
+ unless (o->aa[0][0] == 11) puts("bad 8.1");
+ unless (o->aa[0][1] == 12) puts("bad 8.2");
+ unless (o->aa[1][0] == 13) puts("bad 8.3");
+ unless (o->aa[1][1] == 14) puts("bad 8.4");
+ unless (length(o->aa) == 2) puts("bad 8.5");
+ unless (length(o->aa[0]) == 2) puts("bad 8.6");
+ unless (length(o->aa[1]) == 2) puts("bad 8.7");
+ if (defined(o->aa[2])) puts("bad 8.8");
+}
+class_8_3_main();
+} -output {}
+
+test class-8.4 {check objects in complex variables} -body {
+#lang L --line=1
+class class_8_4_1
+{
+ instance {
+ public class_8_4_1 o;
+ public string s;
+ }
+}
+class class_8_4_2
+{
+ instance {
+ public class_8_4_1 o;
+ public string s;
+ }
+}
+void class_8_4_foo(class_8_4_1 &o, string s)
+{
+ o->s = s;
+}
+void class_8_4_str(string &s1, string s2)
+{
+ s1 = s2;
+}
+void class_8_4_main()
+{
+ class_8_4_1 a[] = { class_8_4_1_new(), class_8_4_1_new() };
+ class_8_4_1 o841 = class_8_4_1_new();
+ class_8_4_2 o842 = class_8_4_2_new();
+
+ o841->s = "841";
+ o842->s = "842";
+ unless ((o841->s eq "841") && (o842->s eq "842")) puts("bad 1.1");
+
+ o841->o = class_8_4_1_new();
+ o841->o->s = "841 in 841";
+ unless (o841->o->s eq "841 in 841") puts("bad 2.1");
+
+ o842->o = class_8_4_1_new();
+ o842->o->s = "841 in 842";
+ unless (o842->o->s eq "841 in 842") puts("bad 3.1");
+
+ o842->o->o = class_8_4_1_new();
+ o842->o->o->s = "841 in 841 in 842";
+ unless (o842->o->o->s eq "841 in 841 in 842") puts("bad 4.1");
+
+ class_8_4_foo(&o842->o->o, "new");
+ unless (o842->o->o->s eq "new") puts("bad 5.1");
+
+ class_8_4_1_delete(o841->o);
+ class_8_4_1_delete(o841);
+ class_8_4_1_delete(o842->o->o);
+ class_8_4_1_delete(o842->o);
+ class_8_4_2_delete(o842);
+
+ unless (length(a) == 2) puts("bad 10.0");
+ a[0]->s = "0-841";
+ a[1]->s = "1-841";
+ unless (a[0]->s eq "0-841") puts("bad 10.1");
+ unless (a[1]->s eq "1-841") puts("bad 10.2");
+ a[0]->o = class_8_4_1_new();
+ a[0]->o->s = "0-841 in 841";
+ unless (a[0]->o->s eq "0-841 in 841") puts("bad 10.3");
+ class_8_4_foo(&a[0]->o, "new");
+ unless (a[0]->o->s eq "new") puts("bad 10.4");
+ class_8_4_str(&a[0]->o->s, "new2");
+ unless (a[0]->o->s eq "new2") puts("bad 10.5");
+}
+class_8_4_main();
+} -output {}
+
+test class-8.5 {check objects as reference parameters} -body {
+#lang L --line=1
+class class_8_5
+{
+ private int n = 0;
+ instance { public int num = n++; }
+}
+void class_8_5_create_1(class_8_5 &o)
+{
+ o = class_8_5_new();
+}
+void class_8_5_create_n(class_8_5 &o[], int n)
+{
+ int i;
+
+ for (i = 0; i < n; ++i) o[i] = class_8_5_new();
+}
+void class_8_5_check_n(class_8_5 o[], class_8_5 &oref[], int n)
+{
+ int i;
+
+ for (i = 0; i < n; ++i) {
+ unless (o[i]->num == (i+2)) puts("bad chk.1");
+ unless (oref[i]->num == (i+2)) puts("bad chk.2");
+ }
+}
+void class_8_5_main()
+{
+ int n = 10;
+ class_8_5 o1, o2;
+ class_8_5 o[];
+
+ class_8_5_create_1(&o1);
+ class_8_5_create_1(&o2);
+ unless (o1->num == 0) puts("bad 1");
+ unless (o2->num == 1) puts("bad 2");
+ class_8_5_delete(o1);
+ class_8_5_delete(o2);
+
+ class_8_5_create_n(&o, n);
+ class_8_5_check_n( o, &o, n);
+}
+class_8_5_main();
+} -output {}
+
+test class-9.1 {check class and instance variables in comma expression} -body {
+#lang L --line=1
+class class_9_1
+{
+ public string cvar = "cvar";
+ instance {
+ public string ivar = "ivar";
+ }
+}
+void class_9_1_main()
+{
+ /*
+ * This checks an obscure case to ensure that a class or
+ * instance variable whose value is discarded -- the first
+ * expression in a comma expression -- is compiled properly.
+ * These are run in a loop as a way to check that the
+ * run-time stack remains balanced.
+ */
+
+ int i;
+ int n = 100;
+ class_9_1 o = class_9_1_new();
+
+ for (i = 0; i < n; ++i) {
+ unless (class_9_1->cvar,"val" eq "val") puts("bad 1.1");
+ unless (o->ivar,"val" eq "val") puts("bad 1.2");
+ }
+}
+class_9_1_main();
+} -output {}
+
+test goto-1 {check goto statement} -body {
+#lang L --line=1
+/*
+ * Test gotos at global scope. None of these labels should clash with
+ * those in goto_1a() or goto_1b() below.
+ */
+ goto L1;
+ puts("bad");
+ L1: puts("L1");
+ goto L2;
+
+/* Now test at proc scope. */
+void goto_1a()
+{
+ int i;
+
+ /* Use before define. */
+ goto L1;
+ puts("bad 1");
+ L1: puts("L1");
+
+ /* Use after define. */
+ i = 0;
+ L2: if (++i == 2) goto L3;
+ puts("L2");
+ goto L2;
+ L3: puts("L3");
+
+ /* Multiple uses before define. */
+ for (i = 0; i < 4; ++i) {
+ if (i == 0) goto L4;
+ if (i == 1) goto L4;
+ if (i == 2) goto L4;
+ if (i == 3) goto L4;
+ continue;
+ L4: puts("L4");
+ }
+
+ /* Multiple uses after define. */
+ for (i = 0; i < 4; ++i) {
+ goto L6;
+ puts("bad");
+ L5: puts("L5");
+ continue;
+ L6: if (i == 0) goto L5;
+ if (i == 1) goto L5;
+ if (i == 2) goto L5;
+ if (i == 3) goto L5;
+ }
+
+ /* Multiple labels per statement. */
+ for (i = 0; i < 4; ++i) {
+ if (i == 0) goto L7;
+ if (i == 1) goto L8;
+ if (i == 2) goto L9;
+ if (i == 3) goto L10;
+ continue;
+ L7:
+ L8:
+ L9:
+ L10:
+ puts("L7-10");
+ }
+
+ /* Label without statement. */
+ do {
+ goto L11;
+ puts("bad");
+ L11:
+ } while(0);
+
+ /* Multiple labels without statement. */
+ for (i = 0; i < 4; ++i) {
+ if (i == 0) goto L12;
+ if (i == 1) goto L13;
+ if (i == 2) goto L14;
+ puts("i == 3");
+ L12:
+ L13:
+ L14:
+ } while(0);
+
+ /*
+ * Label on a single statement (bizarre perhaps, but allowed
+ * by the grammar).
+ */
+
+ goto L15;
+ puts("bad");
+ while (0) L15: puts("L15");
+
+ goto L16;
+ puts("bad");
+ do L16: puts("L16"); while(0);
+
+ goto L17;
+ puts("bad");
+ for (; 0; ) L17: puts("L17");
+
+ goto L18;
+ puts("bad");
+ for (; 0; 0) L18: puts("L18");
+
+ /* Labels in nested scopes. */
+
+ i = 0;
+ goto L19;
+ puts("bad");
+ do {
+ puts("bad");
+ L19: puts("L19");
+ } while (0);
+ if (i++ == 0) goto L19;
+
+ i = 0;
+ goto L20;
+ puts("bad");
+ do {
+ puts("bad");
+ do {
+ puts("bad");
+ L20: puts("L20");
+ }
+ while (0);
+ } while (0);
+ if (i++ == 0) goto L20;
+
+ do {
+ goto L21; // jump out of the scope
+ puts("bad");
+ } while (0);
+ L21: puts("L21");
+}
+void goto_1b()
+{
+ /*
+ * Goto labels should be per proc scope, so none of these labels
+ * should clash with those in goto_1a().
+ */
+
+ goto L1;
+ puts("bad");
+ L1: puts("L1");
+}
+L2:
+goto_1a();
+goto_1b();
+} -output {L1
+L1
+L2
+L3
+L4
+L4
+L4
+L4
+L5
+L5
+L5
+L5
+L7-10
+L7-10
+L7-10
+L7-10
+i == 3
+L15
+L16
+L17
+L18
+L19
+L19
+L20
+L20
+L21
+L1
+}
+
+test goto-2 {check gotos with labels in enclosing scopes} -body {
+#lang L --line=1
+goto L1;
+L2: puts("global L2");
+return;
+void goto_2()
+{
+ goto L2; // should go to goto_2()'s L2, NOT the L2 at global scope
+ puts("bad");
+ L2: puts("L2");
+}
+L1:
+goto_2();
+goto L2; // should go to the L2 at global scope, NOT goto_2()'s L2
+} -output {L2
+global L2
+}
+
+test goto-3 {check goto statement errors} -body {
+#lang L --line=1
+void goto_3()
+{
+ goto L1;
+ L1:
+ L1:
+ L2:
+ L2:
+ L2:
+
+ L3:
+ do {
+ L3:
+ } while (0);
+
+ goto L4;
+ goto L6; // error even though an L6 is defined at global scope
+}
+goto L5;
+L6:
+} -returnCodes error -match regexp -result {.*: L Error: label L1 already defined
+.*: L Error: label L2 already defined
+.*: L Error: label L3 already defined
+.*: L Error: label L4 referenced but not defined
+.*: L Error: label L6 referenced but not defined
+.*: L Error: label L5 referenced but not defined
+}
+
+test goto-4 {check goto with label on first statement in the scope} -body {
+#lang L --line=1
+void goto_4()
+{
+ int i = 0;
+
+ /*
+ * This is a regression test for a parser bug where a labeled
+ * stmt that was first in the stmt list wasn't being reversed,
+ * causing the label to get the wrong offset. With that bug
+ * this test would find i == 1.
+ */
+ if (1) {
+ L: unless (i++) goto L;
+ }
+ unless (i == 2) puts("bad");
+}
+goto_4();
+} -output {}
+
+test fntrace-1 {check function tracing, pragma syntax} -body {
+#lang L --line=1
+// These are all legal syntax.
+#pragma fntrace=on
+unless (__LINE__ == 3) puts("bad 1");
+#pragma fntrace=on, fnhook=myhook
+unless (__LINE__ == 5) puts("bad 2");
+#pragma fntrace=on, fnhook=def
+unless (__LINE__ == 7) puts("bad 3");
+#pragma fntrace=off
+unless (__LINE__ == 9) puts("bad 4");
+#pragma fntrace=off, fnhook=myhook
+unless (__LINE__ == 11) puts("bad 5");
+#pragma fntrace=off, fnhook=def
+unless (__LINE__ == 13) puts("bad 6");
+#pragma fntrace
+} -output {}
+
+test fntrace-2 {check function trace, default hooks} -body {
+#lang L --line=1 -nowarn
+#pragma fntrace=on
+string fntrace_2_3(string a1, string a2)
+{
+ fprintf(stderr, "in fntrace_2_3\n");
+ return ("this is the ret value");
+}
+void fntrace_2_2(string a1)
+{
+ fprintf(stderr, "in fntrace_2_2 before\n");
+ fntrace_2_3(a1, "arg2");
+ fprintf(stderr, "in fntrace_2_2 after\n");
+}
+void fntrace_2_1()
+{
+ fprintf(stderr, "in fntrace_2_1 before\n");
+ fntrace_2_2("arg1");
+ fprintf(stderr, "in fntrace_2_1 after\n");
+}
+void fntrace_2()
+{
+ fprintf(stderr, "in fntrace_2 before\n");
+ fntrace_2_1();
+ fprintf(stderr, "in fntrace_2 after\n");
+}
+fntrace_2();
+} -match regexp -errorOutput {\d+: enter fntrace_2
+in fntrace_2 before
+\d+: enter fntrace_2_1
+in fntrace_2_1 before
+\d+: enter fntrace_2_2 'arg1'
+in fntrace_2_2 before
+\d+: enter fntrace_2_3 'arg1' 'arg2'
+in fntrace_2_3
+\d+: exit fntrace_2_3 'arg1' 'arg2' ret 'this is the ret value'
+in fntrace_2_2 after
+\d+: exit fntrace_2_2 'arg1' ret ''
+in fntrace_2_1 after
+\d+: exit fntrace_2_1 ret ''
+in fntrace_2 after
+\d+: exit fntrace_2 ret ''
+}
+
+test fntrace-3.1 {check function trace, private user hook fn} -body {
+#lang L --line=1 -nowarn
+#pragma fntrace=on, fnhook=fn31_myhook
+private void fn31_myhook(int pre, string av[], string ret)
+{
+ int i;
+ int ac = length(av);
+
+ printf("myhook %s: %s %d args:", pre?"pre":"post", av[0], ac-1);
+ for (i = 1; i < ac; ++i) {
+ printf(" '%s'", av[i]);
+ }
+ unless (pre) printf(" ret: '%s'", ret);
+ printf("\n");
+}
+string fntrace_3_1_3(string a1, string a2)
+{
+ printf("in fntrace_3_1_3\n");
+ return ("this is the ret value");
+}
+void fntrace_3_1_2(string a1)
+{
+ printf("in fntrace_3_1_2 before\n");
+ fntrace_3_1_3(a1, "arg2");
+ printf("in fntrace_3_1_2 after\n");
+}
+void fntrace_3_1_1()
+{
+ printf("in fntrace_3_1_1 before\n");
+ fntrace_3_1_2("arg1");
+ printf("in fntrace_3_1_1 after\n");
+}
+void fntrace_3_1()
+{
+ printf("in fntrace_3_1 before\n");
+ fntrace_3_1_1();
+ printf("in fntrace_3_1 after\n");
+}
+fntrace_3_1();
+#pragma fnhook=def
+} -output {myhook pre: fntrace_3_1 0 args:
+in fntrace_3_1 before
+myhook pre: fntrace_3_1_1 0 args:
+in fntrace_3_1_1 before
+myhook pre: fntrace_3_1_2 1 args: 'arg1'
+in fntrace_3_1_2 before
+myhook pre: fntrace_3_1_3 2 args: 'arg1' 'arg2'
+in fntrace_3_1_3
+myhook post: fntrace_3_1_3 2 args: 'arg1' 'arg2' ret: 'this is the ret value'
+in fntrace_3_1_2 after
+myhook post: fntrace_3_1_2 1 args: 'arg1' ret: ''
+in fntrace_3_1_1 after
+myhook post: fntrace_3_1_1 0 args: ret: ''
+in fntrace_3_1 after
+myhook post: fntrace_3_1 0 args: ret: ''
+}
+
+test fntrace-3.2 {check function trace, public user hook fn} -body {
+#lang L --line=1 -nowarn
+#pragma fntrace=on, fnhook=fntr32_myhook
+void fntr32_myhook(int pre, string av[], string ret)
+{
+ int i;
+ int ac = length(av);
+
+ printf("myhook %s: %s %d args:", pre?"pre":"post", av[0], ac-1);
+ for (i = 1; i < ac; ++i) {
+ printf(" '%s'", av[i]);
+ }
+ unless (pre) printf(" ret: '%s'", ret);
+ printf("\n");
+}
+string fntrace_3_2_3(string a1, string a2)
+{
+ printf("in fntrace_3_2_3\n");
+ return ("this is the ret value");
+}
+void fntrace_3_2_2(string a1)
+{
+ printf("in fntrace_3_2_2 before\n");
+ fntrace_3_2_3(a1, "arg2");
+ printf("in fntrace_3_2_2 after\n");
+}
+void fntrace_3_2_1()
+{
+ printf("in fntrace_3_2_1 before\n");
+ fntrace_3_2_2("arg1");
+ printf("in fntrace_3_2_1 after\n");
+}
+void fntrace_3_2()
+{
+ printf("in fntrace_3_2 before\n");
+ fntrace_3_2_1();
+ printf("in fntrace_3_2 after\n");
+}
+fntrace_3_2();
+#pragma fnhook=def
+} -output {myhook pre: fntrace_3_2 0 args:
+in fntrace_3_2 before
+myhook pre: fntrace_3_2_1 0 args:
+in fntrace_3_2_1 before
+myhook pre: fntrace_3_2_2 1 args: 'arg1'
+in fntrace_3_2_2 before
+myhook pre: fntrace_3_2_3 2 args: 'arg1' 'arg2'
+in fntrace_3_2_3
+myhook post: fntrace_3_2_3 2 args: 'arg1' 'arg2' ret: 'this is the ret value'
+in fntrace_3_2_2 after
+myhook post: fntrace_3_2_2 1 args: 'arg1' ret: ''
+in fntrace_3_2_1 after
+myhook post: fntrace_3_2_1 0 args: ret: ''
+in fntrace_3_2 after
+myhook post: fntrace_3_2 0 args: ret: ''
+}
+
+test fntrace-4 {check pragma errors} -body {
+#lang L --line=1
+#pragma unknown1=on
+#pragma unknown2
+} -returnCodes error -match regexp -result {.*1: L Error: illegal attribute 'unknown1'
+.*2: L Error: illegal attribute 'unknown2'
+}
+
+test fntrace-5 {check switching hooks and enabling/disabling fntrace} -body {
+#lang L --line=1
+#pragma fntrace=off
+void myhook5(int pre, string av[], string ret)
+{
+ int i;
+ int ac = length(av);
+
+ fprintf(stderr, "5: %s: %s %d args:", pre?"pre":"post", av[0], ac-1);
+ for (i = 1; i < ac; ++i) {
+ fprintf(stderr, " '%s'", av[i]);
+ }
+ unless (pre) fprintf(stderr, " ret: '%s'", ret);
+ fprintf(stderr, "\n");
+}
+#pragma fntrace=on, fnhook=def
+// default trace hooks in effect now
+void fntrace_5_def()
+{
+ fprintf(stderr, "in fntrace_5_def\n");
+}
+#pragma fntrace=on, fnhook=myhook5
+// myhook in effect now
+void fntrace_5_myhook()
+{
+ fprintf(stderr, "in fntrace_5_myhook before\n");
+ fntrace_5_def();
+ fprintf(stderr, "in fntrace_5_myhook after\n");
+}
+#pragma fntrace=off
+// function tracing disabled now
+void fntrace_5_off()
+{
+ fprintf(stderr, "in fntrace_5_off before\n");
+ fntrace_5_myhook();
+ fprintf(stderr, "in fntrace_5_off after\n");
+}
+#pragma fntrace=on, fnhook=def
+// back to default hooks
+void fntrace_5()
+{
+ fprintf(stderr, "in fntrace_5 before\n");
+ fntrace_5_off();
+ fprintf(stderr, "in fntrace_5 after\n");
+}
+fntrace_5();
+} -match regexp -errorOutput {\d+: enter fntrace_5
+in fntrace_5 before
+in fntrace_5_off before
+5: pre: fntrace_5_myhook 0 args:
+in fntrace_5_myhook before
+\d+: enter fntrace_5_def
+in fntrace_5_def
+\d+: exit fntrace_5_def ret ''
+in fntrace_5_myhook after
+5: post: fntrace_5_myhook 0 args: ret: ''
+in fntrace_5_off after
+in fntrace_5 after
+\d+: exit fntrace_5 ret ''
+}
+
+test fntrace-6 {check that tracing does not munge function return value} -body {
+#lang L --line=1
+#pragma fntrace=on
+private int myfunc(int a)
+{
+ return (a + 2);
+}
+void fntrace_6()
+{
+ unless (myfunc(2) == 4) puts("bad 1");
+}
+fntrace_6();
+} -output {}
+
+test fntrace-7 {test function tracing in classes} -body {
+#lang L --line=1
+#pragma fntrace=off
+class fntrace_7_cls
+{
+#pragma fntrace=on
+ private void traced() { fprintf(stderr, "traced\n"); }
+ constructor fntrace_7_cls_new()
+ {
+ fprintf(stderr, "constructor\n");
+ traced();
+ not_traced();
+ return (self);
+ }
+#pragma fntrace=off
+ private void not_traced() { fprintf(stderr, "not_traced\n"); }
+ destructor fntrace_7_cls_delete(fntrace_7_cls self)
+ {
+ fprintf(stderr, "destructor\n");
+ traced();
+ not_traced();
+ }
+#pragma fntrace=on
+}
+void fntrace_7()
+{
+ fntrace_7_cls o = fntrace_7_cls_new();
+ fntrace_7_cls_delete(o);
+}
+fntrace_7();
+} -match regexp -errorOutput {\d+: enter fntrace_7
+\d+: enter fntrace_7_cls_new
+constructor
+\d+: enter traced
+traced
+\d+: exit traced ret ''
+not_traced
+\d+: exit fntrace_7_cls_new ret '::L::_instance_fntrace_7_cls1'
+destructor
+\d+: enter traced
+traced
+\d+: exit traced ret ''
+not_traced
+\d+: exit fntrace_7 ret ''
+}
+
+test fntrace-8 {test max depth in function tracing} -body {
+#lang L --line=1
+#pragma fntrace=on, trace_depth=3
+int fn8_d = 0;
+void fn8(int max)
+{
+ ++fn8_d;
+ if (fn8_d < max) fn8(max);
+ --fn8_d;
+}
+void fntrace_8()
+{
+ fn8(2);
+ fn8(3);
+ fn8(4);
+ fn8(100);
+}
+fntrace_8();
+} -match regexp -errorOutput {\d+: enter fntrace_8
+\d+: enter fn8 '2'
+\d+: enter fn8 '2'
+\d+: exit fn8 '2' ret ''
+\d+: exit fn8 '2' ret ''
+\d+: enter fn8 '3'
+\d+: enter fn8 '3'
+\d+: exit fn8 '3' ret ''
+\d+: exit fn8 '3' ret ''
+\d+: enter fn8 '4'
+\d+: enter fn8 '4'
+\d+: exit fn8 '4' ret ''
+\d+: exit fn8 '4' ret ''
+\d+: enter fn8 '100'
+\d+: enter fn8 '100'
+\d+: exit fn8 '100' ret ''
+\d+: exit fn8 '100' ret ''
+\d+: exit fntrace_8 ret ''
+}
+
+test fntrace-9 {test entry only or exit only function tracing hooks} -body {
+#lang L --line=1
+#pragma fntrace=entry
+void fntrace_9_entry() {}
+#pragma fntrace=exit
+void fntrace_9_exit() {}
+#pragma fntrace=on
+void fntrace_9()
+{
+ fntrace_9_entry();
+ fntrace_9_exit();
+}
+fntrace_9();
+} -match regexp -errorOutput {\d+: enter fntrace_9
+\d+: enter fntrace_9_entry
+\d+: exit fntrace_9_exit ret ''
+\d+: exit fntrace_9 ret ''
+}
+
+test fntrace-10.1 {test L_TRACE environment variable, output to file} -setup {
+ set fname [makeFile {
+#pragma fntrace=on
+ void main() {}
+ } fntrace101.l]
+} -body {
+#lang L --line=1
+void fntrace_10_1()
+{
+ int ret;
+ FILE f;
+ string tclsh = eval("interpreter");
+
+ unlink("fntrace10_1.out");
+ putenv("L_TRACE=fntrace10_1.out");
+ ret = system({tclsh, "fntrace101.l"}, undef, undef, undef);
+ unless (ret == 0) puts("bad ret ${ret}");
+
+ unless (f = fopen("fntrace10_1.out", "r")) puts("bad 1");
+ unless (<f> =~ /enter main/) puts("bad 2");
+ unless (<f> =~ /exit main/) puts("bad 3");
+ fclose(f);
+
+ putenv("L_TRACE=");
+ unset("::env(L_TRACE)");
+ unlink("fntrace10_1.out");
+}
+fntrace_10_1();
+} -cleanup {
+ removeFile $fname
+} -output {}
+
+test fntrace-10.2 {test L_TRACE environment variable, output to socket} -setup {
+ set fname1 [makeFile {
+#pragma fntrace=on
+ void main() {}
+ } fntrace102.l]
+ set fname2 [makeFile {
+ void cb(FILE sock, _argused string host, _argused int port)
+ {
+ unless ((<sock> =~ /enter main/) &&
+ (<sock> =~ /exit main/)) {
+ FILE f = fopen("fntrace_10_bad", "w");
+ fclose(f);
+ }
+ fclose(sock);
+ exit(0);
+ }
+ void main()
+ {
+ FILE sock = socket(server: "cb", 0);
+ puts(fconfigure(sock, sockname:)[2]);
+ vwait("forever");
+ }
+ } fntrace102_server.l]
+} -body {
+#lang L --line=1
+void fntrace_10_2()
+{
+ int port, ret;
+ FILE f;
+ string tclsh = eval("interpreter");
+
+ f = popen("'${tclsh}' fntrace102_server.l 2>fntrace102_err", "r");
+ unless (f) {
+ puts("bad server ${stdio_lasterr}");
+ return;
+ }
+ port = (int)<f>;
+ putenv("L_TRACE=localhost:${port}");
+ unlink("fntrace_10_bad");
+ ret = system({tclsh, "fntrace102.l"}, undef, undef, undef);
+ unless (ret == 0) puts("bad ret ${ret}");
+ if (exists("fntrace_10_bad")) puts("bad");
+ unlink("fntrace_10_bad");
+ unlink("fntrace102_err");
+ pclose(f);
+ putenv("L_TRACE=");
+ unset("::env(L_TRACE)");
+}
+fntrace_10_2();
+} -output {}
+
+test fntrace-10.3 {test L_TRACE_FILES and --trace-files} -setup {
+ set fname1 [makeFile {
+ void fntrace_10_3_a() {}
+ } fntrace_10_3_a.l]
+ set fname2 [makeFile {
+ void fntrace_10_3_b() {}
+ } fntrace_10_3_b.l]
+ set fname3 [makeFile {
+// #includes have to start at col 1
+#include "fntrace_10_3_a.l"
+#include "fntrace_10_3_b.l"
+ void main()
+ {
+ fntrace_10_3_a();
+ fntrace_10_3_b();
+ }
+ } fntrace_10_3_c.l]
+} -body {
+#lang L --line=1
+void fntrace_10_3()
+{
+ int ret;
+ string err[];
+ string tclsh = eval("interpreter");
+
+ /* First trace only fntrace_10_3_c.l */
+
+ putenv("L_TRACE_FILES=fntrace_10_3_c.l");
+ ret = system({tclsh, "fntrace_10_3_c.l"}, undef, undef, &err);
+ unless (ret == 0) puts("bad 1.1");
+ unless (err[0] =~ /enter main/) puts("bad 1.2");
+ unless (err[1] =~ /exit main/) puts("bad 1.3");
+ if (err[2]) puts("bad 1.4");
+
+ putenv("L_TRACE_FILES=");
+ unset("::env(L_TRACE_FILES)");
+ ret = system(
+ {tclsh, "--trace-files=fntrace_10_3_c.l", "fntrace_10_3_c.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 1.11");
+ unless (err[0] =~ /enter main/) puts("bad 1.12");
+ unless (err[1] =~ /exit main/) puts("bad 1.13");
+ if (err[2]) puts("bad 1.14");
+
+ // Env var should take precedence over cmd line.
+ putenv("L_TRACE_FILES=fntrace_10_3_c.l");
+ ret = system({tclsh, "--trace-files=*", "fntrace_10_3_c.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 1.21");
+ unless (err[0] =~ /enter main/) puts("bad 1.22");
+ unless (err[1] =~ /exit main/) puts("bad 1.23");
+ if (err[2]) puts("bad 1.24");
+
+ /* Now trace fntrace_10_3_[ab].l */
+
+ putenv("L_TRACE_FILES=fntrace_10_3_[ab].l");
+ ret = system({tclsh, "fntrace_10_3_c.l"}, undef, undef, &err);
+ unless (ret == 0) puts("bad 2.1");
+ unless (err[0] =~ /enter fntrace_10_3_a/) puts("bad 2.2");
+ unless (err[1] =~ /exit fntrace_10_3_a/) puts("bad 2.3");
+ unless (err[2] =~ /enter fntrace_10_3_b/) puts("bad 2.4");
+ unless (err[3] =~ /exit fntrace_10_3_b/) puts("bad 2.5");
+ if (err[4]) puts("bad 2.6");
+
+ putenv("L_TRACE_FILES=");
+ unset("::env(L_TRACE_FILES)");
+ ret = system(
+ {tclsh, "--trace-files=fntrace_10_3_[ab].l","fntrace_10_3_c.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 2.21");
+ unless (err[0] =~ /enter fntrace_10_3_a/) puts("bad 2.22");
+ unless (err[1] =~ /exit fntrace_10_3_a/) puts("bad 2.23");
+ unless (err[2] =~ /enter fntrace_10_3_b/) puts("bad 2.24");
+ unless (err[3] =~ /exit fntrace_10_3_b/) puts("bad 2.25");
+ if (err[4]) puts("bad 2.26");
+
+ // Env var should take precedence over cmd line.
+ putenv("L_TRACE_FILES=fntrace_10_3_[ab].l");
+ ret = system({tclsh, "--trace-files=*","fntrace_10_3_c.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 2.31");
+ unless (err[0] =~ /enter fntrace_10_3_a/) puts("bad 2.32");
+ unless (err[1] =~ /exit fntrace_10_3_a/) puts("bad 2.33");
+ unless (err[2] =~ /enter fntrace_10_3_b/) puts("bad 2.34");
+ unless (err[3] =~ /exit fntrace_10_3_b/) puts("bad 2.35");
+ if (err[4]) puts("bad 2.36");
+
+ /* Now trace them all. */
+
+ putenv("L_TRACE_FILES=*.l");
+ ret = system({tclsh, "fntrace_10_3_c.l"}, undef, undef, &err);
+ unless (ret == 0) puts("bad 3.1");
+ unless (err[0] =~ /enter main/) puts("bad 3.2");
+ unless (err[1] =~ /enter fntrace_10_3_a/) puts("bad 3.3");
+ unless (err[2] =~ /exit fntrace_10_3_a/) puts("bad 3.4");
+ unless (err[3] =~ /enter fntrace_10_3_b/) puts("bad 3.5");
+ unless (err[4] =~ /exit fntrace_10_3_b/) puts("bad 3.6");
+ unless (err[5] =~ /exit main/) puts("bad 3.7");
+ if (err[6]) puts("bad 3.8");
+
+ putenv("L_TRACE_FILES=");
+ unset("::env(L_TRACE_FILES)");
+ ret = system({tclsh, "--trace-files=*", "fntrace_10_3_c.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 3.11");
+ unless (err[0] =~ /enter main/) puts("bad 3.12");
+ unless (err[1] =~ /enter fntrace_10_3_a/) puts("bad 3.13");
+ unless (err[2] =~ /exit fntrace_10_3_a/) puts("bad 3.14");
+ unless (err[3] =~ /enter fntrace_10_3_b/) puts("bad 3.15");
+ unless (err[4] =~ /exit fntrace_10_3_b/) puts("bad 3.16");
+ unless (err[5] =~ /exit main/) puts("bad 3.17");
+ if (err[6]) puts("bad 3.18");
+
+ // Env var should take precedence over cmd line.
+ putenv("L_TRACE_FILES=*.l");
+ ret = system(
+ {tclsh, "--trace-files=fntrace_10_3_c.l", "fntrace_10_3_c.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 3.21");
+ unless (err[0] =~ /enter main/) puts("bad 3.22");
+ unless (err[1] =~ /enter fntrace_10_3_a/) puts("bad 3.23");
+ unless (err[2] =~ /exit fntrace_10_3_a/) puts("bad 3.24");
+ unless (err[3] =~ /enter fntrace_10_3_b/) puts("bad 3.25");
+ unless (err[4] =~ /exit fntrace_10_3_b/) puts("bad 3.26");
+ unless (err[5] =~ /exit main/) puts("bad 3.27");
+ if (err[6]) puts("bad 3.28");
+
+ /* Try -fntrace_10_3_b.l */
+
+ putenv("L_TRACE_FILES=*.l:-fntrace_10_3_b.l");
+ ret = system({tclsh, "fntrace_10_3_c.l"}, undef, undef, &err);
+ unless (ret == 0) puts("bad 4.1");
+ unless (err[0] =~ /enter main/) puts("bad 4.2");
+ unless (err[1] =~ /enter fntrace_10_3_a/) puts("bad 4.3");
+ unless (err[2] =~ /exit fntrace_10_3_a/) puts("bad 4.4");
+ unless (err[3] =~ /exit main/) puts("bad 4.5");
+ if (err[4]) puts("bad 4.6");
+
+ putenv("L_TRACE_FILES=");
+ unset("::env(L_TRACE_FILES)");
+}
+fntrace_10_3();
+} -output {}
+
+test fntrace-10.4 {test L_TRACE_FUNCS and --trace-funcs} -setup {
+ set fname [makeFile {
+ void fntrace_10_4_a() {}
+ void fntrace_10_4_b() {}
+ void fntrace_10_4()
+ {
+ fntrace_10_4_a();
+ fntrace_10_4_b();
+ }
+ fntrace_10_4();
+ } fntrace_10_4.l]
+} -body {
+#lang L --line=1
+void fntrace_10_4()
+{
+ int ret;
+ string err[];
+ string tclsh = eval("interpreter");
+
+ putenv("L_TRACE_FUNCS=fntrace_10_4_a");
+ ret = system({tclsh, "fntrace_10_4.l"}, undef, undef, &err);
+ unless (ret == 0) puts("bad 1.1");
+ unless (err[0] =~ /enter fntrace_10_4_a/) puts("bad 1.2");
+ unless (err[1] =~ /exit fntrace_10_4_a/) puts("bad 1.3");
+ if (err[2]) puts("bad 1.4");
+
+ putenv("L_TRACE_FUNCS=");
+ unset("::env(L_TRACE_FUNCS)");
+ ret = system({tclsh, "--trace-funcs=fntrace_10_4_a", "fntrace_10_4.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 1.11");
+ unless (err[0] =~ /enter fntrace_10_4_a/) puts("bad 1.12");
+ unless (err[1] =~ /exit fntrace_10_4_a/) puts("bad 1.13");
+ if (err[2]) puts("bad 1.14");
+
+ // Env var should take precedence over cmd line.
+ putenv("L_TRACE_FUNCS=fntrace_10_4_a");
+ ret = system({tclsh, "--trace-funcs=*", "fntrace_10_4.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 1.21");
+ unless (err[0] =~ /enter fntrace_10_4_a/) puts("bad 1.22");
+ unless (err[1] =~ /exit fntrace_10_4_a/) puts("bad 1.23");
+ if (err[2]) puts("bad 1.24");
+
+
+ putenv("L_TRACE_FUNCS=fntrace_10_4_[ab]");
+ ret = system({tclsh, "fntrace_10_4.l"}, undef, undef, &err);
+ unless (ret == 0) puts("bad 2.1");
+ unless (err[0] =~ /enter fntrace_10_4_a/) puts("bad 2.2");
+ unless (err[1] =~ /exit fntrace_10_4_a/) puts("bad 2.3");
+ unless (err[2] =~ /enter fntrace_10_4_b/) puts("bad 2.4");
+ unless (err[3] =~ /exit fntrace_10_4_b/) puts("bad 2.5");
+ if (err[4]) puts("bad 2.6");
+
+ putenv("L_TRACE_FUNCS=");
+ unset("::env(L_TRACE_FUNCS)");
+ ret = system({tclsh, "--trace-funcs=fntrace_10_4_[ab]", "fntrace_10_4.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 2.11");
+ unless (err[0] =~ /enter fntrace_10_4_a/) puts("bad 2.12");
+ unless (err[1] =~ /exit fntrace_10_4_a/) puts("bad 2.13");
+ unless (err[2] =~ /enter fntrace_10_4_b/) puts("bad 2.14");
+ unless (err[3] =~ /exit fntrace_10_4_b/) puts("bad 2.15");
+ if (err[4]) puts("bad 2.16");
+
+ // Env var should take precedence over cmd line.
+ putenv("L_TRACE_FUNCS=fntrace_10_4_[ab]");
+ ret = system({tclsh, "--trace-funcs=*", "fntrace_10_4.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 2.21");
+ unless (err[0] =~ /enter fntrace_10_4_a/) puts("bad 2.22");
+ unless (err[1] =~ /exit fntrace_10_4_a/) puts("bad 2.23");
+ unless (err[2] =~ /enter fntrace_10_4_b/) puts("bad 2.24");
+ unless (err[3] =~ /exit fntrace_10_4_b/) puts("bad 2.25");
+ if (err[4]) puts("bad 2.26");
+
+
+ putenv("L_TRACE_FUNCS=*");
+ ret = system({tclsh, "fntrace_10_4.l"}, undef, undef, &err);
+ unless (ret == 0) puts("bad 3.1");
+ unless (err[0] =~ /enter fntrace_10_4/) puts("bad 3.2");
+ unless (err[1] =~ /enter fntrace_10_4_a/) puts("bad 3.3");
+ unless (err[2] =~ /exit fntrace_10_4_a/) puts("bad 3.4");
+ unless (err[3] =~ /enter fntrace_10_4_b/) puts("bad 3.5");
+ unless (err[4] =~ /exit fntrace_10_4_b/) puts("bad 3.6");
+ unless (err[5] =~ /exit fntrace_10_4/) puts("bad 3.7");
+ if (err[6]) puts("bad 3.8");
+
+ putenv("L_TRACE_FUNCS=");
+ unset("::env(L_TRACE_FUNCS)");
+ ret = system({tclsh, "--trace-funcs=*", "fntrace_10_4.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 3.11");
+ unless (err[0] =~ /enter fntrace_10_4/) puts("bad 3.12");
+ unless (err[1] =~ /enter fntrace_10_4_a/) puts("bad 3.13");
+ unless (err[2] =~ /exit fntrace_10_4_a/) puts("bad 3.14");
+ unless (err[3] =~ /enter fntrace_10_4_b/) puts("bad 3.15");
+ unless (err[4] =~ /exit fntrace_10_4_b/) puts("bad 3.16");
+ unless (err[5] =~ /exit fntrace_10_4/) puts("bad 3.17");
+ if (err[6]) puts("bad 3.18");
+
+ // Env var should take precedence over cmd line.
+ putenv("L_TRACE_FUNCS=*");
+ ret = system({tclsh, "--trace-funcs=fntrace_10_4_a", "fntrace_10_4.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 3.21");
+ unless (err[0] =~ /enter fntrace_10_4/) puts("bad 3.22");
+ unless (err[1] =~ /enter fntrace_10_4_a/) puts("bad 3.23");
+ unless (err[2] =~ /exit fntrace_10_4_a/) puts("bad 3.24");
+ unless (err[3] =~ /enter fntrace_10_4_b/) puts("bad 3.25");
+ unless (err[4] =~ /exit fntrace_10_4_b/) puts("bad 3.26");
+ unless (err[5] =~ /exit fntrace_10_4/) puts("bad 3.27");
+ if (err[6]) puts("bad 3.28");
+
+
+ putenv("L_TRACE_FUNCS=*:-fntrace_10_4b");
+ ret = system({tclsh, "fntrace_10_4.l"}, undef, undef, &err);
+ unless (ret == 0) puts("bad 4.1");
+ unless (err[0] =~ /enter fntrace_10_4/) puts("bad 4.2");
+ unless (err[1] =~ /enter fntrace_10_4_a/) puts("bad 4.3");
+ unless (err[2] =~ /exit fntrace_10_4_a/) puts("bad 4.4");
+ unless (err[5] =~ /exit fntrace_10_4/) puts("bad 4.5");
+ if (err[6]) puts("bad 4.6");
+
+ putenv("L_TRACE_FUNCS=");
+ unset("::env(L_TRACE_FUNCS)");
+ ret = system({tclsh, "--trace-funcs=*:-fntrace_10_4b", "fntrace_10_4.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 4.11");
+ unless (err[0] =~ /enter fntrace_10_4/) puts("bad 4.12");
+ unless (err[1] =~ /enter fntrace_10_4_a/) puts("bad 4.13");
+ unless (err[2] =~ /exit fntrace_10_4_a/) puts("bad 4.14");
+ unless (err[5] =~ /exit fntrace_10_4/) puts("bad 4.15");
+ if (err[6]) puts("bad 4.16");
+
+ // Env var should take precedence over cmd line.
+ putenv("L_TRACE_FUNCS=*:-fntrace_10_4b");
+ ret = system({tclsh, "--trace-funcs=*", "fntrace_10_4.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 4.21");
+ unless (err[0] =~ /enter fntrace_10_4/) puts("bad 4.22");
+ unless (err[1] =~ /enter fntrace_10_4_a/) puts("bad 4.23");
+ unless (err[2] =~ /exit fntrace_10_4_a/) puts("bad 4.24");
+ unless (err[5] =~ /exit fntrace_10_4/) puts("bad 4.25");
+ if (err[6]) puts("bad 4.26");
+
+ putenv("L_TRACE_FUNCS=");
+ unset("::env(L_TRACE_FUNCS)");
+}
+fntrace_10_4();
+} -output {}
+
+test fntrace-10.5 {test L_TRACE_SCRIPT and --trace-script, script} -setup {
+ set fname [makeFile {
+ void foo(_argused int a) {}
+ void main()
+ {
+ foo(123);
+ }
+ } fntrace_10_5.l]
+} -body {
+#lang L --line=1
+void fntrace_10_5()
+{
+ int ret;
+ string out[];
+ string tclsh = eval("interpreter");
+
+ /* Test a trace-hook script in L_TRACE_SCRIPT. */
+ putenv("L_TRACE_ALL=on");
+ putenv("L_TRACE_SCRIPT=puts(av)");
+ ret = system({tclsh, "fntrace_10_5.l"}, undef, &out, undef);
+ unless (ret == 0) puts("bad 1.1");
+ unless (out[0] == "main") puts("bad 1.2");
+ unless (out[1] == "foo 123") puts("bad 1.3");
+ unless (out[2] == "foo 123") puts("bad 1.4");
+ unless (out[3] == "main") puts("bad 1.5");
+ if (out[4]) puts("bad 1.6");
+ putenv("L_TRACE_ALL=");
+ putenv("L_TRACE_SCRIPT=");
+ unset("::env(L_TRACE_ALL)");
+ unset("::env(L_TRACE_SCRIPT)");
+
+ /* Test a trace-hook script in --trace-script. */
+ ret = system(
+ {tclsh, "--fntrace=on", "--trace-script=puts(av)", "fntrace_10_5.l"},
+ undef, &out, undef);
+ unless (ret == 0) puts("bad 1.11");
+ unless (out[0] == "main") puts("bad 1.12");
+ unless (out[1] == "foo 123") puts("bad 1.13");
+ unless (out[2] == "foo 123") puts("bad 1.14");
+ unless (out[3] == "main") puts("bad 1.15");
+ if (out[4]) puts("bad 1.16");
+
+ /* Try both. Env variable should take precedence. */
+ putenv("L_TRACE_ALL=on");
+ putenv("L_TRACE_SCRIPT=puts(av)");
+ ret = system(
+ {tclsh, "--fntrace=on --trace-script=puts(33)", "fntrace_10_5.l"},
+ undef, &out, undef);
+ unless (ret == 0) puts("bad 1.21");
+ unless (out[0] == "main") puts("bad 1.22");
+ unless (out[1] == "foo 123") puts("bad 1.23");
+ unless (out[2] == "foo 123") puts("bad 1.24");
+ unless (out[3] == "main") puts("bad 1.25");
+ if (out[4]) puts("bad 1.26");
+
+ putenv("L_TRACE_ALL=");
+ putenv("L_TRACE_SCRIPT=");
+ /* Needed since L's putenv does not really unset the env var. */
+ unset("::env(L_TRACE_ALL)");
+ unset("::env(L_TRACE_SCRIPT)");
+}
+fntrace_10_5();
+} -output {}
+
+test fntrace-10.6 {test L_TRACE_SCRIPT and --trace-script, file} -setup {
+ set fname1 [makeFile {
+ int foo(int a)
+ {
+ return (a+1);
+ }
+ int main()
+ {
+ foo(123);
+ return (0);
+ }
+ } fntrace_10_6.l]
+ set fname2 [makeFile {
+#pragma fnhook=myhook
+ void myhook(int pre, string av[], string ret)
+ {
+ fprintf(stderr, "my: %d %s %s\n", pre, av, ret);
+ }
+ } fntrace_10_6_hooks.l]
+} -body {
+#lang L --line=1
+void fntrace_10_6()
+{
+ int ret;
+ string err[];
+ string tclsh = eval("interpreter");
+
+ /* Test a trace filename in L_TRACE_SCRIPT. */
+ putenv("L_TRACE_ALL=on");
+ putenv("L_TRACE_SCRIPT=fntrace_10_6_hooks.l");
+ ret = system({tclsh, "fntrace_10_6.l"}, undef, undef, &err);
+ unless (ret == 0) puts("bad 1.1");
+ unless (err[0] == "my: 1 main 0") puts("bad 1.2");
+ unless (err[1] == "my: 1 foo 123 0") puts("bad 1.3");
+ unless (err[2] == "my: 0 foo 123 124") puts("bad 1.4");
+ unless (err[3] == "my: 0 main 0") puts("bad 1.5");
+ if (err[4]) puts("bad 1.6");
+ putenv("L_TRACE_ALL=");
+ putenv("L_TRACE_SCRIPT=");
+ unset("::env(L_TRACE_ALL)");
+ unset("::env(L_TRACE_SCRIPT)");
+
+ /* Test a trace filename in --trace-script. */
+ ret = system(
+ {tclsh, "--fntrace=on", "--trace-script=fntrace_10_6_hooks.l",
+ "fntrace_10_6.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 1.11");
+ unless (err[0] == "my: 1 main 0") puts("bad 1.12");
+ unless (err[1] == "my: 1 foo 123 0") puts("bad 1.13");
+ unless (err[2] == "my: 0 foo 123 124") puts("bad 1.14");
+ unless (err[3] == "my: 0 main 0") puts("bad 1.15");
+ if (err[4]) puts("bad 1.16");
+
+ /* Try both. Env variable should take precedence. */
+ putenv("L_TRACE_ALL=on");
+ putenv("L_TRACE_SCRIPT=fntrace_10_6_hooks.l");
+ ret = system({tclsh, "--trace-script=puts(22)", "fntrace_10_6.l"},
+ undef, undef, &err);
+ unless (ret == 0) puts("bad 1.21");
+ unless (err[0] == "my: 1 main 0") puts("bad 1.22");
+ unless (err[1] == "my: 1 foo 123 0") puts("bad 1.23");
+ unless (err[2] == "my: 0 foo 123 124") puts("bad 1.24");
+ unless (err[3] == "my: 0 main 0") puts("bad 1.25");
+ if (err[4]) puts("bad 1.26");
+
+ putenv("L_TRACE_SCRIPT=");
+ /* Needed since L's putenv does not really unset the env var. */
+ unset("::env(L_TRACE_ALL)");
+ unset("::env(L_TRACE_SCRIPT)");
+}
+fntrace_10_6();
+} -output {}
+
+test fntrace-10.7 {test L_TRACE_SCRIPT and --trace-script errors} -setup {
+ set fname [makeFile {
+ void main() {}
+ } fntrace_10_7.l]
+} -body {
+#lang L --line=1
+void fntrace_10_7()
+{
+ int ret;
+ string err[];
+ string tclsh = eval("interpreter");
+
+ putenv("L_TRACE_SCRIPT=bad-does-not-exist.l");
+ ret = system({tclsh, "fntrace_10_7.l"}, undef, undef, &err);
+ unless (ret == 1) puts("bad 1.1");
+ unless (err[0] =~ /couldn.t open "bad-does-not-exist.l"/) {
+ puts("bad 1.2");
+ }
+ putenv("L_TRACE_SCRIPT=");
+ unset("::env(L_TRACE_SCRIPT)");
+
+ ret = system({tclsh, "--trace-script=bad.l", "fntrace_10_7.l"},
+ undef, undef, &err);
+ unless (ret == 1) puts("bad 1.11");
+ unless (err[0] =~ /couldn.t open "bad.l"/) {
+ puts("bad 1.12");
+ }
+
+ putenv("L_TRACE_SCRIPT=");
+ /* Needed since L's putenv does not really unset the env var. */
+ unset("::env(L_TRACE_SCRIPT)");
+}
+fntrace_10_7();
+} -output {}
+
+test fntrace-11 {test that a hook fn does not get traced} -body {
+#lang L --line=1
+#pragma fntrace=on, fnhook=fntrace_11_hook
+void fntrace_11_hook(int pre, _argused poly av[], _argused poly ret)
+{
+ printf("%s %s\n", pre ? "entry" : "exit", av[0]);
+}
+void fntrace_11()
+{
+}
+fntrace_11();
+} -output {entry fntrace_11
+exit fntrace_11
+}
+
+test fntrace-12.1 {test fn _attributes for tracing} -body {
+#lang L --line=1
+void fntrace_12_1_f1() _attribute (fntrace=on) {}
+void fntrace_12_1_f2() {}
+void fntrace_12_1_f3() _attribute (fntrace=off) {}
+void fntrace_12_1()
+{
+ fntrace_12_1_f1();
+ fntrace_12_1_f2();
+ fntrace_12_1_f3();
+}
+fntrace_12_1();
+} -match regexp -errorOutput {\d+: enter fntrace_12_1_f1
+\d+: exit fntrace_12_1_f1 ret ''
+}
+
+test fntrace-12.2 {test more fn _attributes for tracing} -body {
+#lang L --line=1 --trace-out=stdout
+#pragma fnhook=def
+void fntrace_12_2_hook(int pre, _argused poly av[], _argused poly ret)
+{
+ printf("%s %s\n", pre ? "entry" : "exit", av[0]);
+}
+void fntrace_12_2_f1() _attribute (fntrace=on, fnhook=fntrace_12_2_hook) {}
+void fntrace_12_2_f2() {}
+void fntrace_12_2_f3() _attribute (fntrace=off) {}
+void fntrace_12_2_f4() _attribute (fntrace=on) {}
+void fntrace_12_2()
+{
+ fntrace_12_2_f1();
+ fntrace_12_2_f2();
+ fntrace_12_2_f3();
+ fntrace_12_2_f4();
+}
+fntrace_12_2();
+} -match regexp -output {entry fntrace_12_2_f1
+exit fntrace_12_2_f1
+\d+: enter fntrace_12_2_f4
+\d+: exit fntrace_12_2_f4 ret ''
+}
+
+test fntrace-13.1 {test run-time function tracing control} -body {
+#lang L --line=1
+#pragma fntrace=off
+int fn13_d = 0;
+void fn13(int max)
+{
+ ++fn13_d;
+ if (fn13_d < max) fn13(max);
+ --fn13_d;
+}
+void fntrace_13_1_f1() {}
+void fntrace_13_1_f2() {}
+void fntrace_13_1()
+{
+ FILE f;
+
+ fntrace_13_1_f1();
+ Ltrace({"fntrace" => "on", "trace_depth" => 3, "trace_out" => stdout});
+ fntrace_13_1_f1();
+ fn13(100);
+ Ltrace({"fntrace" => "entry", "trace_out" => "fn13.out"});
+ fntrace_13_1_f1();
+ Ltrace({"trace_out" => stdout});
+ Ltrace({"fntrace" => "off"});
+ fntrace_13_1_f2();
+ Ltrace({"trace_funcs" => "fntrace_13_1_f2"});
+ fntrace_13_1_f2();
+ Ltrace({"fntrace" => "off"});
+
+ unless (f = fopen("fn13.out", "r")) puts("bad 1");
+ unless (<f> =~ /\d+: enter fntrace_13_1_f1/) puts("bad 2");
+ if (<f>) puts("bad 3");
+ unlink("fn13.out");
+}
+fntrace_13_1();
+} -match regexp -output {\d+: enter fntrace_13_1_f1
+\d+: exit fntrace_13_1_f1 ret ''
+\d+: enter fn13 '100'
+\d+: enter fn13 '100'
+\d+: exit fn13 '100' ret ''
+\d+: exit fn13 '100' ret ''
+\d+: enter fntrace_13_1_f2
+\d+: exit fntrace_13_1_f2 ret ''
+}
+
+test fntrace-13.2 {test run-time disabling of entry or exit traces} -body {
+#lang L --line=1
+#pragma fntrace=on
+void fntrace_13_2_f(poly arg)
+{
+ Ltrace(arg);
+}
+void fntrace_13_2() _attribute(fntrace=off)
+{
+ fntrace_13_2_f({});
+ fntrace_13_2_f({"fntrace" => "off"});
+ // This next one won't get us exit traces because Tcl won't call
+ // the trace of a function if you turn it on while inside that
+ // function.
+ fntrace_13_2_f({"fntrace" => "on"});
+ fntrace_13_2_f({"fntrace" => "entry"});
+ fntrace_13_2_f({"fntrace" => "exit"});
+ fntrace_13_2_f({"fntrace" => "off"});
+}
+fntrace_13_2();
+} -match regexp -output {\d+: enter fntrace_13_2_f ''
+\d+: exit fntrace_13_2_f '' ret ''
+\d+: enter fntrace_13_2_f 'fntrace off'
+\d+: enter fntrace_13_2_f 'fntrace entry'
+\d+: enter fntrace_13_2_f 'fntrace exit'
+\d+: exit fntrace_13_2_f 'fntrace exit' ret ''
+}
+
+test try-1 {test try/catch} -body {
+#lang L
+void try_1()
+{
+ string err;
+ int caught;
+
+ caught = 0;
+ try {
+ puts(0/0);
+ puts("bad 1.1");
+ } catch(&err) {
+ ++caught;
+ unless (err == "divide by zero") puts("bad 1.2");
+ }
+ unless (caught == 1) puts("bad 1.3");
+
+ caught = 0;
+ try {
+ puts(0/0);
+ puts("bad 2.1");
+ } catch {
+ ++caught;
+ }
+ unless (caught == 1) puts("bad 2.2");
+
+ puts("got here"); // to verify that we executed code after the catches
+}
+try_1();
+} -output "got here\n"
+
+test try-2 {test nested try/catch} -body {
+#lang L
+void try_2()
+{
+ string err1, err2;
+ int caught1, caught2;
+
+ caught1 = caught2 = 0;
+ try {
+ puts(0/0);
+ puts("bad 1.1");
+ } catch(&err1) {
+ ++caught1;
+ unless (err1 == "divide by zero") puts("bad 1.2");
+ try {
+ puts(0/0);
+ puts("bad 1.3");
+ } catch(&err2) {
+ ++caught2;
+ unless (err2 == "divide by zero") puts("bad 1.4");
+ }
+ ++caught2;
+ }
+ unless (caught1 == 1) puts("bad 1.5");
+ unless (caught2 == 2) puts("bad 1.6");
+ puts("got here"); // to verify that we executed code after the catch
+}
+try_2();
+} -output "got here\n"
+
+test try-3 {test try/catch errors} -body {
+#lang L --line=1
+void try_3()
+{
+ string err;
+
+ try {
+ puts(0/0);
+ } catch (err) {} // should be &err
+
+ try {
+ puts(0/0);
+ } catch (&3) {}
+
+ /*
+ * A call to Tcl's catch() isn't allowed by L (have to use ::catch()).
+ */
+ catch("puts bad");
+}
+try_3();
+} -returnCodes error -match regexp -result {.*7: L Error: expected catch\(\&variable\)
+.*11: L Error: illegal operand to \&
+.*16: L Error: catch\(\) is reserved for try/catch; use ::catch\(\) for Tcl\'s catch
+}
+
+::tcltest::cleanupTests
+return
diff --git a/tests/l-leak.test b/tests/l-leak.test
new file mode 100644
index 0000000..3eff659
--- /dev/null
+++ b/tests/l-leak.test
@@ -0,0 +1,686 @@
+# Test the L language.
+# Copyright (c) 2007 BitMover, Inc.
+
+#
+# Tests in this file look for leaks in L core; they are only functional in
+# builds with -DTCL_MEM_DEBUG (--enable-symbols=mem or all)
+#
+
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+ testConstraint exec [llength [info commands exec]]
+}
+
+set haveMem [llength [info commands memory]]
+testConstraint memory $haveMem
+
+#lang L
+int getbytes()
+{
+ return ((int)(split(split(/\n/, Memory_info())[3])[3]));
+}
+#lang tcl
+
+# This causes L to keep running L code even after a compile error.
+set ::env(_L_TEST) 1
+
+# This tells L to run in a backwards compatibility mode for
+# the old eq/ne/le/lt/ge/gt string-comparison operators.
+set ::env(_L_ALLOW_EQ_OPS) 1
+
+test leak-1.1 {leaks in a simple L-loop} -body {
+#lang L --line=1
+ void leak_1_1() {
+ int tmp, end, i, j;
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j=i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_1_1();
+} -constraints memory -output "0 4\n"
+
+test leak-1.2 {leaks in L-func called in a loop} -body {
+#lang L --line=1
+ int leak_1_2_foo (int v) {
+ int k;
+ k = v;
+ return k;
+ }
+ void leak_1_2() {
+ int tmp, end, i, j;
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j=leak_1_2_foo(i);
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_1_2();
+} -constraints memory -output "0 4\n"
+
+test leak-1.3 {leaks in L-func called in a tcl-loop} -body {
+#lang L --line=1
+ int leak_1_3_foo (int v) {
+ int k;
+ k = v;
+ return k;
+ }
+#lang tcl
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ set j [leak_1_3_foo $i]
+ set tmp $end
+ set end [getbytes]
+ }
+ puts [list [expr {$end - $tmp}] $j]
+} -constraints memory -output "0 4\n"
+
+test leak-2.0 {leaks in array reading} -body {
+#lang L --line=1
+ void leak_2_0() {
+ int tmp, end, i, j[2], k, l;
+ j[0]=1;
+ j[1]=2;
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ k = j[0];
+ l = j[1];
+ tmp=end;
+ end = getbytes();
+ }
+ puts(end-tmp);
+ }
+ leak_2_0();
+} -constraints memory -output "0\n"
+
+test leak-2.1 {leaks in array initializers} -body {
+#lang L --line=1
+ void leak_2_1() {
+ int tmp, end, i, k[2];
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ int j[2];
+ k = j;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(end-tmp);
+ }
+ leak_2_1();
+} -constraints memory -output "0\n"
+
+test leak-2.2.0 {leaks in arrays} -body {
+#lang L --line=1
+ void leak_2_2_0() {
+ int tmp, end, i, j[2] = {0,0};
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j[0]=i;
+ j[1]=2*j[0]+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_2_2_0();
+} -constraints memory -output "0 {4 12}\n"
+
+test leak-2.2.1 {leaks in arrays} -body {
+#lang L --line=1
+ void leak_2_2_1() {
+ int tmp, end, i, k[2], j[2];
+ j=k;
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j[0]=i;
+ j[1]=2*j[0]+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_2_2_1();
+} -constraints memory -output "0 {4 12}\n"
+
+test leak-2.3 {leaks in arrays} -body {
+#lang L --line=1
+ int leak_2_3_foo (int v) {
+ int k[2];
+ k[0] = v;
+ k[1] = 2*k[0]+v;
+ return k[1];
+ }
+ void leak_2_3() {
+ int tmp, end, i, j;
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j=leak_2_3_foo(i);
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_2_3();
+} -constraints memory -output "0 12\n"
+
+test leak-2.4 {leaks in arrays} -body {
+#lang L --line=1
+ void leak_2_4() {
+ int tmp, end, i, j[2][2];
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j[0][0]=i;
+ j[0][1]=2*j[0][0]+i;
+ j[1][0]=j[0][0]+j[0][1];
+ j[1][1]=2*j[1][0]+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_2_4();
+} -constraints memory -output "0 {{4 12} {16 36}}\n"
+
+test leak-2.5 {leaks in arrays} -body {
+#lang L --line=1
+ void leak_2_5() {
+ int tmp, end, i, t, j[2][2][2];
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ for (t=0; t < 2; t++) {
+ j[0][i%2][t]=i+t;
+ j[1][i%2][t]=i*i+t;
+ }
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_2_5();
+} -constraints memory -output "0 {{{4 5} {3 4}} {{16 17} {9 10}}}\n"
+
+test leak-3.0 {leaks in hash initializers} -body {
+#lang L --line=1
+ void leak_3_0() {
+ int tmp, end, i;
+ hash k = {"1" => "foo"};
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ hash j = {"1" => "moo"};
+ k = j;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, k));
+ }
+ leak_3_0();
+} -constraints memory -output "0 {1 moo}\n"
+
+test leak-3.1.0 {leaks in hashes} -body {
+#lang L --line=1
+ void leak_3_1_0() {
+ int tmp, end, i;
+ hash j;
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j{"0"}=i;
+ j{"1"}=2*(int)j{"0"}+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j{"1"}));
+ }
+ leak_3_1_0();
+} -constraints memory -output "0 12\n"
+
+test leak-3.1.1 {leaks in hashes} -body {
+#lang L --line=1
+ void leak_3_1_1() {
+ int tmp, end, i;
+ hash j = {"u" => 0};
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j{"0"}=i;
+ j{"1"}=2*(int)j{"0"}+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j{"1"}));
+ }
+ leak_3_1_1();
+} -constraints memory -output "0 12\n"
+
+test leak-3.1.2 {leaks in hashes} -body {
+#lang L --line=1
+ void leak_3_1_2() {
+ int tmp, end, i;
+ hash j, k = {"u" => 0};
+
+ j = k;
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j{"0"}=i;
+ j{"1"}=2*(int)j{"0"}+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j{"1"}));
+ }
+ leak_3_1_2();
+} -constraints memory -output "0 12\n"
+
+test leak-3.2.0 {leaks in hashes} -body {
+#lang L --line=1
+ hash leak_3_2_0_foo (int v) {
+ hash k;
+ k{"0"} = v;
+ k{"1"} = 2*(int)k{"0"}+v;
+ return k;
+ }
+ void leak_3_2_0() {
+ int tmp, end, i;
+ hash j;
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j=leak_3_2_0_foo(i);
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j{"1"}));
+ }
+ leak_3_2_0();
+} -constraints memory -output "0 12\n"
+
+test leak-3.2.1 {leaks in hashes} -body {
+#lang L --line=1
+ hash leak_3_2_1_foo (int v) {
+ hash k = {"a" => "b"};
+ k{"0"} = v;
+ k{"1"} = 2*(int)k{"0"}+v;
+ return k;
+ }
+ void leak_3_2_1() {
+ int tmp, end, i;
+ hash j;
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j=leak_3_2_1_foo(i);
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j{"1"}));
+ }
+ leak_3_2_1();
+} -constraints memory -output "0 12\n"
+
+test leak-3.3 {leaks in nested hashes} -body {
+#lang L --line=1
+ void leak_3_3() {
+ int tmp, end, i;
+ int j{string}{string};
+
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j{"0"}{"0"}=i;
+ j{"0"}{"1"}=2*(int)j{"0"}{"0"}+i;
+ j{"1"}{"0"}=2*i + 1 + (int)j{"0"}{"1"};
+ j{"1"}{"1"}=2*(int)j{"1"}{"0"}+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j{"1"}{"1"}));
+ }
+ leak_3_3();
+} -constraints memory -output "0 46\n"
+
+test leak-4.1 {leaks in structs} -body {
+#lang L --line=1
+ struct leak_4_1_js {int x, y;};
+ void leak_4_1() {
+ int tmp, end, i;
+ struct leak_4_1_js j;
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j.x=i;
+ j.y=2*j.x+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_4_1();
+} -constraints memory -output "0 {4 12}\n"
+
+test leak-4.2 {leaks in structs} -body {
+#lang L --line=1
+ struct leak_4_2_js {int x, y[2];};
+ void leak_4_2() {
+ int tmp, end, i;
+ struct leak_4_2_js j;
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j.x=i;
+ j.y[0]=2*j.x+i;
+ j.y[1]=2*j.y[0]+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_4_2();
+} -constraints memory -output "0 {4 {12 28}}\n"
+
+test leak-4.3 {leaks in structs} -body {
+#lang L --line=1
+ struct leak_4_3_js {int x, y;};
+ void leak_4_3() {
+ int tmp, end, i;
+ struct leak_4_3_js j[2];
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j[0].x=i;
+ j[0].y=2*j[0].x+i;
+ j[1].x=j[0].x+j[0].y;
+ j[1].y=2*j[1].x+i;
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_4_3();
+} -constraints memory -output "0 {{4 12} {16 36}}\n"
+
+test leak-5.1 {leaks in deep diving} -body {
+#lang L --line=1
+ struct leak_5_1_js {string h{string}; poly a[2];};
+ struct leak_5_1_js leak_5_1_j[2];
+ string leak_5_1_h{string};
+ void leak_5_1() {
+ int tmp, end, i;
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ leak_5_1_j[0].h{"foo"}= leak_5_1_j[1].a[1];
+ leak_5_1_j[1].h{"foo"}= "moo";
+ leak_5_1_j[0].a[0]=leak_5_1_j[1].h;
+ leak_5_1_j[0].a[1]=leak_5_1_j[0].h{"foo"};
+ leak_5_1_j[1].a[0]=leak_5_1_j[0].h{"foo"};
+ leak_5_1_j[1].a[1]=leak_5_1_j[1].a[0];
+ tmp=end;
+ end = getbytes();
+ }
+ leak_5_1_h = (hash)leak_5_1_j[0].a[0];
+ puts(list(end-tmp, leak_5_1_h{"foo"}, leak_5_1_j[1].h{"foo"}));
+ }
+ leak_5_1();
+} -constraints memory -output "0 moo moo\n"
+
+test leak-5.2 {leaks in deep diving} -body {
+#lang L --line=1
+ void leak_5_2() {
+ int tmp, end, i, j;
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j = {1,2,3}[1];
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_5_2();
+} -constraints memory -output "0 2\n"
+
+test leak-5.3 {leaks in deep diving} -body {
+#lang L --line=1
+ void leak_5_3() {
+ int tmp, end, i, j;
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j = {{1,2},{3,4},{4,5}}[1][0];
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_5_3();
+} -constraints memory -output "0 3\n"
+
+test leak-5.4 {leaks in deep diving} -body {
+#lang L --line=1
+ void leak_5_4() {
+ int tmp, end, i, j;
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ j = { {{1,2},{3,4}}, {{4,5},{5,6}}, {{7,8},{9,10}} }[1][1][0];
+ { {0,0} }[END][0];
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, j));
+ }
+ leak_5_4();
+} -constraints memory -output "0 5\n"
+
+test leak-5.5 {leaks in deep diving} -body {
+#lang L --line=1
+void leak_5_5()
+{
+ int n = 1000;
+ int i, start, end, types{string}[];
+
+ /*
+ * Push onto a hash element that's an array element while
+ * check memory usage. Allow 1 kB/element. Any more than that
+ * must be a memory leak.
+ */
+ start = getbytes();
+ for (i = 0; i < n; ++i) {
+ push(&types{"foo"}, i);
+ }
+ end = getbytes();
+ if ((end - start) > (1000*n)) {
+ puts("took ${(end-start)/n} bytes per elt");
+ }
+}
+leak_5_5();
+} -constraints memory -output {}
+
+test leak-6.1 {leaks in string indexing} -body {
+#lang L --line=1
+ void leak_6_1() {
+ int end, i, tmp;
+ string a[], s1, s2;
+
+ a[0] = "zero";
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ s1 = a[0];
+ s2 = {"zero"}[0];
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, s1, s2));
+ }
+ leak_6_1();
+} -constraints memory -output "0 zero zero\n"
+
+test leak-6.2 {leaks in string indexing} -body {
+#lang L --line=1
+ void leak_6_2() {
+ int end, i, tmp;
+ string a[][], s1, s2;
+
+ a[0][0] = "zero";
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ s1 = a[0][0];
+ s2 = { {"zero"} }[0][0];
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, s1, s2));
+ }
+ leak_6_2();
+} -constraints memory -output "0 zero zero\n"
+
+test leak-6.3 {leaks in string indexing} -body {
+#lang L --line=1
+ void leak_6_3() {
+ int end, i, tmp;
+ string a[][][], s1, s2;
+
+ a[0][0][0] = "zero";
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ s1 = a[0][0][0];
+ s2 = { { {"zero"} } }[0][0][0];
+ tmp=end;
+ end = getbytes();
+ }
+ puts(list(end-tmp, s1, s2));
+ }
+ leak_6_3();
+} -constraints memory -output "0 zero zero\n"
+
+test leak-6.4 {leaks in string indexing} -body {
+#lang L --line=1
+ void leak_6_4() {
+ int end, i, tmp;
+ string s;
+
+ s = "abcd";
+ end = getbytes();
+ for(i=0; i<5;i++) {
+ s[0] = "w";
+ s[1] = "x";
+ s[2] = "y";
+ s[3] = "z";
+ s[0] = "123";
+ s[1] = "456";
+ s[2] = "789";
+ s[3] = "0yz";
+ s[0] = "";
+ s[1] = "";
+ s[2] = "";
+ s[3] = "";
+ s[4] = "";
+ s[5] = "";
+ s[0] = "";
+ s[0] = "";
+ tmp=end;
+ end = getbytes();
+ }
+ puts(end-tmp);
+ }
+ leak_6_4();
+} -constraints memory -output "0\n"
+
+test leak-7.1 {leaks in classes} -body {
+#lang L --line=1
+class leak_7_1
+{
+ public int v1;
+ instance {
+ public int v2;
+ }
+ constructor leak_7_1_init() {}
+ destructor leak_7_1_free(leak_7_1 self) {}
+}
+void leak_7_1_main()
+{
+ int end, i, tmp;
+ leak_7_1 o;
+
+ end = getbytes();
+ for (i = 0; i < 5; ++i) {
+ o = leak_7_1_init();
+ leak_7_1_free(o);
+ tmp = end;
+ end = getbytes();
+ }
+ puts(end - tmp);
+}
+leak_7_1_main();
+} -constraints memory -output "0\n"
+
+test leak-8.1 {leaks with undef() on hashes} -body {
+#lang L --line=1
+void leak_8_1_main()
+{
+ int end, i, tmp;
+
+ end = getbytes();
+ for (i = 0; i < 5; ++i) {
+ string h{string} = { "1"=>"1", "2"=>"2", "3"=>"3", "4"=>"4" };
+ undef(h{"1"});
+ undef(h{"2"});
+ undef(h{"3"});
+ undef(h{"4"});
+ tmp = end;
+ end = getbytes();
+ }
+ puts(end - tmp);
+}
+leak_8_1_main();
+} -constraints memory -output "0\n"
+
+test leak-8.2 {leaks with undef() on arrays} -body {
+#lang L --line=1
+void leak_8_2_main()
+{
+ int end, i, tmp;
+
+ end = getbytes();
+ for (i = 0; i < 5; ++i) {
+ int a[] = { 1, 2, 3, 4 };
+ undef(a[0]);
+ undef(a[0]);
+ undef(a[0]);
+ undef(a[0]);
+ tmp = end;
+ end = getbytes();
+ }
+ puts(end - tmp);
+}
+leak_8_2_main();
+} -constraints memory -output "0\n"
+
+# Disable the leak-9 test for now. L leaks memory when freeing
+# a Tcl interp. Usually, L code is run all within one interp so
+# this usually isn't a big deal. Some day we'll come back to this.
+::tcltest::cleanupTests
+return
+
+test leak-9 {per-interp L state leak} -body {
+ set end [getbytes]
+ for {set i 0} {$i < 5} {incr i} {
+ interp create slave
+ slave eval expr 1+2+3+4+5+6+7+8+9+10+11+12+13
+ interp delete slave
+ set tmp $end
+ set end [getbytes]
+ }
+ puts [expr {$end - $tmp}]
+} -constraints memory -output "0\n"
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/l-libl.test b/tests/l-libl.test
new file mode 100644
index 0000000..ec40be1
--- /dev/null
+++ b/tests/l-libl.test
@@ -0,0 +1,3922 @@
+# Test the L library.
+# Copyright (c) 2009 BitMover, Inc.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+ testConstraint exec [llength [info commands exec]]
+}
+
+if {$::tcl_platform(platform) eq "windows"} {
+ set _windows 1
+} else {
+ set _windows 0
+}
+
+# This causes L to keep running L code even after a compile error.
+set ::env(_L_TEST) 1
+
+# This tells L to run in a backwards compatibility mode for
+# the old eq/ne/le/lt/ge/gt string-comparison operators.
+set ::env(_L_ALLOW_EQ_OPS) 1
+
+test angle-1 {test <f>} -setup {
+ set fname1 [makeFile "linea1\n" angle1 .]
+ set fname2 [makeFile "lineb1\nlineb2\n" angle2 .]
+ set fname3 [makeFile "linec1\nlinec2\nlinec3\n" angle3 .]
+} -body {
+#lang L --line=1
+void angle1()
+{
+ int i;
+ string s;
+ FILE f;
+
+ unless (defined(f = fopen("angle1", "r"))) puts("bad 1.1");
+ for (i = 1; i <= 1; ++i) {
+ unless (defined(s = <f>)) puts("bad 1.2");
+ unless (s eq "linea${i}") puts("bad 1.3");
+ }
+ if (defined(<f>)) puts("bad 1.4");
+ unless (fclose(f) == 0) puts("bad 1.5");
+
+ unless (defined(f = fopen("angle2", "r"))) puts("bad 3.1");
+ for (i = 1; i <= 2; ++i) {
+ unless (defined(s = <f>)) puts("bad 3.2");
+ unless (s eq "lineb${i}") puts("bad 3.3");
+ }
+ if (defined(<f>)) puts("bad 3.4");
+ unless (fclose(f) == 0) puts("bad 3.5");
+
+ unless (defined(f = fopen("angle3", "r"))) puts("bad 4.1");
+ for (i = 1; i <= 3; ++i) {
+ unless (defined(s = <f>)) puts("bad 4.2");
+ unless (s eq "linec${i}") puts("bad 4.3");
+ }
+ if (defined(<f>)) puts("bad 4.4");
+ unless (fclose(f) == 0) puts("bad 4.5");
+
+ /* Create and read an empty file. */
+ unless (defined(f = fopen("angle4", "w"))) puts("bad 5.1");
+ fclose(f);
+ unless (defined(f = fopen("angle4", "r"))) puts("bad 5.2");
+ if (defined(<f>)) puts("bad 5.3");
+ unless (fclose(f) == 0) puts("bad 5.4");
+ unlink("angle4");
+}
+angle1();
+} -output {}
+
+test angle-2 {test <>} -setup {
+ set script [makeFile {
+ void main() {
+ string s;
+ printf("<");
+ while (defined(s=<>)) puts(s);
+ printf(">");
+ }
+ } angle2.l .]
+ set fname1 [makeFile "linea1\n" angle2-1 .]
+ set fname2 [makeFile "lineb1\nlineb2\n" angle2-2 .]
+ set fname3 [makeFile "linec1\nlinec2\nlinec3\n" angle2-3 .]
+} -constraints {
+ exec
+} -body {
+ puts [exec [interpreter] $script $fname1]
+ puts [exec [interpreter] $script $fname1 $fname2]
+ puts [exec [interpreter] $script $fname1 $fname2 $fname3]
+ puts [exec [interpreter] $script $fname1 $fname1]
+ puts [exec [interpreter] $script $fname1 $fname1 $fname1]
+} -output {<linea1
+>
+<linea1
+lineb1
+lineb2
+>
+<linea1
+lineb1
+lineb2
+linec1
+linec2
+linec3
+>
+<linea1
+linea1
+>
+<linea1
+linea1
+linea1
+>
+}
+
+test angle-2.1 {test <> reading stdin} -setup {
+ makeFile {
+ void main()
+ {
+ string s;
+ while (s = <>) puts("<${s}>");
+ }
+ } angle-2.1-1.l .
+ makeFile {
+ void main()
+ {
+ string s;
+ while (s = <stdin>) puts("<${s}>");
+ }
+ } angle-2.1-2.l .
+} -body {
+#lang L
+void angle_2_1()
+{
+ int ret;
+ string err, in[], out[];
+ string tclsh = eval("interpreter");
+
+ in = { "line1", "line2", "line3" };
+ ret = system({tclsh, "angle-2.1-1.l"}, in, &out, &err);
+ if (ret) puts("bad 1.1");
+ unless (eq(out, {"<line1>","<line2>","<line3>"})) {
+ puts("bad 1.2 got '${out}'");
+ }
+ if (err) puts("bad 1.3");
+
+ in = { "line1", "line2", "line3" };
+ ret = system({tclsh, "angle-2.1-2.l"}, in, &out, &err);
+ if (ret) puts("bad 2.1");
+ unless (eq(out, {"<line1>","<line2>","<line3>"})) {
+ puts("bad 2.2 got '${out}'");
+ }
+ if (err) puts("bad 2.3");
+}
+angle_2_1();
+} -output {}
+
+test angle-3 {test <f> errors} -body {
+#lang L --line=1
+void angle3()
+{
+ FILE f;
+
+ if (defined(<f>)) puts("bad 1");
+}
+angle3();
+} -output {}
+
+test angle-4 {test <> type errors} -body {
+#lang L --line=1
+void angle4()
+{
+ string arr[];
+ string hsh{string};
+ struct { string s; } st;
+
+ /* These are all type errors. */
+ <0>;
+ <0.0>;
+ <{0}>;
+ <arr>;
+ <st>;
+ <hsh>;
+}
+} -returnCodes error -match regexp -result {.*8: L Error: expect FILE in <>
+.*9: L Error: expect FILE in <>
+.*10: L Error: expect FILE in <>
+.*11: L Error: expect FILE in <>
+.*12: L Error: expect FILE in <>
+.*13: L Error: expect FILE in <>
+}
+
+test angle-5 {test <> file-open errors} -setup {
+ set script [makeFile {
+ void main() {
+ string s;
+ while (defined(s=<>)) puts(s);
+ }
+ } angle5.l .]
+ set fname [makeFile "line1\n" angle5-1 .]
+} -constraints {
+ exec
+} -body {
+ puts [exec [interpreter] $script bad1 2>err]
+ puts [exec cat err]
+ puts [exec [interpreter] $script bad2 $fname 2>err]
+ puts [exec cat err]
+ puts [exec [interpreter] $script $fname bad3 $fname 2>err]
+ puts [exec cat err]
+ puts [exec [interpreter] $script $fname bad4 bad5 $fname bad6 2>err]
+ puts [exec cat err]
+} -output {
+couldn't open "bad1": no such file or directory
+line1
+couldn't open "bad2": no such file or directory
+line1
+line1
+couldn't open "bad3": no such file or directory
+line1
+line1
+couldn't open "bad4": no such file or directory
+couldn't open "bad5": no such file or directory
+couldn't open "bad6": no such file or directory
+}
+
+test assert-1 {test assert} -setup {
+ set fname [makeFile {
+ int i = 0;
+ assert(i > 0);
+ } assert1.l]
+} -body {
+#lang L --line=1
+/*
+ * Some contortions here to run tclsh on assert1.l (above) which
+ * prints to stderr and then exits(1), so we can capture stderr and
+ * check the return status. Otherwise, tcltest sees anything to
+ * stderr as an error and fails the test.
+ */
+void assert1()
+{
+ int ret;
+ string cmd = "\"${eval('interpreter')}\" assert1.l";
+ string err[], out[];
+
+ ret = system(cmd, undef, &out, &err);
+ unless (ret == 1) puts("bad status ${ret}");
+ unless (length(out) == 0) puts("bad 2");
+ unless (err[0] eq "ASSERTION FAILED assert1.l:3: i > 0") {
+ puts("bad stderr ${err}");
+ }
+}
+assert1();
+} -output {}
+
+test basename-1 {test basename} -body {
+#lang L --line=1
+void basename1()
+{
+ unless (basename("x") eq "x") puts("bad 1");
+ unless (basename("") eq "") puts("bad 2");
+ unless (basename("/x/y") eq "y") puts("bad 3");
+ unless (basename("/path/to/file") eq "file") puts("bad 4");
+ unless (basename("path/to/file") eq "file") puts("bad 5");
+ unless (basename("with spaces/to/f ile") eq "f ile") puts("bad 6");
+ unless (basename("with brace/to/f {}le") eq "f {}le") puts("bad 7");
+ unless (basename("with quotes/f \"\'le") eq "f \"\'le") puts("bad 8");
+}
+basename1();
+} -output {}
+
+test chdir-1 {test chdir} -setup {
+ file mkdir testdir1
+ file mkdir {test dir 2}
+ file mkdir testdir\{3\}
+ if {!$_windows} {file mkdir {testdir "'4}}
+ # '"
+} -body {
+#lang L --line=1
+void chdir1()
+{
+ unless (chdir("testdir1") == 0) puts("bad 1.1");
+ unless (basename(pwd()) eq "testdir1") puts("bad 1.2");
+ unless (chdir("..") == 0) puts("bad 1.3");
+
+ unless (chdir("test dir 2") == 0) puts("bad 2.1");
+ unless (basename(pwd()) eq "test dir 2") puts("bad 2.2");
+ unless (chdir("..") == 0) puts("bad 2.3");
+
+ unless (chdir("testdir{3}") == 0) puts("bad 3.1");
+ unless (basename(pwd()) eq "testdir{3}") puts("bad 3.2");
+ unless (chdir("..") == 0) puts("bad 3.3");
+
+ unless (platform() eq "windows") {
+ unless (chdir("testdir \"\'4") == 0) puts("bad 4.1");
+ unless (basename(pwd()) eq "testdir \"\'4") puts("bad 4.2");
+ unless (chdir("..") == 0) puts("bad 4.3");
+ }
+
+ unless (chdir("does-not-exist") == -1) puts("bad 10.1");
+}
+chdir1();
+} -cleanup {
+ file delete -force testdir1
+ file delete -force {test dir 2}
+ file delete -force testdir\{3\}
+ if {!$_windows} {file delete -force {testdir "'4}}
+ # '"
+} -output {}
+
+test caller-1 {test caller} -body {
+#lang L --line=1
+void caller1_foo()
+{
+ unless (caller(0) eq "caller1_foo") puts("bad 2.1");
+ unless (caller(1) eq "caller1") puts("bad 2.2");
+}
+void caller1()
+{
+ unless (caller(0) eq "caller1") puts("bad 1.1");
+ if (defined(caller(1000))) puts("bad 1.2");
+}
+caller1();
+} -output {}
+
+test chmod-1 {test chmod} -constraints tempNotWin -setup {
+ set fname1 [makeFile {test} chmod_test1 .]
+ set fname2 [makeFile {test} {chmod test 2} .]
+ set fname3 [makeFile {test} chmodtest\{3\} .]
+ set fname4 [makeFile {test} {chmod test \"\'4} .]
+} -body {
+#lang L --line=1
+void chmod1(string nm)
+{
+ FILE f;
+ struct stat stat;
+
+ f = fopen(nm, "r");
+ unless (defined(f)) puts("bad 1.1");
+ unless (chmod(nm, "444") == 0) puts("bad 1.2");
+ unless (lstat(nm, &stat) == 0) puts("bad 1.3");
+ unless (stat.st_mode & 0444) puts("bad 1.4");
+ unless (chmod(nm, "666") == 0) puts("bad 1.5");
+ unless (lstat(nm, &stat) == 0) puts("bad 1.6");
+ unless (stat.st_mode & 0666) puts("bad 1.7");
+ fclose(f);
+
+ unless (chmod("does-not-exist", "755") == -1) puts("bad 10.1");
+}
+#lang tcl
+chmod1 $fname1
+chmod1 $fname2
+chmod1 $fname3
+chmod1 $fname4
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+ removeFile $fname4
+} -output {}
+
+test chown-1 {test chown} -constraints tempNotWin -setup {
+ set fname1 [makeFile {test} chown_test1 .]
+ set fname2 [makeFile {test} {chown test 2} .]
+ set fname3 [makeFile {test} chowntest\{3\} .]
+ set fname4 [makeFile {test} {chown test \"\'4} .]
+} -body {
+#lang L --line=1
+/*
+ * This isn't the greatest test, because we can't be sure which users
+ * or groups are available on the test machine. So we create some
+ * files, get the current users and groups, and chown the file with
+ * those, verifying that this doesn't change the file user or group.
+ */
+void chown1(string nm)
+{
+ FILE f;
+ string group, owner;
+
+ f = fopen(nm, "r");
+ unless (defined(f)) puts("bad 1.1");
+ owner = file("attributes", nm, "-owner");
+ group = file("attributes", nm, "-group");
+
+ unless (chown(owner, "", nm) == 0) puts("bad 1.2");
+ unless (file("attributes", nm, "-owner") eq owner) puts("bad 1.3");
+
+ unless (chown("", group, nm) == 0) puts("bad 1.4");
+ unless (file("attributes", nm, "-group") eq group) puts("bad 1.5");
+
+ unless (chown(owner, group, nm) == 0) puts("bad 1.6");
+ unless (file("attributes", nm, "-owner") eq owner) puts("bad 1.7");
+ unless (file("attributes", nm, "-group") eq group) puts("bad 1.8");
+
+ fclose(f);
+
+ unless (chmod("does-not-exist", "755") == -1) puts("bad 10.1");
+}
+#lang tcl
+chown1 $fname1
+chown1 $fname2
+chown1 $fname3
+chown1 $fname4
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+ removeFile $fname4
+} -output {}
+
+test cpus-1 {test cpus api} -body {
+#lang L
+void cpus1()
+{
+ if (exists("/proc/cpuinfo")) {
+ unless (cpus() > 0) puts("bad");
+ }
+}
+cpus1();
+} -output {}
+
+test die-1 {test die} -setup {
+ makeFile {
+ die("die: %s\n", "s1");
+ } die1-1.l
+ makeFile {
+ die("die: %s %s\n", "s1", "s2");
+ } die1-2.l
+ makeFile {
+ die("die: %s", "s1");
+ } die1-3.l
+ makeFile {
+ die("die: %s %s", "s1", "s2");
+ } die1-4.l
+
+} -body {
+#lang L --line=1
+void die1()
+{
+ int ret;
+ string err, out;
+ string tclsh = eval("interpreter");
+
+ ret = system({tclsh, "die1-1.l"}, undef, &out, &err);
+ unless (ret == 1) puts("bad 1.1");
+ if (out) puts("bad 1.2");
+ unless (err == "die: s1\n") puts("bad 1.3");
+
+ ret = system({tclsh, "die1-2.l"}, undef, &out, &err);
+ unless (ret == 1) puts("bad 2.1");
+ if (out) puts("bad 2.2");
+ unless (err == "die: s1 s2\n") puts("bad 2.3");
+
+ ret = system({tclsh, "die1-3.l"}, undef, &out, &err);
+ unless (ret == 1) puts("bad 3.1");
+ if (out) puts("bad 3.2");
+ unless (err =~ /die: s1 at die1-3.l line 2.\n/) {
+ puts("bad 3.3 ${err}");
+ }
+
+ ret = system({tclsh, "die1-4.l"}, undef, &out, &err);
+ unless (ret == 1) puts("bad 4.1");
+ if (out) puts("bad 4.2");
+ unless (err =~ /die: s1 s2 at die1-4.l line 2.\n/) {
+ puts("bad 4.3 ${err}");
+ }
+}
+die1();
+} -output {}
+
+test die-2 {test die errors} -body {
+#lang L --line=1
+void die2()
+{
+ die("%s");
+}
+die2();
+} -returnCodes error -match regexp -result {.*3: L Warning: bad format specifier
+}
+
+test dirname-1 {test dirname} -body {
+#lang L --line=1
+void dirname1()
+{
+ unless (dirname("x") eq ".") puts("bad 1");
+ unless (dirname("") eq ".") puts("bad 2");
+ unless (dirname("/x/y") eq "/x") puts("bad 3");
+ unless (dirname("/path/to/file") eq "/path/to") puts("bad 4");
+ unless (dirname("path/to/file") eq "path/to") puts("bad 5");
+ unless (dirname("with spaces/to/f ile") eq "with spaces/to") {
+ puts("bad 6");
+ }
+ unless (platform() eq "windows") {
+ unless (dirname("with \"\'quotes/to/f ile") eq
+ "with \"\'quotes/to") {
+ puts("bad 7");
+ }
+ }
+}
+dirname1();
+} -output {}
+
+test env-1 {getenv and putenv} -body {
+#lang L --line=1
+void env1()
+{
+ string fmt;
+
+ unless (putenv("LIBLTEST=123") eq "123") puts("bad 0");
+ unless (getenv("LIBLTEST") eq "123") puts("bad 1");
+ unless (putenv("LIBLTEST=") eq "") puts("bad 1.2");
+ if (defined(getenv("LIBLTEST"))) puts("bad 2");
+
+ unless (defined(getenv("PATH"))) puts("bad 3");
+
+ putenv("LIBLTEST=%s%s", "one", "two");
+ unless (getenv("LIBLTEST") eq "onetwo") puts("bad 4");
+
+ /* The value can contain = */
+ unless (putenv("LIBLTEST=HAS=") eq "HAS=") puts("bad 5.1");
+ unless (getenv("LIBLTEST") eq "HAS=") puts("bad 5.2");
+ unless (putenv("LIBLTEST=HAS=X") eq "HAS=X") puts("bad 5.3");
+ unless (getenv("LIBLTEST") eq "HAS=X") puts("bad 5.4");
+ unless (putenv("LIBLTEST=HAS==") eq "HAS==") puts("bad 5.5");
+ unless (getenv("LIBLTEST") eq "HAS==") puts("bad 5.6");
+ unless (putenv("LIBLTEST=HAS=TWO=") eq "HAS=TWO=") puts("bad 5.7");
+ unless (getenv("LIBLTEST") eq "HAS=TWO=") puts("bad 5.8");
+ unless (putenv("LIBLTEST=HAS=TWO==") eq "HAS=TWO==") puts("bad 5.9");
+ unless (getenv("LIBLTEST") eq "HAS=TWO==") puts("bad 5.10");
+ unless (putenv("LIBLTEST==") eq "=") puts("bad 5.11");
+ unless (getenv("LIBLTEST") eq "=") puts("bad 5.12");
+ unless (putenv("LIBLTEST=====") eq "====") puts("bad 5.13");
+ unless (getenv("LIBLTEST") eq "====") puts("bad 5.14");
+
+ /* Check bad putenv format. */
+ if (defined(putenv("BAD"))) puts("bad 6.1");
+ if (defined(putenv(""))) puts("bad 6.2");
+ fmt = "BAD=%s";
+ if (defined(putenv(fmt))) puts("bad 6.3");
+}
+env1();
+} -output {}
+
+test exists-1 {test exists} -setup {
+ set fname1 [makeFile {test} exists_test1 .]
+ set fname2 [makeFile {test} {exists test 2} .]
+ set fname3 [makeFile {test} existstest\{3\} .]
+ if {!$_windows} {set fname4 [makeFile {test} {exists test \"\'4} .]}
+} -body {
+#lang L --line=1
+void exists1(string nm)
+{
+ unless (exists(nm)) puts("bad 1");
+
+}
+if (exists("does-not-exist")) puts("bad 2");
+#lang tcl
+exists1 $fname1
+exists1 $fname2
+exists1 $fname3
+if {!$_windows} {exists1 $fname4}
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+ if {!$_windows} {removeFile $fname4}
+} -output {}
+
+test fclose-1 {test fclose errors} -body {
+#lang L --line=1
+void fclose1()
+{
+ FILE f = "bad";
+
+ fclose(f);
+ unless (stdio_lasterr eq 'can not find channel named "bad"') {
+ puts("bad 1");
+ }
+}
+fclose1();
+} -output {}
+
+test fclose-2 {test fclose type errors} -body {
+#lang L --line=1
+void fclose2()
+{
+ fclose("not a FILE");
+}
+} -returnCodes error -match regexp -result {.*3: L Error: parameter 1 has incompatible type
+}
+
+test file-1 {test fopen/fclose/fprintf} -body {
+#lang L --line=1
+void file1(string nm)
+{
+ FILE f;
+
+ f = fopen(nm, "w");
+ unless (defined(f)) puts("bad 1.1");
+ unless (fprintf(f, "file-1 test\n") == 0) puts("bad 1.2");
+ unless (fclose(f) == 0) puts("bad 1.3");
+
+ unlink(nm);
+}
+file1("filetest1");
+file1("file test 2");
+file1("file test {3}");
+unless (platform() eq "windows") file1("file test \"4\'");
+} -output {}
+
+test file-2 {test fopen/fclose/fprintf run-time errors} -setup {
+ file delete -force "does not exist"
+} -body {
+#lang L --line=1
+void file2()
+{
+ FILE f;
+ string fmt;
+
+ if (defined(f = fopen("does not exist", "rw"))) puts("bad 1");
+
+ unless (fclose(f) == -1) puts("bad 2");
+ unless (fprintf(f, "bad") == -1) puts("bad 4");
+
+ unless (f = fopen("file2tst", "w")) puts("bad 4.1");
+ fmt = "%s";
+ unless (fprintf(f, fmt) == -1) puts("bad 4.2");
+ fclose(f);
+ unlink("file2tst");
+}
+file2();
+} -output {}
+
+test file-2.1 {test fprintf compile-time errors} -body {
+#lang L --line=1
+void file2_1()
+{
+ FILE f;
+
+ fprintf(f, "%s");
+}
+file2_1();
+} -returnCodes error -match regexp -result {.*5: L Warning: bad format specifier
+}
+
+test file-3 {test fprintf type errors} -body {
+#lang L --line=1
+void file3()
+{
+ fprintf("not a FILE", "%s", "bad");
+}
+} -returnCodes error -match regexp -result {.*3: L Error: parameter 1 has incompatible type
+}
+
+test fopen-1 {test fopen errors} -body {
+#lang L --line=1
+void fopen1()
+{
+ if (defined(fopen("bad1", "r"))) puts("bad 1");
+ unless (stdio_lasterr eq 'couldn\'t open "bad1": no such file or directory') {
+ puts("bad 2");
+ }
+ if (defined(fopen("bad2", "rv"))) puts("bad 3");
+ if (defined(fopen("bad3", "vrv"))) puts("bad 4");
+}
+fopen1();
+} -errorOutput {fopen(bad2, r) = couldn't open "bad2": no such file or directory
+fopen(bad3, r) = couldn't open "bad3": no such file or directory
+} -output {}
+
+test fprintf-1 {test fprintf compile-time errors} -body {
+#lang L --line=1
+void fprintf1()
+{
+ fprintf(stderr, "%s");
+}
+fprintf1();
+} -returnCodes error -match regexp -result {.*3: L Warning: bad format specifier
+}
+
+test fprintf-2 {test fprintf run-time errors} -body {
+#lang L
+void fprintf2()
+{
+ string fmt = "%s";
+
+ unless (fprintf(stderr, fmt) == -1) puts("bad 1");
+}
+fprintf2();
+} -output {}
+
+test Fprintf-1 {test Fprintf} -body {
+#lang L --line=1
+void Fprintf1()
+{
+ FILE f;
+
+ unless (Fprintf("/this/is/bad", "bad") < 0) puts("bad 1.1");
+
+ unless (Fprintf("fprintf-tst", "hello Fprintf\n") == 0) puts("bad 2.1");
+ unless (f = fopen("fprintf-tst", "r")) puts("bad 2.2");
+ unless (<f> eq "hello Fprintf") puts("bad 2.3");
+ if (<f>) puts("bad 2.4");
+ fclose(f);
+
+ unless (Fprintf("fprintf-tst", "%s %s %s", "a", "b", "c") == 0) {
+ puts("bad 3.1");
+ }
+ unless (f = fopen("fprintf-tst", "r")) puts("bad 3.2");
+ unless (<f> eq "a b c") puts("bad 3.3");
+ if (<f>) puts("bad 3.4");
+ fclose(f);
+
+ unlink("fprintf-tst");
+}
+Fprintf1();
+} -output {}
+
+test Fprintf-2 {test Fprintf compile-time errors} -body {
+#lang L --line=1
+void Fprintf2()
+{
+ Fprintf("fname", "%s");
+}
+Fprintf2();
+} -cleanup {
+ removeFile "fname"
+} -returnCodes error -match regexp -result {.*3: L Warning: bad format specifier
+}
+
+test Fprintf-2-1 {test Fprintf run-time errors} -body {
+#lang L
+void Fprintf2_1()
+{
+ string fmt = "%s";
+ unless (Fprintf("fname", fmt) == -1) puts("bad 1");
+}
+Fprintf2_1();
+} -cleanup {
+ removeFile "fname"
+} -output {}
+
+test ftype-1 {test ftpye} -setup {
+ set fname1 [makeFile {test} ftype_test1 .]
+ set fname2 [makeFile {test} {ftype test 2} .]
+ set fname3 [makeFile {test} ftypetest\{3\} .]
+ if {!$_windows} {set fname4 [makeFile {test} {ftype test \"\'4} .]}
+ set fdirname1 ftypedir1
+ set fdirname2 {ftype dir 2}
+ set fdirname3 ftypedir\{3\}
+ if {!$_windows} {set fdirname4 {ftypedir "'4}}
+ # '"
+ file mkdir $fdirname1
+ file mkdir $fdirname2
+ file mkdir $fdirname3
+ if {!$_windows} {file mkdir $fdirname4}
+} -body {
+#lang L --line=1
+void ftype1(string nm, string t)
+{
+ unless (ftype(nm) eq t) puts("bad 1");
+}
+#lang tcl
+ftype1 $fname1 file
+ftype1 $fname2 file
+ftype1 $fname3 file
+if {!$_windows} {ftype1 $fname4 file}
+ftype1 $fdirname1 directory
+ftype1 $fdirname2 directory
+ftype1 $fdirname3 directory
+if {!$_windows} {ftype1 $fdirname4 directory}
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+ if {!$_windows} {removeFile $fname4}
+ file delete -force $fdirname1
+ file delete -force $fdirname2
+ file delete -force $fdirname3
+ if {!$_windows} {file delete -force $fdirname4}
+} -output {}
+
+test ftype-2 {test ftype errors} -setup {
+ file delete -force "does not exist"
+} -body {
+#lang L --line=1
+void ftype2()
+{
+ if (defined(ftype("does not exist"))) puts("bad 1");
+}
+ftype2();
+} -output {}
+
+test getdir-1 {test getdir} -setup {
+ file mkdir getdirtest
+ set fname1 [makeFile {test1} f1 getdirtest]
+ set fname2 [makeFile {test2} f2 getdirtest]
+ set fname3 [makeFile {test3} f3 getdirtest]
+ file delete -force "does not exist"
+} -body {
+#lang L --line=1
+void getdir1()
+{
+ string dirs[];
+
+ dirs = getdir("getdirtest", "*");
+ unless (length(dirs) == 3) puts("bad 1.1");
+ unless (dirs[0] eq "getdirtest/f1") puts("bad 1.2");
+ unless (dirs[1] eq "getdirtest/f2") puts("bad 1.3");
+ unless (dirs[2] eq "getdirtest/f3") puts("bad 1.4");
+
+ dirs = getdir("getdirtest", "f2");
+ unless (length(dirs) == 1) puts("bad 2.1");
+ unless (dirs[0] eq "getdirtest/f2") puts("bad 2.2");
+
+ dirs = getdir("getdirtest", "*3");
+ unless (length(dirs) == 1) puts("bad 3.1");
+ unless (dirs[0] eq "getdirtest/f3") puts("bad 3.2");
+
+ dirs = getdir("getdirtest");
+ unless (length(dirs) == 3) puts("bad 4.1");
+ unless (dirs[0] eq "getdirtest/f1") puts("bad 4.2");
+ unless (dirs[1] eq "getdirtest/f2") puts("bad 4.3");
+ unless (dirs[2] eq "getdirtest/f3") puts("bad 4.4");
+
+ dirs = getdir("does not exist", "*");
+ unless (length(dirs) == 0) puts("bad 10.1");
+
+ if (defined(getdir("dir", "*", "too-many-args"))) puts("bad 11.1");
+
+ /* getdir should strip any leading ./ now */
+ cd("getdirtest");
+ dirs = getdir(".");
+ unless (length(dirs) == 3) puts("bad 12.1");
+ unless (dirs[0] eq "f1") puts("bad 12.2");
+ unless (dirs[1] eq "f2") puts("bad 12.3");
+ unless (dirs[2] eq "f3") puts("bad 12.4");
+ cd("..");
+}
+getdir1();
+} -cleanup {
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+ file delete -force getdirtest
+} -output {}
+
+test getdirx-1 {test getdirx} -setup {
+ file delete -force getdirx1-tst
+ file mkdir getdirx1-tst
+} -body {
+#lang L --line=1
+int getdirx1_compar(dirent d1, dirent d2)
+{
+ if (d1.name < d2.name) {
+ return (-1);
+ } else if (d1.name > d2.name) {
+ return (1);
+ } else {
+ return (0);
+ }
+}
+void getdirx1()
+{
+ dirent files[];
+
+ cd("getdirx1-tst");
+
+ if (mkdir("files-only")) puts("bad 1.1");
+ cd("files-only");
+ Fprintf("f2", "file2");
+ Fprintf(".h1", "hidden1");
+ Fprintf("f1", "file1");
+ cd("..");
+
+ if (mkdir("dirs-only")) puts("bad 2.1");
+ cd("dirs-only");
+ mkdir(".hd1");
+ mkdir("d2");
+ mkdir("d1");
+ cd("..");
+
+ if (mkdir("mix")) puts("bad 3.1");
+ cd("mix");
+ mkdir(".hd2");
+ mkdir("d6");
+ mkdir("d5");
+ Fprintf(".h2", "hidden2");
+ Fprintf("f6", "file6");
+ Fprintf("f5", "file5");
+ cd("..");
+
+ files = sort(command: &getdirx1_compar, getdirx("."));
+ unless (length(files) == 5) puts("bad 10.1");
+ unless (files[0] == {".","directory",1}) puts("bad 10.2");
+ unless (files[1] == {"..","directory",1}) puts("bad 10.3");
+ unless (files[2] == {"dirs-only","directory",0}) puts("bad 10.4");
+ unless (files[3] == {"files-only","directory",0}) puts("bad 10.5");
+ unless (files[4] == {"mix","directory",0}) puts("bad 10.6");
+
+ files = sort(command: &getdirx1_compar, getdirx("dirs-only"));
+ unless (length(files) == 5) puts("bad 11.1");
+ unless (files[0] == {".","directory",1}) puts("bad 11.2");
+ unless (files[1] == {"..","directory",1}) puts("bad 11.3");
+ unless (files[2] == {".hd1","directory",1}) puts("bad 11.4");
+ unless (files[3] == {"d1","directory",0}) puts("bad 11.5");
+ unless (files[4] == {"d2","directory",0}) puts("bad 11.6");
+
+ files = sort(command: &getdirx1_compar, getdirx("files-only"));
+ unless (length(files) == 5) puts("bad 12.1");
+ unless (files[0] == {".","directory",1}) puts("bad 12.2");
+ unless (files[1] == {"..","directory",1}) puts("bad 12.3");
+ unless (files[2] == {".h1","file",1}) puts("bad 12.4");
+ unless (files[3] == {"f1","file",0}) puts("bad 12.5");
+ unless (files[4] == {"f2","file",0}) puts("bad 12.6");
+
+ files = sort(command: &getdirx1_compar, getdirx("mix"));
+ unless (length(files) == 8) puts("bad 13.1");
+ unless (files[0] == {".","directory",1}) puts("bad 13.2");
+ unless (files[1] == {"..","directory",1}) puts("bad 13.3");
+ unless (files[2] == {".h2","file",1}) puts("bad 13.7");
+ unless (files[3] == {".hd2","directory",1}) puts("bad 13.4");
+ unless (files[4] == {"d5","directory",0}) puts("bad 13.5");
+ unless (files[5] == {"d6","directory",0}) puts("bad 13.6");
+ unless (files[6] == {"f5","file",0}) puts("bad 13.8");
+ unless (files[7] == {"f6","file",0}) puts("bad 13.9");
+
+ // error case
+ stdio_lasterr = "";
+ if (defined(getdirx("does-not-exist"))) puts("bad 20.1");
+ unless ((stdio_lasterr =~ /no such file/i) ||
+ (stdio_lasterr =~ /cannot find/i)) {
+ puts("bad 20.2: '${stdio_lasterr}'");
+ }
+
+ cd("..");
+}
+getdirx1();
+} -cleanup {
+ file delete -force getdirx1-tst
+} -output {}
+
+test getopt-1 {test getopt} -body {
+#lang L --line=1
+private string doit(string av[], string opts, string lopts[])
+{
+ string c, s = "";
+
+ getoptReset();
+ while (defined(c = getopt(av, opts, lopts))) {
+ if (c eq "") {
+ s .= "<${optopt}|err>";
+ break;
+ } else {
+ if (optarg) {
+ s .= "<${c}|${optarg}|${optind}>";
+ } else {
+ s .= "<${c}|#|${optind}>";
+ }
+ }
+ }
+ return (s);
+}
+void getopt1()
+{
+ string s;
+
+ /*
+ * This could be more exhaustive. It covers cases only for a
+ * single arg.
+ */
+
+ s = doit({}, "", {});
+ unless (s eq "") puts("bad 1.1");
+
+ /* opt a */
+ s = doit({"a.out","-a","x"}, "a", {});
+ unless (s eq "<a|#|2>") puts("bad 3.1");
+
+ /* opt a: */
+ s = doit({"a.out","-a","x"}, "a:", {});
+ unless (s eq "<a|x|3>") puts("bad 4.1");
+ s = doit({"a.out","-ax"}, "a:", {});
+ unless (s eq "<a|x|2>") puts("bad 4.2");
+ s = doit({"a.out","-a"}, "a:", {});
+ unless (s eq "<a|err>") puts("bad 4.3");
+ s = doit({"a.out","-a","-b"}, "a:", {});
+ unless (s eq "<a|err>") puts("bad 4.4");
+
+ /* opt a; */
+ s = doit({"a.out","-ax"}, "a;", {});
+ unless (s eq "<a|x|2>") puts("bad 5.1");
+ s = doit({"a.out","-a","x"}, "a;", {});
+ unless (s eq "<a|err>") puts("bad 5.2");
+ s = doit({"a.out","-a"}, "a;", {});
+ unless (s eq "<a|err>") puts("bad 5.3");
+
+ /* opt a| */
+ s = doit({"a.out","-ax"}, "a|", {});
+ unless (s eq "<a|x|2>") puts("bad 6.1");
+ s = doit({"a.out","-a","x"}, "a|", {});
+ unless (s eq "<a|#|2>") puts("bad 6.2");
+
+ /* longopt long */
+ s = doit({"a.out","--long", "x"}, "", {"long"});
+ unless (s eq "<long|#|2>") puts("bad 7.1");
+
+ /* longopt long: */
+ s = doit({"a.out","--long", "x"}, "", {"long:"});
+ unless (s eq "<long|x|3>") puts("bad 8.1");
+ s = doit({"a.out","--long=x"}, "", {"long:"});
+ unless (s eq "<long|x|2>") puts("bad 8.2");
+ s = doit({"a.out","--long:x"}, "", {"long:"});
+ unless (s eq "<long|x|2>") puts("bad 8.2.1");
+ s = doit({"a.out","--long"}, "", {"long:"});
+ unless (s eq "<|err>") puts("bad 8.3");
+
+ /* longopt long; */
+ s = doit({"a.out","--long", "x"}, "", {"long;"});
+ unless (s eq "<|err>") puts("bad 9.1");
+ s = doit({"a.out","--long=x"}, "", {"long;"});
+ unless (s eq "<long|x|2>") puts("bad 9.2");
+ s = doit({"a.out","--long"}, "", {"long;"});
+ unless (s eq "<|err>") puts("bad 9.3");
+
+ /* longopt long| */
+ s = doit({"a.out","--long", "x"}, "", {"long|"});
+ unless (s eq "<long|#|2>") puts("bad 10.1");
+ s = doit({"a.out","--long=x"}, "", {"long|"});
+ unless (s eq "<long|x|2>") puts("bad 10.2");
+ s = doit({"a.out","--long"}, "", {"long|"});
+ unless (s eq "<long|#|2>") puts("bad 10.3");
+}
+getopt1();
+} -output {}
+
+test getopt-2 {test getopt optind} -body {
+#lang L
+void getopt2()
+{
+ string av[], c, s;
+
+ av = { "prog", "-a", "-b", "-c" };
+ s = "";
+
+ /* This tests that changing optind works as expected. */
+
+ getoptReset();
+ if (optind) puts("bad 0.1");
+ unless (optopt == "") puts("bad 0.2");
+ if (optarg) puts("bad 0.3");
+
+ while (c = getopt(av, "abc", undef)) {
+ switch (c) {
+ case "a":
+ ++optind;
+ s .= c;
+ break;
+ case /[bc]/:
+ s .= c;
+ break;
+ }
+ }
+ unless (s == "ac") puts("bad 1.1 '${s}'");
+ unless (optind == 4) puts("bad 1.2");
+}
+getopt2();
+} -output {}
+
+test getpid-1 {test getpid} -body {
+#lang L --line=1
+void getpid1()
+{
+ unless (getpid() == pid()) puts("bad");
+}
+getpid1();
+} -output {}
+
+test here-1 {test here} -body {
+#lang L --line=1
+void here1func() {
+ here();
+}
+void here1()
+{
+ here();
+ here(); here();
+ here1func();
+
+ here();
+}
+here1();
+here();
+} -match regexp -errorOutput {here1\(\) in l-libl.test:6
+here1\(\) in l-libl.test:7
+here1\(\) in l-libl.test:7
+here1func\(\) in l-libl.test:2
+here1\(\) in l-libl.test:10
+\d+%l_toplevel\(\) in l-libl.test:13
+} -output {}
+
+test here-2 {test here errors} -body {
+#lang L --line=1
+void here2()
+{
+ here("bad");
+}
+} -returnCodes error -match regexp -result {.*3: L Error: here\(\) takes no arguments
+}
+
+test here-3 {test here with #includes} -setup {
+ set fname1 [makeFile {here();
+#include "here3b.l"
+here();
+ } here3a.l [file dirname [info script]]]
+ set fname2 [makeFile {here();
+#include "here3c.l"
+here();
+ } here3b.l]
+ set fname3 [makeFile {here();
+ } here3c.l]
+} -body {
+#lang L --line=1
+#include "here3a.l"
+void here3()
+{
+ here();
+}
+here3();
+} -match regexp -errorOutput {\d+%l_toplevel\(\) in here3a.l:1
+\d+%l_toplevel\(\) in here3b.l:1
+\d+%l_toplevel\(\) in here3c.l:1
+\d+%l_toplevel\(\) in here3b.l:3
+\d+%l_toplevel\(\) in here3a.l:3
+here3\(\) in l-libl.test:4
+} -output {}
+
+test is-1 {test isdir/isreg/islink} -setup {
+ set fdirname1 istestdir1
+ set fdirname2 {is test dir2}
+ set fdirname3 istestdir\{3\}
+ if {!$_windows} {set fdirname4 {istestdir "' 4}}
+ # '"
+ file mkdir $fdirname1
+ file mkdir $fdirname2
+ file mkdir $fdirname3
+ if {!$_windows} {file mkdir $fdirname4}
+ set fname1 [makeFile {test} istestfile1 .]
+ set fname2 [makeFile {test} {is test file 2} .]
+ set fname3 [makeFile {test} istestfile\{3\} .]
+ if {!$_windows} {set fname4 [makeFile {test} {is test file \"\'4} .]}
+ if {!$_windows} {
+ set flink1 islink1
+ set flink2 {is link 2}
+ set flink3 islink\{3\}
+ set flink4 {is link \"\'4}
+ file delete -force $flink1 $flink2 $flink3 $flink4
+ file link $flink1 $fname1
+ file link $flink2 $fname1
+ file link $flink3 $fname1
+ file link $flink4 $fname1
+ } else {
+ set flink1 ""
+ set flink2 ""
+ set flink3 ""
+ set flink4 ""
+ }
+ file delete -force "does not exist"
+} -body {
+#lang L --line=1
+void is1(string dirnm, string filenm, string linknm)
+{
+ unless (isdir(dirnm)) puts("bad 3.1");
+ unless (isreg(filenm)) puts("bad 4.1");
+ unless (platform() eq "windows") {
+ unless (islink(linknm)) puts("bad 5.1");
+ }
+
+ if (isdir("does not exist")) puts("bad 10.1");
+ if (isreg("does not exist")) puts("bad 10.2");
+ unless (platform() eq "windows") {
+ if (islink("does not exist")) puts("bad 10.3");
+ }
+}
+#lang tcl
+is1 $fdirname1 $fname1 $flink1
+is1 $fdirname2 $fname2 $flink2
+is1 $fdirname3 $fname3 $flink3
+if {!$_windows} {is1 $fdirname4 $fname4 $flink4}
+} -cleanup {
+ if {!$_windows} {file delete -force $flink1 $flink2 $flink3 $flink4}
+ file delete -force $fdirname1 $fdirname2 $fdirname3
+ if {!$_windows} {file delete -force $fdirname4}
+ removeFile $fname1
+ removeFile $fname2
+ removeFile $fname3
+ if {!$_windows} {removeFile $fname4}
+} -output {}
+
+test lc-1 {test lc} -body {
+#lang L --line=1
+void lc1()
+{
+ unless (lc("abcde") eq "abcde") puts("bad 1");
+ unless (lc("ABCDE") eq "abcde") puts("bad 2");
+ unless (lc("AbCdE") eq "abcde") puts("bad 3");
+ unless (lc("") eq "") puts("bad 4");
+}
+lc1();
+} -output {}
+
+test link-1 {test link} -setup {
+ set fname [makeFile {123456} linktest .]
+ file delete -force linktest2
+} -body {
+#lang L --line=1
+void link1()
+{
+ /* Error if target does not exist. */
+ unless (link("link", "does not exist") == -1) puts("bad 1.1");
+
+ /*
+ * This isn't supported on all platforms, so if it returns
+ * failure, don't check for the link.
+ */
+ if (link("linktest", "linktest2") == 0) {
+ unless (exists("linktest2")) puts("bad 2.1");
+ unless (size("linktest") == size("linktest2")) puts("bad 2.2");
+ }
+}
+link1();
+} -cleanup {
+ file delete -force linktest linktest2
+} -output {}
+
+test mkdir-1 {test mkdir} -setup {
+ set fname [makeFile {test} mkdir_file .]
+} -body {
+#lang L --line=1
+void mkdir1()
+{
+ string f1 = "mkdir1";
+ string f2 = "mk dir 2";
+ string f3 = "mkdir{3}";
+ string f4 = "mkdir\"\'4";
+
+ unless (mkdir(f1) == 0) puts("bad 1.1");
+ unless (mkdir(f2) == 0) puts("bad 1.2");
+ unless (mkdir(f3) == 0) puts("bad 1.3");
+ unless (platform() eq "windows") {
+ unless (mkdir(f4) == 0) puts("bad 1.4");
+ }
+
+ unless (ftype(f1) eq "directory") puts("bad 2.1");
+ unless (ftype(f2) eq "directory") puts("bad 2.2");
+ unless (ftype(f3) eq "directory") puts("bad 2.3");
+ unless (platform() eq "windows") {
+ unless (ftype(f4) eq "directory") puts("bad 2.4");
+ }
+
+ unlink(f1);
+ unlink(f2);
+ unlink(f3);
+ unless (platform() eq "windows") {
+ unlink(f4);
+ }
+
+ /* Check that the entire path is created. */
+ unless (mkdir("path/to/the/file") == 0) puts("bad 3.1");
+ unless (ftype("path") eq "directory") puts("bad 3.2");
+ unless (ftype("path/to") eq "directory") puts("bad 3.3");
+ unless (ftype("path/to/the") eq "directory") puts("bad 3.4");
+ unless (ftype("path/to/the/file") eq "directory") puts("bad 3.5");
+ unlink("path/to/the/file");
+ unlink("path/to/the");
+ unlink("path/to");
+ unlink("path");
+
+ /* Error if file already exists as a regular file. */
+ unless (mkdir("mkdir_file") == -1) puts("bad 4.1");
+}
+mkdir1();
+} -cleanup {
+ file delete -force $fname
+} -output {}
+
+test mtime-1 {test mtime} -setup {
+ set fname [makeFile {test} mtime_file .]
+ file delete -force "does not exist"
+} -body {
+#lang L --line=1
+void mtime1()
+{
+ /*
+ * Check the success is returned. Not sure how to check that
+ * the return value is actually correct.
+ */
+ unless (mtime("mtime_file") > 0) puts("bad 1");
+
+ /* Check error case. */
+ unless (mtime("does not exist") == 0) puts("bad 2");
+}
+mtime1();
+} -cleanup {
+ file delete -force $fname
+} -output {}
+
+test normalize-1 {test normalize} -body {
+#lang L --line=1
+void normalize1()
+{
+ unless (normalize("") eq "") puts("bad 1");
+ unless (normalize("./x") eq (pwd() . "/x")) puts("bad 2");
+}
+normalize1();
+} -output {}
+
+test ord-1 {test ord} -body {
+#lang L --line=1
+void ord1()
+{
+ string s;
+
+ unless (ord("A") == 65) puts("bad 1");
+ unless (ord("BCD") == 66) puts("bad 2");
+ unless (ord("") == -1) puts("bad 3");
+ s = "";
+ unless (ord(s) == -1) puts("bad 4");
+}
+ord1();
+ } -output {}
+
+test pclose-1 {test pclose errors} -body {
+#lang L --line=1
+void pclose1()
+{
+ FILE fd;
+ STATUS st;
+
+ pclose();
+ pclose(0, undef, 0);
+ pclose(fd, st);
+ pclose("not a FILE");
+}
+} -returnCodes error -match regexp -result {.*6: L Error: not enough arguments for function pclose
+.*7: L Error: too many arguments for function pclose
+.*8: L Error: parameter 2 has incompatible type
+.*9: L Error: parameter 1 has incompatible type
+}
+
+test pclose-2 {test pclose with errors} -body {
+#lang L --line=1
+void pclose2()
+{
+ FILE fd;
+ string cmd;
+ STATUS st;
+
+ cmd = "perl -e 'print STDERR \"to err\"; exit 0;'";
+ fd = popen(cmd, "r", undef);
+ fconfigure(fd, blocking: 0);
+
+ pclose(fd, &st);
+ puts(stdio_lasterr);
+}
+pclose2();
+} -output {to err
+}
+
+test popen-1 {test popen/pclose} -setup {
+ set fname [makeFile "line1\nline2\nline3\n" popen_file .]
+} -body {
+#lang L --line=1
+void popen1()
+{
+ int i;
+ FILE f;
+ string buf;
+ STATUS st;
+
+ /* There are more popen() tests in system1() later on. */
+
+ f = popen("cat popen_file", "r");
+ unless (defined(f)) puts("bad 1");
+
+ i = 1;
+ while (defined(buf = <f>)) {
+ unless (buf eq "line${i}") printf("bad i=%d\n", i);
+ ++i;
+ }
+ unless (i == 4) puts("bad 2");
+
+ unless (pclose(f, &st) == 0) puts("bad 3.1");
+ unless (st.exit == 0) puts("bad 3.2");
+
+ /* Check error case. */
+ f = popen("what-the-heck bad-command", "r");
+ if (defined(f)) puts("bad 10");
+
+ /* Check passing the command as an argv[]. */
+
+ f = popen({"cat","popen_file"}, "r");
+ unless (defined(f)) puts("bad 11");
+ i = 1;
+ while (defined(buf = <f>)) {
+ unless (buf eq "line${i}") printf("bad 2 i=%d\n", i);
+ ++i;
+ }
+ unless (i == 4) puts("bad 12");
+
+ unless (pclose(f, &st) == 0) puts("bad 13.1");
+ unless (st.exit == 0) puts("bad 13.2");
+}
+popen1();
+} -output {}
+
+test popen-2 {test popen errors} -body {
+#lang L --line=1
+void popen2()
+{
+ if (defined(popen("bad-cmd1", "r"))) puts("bad 1");
+ unless (stdio_lasterr =~ /couldn\'t execute \"bad cmd1\"/) {
+ puts("bad 2");
+ }
+
+ if (defined(popen("bad-cmd2", "rv"))) puts("bad 5");
+ if (defined(popen("bad-cmd3", "vrv"))) puts("bad 6");
+}
+popen2();
+} -match regexp -errorOutput {popen\(bad-cmd2, r\) = couldn't execute "bad-cmd2".*
+popen\(bad-cmd3, r\) = couldn't execute "bad-cmd3".*
+} -output {}
+
+test popen-3 {test popen stderr} -setup {
+ set fname [makeFile {
+ string cmd;
+ FILE f;
+
+ cmd = "perl -e 'print \"to out\"; print STDERR \"to err\";'";
+ f = popen(cmd, "r");
+ unless (defined(f)) die("popen");
+ unless (<f> eq "to out") puts("bad stdout");
+ pclose(f);
+ } popen3.l]
+} -body {
+#lang L --line=1
+/*
+ * Some contortions here to run tclsh on popen3.l (above) which prints
+ * to stderr, so we can capture stderr and check it. Otherwise,
+ * tcltest sees anything to stderr as an error and fails the test.
+ */
+void popen3()
+{
+ int ret;
+ string cmd = "\"${eval('interpreter')}\" popen3.l";
+ string err[], out[];
+
+ ret = system(cmd, undef, &out, &err);
+ unless (defined(ret)) puts("bad status ${ret}");
+ unless (length(out) == 0) puts("bad 2");
+ unless (err[0] eq "to err") puts("bad 3");
+}
+popen3();
+} -output {}
+
+test popen-4 {test popen stderr re-direction} -body {
+#lang L --line=1
+void popen4()
+{
+ string cmd;
+ FILE f;
+
+ cmd = "perl -e 'print \"to out\"; print STDERR \"to err\";' 2>p4err";
+
+ f = popen(cmd, "r");
+ unless (defined(f)) puts("bad 1.1");
+ unless (<f> eq "to out") puts("bad 1.2");
+ pclose(f);
+
+ f = fopen("p4err", "r");
+ unless (defined(f)) puts("bad 2.1");
+ unless (<f> eq "to err") puts("bad 2.2");
+ fclose(f);
+}
+popen4();
+} -cleanup {
+ removeFile "p4err"
+} -output {}
+
+test popen-5.1 {test popen stderr callback 1} -body {
+#lang L --line=1
+string p51cmd = <<'END'
+perl -e 'print STDERR "to err1\n";
+ print "to out\n";
+ print STDERR "to err2\n";'
+END
+int p51cb_lines = 0;
+int p51cb_eof = 0;
+void p51cb(string cmd, FILE f)
+{
+ string s;
+
+ unless (cmd == p51cmd) puts("bad 2.1");
+
+ if (Chan_names(f) == "") puts("bad 2.1.1");
+ while (s = <f>) {
+ switch (++p51cb_lines) {
+ case 1:
+ unless (s == "to err1") puts("bad 2.2 ${s}");
+ break;
+ case 2:
+ unless (s == "to err2") puts("bad 2.3 ${s}");
+ break;
+ default:
+ puts("bad 2.4");
+ break;
+ }
+ }
+ if (eof(f)) ++p51cb_eof;
+}
+void popen5_1()
+{
+ FILE f;
+
+ /*
+ * This test tries to get the popen()'d process to complete
+ * before we call pclose();
+ */
+
+ f = popen(p51cmd, "r", &p51cb);
+ unless (f) puts("bad 1.1");
+ unless (<f> == "to out") puts("bad 1.2");
+ /*
+ * Let the process complete so we get a call to the p51cb where
+ * EOF if seen, then call pclose().
+ */
+ sleep(1);
+ update();
+ pclose(f);
+ if (<f>) puts("bad 1.2.1");
+ unless (p51cb_lines == 2) puts("bad 1.3 ${p51cb_lines}");
+ unless (p51cb_eof) puts("bad 1.4 ${p51cb_eof}");
+}
+popen5_1();
+} -output {}
+
+test popen-5.2 {test popen stderr callback 2} -body {
+#lang L --line=1
+string p52cmd = <<'END'
+perl -e 'print STDERR "to err1\n";
+ print "to out\n";
+ print STDERR "to err2\n";'
+END
+int p52cb_lines = 0;
+int p52cb_eof = 0;
+void p52cb(string cmd, FILE f)
+{
+ string s;
+
+ unless (cmd == p52cmd) puts("bad 2.1");
+
+ if (Chan_names(f) == "") puts("bad 2.1.1");
+ while (s = <f>) {
+ switch (++p52cb_lines) {
+ case 1:
+ unless (s == "to err1") puts("bad 2.2 ${s}");
+ break;
+ case 2:
+ unless (s == "to err2") puts("bad 2.3 ${s}");
+ // Delay so pclose() below is called before we exit.
+ sleep(1);
+ break;
+ default:
+ puts("bad 2.4");
+ break;
+ }
+ }
+ if (eof(f)) ++p52cb_eof;
+}
+void popen5_2()
+{
+ FILE f;
+
+ /*
+ * This test tries to call pclose() before the popen()'d
+ * process exits.
+ */
+
+ f = popen(p52cmd, "r", &p52cb);
+ unless (f) puts("bad 1.1");
+ unless (<f> == "to out") puts("bad 1.2");
+ pclose(f);
+ if (<f>) puts("bad 1.2.1");
+ unless (p52cb_lines == 2) puts("bad 1.3 ${p52cb_lines}");
+ unless (p52cb_eof) puts("bad 1.4 ${p52cb_eof}");
+}
+popen5_2();
+} -output {}
+
+test popen-5.3 {test stderr callback that closes the pipe} -body {
+#lang L --line=1
+/*
+ * This tests a stderr callback that closes the read end of
+ * the pipe. It used to cause lib L to thrown an exception.
+ */
+int popen_5_3_called = 0;
+void popen_5_3_cb(_argused string cmd, FILE f)
+{
+ ++popen_5_3_called;
+ close(f);
+}
+void popen_5_3()
+{
+ FILE f;
+ string cmd = "perl -e 'print STDERR \"to err\";'";
+
+ f = popen(cmd, "r", &popen_5_3_cb);
+ unless (f) puts("bad 1.1");
+ if (pclose(f)) puts("bad 1.2");
+ unless (popen_5_3_called == 1) puts("bad 1.3: ${popen_5_3_called}");
+}
+popen_5_3();
+} -output {}
+
+test popen-6 {test popen stderr ignore} -setup {
+ set fname [makeFile {
+ string cmd;
+ FILE f;
+
+ cmd = "perl -e 'print \"to out\"; print STDERR \"to err\";'";
+ f = popen(cmd, "r", undef);
+ unless (defined(f)) die("popen");
+ unless (<f> eq "to out") puts("bad stdout");
+ pclose(f);
+ } popen6.l]
+} -body {
+#lang L --line=1
+/*
+ * This is like popen3() but stderr should be ignored.
+ */
+void popen6()
+{
+ int ret;
+ string tclsh = eval('interpreter');
+ string err[], out[];
+
+ ret = system({tclsh, "popen6.l"}, undef, &out, &err);
+ unless (ret == 0) puts("bad status ${ret}");
+ if (out) puts("bad 2");
+ if (err) puts("bad 3: ${err}");
+}
+popen6();
+} -output {}
+
+test popen-7 {test popen type checking} -body {
+#lang L --line=1
+void popen7_bad1();
+void popen7_bad2(string cmd);
+void popen7_bad3(FILE f);
+int popen7_bad4(string cmd, FILE f);
+int popen7_bad5(string cmd, string f);
+void popen7_good(string cmd, string f);
+void popen_7()
+{
+ popen("cmd", "r", popen7_bad1);
+ popen("cmd", "r", popen7_bad2);
+ popen("cmd", "r", popen7_bad3);
+ popen("cmd", "r", popen7_bad4);
+ popen("cmd", "r", popen7_bad5);
+
+ popen();
+ popen("cmd", "mode", popen7_good, "too many");
+
+ popen(123, "mode");
+ popen("cmd", 123);
+ popen("cmd", 123, popen7_good);
+}
+popen_7();
+} -returnCodes error -match regexp -result {.*9: L Error: illegal type for stderr callback
+.*10: L Error: illegal type for stderr callback
+.*11: L Error: illegal type for stderr callback
+.*12: L Error: illegal type for stderr callback
+.*13: L Error: illegal type for stderr callback
+.*15: L Error: incorrect # args to popen
+.*16: L Error: incorrect # args to popen
+.*18: L Error: first arg to popen must be string or string array
+.*19: L Error: expected type string but got int in second arg to popen
+.*20: L Error: expected type string but got int in second arg to popen
+}
+
+test printf-1 {test printf} -body {
+#lang L --line=1
+void printf1()
+{
+ printf("Test1\n");
+ printf("Test%s\n", "2");
+ printf("Test%d - last one\n", 3);
+}
+printf1();
+} -output {Test1
+Test2
+Test3 - last one
+}
+
+test printf-2 {test that we exit silently on broken stdout pipe} -setup {
+ set fname [makeFile {
+ while (1) puts("printf2 test");
+ } printf2.l]
+} -body {
+#lang L --line=1
+void printf2()
+{
+ int ret;
+ string cmd, err[], out[];
+
+ /*
+ * This runs the printf2.l script (above) in a separate
+ * instance of the L interpreter and pipes it to a perl script
+ * that reads only the first two lines and then exits. L
+ * should ignore the broken output pipe error and silently
+ * exit.
+ */
+ cmd = "\"${eval('interpreter')}\" printf2.l | perl -e '$_=<>;$_=<>'";
+ ret = system(cmd, undef, &out, &err);
+ unless (defined(ret)) perror("system");
+ unless (length(out) == 0) puts("bad 2 ${out}");
+ unless (length(err) == 0) puts("bad 3 ${err}");
+}
+printf2();
+} -output {}
+
+test printf-3 {test printf run-time errors} -body {
+#lang L --line=1
+void printf3()
+{
+ string fmt = "%s";
+
+ unless (printf(fmt) == -1) puts("bad 1");
+}
+printf3();
+} -output {}
+
+test printf-3.1 {test printf compile-time errors} -body {
+#lang L --line=1
+void printf3_1()
+{
+ printf("%s");
+}
+printf3_1();
+} -returnCodes error -match regexp -result {.*3: L Warning: bad format specifier
+}
+
+test putenv-1 {test putenv errors} -body {
+#lang L --line=1
+void putenv1()
+{
+ putenv("BAD=%s");
+}
+putenv1();
+} -returnCodes error -match regexp -result {.*3: L Warning: bad format specifier
+}
+
+test read-1 {test read} -setup {
+ set fname [makeFile "012345678901234567\n" read_test .]
+} -body {
+#lang L --line=1
+void read1()
+{
+ int n;
+ FILE f;
+ string buf;
+
+ f = fopen("read_test", "r");
+ unless (defined(f)) puts("bad 1.1");
+
+ buf = undef;
+ n = read(f, &buf, 5);
+ unless (defined(buf)) puts("bad 2.1");
+ unless ((n == 5) && (buf eq "01234")) puts("bad 2.2");
+
+ buf = undef;
+ n = read(f, &buf, 5);
+ unless (defined(buf)) puts("bad 2.3");
+ unless ((n == 5) && (buf eq "56789")) puts("bad 2.4");
+
+ buf = undef;
+ n = read(f, &buf, 5);
+ unless (defined(buf)) puts("bad 2.5");
+ unless ((n == 5) && (buf eq "01234")) puts("bad 2.6");
+
+ buf = undef;
+ n = read(f, &buf, 5);
+ unless (defined(buf)) puts("bad 2.7");
+ unless ((n == 4) && (buf eq "567\n")) puts("bad 2.8");
+
+ n = read(f, &buf, 1);
+ unless (n == -1) puts("bad 2.9");
+ n = read(f, &buf, 1);
+ unless (n == -1) puts("bad 2.10");
+
+ fclose(f);
+
+ f = fopen("read_test", "r");
+ unless (defined(f)) puts("bad 3.1");
+
+ buf = undef;
+ n = read(f, &buf, -1);
+ unless (defined(buf)) puts("bad 4.1");
+ unless ((n == 19) && (buf eq "012345678901234567\n")) puts("bad 4.2");
+
+ fclose(f);
+
+ /* Check that last arg is optional. */
+
+ f = fopen("read_test", "r");
+ unless (defined(f)) puts("bad 5.1");
+ buf = undef;
+ n = read(f, &buf);
+ unless (defined(buf)) puts("bad 5.2");
+ unless ((n == 19) && (buf eq "012345678901234567\n")) puts("bad 5.3");
+ fclose(f);
+}
+read1();
+} -cleanup {
+ file delete -force $fname
+} -output {}
+
+test read-2 {test read type errors} -body {
+#lang L --line=1
+void read2()
+{
+ FILE f;
+ string s;
+
+ read();
+ read(f);
+ read(f, &s, -1, "too many");
+ read(0, &s, -1);
+ read(f, 0, -1);
+ read(f, &s, s);
+}
+} -returnCodes error -match regexp -result {.*6: L Error: incorrect # args to read\(\)
+.*7: L Error: incorrect # args to read\(\)
+.*8: L Error: incorrect # args to read\(\)
+.*9: L Error: first arg to read\(\) must have type FILE
+.*10: L Error: second arg to read\(\) must have type string\&
+.*11: L Error: third arg to read\(\) must have type int
+}
+
+test rename-1 {test rename} -setup {
+ set fname1 [makeFile {test} rename_test1 .]
+ set fname2 [makeFile {test} {rename test 2} .]
+ set fname3 [makeFile {test} renametest\{3\} .]
+ if {!$_windows} {set fname4 [makeFile {test} {rename test \"\'4} .]}
+} -body {
+#lang L --line=1
+void rename1(string old)
+{
+ FILE f;
+ string buf;
+ string new = old . "-renamed";
+
+ unless (rename(old, new) == 0) puts("bad 1.1");
+ f = fopen(new, "r");
+ unless (defined(f)) puts("bad 2.1");
+ unless (defined(buf = <f>)) puts("bad 2.2");
+ unless (buf eq "test") puts("bad 2.3");
+ if (defined(buf = <f>)) puts("bad 2.4");
+ unless (fclose(f) == 0) puts("bad 2.5");
+
+ unlink(new);
+}
+#lang tcl
+rename1 $fname1
+rename1 $fname2
+rename1 $fname3
+if {!$_windows} {rename1 $fname4}
+} -output {}
+
+test rename-2 {test rename errors} -setup {
+ file delete -force "does not exist"
+} -body {
+#lang L --line=1
+void rename2()
+{
+ unless (rename("does not exist", "bad") == -1) puts("bad 1");
+}
+rename2();
+} -output {}
+
+test require-1 {test require errors} -body {
+#lang L --line=1
+void require1()
+{
+ if (defined(require("non-existent package for sure"))) puts("bad");
+}
+require1();
+} -output {}
+
+test require-2 {test package version number} -body {
+#lang L --line=1
+void require2()
+{
+ string v = Lver();
+
+ unless (require("L", v) == v) puts("bad 1");
+ if (require("L", (float)v+1.0)) puts("bad 2");
+ if (require("L", (float)v+0.1)) puts("bad 3");
+}
+require2();
+} -output {}
+
+test rmdir-1 {test rmdir} -setup {
+ set fdirname1 rmdir1
+ set fdirname2 {rm dir 2}
+ set fdirname3 rmdir\{3\}
+ if {!$_windows} {set fdirname4 {rmdir "' 4}}
+ # '"
+ set fdirname5 rmdir_nonempty
+ file mkdir $fdirname1
+ file mkdir $fdirname2
+ file mkdir $fdirname3
+ if {!$_windows} {file mkdir $fdirname4}
+ file mkdir $fdirname5
+ file delete -force "does not exist"
+ set fname [makeFile {test} file rmdir_nonempty]
+} -body {
+#lang L --line=1
+void rmdir1a(string nm)
+{
+ unless (rmdir(nm) == 0) puts("bad 1");
+ unless (rmdir("does not exist") == 0) puts("bad 2");
+}
+void rmdir1b(string nm)
+{
+ /* Check error case (trying to remove non-empty directory). */
+ unless (rmdir(nm) == -1) puts("bad 3");
+}
+#lang tcl
+rmdir1a $fdirname1
+rmdir1a $fdirname2
+rmdir1a $fdirname3
+if {!$_windows} {rmdir1a $fdirname4}
+rmdir1b $fdirname5
+} -cleanup {
+ file delete -force $fdirname1 $fdirname2 $fdirname3
+ if {!$_windows} {file delete -force $fdirname4}
+ file delete -force $fname $fdirname5
+} -output {}
+
+test size-1 {test size} -setup {
+ set fname1 [makeFile {123456} size1 .]
+ set fname2 [makeFile {123456} {si ze 2} .]
+ set fname3 [makeFile {123456} size\{3\} .]
+ if {!$_windows} {set fname4 [makeFile {123456} {size "' 4} .]}
+ # '"
+ file delete -force "does not exist"
+} -body {
+#lang L --line=1
+void size1(string nm)
+{
+ unless (size(nm) == 7) printf("bad 1 for '%s'\n", nm);
+ unless (size("does not exist") == -1) puts("bad 2");
+}
+#lang tcl
+size1 $fname1
+size1 $fname2
+size1 $fname3
+if {!$_windows} {size1 $fname4}
+} -cleanup {
+ file delete -force $fname1 $fname2 $fname3
+ if {!$_windows} {file delete -force $fname4}
+} -output {}
+
+test sleep-1 {test sleep} -body {
+#lang L --line=1
+void sleep1()
+{
+ /*
+ * Touch a file before and after a sleep(3) and check that the
+ * two mod times are at least two seconds apart.
+ */
+
+ int t1, t2;
+ FILE f;
+
+ f = fopen("sleep_test", "w");
+ unless (defined(f)) puts("bad 1");
+ fprintf(f, "test1\n");
+ fclose(f);
+ t1 = mtime("sleep_test");
+
+ sleep(3.0);
+
+ f = fopen("sleep_test", "a");
+ unless (defined(f)) puts("bad 2");
+ fprintf(f, "test2\n");
+ fclose(f);
+ t2 = mtime("sleep_test");
+
+ unless ((t2 - t1) >= 2) puts("bad 3");
+
+ unlink("sleep_test");
+}
+sleep1();
+} -output {}
+
+test spawn1 {test spawn type errors} -body {
+#lang L --line=1
+void spawn1()
+{
+ int iarr[];
+ string arr[], s;
+ STATUS status;
+ FILE f;
+
+ spawn();
+ spawn("not", "enough", "args");
+ spawn("cmd", "in", "out", "err", "status", "toomany");
+
+ /*
+ * Type errors in cmd arg. It must be string or string[].
+ */
+ spawn(&s);
+ spawn(&arr);
+ spawn(iarr);
+
+ /*
+ * Type errors in status arg. It must be STATUS&.
+ */
+ spawn(s, status);
+ spawn(s, s);
+
+ /*
+ * Type errors in "in" arg. It must be string[], a string
+ * constant, string variable, or FILE.
+ */
+ spawn(s, &arr, "out", "err");
+ spawn(s, iarr, "out", "err");
+ spawn(s, &f, "out", "err");
+
+ /*
+ * Type errors in "out" arg. It must be string constant, or
+ * FILE.
+ */
+ spawn(s, "in", s, "err");
+ spawn(s, "in", &s, "err");
+ spawn(s, "in", &arr, "err");
+ spawn(s, "in", arr, "err");
+ spawn(s, "in", &iarr, "err");
+ spawn(s, "in", &f, "err");
+
+ /*
+ * Type errors in "err" arg. Same as for "out" arg.
+ */
+ spawn(s, "in", "out", s);
+ spawn(s, "in", "out", &s);
+ spawn(s, "in", "out", &arr);
+ spawn(s, "in", "out", arr);
+ spawn(s, "in", "out", &iarr);
+ spawn(s, "in", "out", &f);
+}
+} -returnCodes error -match regexp -result {.*8: L Error: incorrect # args
+.*9: L Error: incorrect # args
+.*10: L Error: incorrect # args
+.*15: L Error: first arg must be string or string array
+.*16: L Error: first arg must be string or string array
+.*17: L Error: first arg must be string or string array
+.*22: L Error: last arg must be of type STATUS \&
+.*23: L Error: last arg must be of type STATUS \&
+.*29: L Error: second arg must be FILE, or string constant/variable/array
+.*30: L Error: second arg must be FILE, or string constant/variable/array
+.*31: L Error: second arg must be FILE, or string constant/variable/array
+.*37: L Error: third arg must be FILE, or string constant
+.*38: L Error: third arg must be FILE, or string constant
+.*39: L Error: third arg must be FILE, or string constant
+.*40: L Error: third arg must be FILE, or string constant
+.*41: L Error: third arg must be FILE, or string constant
+.*42: L Error: third arg must be FILE, or string constant
+.*47: L Error: fourth arg must be FILE, or string constant
+.*48: L Error: fourth arg must be FILE, or string constant
+.*49: L Error: fourth arg must be FILE, or string constant
+.*50: L Error: fourth arg must be FILE, or string constant
+.*51: L Error: fourth arg must be FILE, or string constant
+.*52: L Error: fourth arg must be FILE, or string constant
+}
+
+test spawn2 {test spawn error return values} -body {
+#lang L --line=1
+void spawn2()
+{
+ int pid;
+
+ /*
+ * Possible errors:
+ * error parsing shell quoting in argv[] command
+ * command not found
+ * cannot open input file
+ * cannot open output file
+ * cannot open err file
+ * error from Tcl open command (unclear how to get this)
+ */
+
+ pid = spawn("'bad quoting");
+ if (defined(pid)) puts("bad 1.1");
+
+ pid = spawn("command-not-found");
+ if (defined(pid)) puts("bad 2.1");
+
+ pid = spawn("date", "bad-input-file", undef, undef);
+ if (defined(pid)) puts("bad 2.1");
+
+ pid = spawn("date", undef, "/bad/bad-file", undef);
+ if (defined(pid)) puts("bad 2.2");
+ pid = spawn("date", undef, undef, "/bad/bad-file");
+ if (defined(pid)) puts("bad 2.3");
+}
+spawn2();
+} -output {}
+
+test spawn3 {test spawn pid return value} -body {
+#lang L --line=1
+void spawn3()
+{
+ int pid;
+ FILE f;
+
+ /*
+ * For a pipeline, spawn should return the pid of the last
+ * command, like bash does with #!, not a list of pids like
+ * Tcl's pid() does.
+ */
+
+ pid = spawn("date | perl -e 'print $$'", undef, "spawn3-out", undef);
+ unless (defined(pid)) puts("bad 1");
+ unless ((poly)pid =~ /^\d+$/) puts("bad 2");
+ waitpid(pid, undef, 0);
+ unless (exists("spawn3-out")) puts("bad 3");
+ unless (f = fopen("spawn3-out", "r")) puts("bad 4");
+ unless ((int)<f> == pid) puts("bad 5");
+ fclose(f);
+ unlink("spawn3-out");
+}
+spawn3();
+} -output {}
+
+test spawn4 {test spawn output options} -body {
+#lang L
+void spawn4()
+{
+ /*
+ * Test some cases that were omitted elsewhere.
+ */
+
+ int pid;
+ FILE fe, fo;
+ string cmd, in;
+
+ // Test that file handles for stdout and stderr are not closed.
+
+ unless (fo = fopen("spawn4-out", "w")) puts("bad 1.1");
+ unless (fe = fopen("spawn4-err", "w")) puts("bad 1.2");
+ cmd = "perl -e 'while (<>) { print uc $_; print STDERR lc $_; }'";
+ in = "LinE1\n";
+ pid = spawn(cmd, in, fo, fe);
+ unless (defined(pid)) puts("bad 1.3 ${stdio_lasterr}");
+ unless (waitpid(pid, undef, 0) == pid) puts("bad 1.4");
+ if (fprintf(fo, "line2\n")) puts("bad 1.5");
+ if (fprintf(fe, "line3\n")) puts("bad 1.6");
+ fclose(fo);
+ fclose(fe);
+ unless (fo = fopen("spawn4-out", "r")) puts("bad 1.7");
+ unless (fe = fopen("spawn4-err", "r")) puts("bad 1.8");
+ unless ((<fo> == "LINE1") && (<fo> == "line2") && !<fo>) {
+ puts("bad 1.9");
+ }
+ unless ((<fe> == "line1") && (<fe> == "line3") && !<fe>) {
+ puts("bad 1.10");
+ }
+ fclose(fo);
+ fclose(fe);
+
+ // Test that a list of strings is OK for the stdin arg.
+
+ cmd = "perl -e 'print uc $_ while (<>)'";
+ pid = spawn(cmd, {"line1","line2"}, "spawn4-out", undef);
+ unless (defined(pid)) puts("bad 1.1 ${stdio_lasterr}");
+ unless (waitpid(pid, undef, 0) == pid) puts("bad 2.2");
+ unless (fo = fopen("spawn4-out", "r")) puts("bad 2.3");
+ unless ((<fo> == "LINE1") && (<fo> == "LINE2") && !<fo>) {
+ puts("bad 2.4");
+ }
+ fclose(fo);
+
+ unlink("spawn4-out");
+ unlink("spawn4-err");
+}
+spawn4();
+} -output {}
+
+test sprintf-1 {test sprintf} -body {
+#lang L --line=1
+void sprintf1()
+{
+ string s;
+
+ s = sprintf("Test1");
+ unless (s eq "Test1") puts("bad 1");
+
+ s = sprintf("Test%s", "2");
+ unless (s eq "Test2") puts("bad 2");
+
+ s = sprintf("Test%s%d", "3", 4);
+ unless (s eq "Test34") puts("bad 3");
+}
+sprintf1();
+} -output {}
+
+test sprintf-2 {test sprintf run-time errors} -body {
+#lang L --line=1
+void sprintf2()
+{
+ string fmt = "%s";
+
+ if (sprintf(fmt)) puts("bad 1");
+}
+sprintf2();
+} -output {}
+
+test sprintf-2.1 {test sprintf compile-time errors} -body {
+#lang L --line=1
+void sprintf2_1()
+{
+ sprintf("%s");
+}
+sprintf2_1();
+} -returnCodes error -match regexp -result {.*3: L Warning: bad format specifier
+}
+
+test stat-1 {test lstat and stat} -setup {
+ # put 33 digits into the files
+ set fname1 [makeFile {123456789012345678901234567890123} statfile1 .]
+ set fname2 [makeFile {123456789012345678901234567890123} {stat file 2} .]
+ set fname3 [makeFile {123456789012345678901234567890123} statfile\{3\} .]
+ if {!$_windows} {
+ set fname4 [makeFile {123456789012345678901234567890123} {stat file \"\' 4} .]
+ }
+ file delete -force "does not exist"
+} -body {
+#lang L --line=1
+void stat1(string target)
+{
+ string lnk = target . "_link";
+ struct stat buf;
+
+ /*
+ * Links aren't supported on all platforms, so don't test
+ * lstat if the link can't be created.
+ */
+ unlink(lnk);
+ if (symlink(lnk, target) == 0) {
+ unless (lstat(lnk, &buf) == 0) puts("bad 1.1");
+ if (buf.st_size == 34) puts("bad 1.2");
+ unless (buf.st_type eq "link") puts("bad 1.3");
+ }
+ unlink(lnk);
+
+ /* Error if file does not exist. */
+ unless (lstat("does not exist", &buf) == -1) puts("bad 2.1");
+
+ unless (stat(target, &buf) == 0) puts("bad 5.1");
+ unless (buf.st_size == 34) puts("bad 5.2");
+ unless (buf.st_type eq "file") puts("bad 5.3");
+ unless (buf.st_mtime == mtime(target)) puts("bad 5.4");
+}
+#lang tcl
+stat1 $fname1
+stat1 $fname2
+stat1 $fname3
+if {!$_windows} {stat1 $fname4}
+} -cleanup {
+ file delete -force $fname1 $fname2 $fname3
+ if {!$_windows} {file delete -force $fname4}
+} -output {}
+
+test strchr-1 {test strchr} -body {
+#lang L --line=1
+void strchr1()
+{
+ unless (strchr("abcabc", "a") == 0) puts("bad 1");
+ unless (strchr("abcabc", "b") == 1) puts("bad 2");
+ unless (strchr("abcabc", "c") == 2) puts("bad 3");
+ unless (strchr("abcabc", "d") == -1) puts("bad 4");
+}
+strchr1();
+} -output {}
+
+test streq-1 {test streq} -body {
+#lang L --line=1
+void streq1()
+{
+ unless (streq("abc", "abc") == 1) puts("bad 1");
+ unless (streq("abc", "cba") == 0) puts("bad 2");
+}
+streq1();
+} -output {}
+
+test strlen-1 {test strlen} -body {
+#lang L --line=1
+void strlen1()
+{
+ int i;
+ int n = 10;
+ string s;
+
+ for (s = "", i = 0; i < n; ++i) {
+ unless (strlen(s) == i) printf("bad 1 i=%d\n", i);
+ s = s . "x";
+ }
+}
+strlen1();
+} -output {}
+
+test strneq-1 {test strneq} -body {
+#lang L --line=1
+void strneq1()
+{
+ unless (strneq("abc", "abc", 10) == 1) puts("bad 1");
+ unless (strneq("abc", "cba", 10) == 0) puts("bad 2");
+ unless (strneq("abc", "abc", 3) == 1) puts("bad 3");
+ unless (strneq("abc", "cba", 3) == 0) puts("bad 4");
+ unless (strneq("abc", "abc", 2) == 1) puts("bad 5");
+ unless (strneq("abc", "cba", 2) == 0) puts("bad 6");
+
+ unless (strneq("abc", "abd", 2) == 1) puts("bad 7");
+ unless (strneq("abc", "aaa", 1) == 1) puts("bad 8");
+}
+strneq1();
+
+} -output {}
+
+test strrchr-1 {test strrchr} -body {
+#lang L --line=1
+void strrchr1()
+{
+ unless (strrchr("abcabc", "a") == 3) puts("bad 1");
+ unless (strrchr("abcabc", "b") == 4) puts("bad 2");
+ unless (strrchr("abcabc", "c") == 5) puts("bad 3");
+ unless (strrchr("abcabc", "d") == -1) puts("bad 4");
+}
+strrchr1();
+} -output {}
+
+test system-1 {test system and popen shell quoting} -body {
+#lang L --line=1
+private string do_popen(string cmd)
+{
+ FILE f;
+ string ret;
+
+ unless (defined(f = popen(cmd, "r"))) return (undef);
+ read(f, &ret, -1);
+ pclose(f);
+ return (ret);
+}
+void system1()
+{
+ /*
+ * This test checks that we got the shell-quoting semantics right.
+ * It uses a perl script to echo each element of the argv array
+ * bracketed with < and >.
+ *
+ * xyz -- all escapes are processed except \<newline> ignored
+ * 'xyz' -- no single quotes allowed inside, no escapes processed
+ * "xyz" -- only \\ and \" are processed, \<newline> ignored
+ */
+
+ int ret;
+ string s, t;
+ string perl = "perl -e 'foreach (@ARGV) {print \"<\${_}>\"}'";
+
+ /*
+ * Format is <argv element> | <expected output from perl script>
+ * Note that the Tcl parser requires that the *test* itself
+ * have balanced {}, so be careful with the order of braces below.
+ */
+ string tests = <<'END'
+x | <x>
+xy | <xy>
+x\yz | <xyz>
+x\y\zx | <xyzx>
+x\\\\y | <x\\y>
+x\ny | <xny>
+$x | <$x>
+[ | <[>
+] | <]>
+"x" | <x>
+"xy" | <xy>
+"x y" | <x y>
+"x\yz" | <x\yz>
+"x\"y" | <x"y>
+"x\\y" | <x\y>
+'x' | <x>
+'xy' | <xy>
+'x y' | <x y>
+'x\\' | <x\\>
+'x\y' | <x\y>
+x"y" | <xy>
+x"y"z | <xyz>
+x"y""z" | <xyz>
+x'y' | <xy>
+x'y'z | <xyz>
+x'y''z' | <xyz>
+x"y"'z' | <xyz>
+x'y'"z" | <xyz>
+"{" | <{>
+} | <}>
+{ | <{>
+"}" | <}>
+{} | <{}>
+}{ | <}{>
+"{}" | <{}>
+"}{" | <}{>
+x y | <x><y>
+ x y | <x><y>
+ x y | <x><y>
+ x y | <x><y>
+ x y | <x><y>
+x y | <x><y>
+x y | <x><y>
+x y z | <x><y><z>
+- | <->
+-- --x | <--x>
+END
+//" (to balance quotes for emacs)
+ foreach (t in split(/\n/, tests)) {
+ string a[] = split(/\s*\|\s*/, t);
+ assert(length(a) == 2);
+ unless (defined(system("${perl} ${a[0]}", undef, &s, undef))) {
+ puts("system: error for ${a[0]}");
+ }
+ unless (s eq a[1]) {
+ puts("system: for ${a[0]} got ${s} wanted ${a[1]}");
+ }
+ unless ((s = do_popen("${perl} ${a[0]}")) eq a[1]) {
+ puts("popen: for ${a[0]} got ${s} wanted ${a[1]}");
+ }
+ }
+
+ /* Check \<newline> escapes. */
+ ret = system("${perl} x\\\ny", undef, &s, undef); // x\ny
+ unless (defined(ret) && (s eq "<xy>")) puts("bad 1.1");
+ ret = system("${perl} \"x\\\ny\"", undef, &s, undef); // "x\ny"
+ unless (defined(ret) && (s eq "<xy>")) puts("bad 1.2");
+ ret = system("${perl} 'x\\\ny'", undef, &s, undef); // 'x\ny'
+ unless (defined(ret) && (s eq "<x\\\ny>")) puts("bad 1.3");
+ s = do_popen("${perl} x\\\ny"); // x\ny
+ unless (s eq "<xy>") puts("bad 1.4");
+ s = do_popen("${perl} \"x\\\ny\""); // "x\ny"
+ unless (s eq "<xy>") puts("bad 1.5");
+
+ /* Check error cases (unterminated escapes and quoted strings). */
+
+ if (defined(system("\\"))) puts("bad 2.1");
+ unless (stdio_lasterr eq "trailing \\") puts("bad 2.2");
+ if (defined(system("\"\\"))) puts("bad 2.3");
+ unless (stdio_lasterr eq "unterminated \"") puts("bad 2.4");
+ if (defined(system("\'\\"))) puts("bad 2.5");
+ unless (stdio_lasterr eq "unterminated '") puts("bad 2.6");
+ if (defined(system("\""))) puts("bad 2.7");
+ unless (stdio_lasterr eq "unterminated \"") puts("bad 2.8");
+ if (defined(system("\'"))) puts("bad 2.9");
+ unless (stdio_lasterr eq "unterminated '") puts("bad 2.10");
+ if (defined(system(""))) puts("bad 2.11");
+ if (defined(system("bad-executable"))) puts("bad 2.12");
+
+ if (defined(do_popen("\\"))) puts("bad 3.1");
+ unless (stdio_lasterr eq "trailing \\") puts("bad 3.2");
+ if (defined(do_popen("\"\\"))) puts("bad 3.3");
+ unless (stdio_lasterr eq "unterminated \"") puts("bad 3.4");
+ if (defined(do_popen("\'\\"))) puts("bad 3.5");
+ unless (stdio_lasterr eq "unterminated '") puts("bad 3.6");
+ if (defined(do_popen("\""))) puts("bad 3.7");
+ unless (stdio_lasterr eq "unterminated \"") puts("bad 3.8");
+ if (defined(do_popen("\'"))) puts("bad 3.9");
+ unless (stdio_lasterr eq "unterminated '") puts("bad 3.10");
+ if (defined(do_popen(""))) puts("bad 3.11");
+ if (defined(do_popen("bad-executable"))) puts("bad 3.12");
+}
+system1();
+} -output {}
+
+test system-2 {test system type errors} -body {
+#lang L --line=1
+void system2()
+{
+ int iarr[];
+ string arr[], s;
+ STATUS status;
+ FILE f;
+
+ system();
+ system("not", "enough", "args");
+ system("cmd", "in", "out", "err", "status", "toomany");
+
+ /*
+ * Type errors in cmd arg. It must be string or string[].
+ */
+ system(&s);
+ system(&arr);
+ system(iarr);
+
+ /*
+ * Type errors in status arg. It must be STATUS&.
+ */
+ system(s, status);
+ system(s, s);
+
+ /*
+ * Type errors in "in" arg. It must be string[], a string
+ * constant, string variable, or FILE.
+ */
+ system(s, &arr, "out", "err");
+ system(s, iarr, "out", "err");
+ system(s, &f, "out", "err");
+
+ /*
+ * Type errors in "out" arg. It must be string[]&, string&,
+ * string constant, or FILE.
+ */
+ system(s, "in", s, "err");
+ system(s, "in", arr, "err");
+ system(s, "in", &iarr, "err");
+ system(s, "in", &f, "err");
+
+ /*
+ * Type errors in "err" arg. Same as for "out" arg.
+ */
+ system(s, "in", "out", s);
+ system(s, "in", "out", arr);
+ system(s, "in", "out", &iarr);
+ system(s, "in", "out", &f);
+}
+} -returnCodes error -match regexp -result {.*8: L Error: incorrect # args
+.*9: L Error: incorrect # args
+.*10: L Error: incorrect # args
+.*15: L Error: first arg must be string or string array
+.*16: L Error: first arg must be string or string array
+.*17: L Error: first arg must be string or string array
+.*22: L Error: last arg must be of type STATUS \&
+.*23: L Error: last arg must be of type STATUS \&
+.*29: L Error: second arg must be FILE, or string constant/variable/array
+.*30: L Error: second arg must be FILE, or string constant/variable/array
+.*31: L Error: second arg must be FILE, or string constant/variable/array
+.*37: L Error: third arg must be FILE, string constant, or reference to string or string array
+.*38: L Error: third arg must be FILE, string constant, or reference to string or string array
+.*39: L Error: third arg must be FILE, string constant, or reference to string or string array
+.*45: L Error: fourth arg must be FILE, string constant, or reference to string or string array
+.*46: L Error: fourth arg must be FILE, string constant, or reference to string or string array
+.*47: L Error: fourth arg must be FILE, string constant, or reference to string or string array
+}
+
+test system-3 {test system return values} -body {
+#lang L --line=1
+void system3()
+{
+ int ret;
+ string err[], out[];
+ STATUS status;
+ FILE not_open;
+
+ /* Check that a non-zero cmd return status is surfaced as an error. */
+ ret = system("perl -e 'print \"out\";exit(123)'",
+ undef, &out, &err, &status);
+ unless (ret == 123) puts("bad 1.1");
+ unless (status.exit == 123) puts("bad 1.2");
+ if (defined(status.signal)) puts("bad 1.3");
+
+ /* Writing to stderr is NOT an error, unlike with Tcl's exec cmd. */
+
+ stdio_lasterr = undef;
+ ret = system("perl -e 'print STDERR \"err\"; exit(0)'",
+ undef, &out, &err, &status);
+ unless (ret == 0) puts("bad 2.1");
+ unless (status.exit == 0) puts("bad 2.2");
+ if (stdio_lasterr) puts("bad 2.3");
+
+ ret = system("perl -e 'print STDERR \"err\"; exit(123)'",
+ undef, &out, &err, &status);
+ unless (ret == 123) puts("bad 2.4");
+ unless (status.exit == 123) puts("bad 2.5");
+
+ /*
+ * This is a poor test, but to check the name and path members
+ * of the status, check that "perl" is a pathname of some sort.
+ */
+ ret = system("perl -e ''", undef, &out, &err, &status);
+ unless (ret == 0) puts("bad 3.1");
+ unless (status.argv[0] eq "perl") puts("bad 3.2");
+ unless (status.path =~ /.+perl(.exe)?$/i) puts("bad 3.3");
+
+ /* Check that the path comes back undef if executable not found. */
+ ret = system("verybadxyz", undef, &out, &err, &status);
+ if (defined(ret)) puts("bad 4.1");
+ if (defined(status.path)) puts("bad 4.2");
+
+ /* Error parsing shell quoting in argv[] command. */
+ ret = system("'bad quoting");
+ if (defined(ret)) puts("bad 5.1");
+
+ /* Command not found. */
+ ret = system("command-not-found");
+ if (defined(ret)) puts("bad 6.1");
+
+ /* Cannot open input file. */
+ ret = system("date", "bad-input-file", "out", "err");
+ if (defined(ret)) puts("bad 7.1");
+
+ /* Cannot open output file. */
+ ret = system("date", undef, "/bad/unwritable", "err");
+ if (defined(ret)) puts("bad 7.3");
+
+ /* Cannot open error file. */
+ ret = system("date", undef, "out", "/bad/unwritable");
+ if (defined(ret)) puts("bad 8.1");
+
+ /* A passed-in FILE that is undef. */
+ ret = system("date", not_open, undef, undef);
+ if (defined(ret)) puts("bad 9.1");
+ ret = system("date", undef, not_open, undef);
+ if (defined(ret)) puts("bad 9.2");
+ ret = system("date", undef, undef, not_open);
+ if (defined(ret)) puts("bad 9.3");
+
+ /* A passed-in FILE that was open but is now closed. */
+ not_open = open("out", "w");
+ unless (not_open) puts("bad 10.1");
+ fclose(not_open);
+ ret = system("date", not_open, undef, undef);
+ if (defined(ret)) puts("bad 10.2");
+ ret = system("date", undef, not_open, undef);
+ if (defined(ret)) puts("bad 10.3");
+ ret = system("date", undef, undef, not_open);
+ if (defined(ret)) puts("bad 10.4");
+
+ unlink("out");
+ unlink("err");
+}
+system3();
+} -output {}
+
+test system-3.1 {test system return value when process exits from signal} -constraints unix -body {
+#lang L
+void system3_1()
+{
+ int ret;
+ string err, out;
+ STATUS status;
+
+ ret = system("perl -e '$pid=$$; print \"out\n\"; system(\"kill $pid\");'",
+ undef, &out, &err, &status);
+ if (defined(ret)) puts("bad 1: ${ret}");
+ if (out) puts("bad 2: ${out}");
+ if (err) puts("bad 3: ${err}");
+ unless (stdio_status.signal == 15) puts("bad 4: ${stdio_status.signal}");
+ unless (status.signal == 15) puts("bad 5: ${status.signal}");
+ if (defined(stdio_status.exit)) puts("bad 6");
+ if (defined(status.exit)) puts("bad 7");
+}
+system3_1();
+} -output {}
+
+test system-4 {test system and spawn I/O} -body {
+#lang L --line=1
+// Write lines[] to file fname w/open file handle f, then re-open.
+private FILE tstwriteh(FILE f, string fname, string lines[])
+{
+ string s;
+
+ foreach (s in lines) puts(f, s);
+ fclose(f);
+ unless (defined(f = fopen(fname, "r"))) {
+ puts("cannot open ${fname} for read");
+ return (undef);
+ }
+ return (f);
+}
+// Write lines[] to file fname, then close.
+private void tstwritef(string fname, string lines[])
+{
+ string s;
+ FILE f;
+
+ unless (defined(f = fopen(fname, "w"))) return;
+ foreach (s in lines) puts(f, s);
+ fclose(f);
+}
+// Read from open file handle f, verify it has lines[].
+private int tstreadh(FILE f, string lines[])
+{
+ string s;
+
+ while (defined(s = <f>)) {
+ unless (defined(lines[0])) {
+ puts("file too long");
+ return (1);
+ }
+ unless (s eq lines[0]) {
+ puts("expected \"${lines[0]}\" got \"${s}\"");
+ return (1);
+ }
+ undef(lines[0]);
+ }
+ if (defined(lines[0])) {
+ puts("file too short");
+ return (1);
+ }
+ return (0);
+}
+// Read from file name fname, verify it has lines[].
+private int tstreadf(string fname, string lines[])
+{
+ int ret;
+ FILE f;
+
+ unless (defined(f = fopen(fname, "r"))) {
+ puts("cannot open ${fname} for read");
+ return (1);
+ }
+ ret = tstreadh(f, lines);
+ fclose(f);
+ return (ret);
+}
+void system4()
+{
+ int pid, ret;
+ string cmd, strIn, strOut, strErr;
+ string av[], err[], in[], out[];
+ string errNm, inNm, outNm;
+ FILE errf, inf, outf;
+
+ /* Try a cmd that copies stdin to stdout and converts to upper case. */
+ cmd = "perl -e 'print uc $_ while (<>)'";
+ in = { "this is line 1", "and line 2", "line 3" };
+ ret = system(cmd, in, &out, &err);
+ unless (ret == 0) puts("bad 1.1");
+ unless ((tcl)out eq (tcl){"THIS IS LINE 1", "AND LINE 2", "LINE 3"}) {
+ puts("bad 1.2");
+ }
+ if (err) puts("bad 1.3");
+
+ /* Same, with stdin coming from a list. */
+ cmd = "perl -e 'print uc $_ while (<>)'";
+ ret = system(cmd, { "this is line 1", "and line 2", "line 3" },
+ &out, &err);
+ unless (ret == 0) puts("bad 1.4");
+ unless ((tcl)out eq (tcl){"THIS IS LINE 1", "AND LINE 2", "LINE 3"}) {
+ puts("bad 1.5");
+ }
+ if (err) puts("bad 1.6");
+
+ /* Same, with the command in av[]. */
+ av = { "perl", "-e", "print uc $_ while (<>)" };
+ in = { "this is line 1", "and line 2", "line 3" };
+ ret = system(av, in, &out, &err);
+ unless (ret == 0) puts("bad 2.1");
+ unless ((tcl)out eq (tcl){"THIS IS LINE 1", "AND LINE 2", "LINE 3"}) {
+ puts("bad 2.2");
+ }
+ if (err) puts("bad 2.3");
+
+ /* Same, reading and writing to files. */
+ av = { "perl", "-e", "print uc $_ while (<>)" };
+ tstwritef("in", { "this is line 1", "and line 2", "line 3" });
+ ret = system(av, "in", "out", "err");
+ unless (ret == 0) puts("bad 3.1");
+ if (tstreadf("out", {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 3.2");
+ }
+ if (tstreadf("err", {})) {
+ puts("bad 3.3");
+ }
+ unlink("in");
+ unlink("out");
+ unlink("err");
+
+ /* Same, reading and writing to files w/filename in interpolated string. */
+ av = { "perl", "-e", "print uc $_ while (<>)" };
+ tstwritef("in", { "this is line 1", "and line 2", "line 3" });
+ inNm = "in";
+ outNm = "out";
+ errNm = "err";
+ ret = system(av, "${inNm}", "${outNm}", "${errNm}");
+ unless (ret == 0) puts("bad 3.1");
+ if (tstreadf(outNm, {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 3.2");
+ }
+ if (tstreadf("err", {})) {
+ puts("bad 3.3");
+ }
+ unlink(inNm);
+ unlink(outNm);
+ unlink(errNm);
+
+ /* Same, using spawn(). */
+ av = { "perl", "-e", "print uc $_ while (<>)" };
+ tstwritef("in", { "this is line 1", "and line 2", "line 3" });
+ pid = spawn(av, "in", "out", "err");
+ unless (defined(pid)) puts("bad 3.10");
+ unless (waitpid(pid, undef, 0) >= 0) puts("bad 3.11");
+ if (tstreadf("out", {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 3.12");
+ }
+ if (tstreadf("err", {})) {
+ puts("bad 3.13");
+ }
+ unlink("in");
+ unlink("out");
+ unlink("err");
+
+ /* Same, using spawn() w/filename in interpolated string. */
+ av = { "perl", "-e", "print uc $_ while (<>)" };
+ tstwritef("in", { "this is line 1", "and line 2", "line 3" });
+ inNm = "in";
+ outNm = "out";
+ errNm = "err";
+ pid = spawn(av, "${inNm}", "${outNm}", "${errNm}");
+ unless (defined(pid)) puts("bad 3.10");
+ unless (waitpid(pid, undef, 0) >= 0) puts("bad 3.11");
+ if (tstreadf("out", {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 3.12");
+ }
+ if (tstreadf("err", {})) {
+ puts("bad 3.13");
+ }
+ unlink(inNm);
+ unlink(outNm);
+ unlink(errNm);
+
+ /* Same, reading and writing to open file handles. */
+ av = { "perl", "-e", "print uc $_ while (<>)" };
+ inf = File_Tempfile(&inNm);
+ outf = File_Tempfile(&outNm);
+ errf = File_Tempfile(&errNm);
+ inf = tstwriteh(inf, inNm, { "this is line 1", "and line 2", "line 3" });
+ ret = system(av, inf, outf, errf);
+ unless (ret == 0) puts("bad 4.1");
+ // Verify that the handles are still open by writing some more.
+ fprintf(outf, "AND 4\n");
+ fprintf(errf, "only one\n");
+ fclose(inf);
+ fclose(outf);
+ fclose(errf);
+ if (tstreadf(outNm, {"THIS IS LINE 1", "AND LINE 2", "LINE 3", "AND 4"})) {
+ puts("bad 4.2");
+ }
+ if (tstreadf(errNm, {"only one"})) {
+ puts("bad 4.3");
+ }
+ unlink(inNm);
+ unlink(outNm);
+ unlink(errNm);
+
+ /* Same, using spawn(). */
+ av = { "perl", "-e", "print uc $_ while (<>)" };
+ inf = File_Tempfile(&inNm);
+ outf = File_Tempfile(&outNm);
+ errf = File_Tempfile(&errNm);
+ inf = tstwriteh(inf, inNm, { "this is line 1", "and line 2", "line 3" });
+ pid = spawn(av, inf, outf, errf);
+ unless (defined(pid)) puts("bad 4.10");
+ unless (waitpid(pid, undef, 0) >= 0) puts("bad 4.11");
+ fclose(inf);
+ fclose(outf);
+ fclose(errf);
+ if (tstreadf(outNm, {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 4.12");
+ }
+ if (tstreadf(errNm, {})) {
+ puts("bad 4.13");
+ }
+ unlink(inNm);
+ unlink(outNm);
+ unlink(errNm);
+
+ /* Same, with I/O to and from string variables. */
+ av = { "perl", "-e", "print uc $_ while (<>)" };
+ strIn = "this is line 1\nand line 2\nline 3";
+ ret = system(av, strIn, &strOut, &strErr);
+ unless (ret == 0) puts("bad 5.1");
+ unless (strOut eq "THIS IS LINE 1\nAND LINE 2\nLINE 3") puts("bad 5.2");
+ if (strErr) puts("bad 5.3");
+
+ /* Same, using spawn() with input from a string variable. */
+ av = { "perl", "-e", "print uc $_ while (<>)" };
+ strIn = "this is line 1\nand line 2\nline 3";
+ pid = spawn(av, strIn, "out", "err");
+ unless (defined(pid)) puts("bad 5.10");
+ unless (waitpid(pid, undef, 0) >= 0) puts("bad 5.11");
+ fclose(inf);
+ fclose(outf);
+ fclose(errf);
+ if (tstreadf("out", {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 5.12");
+ }
+ if (tstreadf("err", {})) {
+ puts("bad 5.13");
+ }
+ unlink("out");
+ unlink("err");
+
+ /* Try a cmd that copies stdin to stderr and converts to upper case. */
+ cmd = "perl -e 'print STDERR uc $_ while (<>)'";
+ in = { "this is line 1", "and line 2", "line 3" };
+ ret = system(cmd, in, &out, &err);
+ unless (ret == 0) puts("bad 10.1");
+ if (out) puts("bad 10.2");
+ unless ((tcl)err eq (tcl){"THIS IS LINE 1", "AND LINE 2", "LINE 3"}) {
+ puts("bad 10.3");
+ }
+
+ /* Same, with the command in av[]. */
+ av = { "perl", "-e", "print STDERR uc $_ while (<>)" };
+ in = { "this is line 1", "and line 2", "line 3" };
+ ret = system(cmd, in, &out, &err);
+ unless (ret == 0) puts("bad 11.1");
+ if (out) puts("bad 11.2");
+ unless ((tcl)err eq (tcl){"THIS IS LINE 1", "AND LINE 2", "LINE 3"}) {
+ puts("bad 11.3");
+ }
+
+ /* Same, reading and writing to files. */
+ av = { "perl", "-e", "print STDERR uc $_ while (<>)" };
+ tstwritef("in", { "this is line 1", "and line 2", "line 3" });
+ ret = system(av, "in", "out", "err");
+ unless (ret == 0) puts("bad 12.1");
+ if (tstreadf("out", {})) {
+ puts("bad 12.2");
+ }
+ if (tstreadf("err", {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 12.3");
+ }
+ unlink("in");
+ unlink("out");
+ unlink("err");
+
+ /* Same, using spawn(). */
+ av = { "perl", "-e", "print STDERR uc $_ while (<>)" };
+ tstwritef("in", { "this is line 1", "and line 2", "line 3" });
+ pid = spawn(av, "in", "out", "err");
+ unless (defined(pid)) puts("bad 12.10");
+ unless (waitpid(pid, undef, 0) >= 0) puts("bad 12.11");
+ if (tstreadf("out", {})) {
+ puts("bad 12.12");
+ }
+ if (tstreadf("err", {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 12.13");
+ }
+ unlink("in");
+ unlink("out");
+ unlink("err");
+
+ /* Same, reading and writing to open file handles. */
+ av = { "perl", "-e", "print STDERR uc $_ while (<>)" };
+ inf = File_Tempfile(&inNm);
+ outf = File_Tempfile(&outNm);
+ errf = File_Tempfile(&errNm);
+ inf = tstwriteh(inf, inNm, { "this is line 1", "and line 2", "line 3" });
+ ret = system(av, inf, outf, errf);
+ unless (ret == 0) puts("bad 13.1");
+ // Verify that the handles are still open by writing some more.
+ fprintf(outf, "only one\n");
+ fprintf(errf, "AND 4\n");
+ fclose(inf);
+ fclose(outf);
+ fclose(errf);
+ if (tstreadf(outNm, {"only one"})) {
+ puts("bad 13.2");
+ }
+ if (tstreadf(errNm, {"THIS IS LINE 1", "AND LINE 2", "LINE 3", "AND 4"})) {
+ puts("bad 13.3");
+ }
+ unlink(inNm);
+ unlink(outNm);
+ unlink(errNm);
+
+ /* Same, using spawn(). */
+ av = { "perl", "-e", "print STDERR uc $_ while (<>)" };
+ inf = File_Tempfile(&inNm);
+ outf = File_Tempfile(&outNm);
+ errf = File_Tempfile(&errNm);
+ inf = tstwriteh(inf, inNm, { "this is line 1", "and line 2", "line 3" });
+ pid = spawn(av, inf, outf, errf);
+ unless (defined(pid)) puts("bad 13.10");
+ unless (waitpid(pid, undef, 0) >= 0) puts("bad 13.11");
+ fclose(inf);
+ fclose(outf);
+ fclose(errf);
+ if (tstreadf(outNm, {})) {
+ puts("bad 13.12");
+ }
+ if (tstreadf(errNm, {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 13.13");
+ }
+ unlink(inNm);
+ unlink(outNm);
+ unlink(errNm);
+
+ /* Same, with I/O to and from string variables. */
+ av = { "perl", "-e", "print STDERR uc $_ while (<>)" };
+ strIn = "this is line 1\nand line 2\nline 3";
+ ret = system(cmd, strIn, &strOut, &strErr);
+ unless (ret == 0) puts("bad 14.1");
+ if (strOut) puts("bad 14.2");
+ unless (strErr eq "THIS IS LINE 1\nAND LINE 2\nLINE 3") {
+ puts("bad 14.3");
+ }
+
+ /* Same, using spawn() with input from a string variable. */
+ av = { "perl", "-e", "print STDERR uc $_ while (<>)" };
+ strIn = "this is line 1\nand line 2\nline 3";
+ pid = spawn(cmd, strIn, "out", "err");
+ unless (defined(pid)) puts("bad 14.10");
+ unless (waitpid(pid, undef, 0) >= 0) puts("bad 14.11");
+ if (tstreadf("out", {})) {
+ puts("bad 14.12");
+ }
+ if (tstreadf("err", {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 14.13");
+ }
+ unlink("out");
+ unlink("err");
+
+ /* Try a cmd that copies to both stdin and stderr. */
+ cmd = "perl -e 'while (<>) {print lc $_;print STDERR uc $_}'";
+ in = { "this is line 1", "and line 2", "line 3" };
+ ret = system(cmd, in, &out, &err);
+ unless (ret == 0) puts("bad 20.1");
+ unless ((tcl)out eq (tcl){"this is line 1", "and line 2", "line 3"}) {
+ puts("bad 20.2");
+ }
+ unless ((tcl)err eq (tcl){"THIS IS LINE 1", "AND LINE 2", "LINE 3"}) {
+ puts("bad 20.3");
+ }
+
+ /* Same, with the command in av[]. */
+ av = { "perl", "-e", "while (<>) {print lc $_;print STDERR uc $_}" };
+ in = { "this is line 1", "and line 2", "line 3" };
+ ret = system(cmd, in, &out, &err);
+ unless (ret == 0) puts("bad 21.1");
+ unless ((tcl)out eq (tcl){"this is line 1", "and line 2", "line 3"}) {
+ puts("bad 21.2");
+ }
+ unless ((tcl)err eq (tcl){"THIS IS LINE 1", "AND LINE 2", "LINE 3"}) {
+ puts("bad 21.3");
+ }
+
+ /* Same, reading and writing to files. */
+ av = { "perl", "-e", "while (<>) {print lc $_;print STDERR uc $_}" };
+ tstwritef("in", { "this is line 1", "and line 2", "line 3" });
+ ret = system(av, "in", "out", "err");
+ unless (ret == 0) puts("bad 22.1");
+ if (tstreadf("out", {"this is line 1", "and line 2", "line 3"})) {
+ puts("bad 22.2");
+ }
+ if (tstreadf("err", {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 22.3");
+ }
+ unlink("in");
+ unlink("out");
+ unlink("err");
+
+ /* Same, using spawn(). */
+ av = { "perl", "-e", "while (<>) {print lc $_;print STDERR uc $_}" };
+ tstwritef("in", { "this is line 1", "and line 2", "line 3" });
+ pid = spawn(av, "in", "out", "err");
+ unless (defined(pid)) puts("bad 22.10");
+ unless (waitpid(pid, undef, 0) >= 0) puts("bad 22.11");
+ if (tstreadf("out", {"this is line 1", "and line 2", "line 3"})) {
+ puts("bad 22.12");
+ }
+ if (tstreadf("err", {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 22.13");
+ }
+ unlink("in");
+ unlink("out");
+ unlink("err");
+
+ /* Same, reading and writing to open file handles. */
+ av = { "perl", "-e", "while (<>) {print lc $_;print STDERR uc $_}" };
+ inf = File_Tempfile(&inNm);
+ outf = File_Tempfile(&outNm);
+ errf = File_Tempfile(&errNm);
+ inf = tstwriteh(inf, inNm, { "this is line 1", "and line 2", "line 3" });
+ ret = system(av, inf, outf, errf);
+ unless (ret == 0) puts("bad 23.1");
+ // Verify that the handles are still open by writing some more.
+ fprintf(outf, "and 4\n");
+ fprintf(errf, "AND 4\n");
+ fclose(inf);
+ fclose(outf);
+ fclose(errf);
+ if (tstreadf(outNm, {"this is line 1", "and line 2", "line 3", "and 4"})) {
+ puts("bad 23.2");
+ }
+ if (tstreadf(errNm, {"THIS IS LINE 1", "AND LINE 2", "LINE 3", "AND 4"})) {
+ puts("bad 23.3");
+ }
+ unlink(inNm);
+ unlink(outNm);
+ unlink(errNm);
+
+ /* Same, using spawn(). */
+ av = { "perl", "-e", "while (<>) {print lc $_;print STDERR uc $_}" };
+ inf = File_Tempfile(&inNm);
+ outf = File_Tempfile(&outNm);
+ errf = File_Tempfile(&errNm);
+ inf = tstwriteh(inf, inNm, { "this is line 1", "and line 2", "line 3" });
+ pid = spawn(av, inf, outf, errf);
+ unless (defined(pid)) puts("bad 23.10");
+ unless (waitpid(pid, undef, 0) >= 0) puts("bad 23.11");
+ fclose(inf);
+ fclose(outf);
+ fclose(errf);
+ if (tstreadf(outNm, {"this is line 1", "and line 2", "line 3"})) {
+ puts("bad 23.12");
+ }
+ if (tstreadf(errNm, {"THIS IS LINE 1", "AND LINE 2", "LINE 3"})) {
+ puts("bad 23.13");
+ }
+ unlink(inNm);
+ unlink(outNm);
+ unlink(errNm);
+}
+system4();
+} -output {}
+
+test system-5 {test system quoting some more} -body {
+#lang L --line=1
+void system5()
+{
+ string t;
+ string err, out;
+ string perl[] = { 'perl', '-e', 'foreach (@ARGV) {print "<${_}>"}' };
+
+ /*
+ * This checks that the args are literally sent to the cmd,
+ * with no quote or escape processing. It uses a perl script
+ * to echo each element of the argv array bracketed with < and >.
+ *
+ * Format is <arg1> | <arg2> | ... | <argn> | <expected output>
+ * Note that the Tcl parser requires that the *test* itself
+ * have balanced {}, so be careful with the order of braces below.
+ */
+ string tests = <<'END'
+x | <x>
+x | y | <x><y>
+x | y | z | <x><y><z>
+x\ | <x\>
+x\\ | <x\\>
+x\\\ | <x\\\>
+x\y | <x\y>
+'x' | <'x'>
+"x" | <"x">
+{x} | <{x}>
+{x} | {y} | <{x}><{y}>
+{{x}} | {{y}} | <{{x}}><{{y}}>
+{{x}} {{y}} | <{{x}} {{y}}>
+"'}{ { } " ' " | <"'}{ { } " ' ">
+"'}{ | { | } | " | ' ' | <"'}{><{><}><"><' '>
+- | <->
+-- | --x | <--x>
+END
+ foreach (t in split(/\n/, tests)) {
+ string a[] = split(/\s*\|\s*/, t);
+ string cmd[] = { (expand)perl, (expand)a[0..END-1] };
+ unless (system(cmd, undef, &out, &err) == 0) puts("bad 1");
+ unless (out eq a[END]) {
+ puts("for ${a[0..END-1]} got ${out} want ${a[END]}");
+ }
+ if (err) puts("bad 2");
+ }
+}
+system5();
+} -output {}
+
+test system6 {test system and spawn chomping} -body {
+#lang L --line=1
+int s6chk(string fname, string contents)
+{
+ FILE f;
+ string buf;
+
+ unless (defined(f = fopen(fname, "r"))) return (0);
+ if (read(f, &buf, -1) < 0) return (0);
+ fclose(f);
+ return (buf eq contents);
+}
+void system6()
+{
+ int pid;
+ string errNm, errStr, outNm, outStr;
+ string errArr[], outArr[];
+ FILE errHandle, outHandle;
+ string av[] = {'perl', '-e', 'print "xx\n\n";print STDERR "yy\n\n"'};
+ STATUS status;
+
+ /*
+ * For system() and spawn(), a string arg is passed in/out
+ * without chomping or appending a newline. Same for FILE and
+ * "filename". For a string[], when used as the input, each
+ * element is appending with a newline, and when used as the
+ * output (system() only), each element is chomped.
+ */
+
+ system(av, undef, &outStr, &errStr);
+ unless (outStr eq "xx\n\n") puts("bad 1.1");
+ unless (errStr eq "yy\n\n") puts("bad 1.2");
+
+ system(av, undef, &outArr, &errArr);
+ unless (length(outArr) == 2) puts("bad 2.1");
+ unless (length(errArr) == 2) puts("bad 2.2");
+ unless ((outArr[0] eq "xx") && (outArr[1] eq "")) puts("bad 2.3");
+ unless ((errArr[0] eq "yy") && (errArr[1] eq "")) puts("bad 2.4");
+
+ system(av, undef, "s6tst-out", "s6tst-err");
+ unless (s6chk("s6tst-out", "xx\n\n")) puts("bad 3.1");
+ unless (s6chk("s6tst-err", "yy\n\n")) puts("bad 3.2");
+ unlink("s6tst-out");
+ unlink("s6tst-err");
+
+ pid = spawn(av, undef, "s6tst-out", "s6tst-err");
+ unless (defined(pid)) puts("bad 3.5");
+ unless (waitpid(pid, &status, 0) >= 0) puts("bad 3.6");
+ unless (s6chk("s6tst-out", "xx\n\n")) puts("bad 3.7");
+ unless (s6chk("s6tst-err", "yy\n\n")) puts("bad 3.8");
+ unlink("s6tst-out");
+ unlink("s6tst-err");
+
+ outHandle = File_Tempfile(&outNm);
+ errHandle = File_Tempfile(&errNm);
+ system(av, undef, outHandle, errHandle);
+ fclose(outHandle);
+ fclose(errHandle);
+ unless (s6chk(outNm, "xx\n\n")) puts("bad 4.1");
+ unless (s6chk(errNm, "yy\n\n")) puts("bad 4.2");
+ unlink(outNm);
+ unlink(errNm);
+
+ outHandle = File_Tempfile(&outNm);
+ errHandle = File_Tempfile(&errNm);
+ pid = spawn(av, undef, outHandle, errHandle);
+ unless (waitpid(pid, &status, 0) >= 0) puts("bad 5.1");
+ fclose(outHandle);
+ fclose(errHandle);
+ unless (s6chk(outNm, "xx\n\n")) puts("bad 5.2");
+ unless (s6chk(errNm, "yy\n\n")) puts("bad 5.3");
+ unlink(outNm);
+ unlink(errNm);
+}
+system6();
+} -output {}
+
+test system7 {misc system and spawn tests} -body {
+#lang L --line=1
+void system7()
+{
+ int ret;
+ string out;
+ FILE f;
+
+ /* These used to be type errors. */
+
+ out = undef;
+ ret = undef;
+ ret = system({'perl', '-e', 'print "SYSTEM7"'}, undef, &out, undef);
+ unless (defined(ret)) puts("bad 1.1");
+ unless (out eq "SYSTEM7") puts("bad 1.2");
+
+ out = undef;
+ ret = undef;
+ ret = spawn({'perl', '-e', 'print "SYSTEM7"'}, undef, "out7", undef);
+ unless (defined(ret) && (ret > 0)) puts("bad 2.1");
+ waitpid(ret, undef, 0);
+ unless (f = fopen("out7", "r")) puts("bad 2.2");
+ unless (<f> eq "SYSTEM7") puts("bad 2.3");
+ fclose(f);
+ unlink("out7");
+
+ out = undef;
+ ret = undef;
+ ret = system({'perl', '-e', 'print "SYSTEM7"'}, undef, &out, undef,
+ undef);
+ unless (defined(ret)) puts("bad 3.1");
+ unless (out eq "SYSTEM7") puts("bad 3.2");
+
+ out = undef;
+ ret = undef;
+ ret = spawn({'perl', '-e', 'print "SYSTEM7"'}, undef, "out7", undef,
+ undef);
+ unless (defined(ret) && (ret > 0)) puts("bad 4.1");
+ waitpid(ret, undef, 0);
+ unless (f = fopen("out7", "r")) puts("bad 4.2");
+ unless (<f> eq "SYSTEM7") puts("bad 4.3");
+ fclose(f);
+ unlink("out7");
+}
+system7();
+} -output {}
+
+test system-8 {test system output re-direction} -body {
+#lang L --line=1
+string sys8_file(string filename)
+{
+ string ret;
+ FILE f;
+
+ unless (f = fopen(filename, "r")) return ("fopen ${filename}");
+ ret = <f>;
+ fclose(f);
+ return (ret);
+}
+void system8()
+{
+ int ret;
+ string cmd_in = "perl -e 'print $_ while (<>)' <in";
+ string cmd_out = "perl -e 'print \"OUT8\"' >out";
+ string cmd_err = "perl -e 'print STDERR \"ERR8\"' 2>err";
+ string cmd_both = "perl -e 'print \"BOTH8o\"; print STDERR \"BOTH8e\"' >out 2>err";
+ string err, out;
+
+ Fprintf("in", "sys8 in");
+ ret = system(cmd_in, undef, &out, &err);
+ unless (ret == 0) puts("bad 1.1");
+ unless (out eq "sys8 in") puts("bad 1.2");
+ if (err) puts("bad 1.3");
+
+ unlink("out");
+ ret = system(cmd_out);
+ unless (ret == 0) puts("bad 2.1");
+ unless (sys8_file("out") eq "OUT8") puts("bad 2.2");
+
+ unlink("out");
+ ret = system(cmd_out, undef, undef, undef);
+ unless (ret == 0) puts("bad 3.1");
+ unless (sys8_file("out") eq "OUT8") puts("bad 3.2");
+
+ unlink("err");
+ ret = system(cmd_err);
+ unless (ret == 0) puts("bad 4.1");
+ unless (sys8_file("err") eq "ERR8") puts("bad 4.2");
+
+ unlink("err");
+ ret = system(cmd_err, undef, undef, undef);
+ unless (ret == 0) puts("bad 5.1");
+ unless (sys8_file("err") eq "ERR8") puts("bad 5.2");
+
+ unlink("out"); unlink("err");
+ ret = system(cmd_both);
+ unless (ret == 0) puts("bad 6.1");
+ unless (sys8_file("out") eq "BOTH8o") puts("bad 6.2");
+ unless (sys8_file("err") eq "BOTH8e") puts("bad 6.3");
+
+ unlink("out"); unlink("err");
+ ret = system(cmd_both, undef, undef, undef);
+ unless (ret == 0) puts("bad 7.1");
+ unless (sys8_file("out") eq "BOTH8o") puts("bad 7.2");
+ unless (sys8_file("err") eq "BOTH8e") puts("bad 7.3");
+
+ unlink("out"); unlink("err");
+
+ ret = system(cmd_in, "in", "out", undef);
+ if (defined(ret)) puts("bad 10.1");
+ unless (stdio_lasterr eq "cannot both specify and re-direct stdin") {
+ puts("bad 10.2");
+ }
+ if (exists("out")) puts("bad 10.3");
+
+ ret = system(cmd_out, undef, "out", undef);
+ if (defined(ret)) puts("bad 11.1");
+ unless (stdio_lasterr eq "cannot both specify and re-direct stdout") {
+ puts("bad 11.2");
+ }
+ if (exists("out")) puts("bad 11.3");
+
+ ret = system(cmd_err, undef, undef, "err2");
+ if (defined(ret)) puts("bad 12.1");
+ unless (stdio_lasterr eq "cannot both specify and re-direct stderr") {
+ puts("bad 12.2");
+ }
+ if (exists("err2")) puts("bad 12.3");
+ unlink("err2");
+
+ unlink("in");
+}
+system8();
+} -output {}
+
+test system-9 {test that unredirected stderr output causes no error} -setup {
+ makeFile {
+ int main() {
+ int ret;
+
+ stdio_lasterr = undef;
+ ret = system("perl -e 'print STDERR \"err9\";exit(0)'");
+ unless (defined(ret) && (ret == 0)) puts("bad 1");
+ if (stdio_lasterr) puts("bad 3");
+ return (0);
+ }
+ } system-9.l .
+} -body {
+#lang L
+void system9()
+{
+ int ret;
+ string err, out;
+ string tclsh = eval("interpreter");
+
+ ret = system({tclsh, "system-9.l"}, undef, &out, &err);
+ if (ret) puts("bad 1.1 ret=${ret}");
+ if (out) puts("bad 1.2");
+ unless (err == "err9") puts("bad 1.3 err='${err}'");
+}
+system9();
+} -output {}
+
+test system-10 {test indirectly passed undef references for out and err args} -body {
+#lang L
+/*
+ * The omitted _optional call-by-reference reference arg is passed on
+ * to system() which used to crash because it tried to reference it
+ * without checking for undef first.
+ */
+void system10_out(_optional string &s)
+{
+ if (system("perl -e exit 0", undef, &s, undef)) puts("bad 1");
+}
+void system10_err(_optional string &s)
+{
+ if (system("perl -e exit 0", undef, undef, &s)) puts("bad 2");
+}
+void system10()
+{
+ system10_out();
+ system10_err();
+}
+system10();
+} -output {}
+
+test symlink-1 {test symlink} -setup {
+ set fname [makeFile {test} linktest .]
+ file delete -force linktest2
+} -body {
+#lang L --line=1
+void symlink1()
+{
+ /* Error if target does not exist. */
+ unless (symlink("link", "does not exist") == -1) puts("bad 1.1");
+
+ /*
+ * This isn't supported on all platforms, so if it returns
+ * failure, don't check for the symlink.
+ */
+ if (symlink("linktest", "linktest2") == 0) {
+ unless (islink("linktest2")) puts("bad 2.1");
+ unless (exists("linktest2")) puts("bad 2.2");
+ }
+}
+symlink1();
+} -cleanup {
+ file delete -force linktest linktest2
+} -output {}
+
+test backtick-1 {test backtick} -setup {
+ set fname [makeFile "line1\nline2\nline3\n" system_file .]
+} -body {
+#lang L --line=1
+void backtick1()
+{
+ string s;
+
+ /* Note: back-tick trims trailing newline. */
+ s = `cat system_file`;
+ unless (s eq "line1\nline2\nline3") puts("bad 1");
+
+ /* Check error case. */
+ s = `what-the-heck bad-command`;
+ if (defined(s)) puts("bad 2");
+
+ s = `perl -e 'print "%s"'`;
+ unless (s == "%s") puts("bad 3");
+}
+backtick1();
+} -output {}
+
+test backtick-2 {test backtick stderr} -setup {
+ set fname [makeFile {
+ string ret;
+
+ ret = `perl -e 'print "to out"; print STDERR "to err";'`;
+ unless (ret eq "to out") puts("bad stdout ${ret}");
+ unless (stdio_status.argv[0] eq "perl") puts("bad 10");
+ unless (stdio_status.path =~ /.+perl(.exe)?$/i) puts("bad 11");
+ unless (stdio_status.exit == 0) puts("bad 12");
+ if (defined(stdio_status.signal)) puts("bad 13");
+ } backtick2.l]
+} -body {
+#lang L --line=1
+/*
+ * Some contortions here to run tclsh on backtick2.l (above) which
+ * prints to stderr, so we can capture stderr and check it.
+ * Otherwise, tcltest sees anything to stderr as an error and fails
+ * the test.
+ */
+void backtick2()
+{
+ int ret;
+ string cmd = "\"${eval('interpreter')}\" backtick2.l";
+ string err[], out[];
+
+ ret = system(cmd, undef, &out, &err);
+ unless (defined(ret)) puts("bad status ${ret}");
+ unless (length(out) == 0) puts("bad 2 ${out}");
+ unless (err[0] eq "to err") puts("bad 3 ${err}");
+}
+backtick2();
+} -output {}
+
+test backtick-3 {test backtick stderr} -setup {
+ set fname [makeFile {
+ string ret;
+
+ ret = `perl -e 'print "to out"; print STDERR "to err";exit 3'`;
+ unless (ret eq "to out") puts("bad stdout ${ret}");
+ unless (stdio_status.argv[0] eq "perl") puts("bad 10");
+ unless (stdio_status.path =~ /.+perl(.exe)?$/i) puts("bad 11");
+ unless (stdio_status.exit == 3) puts("bad 12");
+ if (defined(stdio_status.signal)) puts("bad 13");
+ } backtick3.l]
+} -body {
+#lang L --line=1
+/*
+ * Same as backtick2() above except with non-zero exit status.
+ */
+void backtick3()
+{
+ int ret;
+ string cmd = "\"${eval('interpreter')}\" backtick3.l";
+ string err[], out[];
+
+ ret = system(cmd, undef, &out, &err);
+ unless (defined(ret)) puts("bad status ${ret}");
+ unless (length(out) == 0) puts("bad 2 ${out}");
+ unless (err[0] eq "to err") puts("bad 3 ${err}");
+}
+backtick3();
+} -output {}
+
+test trim-1 {test trim} -body {
+#lang L --line=1
+void trim1()
+{
+ unless (trim("") eq "") puts("bad 1");
+ unless (trim(" ") eq "") puts("bad 2");
+ unless (trim(" ") eq "") puts("bad 3");
+ unless (trim("abc") eq "abc") puts("bad 4");
+ unless (trim(" abc") eq "abc") puts("bad 5");
+ unless (trim("abc ") eq "abc") puts("bad 6");
+ unless (trim(" abc") eq "abc") puts("bad 7");
+ unless (trim("abc ") eq "abc") puts("bad 8");
+ unless (trim("\tabc") eq "abc") puts("bad 9");
+ unless (trim("abc\t") eq "abc") puts("bad 10");
+ unless (trim("\nabc") eq "abc") puts("bad 11");
+ unless (trim("abc\n") eq "abc") puts("bad 12");
+}
+trim1();
+} -output {}
+
+test unlink-1 {test lunlink and unlink} -setup {
+ set fname1 [makeFile {test} unlinkfile1 .]
+ set fname2 [makeFile {test} {unlink file 2} .]
+ set fname3 [makeFile {test} unlinkfile\{3\} .]
+ if {!$_windows} {set fname4 [makeFile {test} {unlink file \"\' 4} .]}
+ file delete -force "does not exist"
+} -body {
+#lang L --line=1
+void unlink1(string nm)
+{
+ unless (unlink(nm) == 0) puts("bad 1");
+ if (exists(nm)) puts("bad 2");
+}
+#lang tcl
+unlink1 $fname1
+unlink1 $fname2
+unlink1 $fname3
+if {!$_windows} {unlink1 $fname4}
+} -cleanup {
+ file delete -force $fname1 $fname2 $fname3
+ if {!$_windows} {file delete -force $fname4}
+} -output {}
+
+test uc-1 {test uc} -body {
+#lang L --line=1
+void uc1()
+{
+ unless (uc("abcde") eq "ABCDE") puts("bad 1");
+ unless (uc("ABCDE") eq "ABCDE") puts("bad 2");
+ unless (uc("AbCdE") eq "ABCDE") puts("bad 3");
+ unless (uc("") eq "") puts("bad 5");
+}
+uc1();
+} -output {}
+
+test waitpid-1 {test waitpid, nohang} -body {
+#lang L --line=1
+void wpDoit(int exit_status)
+{
+ int i, pid, ret, reaped, secs;
+ string av[];
+ STATUS st;
+
+ secs = 2;
+ av = {"perl", "-e", "sleep ${secs}; exit ${exit_status}"};
+ pid = spawn(av);
+ unless (defined(pid)) puts("bad 1.1");
+
+ /* Poll waitpid every 1/4 second up to secs+1 seconds. */
+ reaped = 0;
+ for (i = 0; !reaped && (i < (secs+1)*4); ++i) {
+ ret = waitpid(pid, &st, 1);
+ switch (ret) {
+ case 0: // process still running
+ break;
+ case -1: // error
+ puts("bad 2.0");
+ break;
+ undef: // should never happen
+ puts("bad 2.1");
+ break;
+ default: // should be pid
+ unless (ret == pid) puts("bad 2.2");
+ unless (defined(st.exit)) puts("bad 2.3");
+ unless (st.exit == exit_status) puts("bad 2.4");
+ if (defined(st.signal)) puts("bad 2.5");
+ ++reaped;
+ break;
+ }
+ sleep(0.25);
+ }
+ unless (reaped) puts("bad 3.1");
+}
+void waitpid1()
+{
+ wpDoit(0);
+ wpDoit(1);
+ wpDoit(100);
+}
+waitpid1();
+} -output {}
+
+test waitpid-2 {test waitpid on exited process} -body {
+#lang L --line=1
+void waitpid2()
+{
+ int pid;
+ FILE f;
+
+ /* Test waitpid on an already exited process. */
+
+ pid = spawn({'perl', '-e', 'print "waitpid2"'},
+ undef, "outp2", undef);
+ unless (pid > 0) puts("bad 1.1");
+ sleep(1);
+ unless (waitpid(pid, undef, 0) == pid) puts("bad 1.2");
+ // check that if you call again, you get -1
+ unless (waitpid(pid, undef, 0) == -1) puts("bad 1.2.1");
+ unless (f = fopen("outp2", "r")) puts("bad 1.3");
+ unless (<f> eq "waitpid2") puts("bad 1.4");
+ fclose(f);
+ unlink("outp2");
+}
+waitpid2();
+} -output {}
+
+test waitpid-3 {test waitpid with multiple procs} -body {
+#lang L --line=1
+/* This test is from Larry. */
+void waitpid3(int n, int parallel)
+{
+ string cmd[];
+ string pids{int};
+ int i, pid, reaped, ret;
+ int bg = 0;
+ int usleep = getpid();
+ STATUS st;
+
+ for (i = 0; i < n; ++i) {
+ while (bg > parallel) {
+ reaped = 0;
+ foreach (pid in keys(pids)) {
+ ret = waitpid(pid, &st, 1);
+ if (ret == 0) continue;
+ if (ret < 0) puts("bad 1.1");
+ unless (ret == pid) puts("bad 1.2");
+ unless (st.exit == 0) puts("bad 1.3");
+ reaped++;
+ bg--;
+ undef(pids{pid});
+ // check that if you call again, you get -1
+ unless (waitpid(pid, undef, 1) == -1) {
+ puts("bad 1.4");
+ }
+ break;
+ }
+ if (reaped) break;
+ sleep(0.1);
+ }
+ cmd = {
+ "bk",
+ "_usleep",
+ (string)usleep,
+ };
+ unless (defined(pid = spawn(cmd))) puts("spawn failed: ${cmd}");
+ pids{pid} = join(" ", cmd);
+ bg++;
+ usleep = pid; // move the amounts around
+ }
+ foreach (pid in keys(pids)) {
+ unless (waitpid(pid, &st, 0) == pid) puts("bad 2.1");
+ unless (waitpid(pid, &st, 0) == -1) puts("bad 2.1.1");
+ unless (st.exit == 0) puts("bad 2.2");
+ }
+}
+waitpid3(10, 5);
+} -output {}
+
+test waitpid-4 {test waitpid with multiple procs, wait on any} -body {
+#lang L
+/* This test is from Larry. */
+void
+waitpid4(void)
+{
+ int i, pid;
+ string cmd, pids{int};
+
+ for (i = 0; i < 5; i++) {
+ cmd = "bk _usleep ${i * 100000}";
+ pid = spawn(cmd);
+ unless (defined(pid)) puts("spawn err ${cmd}");
+ pids{pid} = cmd;
+ }
+ for (i = 0; i < 5; i++) {
+ if (i < 3) {
+ pid = waitpid(-1, undef, 0);
+ } else {
+ pid = wait(undef);
+ }
+ if (pids{pid}) {
+ cmd = join(" ", stdio_status.argv);
+ unless(cmd == pids{pid}) {
+ puts("bad argv: want ${cmd} got ${pids{pid}}");
+ }
+ undef(pids{pid});
+ } else {
+ puts("${i} waitpid error ${pid}");
+ }
+ }
+ unless ((pid = waitpid(-1, undef, 0)) == -1) {
+ puts("waitpid w/ no processes=${pid}");
+ }
+ unless ((pid = wait(undef)) == -1) {
+ puts("wait w/ no processes=${pid}");
+ }
+}
+waitpid4();
+} -output {}
+
+test warn-1 {test warn} -body {
+#lang L --line=1
+void warn1()
+{
+ string s1 = "s1", s2 = "s2";
+
+ warn("warning: %s\n", s1);
+ warn("warning: %s %s\n", s1, s2);
+
+ /* No trailing newline -- warn should append file,line. */
+
+ warn("warning: %s", s1);
+ warn("warning: %s %s", s1, s2);
+}
+warn1();
+} -match regexp -errorOutput {warning: s1
+warning: s1 s2
+warning: s1 at .*.test line 10.
+warning: s1 s2 at .*.test line 11.
+} -output {}
+
+test warn-2 {test warn errors} -body {
+#lang L --line=1
+void warn2()
+{
+ warn("%s");
+}
+warn2();
+} -returnCodes error -match regexp -result {.*3: L Warning: bad format specifier
+}
+
+test write-1 {test write} -body {
+#lang L --line=1
+void write1()
+{
+ int n;
+ string s;
+ widget w;
+ FILE f;
+
+ f = fopen("write1", "w");
+ unless (defined(f)) puts("bad 1.1");
+ s = "x";
+ unless (write(f, s, 1) == 1) puts("bad 1.2");
+ s = "yz";
+ unless (write(f, s, 2) == 2) puts("bad 1.3");
+ s = "0123456789";
+ unless (write(f, s, 10) == 10) puts("bad 1.4");
+ w = "w";
+ unless (write(f, w, 1) == 1) puts("bad 1.5");
+ fclose(f);
+
+ f = fopen("write1", "r");
+ unless (defined(f)) puts("bad 2.1");
+ n = read(f, &s, -1);
+ unless (n == 14) puts("bad 2.2");
+ unless (s eq "xyz0123456789w") puts("bad 2.3");
+ fclose(f);
+}
+write1();
+} -cleanup {
+ removeFile write1
+} -output {}
+
+test write-2 {test write type errors} -body {
+#lang L --line=1
+void write2()
+{
+ FILE f;
+ string s;
+
+ write();
+ write(f);
+ write(f, s);
+ write(f, s, -1, "too many");
+ write(0, s, -1);
+ write(f, 0, -1);
+ write(f, s, s);
+}
+} -returnCodes error -match regexp -result {.*6: L Error: incorrect # args to write\(\)
+.*7: L Error: incorrect # args to write\(\)
+.*8: L Error: incorrect # args to write\(\)
+.*9: L Error: incorrect # args to write\(\)
+.*10: L Error: first arg to write\(\) must have type FILE
+.*11: L Error: second arg to write\(\) must have type string
+.*12: L Error: third arg to write\(\) must have type int
+}
+
+test write-3 {test write run-time errors} -body {
+#lang L --line=1
+void write3()
+{
+ string s;
+ FILE f;
+
+ f = fopen("write3", "w");
+ unless (defined(f)) puts("bad 1");
+ fclose(f);
+ f = fopen("write3", "r");
+ unless (defined(f)) puts("bad 2");
+ unless (write(f, s, 1) == -1) puts("bad 3");
+ unless (stdio_lasterr =~ /wasn\'t opened for writing/) puts("bad 4");
+ fclose(f);
+}
+write3();
+} -cleanup {
+ removeFile write3
+} -output {}
+
+test write-4 {test write with binary data} -body {
+#lang L --line=1
+void write4()
+{
+ /*
+ * Write all the ordinals from 0 to 255 to a file a few times
+ * and read them back.
+ */
+
+ int i, n;
+ int niters = 3;
+ FILE f;
+ string buf;
+
+ unless (f = fopen("write4-out", "w")) puts("bad 1");
+ fconfigure(f, translation: "binary");
+ for (i = 0; i < 256*niters; ++i) {
+ buf = sprintf("%c", i%256);
+ assert(length(buf) == 1);
+ write(f, buf, 1);
+ }
+ fclose(f);
+
+ unless (f = fopen("write4-out", "r")) puts("bad 2");
+ fconfigure(f, translation: "binary");
+ i = 0;
+ while ((n = read(f, &buf, 1)) > 0) {
+ unless (n == 1) puts("bad 3");
+ unless (length(buf) == 1) puts("bad 4");
+ unless (ord(buf[0]) == (i%256)) puts("bad 5 @${i}");
+ ++i;
+ }
+ unless (n == 0) puts("bad 6");
+ unless (i == 256*niters) puts("bad 7 ${i}");
+ unlink("write4-out");
+}
+write4();
+} -output {}
+
+::tcltest::cleanupTests
+return
diff --git a/tests/l-regression.test b/tests/l-regression.test
new file mode 100644
index 0000000..b1ae3de
--- /dev/null
+++ b/tests/l-regression.test
@@ -0,0 +1,381 @@
+# Test to make sure that bugs don't creep back into L
+# Copyright (c) 2007 BitMover, Inc.
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest 2
+ namespace import -force ::tcltest::*
+}
+
+# This causes L to keep running L code even after a compile error.
+set ::env(_L_TEST) 1
+
+# This tells L to run in a backwards compatibility mode for
+# the old eq/ne/le/lt/ge/gt string-comparison operators.
+set ::env(_L_ALLOW_EQ_OPS) 1
+
+test empty-1.0 {empty code blocks} -body {
+#lang L --line=1
+void empty_1_0() {
+}
+#lang tcl
+empty_1_0
+}
+
+test empty-1.1 {empty code blocks with some control flow} -body {
+#lang L --line=1
+void empty_1_1() {
+ /* note that none of these conditions is true,
+ so no code is executed */
+ unless(1) {
+ puts("1 broken");
+ } else if (0) {
+ puts("1.1 broken");
+ } else unless(1) {
+ puts("1 working");
+ }
+}
+#lang tcl
+empty_1_1
+}
+
+test values-1.0 {the values of struct increment and assignment} -body {
+#lang L --line=1
+struct values_1_0 {
+ int clicks;
+ string value;
+};
+
+void values_1_0() {
+ struct values_1_0 main_entry;
+ puts(main_entry.clicks = 0);
+ puts(++main_entry.clicks);
+}
+#lang tcl
+values_1_0
+} -output "0\n1\n"
+
+
+test multi-dimensional-1.0 {move[state][read_symbol] was being evaluated as
+move[state][state[read_symbol]][read_symbol], or thereabouts, because the AST
+was built in an ambiguous way.} -body {
+#lang L --line=1
+string dump_tape(int tape[]);
+void turing(int step, int state, int tape[], int pos) {
+ int write_symbol[5][2], move[5][2], new_state[5][2], read_symbol;
+
+ write_symbol[0][1] = 0; move[0][1] = 1; new_state[0][1] = 1;
+ write_symbol[1][1] = 1; move[1][1] = 1; new_state[1][1] = 1;
+ write_symbol[1][0] = 0; move[1][0] = 1; new_state[1][0] = 2;
+ write_symbol[2][0] = 1; move[2][0] = 0; new_state[2][0] = 3;
+ write_symbol[2][1] = 1; move[2][1] = 1; new_state[2][1] = 2;
+ write_symbol[3][1] = 1; move[3][1] = 0; new_state[3][1] = 3;
+ write_symbol[3][0] = 0; move[3][0] = 0; new_state[3][0] = 4;
+ write_symbol[4][1] = 1; move[4][1] = 0; new_state[4][1] = 4;
+ write_symbol[4][0] = 1; move[4][0] = 1; new_state[4][0] = 0;
+
+ read_symbol = tape[pos];
+ puts(append("", " ", step, "\ts", state + 1, "\t", dump_tape(tape)));
+
+ // state 0 and symbol 0 means to halt
+ if (read_symbol + state) {
+ tape[pos] = write_symbol[state][read_symbol];
+ if (move[state][read_symbol]) {
+ pos++;
+ } else {
+ pos--;
+ }
+ turing(step + 1, new_state[state][read_symbol], tape, pos);
+ } else {
+ puts("-- halt --");
+ }
+}
+
+/* dump the tape to a string */
+string
+dump_tape(int tape[]) {
+ return format("%d %d %d %d %d",
+ tape[0], tape[1], tape[2], tape[3], tape[4]);
+}
+
+void multi_dimensional_1_0() {
+ int tape[5];
+
+ tape[0] = 1; tape[1] = 1; tape[2] = 0; tape[3] = 0; tape[4] = 0;
+ puts("Step\tState\tTape");
+ puts("- - - - - - - - - -");
+ turing(1, 0, tape, 0);
+}
+#lang tcl
+multi_dimensional_1_0
+} -output {Step State Tape
+- - - - - - - - - -
+ 1 s1 1 1 0 0 0
+ 2 s2 0 1 0 0 0
+ 3 s2 0 1 0 0 0
+ 4 s3 0 1 0 0 0
+ 5 s4 0 1 0 1 0
+ 6 s5 0 1 0 1 0
+ 7 s5 0 1 0 1 0
+ 8 s1 1 1 0 1 0
+ 9 s2 1 0 0 1 0
+ 10 s3 1 0 0 1 0
+ 11 s3 1 0 0 1 0
+ 12 s4 1 0 0 1 1
+ 13 s4 1 0 0 1 1
+ 14 s5 1 0 0 1 1
+ 15 s1 1 1 0 1 1
+-- halt --
+}
+
+test initializers-1.0 {initialize a whole array at once} -body {
+#lang L --line=1
+void initializers_1_1() {
+ string foo[] = initializers_1_1_returnarray();
+
+ printf("foo[0] is %s\n", foo[0]);
+ printf("foo[1] is %s\n", foo[1]);
+}
+
+poly initializers_1_1_returnarray() {
+ return "foo bar";
+}
+#lang tcl
+initializers_1_1
+} -output "foo\[0\] is foo\nfoo\[1\] is bar\n"
+
+test cast-1.0 {don't segfault when casting to a string} -body {
+#lang L --line=1
+void cast_1_0() {
+ puts((string)"asdf");
+}
+#lang tcl
+cast_1_0
+} -output "asdf\n"
+
+
+test typecheck-1.0 {typechecker segfaults on unop check that must be queued} -body {
+#lang L --line=1
+int typecheck_1_0_bar() {
+ return 22;
+}
+string typecheck_1_0_foo(string foo) {
+ return foo;
+}
+void typecheck_1_0() {
+ // note the -
+ typecheck_1_0_foo(-typecheck_1_0_bar());
+}
+#lang tcl
+typecheck_1_0
+} -returnCodes {error} -match glob -result \
+ "*:9: L Error: parameter 1 has incompatible type\n"
+
+test decl-1.0 {don't drop array dimensions from typedef when declaring multiple variables} -body {
+#lang L --line=1
+typedef int atype[2];
+void decl_1_0() {
+ atype foo[3], bar;
+ foo[2][1] = 0;
+ bar[1] = 0;
+ puts(foo);
+ puts(bar);
+}
+#lang tcl
+decl_1_0
+} -output "{} {} {{} 0}\n{} 0\n"
+
+test if-1.0 {jump target is wrong when else block gets too big} -body {
+#lang L --line=1 -nowarn
+void if_1_0() {
+ string w = ".asdf";
+ string btm = "${w}.btm", e = "${w}.e";
+ if (0) {
+ puts("wicky wicky2");
+ wm("withdraw", btm);
+ } else {
+ string width, h, h1, x, y;
+ puts("wicky wicky3");
+ width = winfo("width", e);
+ h = winfo("reqheight", w);
+ h1 = winfo("reqheight", btm);
+ x = winfo("rootx", w);
+ y = winfo("rooty", w);
+ /* XXX, wtf? */
+ puts(width);
+ puts(h1);
+ puts(x);
+ }
+}
+
+string winfo(string a, string b) {return "42";}
+#lang tcl
+if_1_0
+} -output {wicky wicky3
+42
+42
+42
+}
+
+test scope-1.0 {if a global is first used as a reference, it gets erroneously created twice} -body {
+#lang L --line=1
+string avar = "foo";
+void frob(string &str) {
+ str = "bar";
+}
+void scope_1_0() {
+ frob(&avar);
+ puts(avar);
+}
+#lang tcl
+scope_1_0
+} -output "bar\n";
+
+test scope-1.1 {a block introduces a new scope} -body {
+#lang L --line=1
+void scope_1_1() {
+ {
+ int a;
+ a = 5;
+ }
+ puts(a);
+}
+#lang tcl
+scope_1_1
+} -returnCodes {error} -match glob -result "*:6: L Error: undeclared variable: a\n"
+
+test regexp-1.0 {regexps might start with a dash, so call regex/regsub with -- before the regexp} -body {
+#lang L --line=1
+void regexp_1_0() {
+ string v = "a-b-c";
+ v =~ s/-/\&ndash;/g;
+ puts(v);
+}
+#lang tcl
+regexp_1_0
+} -output "a&ndash;b&ndash;c\n"
+
+test errors-1.0 {don't run L code if there were compilation errors} -body {
+#lang L --line=1
+void errors_1_0() {
+ int argc;
+ // we want "this is text" to _not_ print
+ puts("this is text");
+ puts(argc[1]);
+}
+errors_1_0();
+#lang tcl
+} -returnCodes {error} -match glob -result "*:5: L Error: not an array*\n" \
+-output {}
+
+test break-1.0 {breaks break when loop jump instructions grow because the loop body is big} -body {
+#lang L --line=1
+void break_1_0() {
+ int i;
+
+ for (i = 0; i<10; i++) {
+ printf("${i}");
+ printf("${i}");
+ printf("${i}");
+ printf("${i}");
+ printf("${i}");
+ break;
+ }
+}
+break_1_0();
+#lang tcl
+} -output {00000}
+
+test typedef-1.0 {L redeclaring types is allowed for same types} -body {
+#lang L --line=1
+typedef string typedef_1_0_FOO;
+typedef string typedef_1_0_FOO;
+#lang tcl
+} -output ""
+
+test typedef-1.1 {L redefining types is not allowed} -body {
+#lang L --line=1
+typedef string typedef_1_1_BAR;
+typedef int typedef_1_1_BAR;
+#lang tcl
+} -returnCodes {error} -match glob -result \
+ "*:2: L Error: Cannot redefine type typedef_1_1_BAR*"
+
+test crash-1.1 {crashing in some interim versions} -body {
+#lang L --line=1
+struct c11xy { int x,y; };
+void
+crash_1_1()
+{
+ struct c11xy xys[2];
+ xys[0].x = 1;
+ printf("%s", xys);
+}
+crash_1_1();
+} -output "1"
+
+
+test pattern-1.2 {L widget pattern functions} -body {
+#lang L --line=1
+void pattern_1_2_foo(...args)
+{
+ puts(args);
+}
+
+void pattern_1_2()
+{
+ widget w = "pattern_1_2_foo";
+ Text_insert(w, "end", "FOO");
+}
+pattern_1_2();
+#lang tcl
+} -output "insert end FOO\n"
+
+test empty-stmt {empty stmt crashed in parser} -body {
+#lang L --line=1
+void empty_stmt()
+{
+ printf("Should be OK now.\n");; // Note the two semicolons.
+}
+#lang tcl
+empty_stmt
+} -output "Should be OK now.\n"
+
+test struct-typedef-1.1 {check struct typedef bug} -body {
+#lang L --line=1
+typedef struct {
+ int x;
+ int y;
+} foo_st_11;
+
+foo_st_11 bars_st_11{string};
+
+void a_st_11(foo_st_11 f)
+{
+ bars_st_11{"FOO"} = f;
+ puts("X = ${f.x}");
+}
+
+void struct_typedef_1_1()
+{
+ foo_st_11 f = {66,63};
+ a_st_11(f);
+ puts(bars_st_11);
+}
+#lang tcl
+struct_typedef_1_1
+} -output "X = 66\nFOO {66 63}\n"
+
+test list-1 {check list creation bug} -body {
+#lang L --line=1
+void list_1()
+{
+ /* This used to trip an assert. */
+ {undeclared_variable};
+}
+list_1();
+} -returnCodes {error} -match regexp -result {.*4: L Error: undeclared variable.*
+}
+
+# cleanup
+::tcltest::cleanupTests
+return
diff --git a/tests/langbench/BEFORE-PERF b/tests/langbench/BEFORE-PERF
new file mode 100644
index 0000000..831ee2a
--- /dev/null
+++ b/tests/langbench/BEFORE-PERF
@@ -0,0 +1,26 @@
+These are the langbench results from the source base as of early Nov-2007.
+
+lang cat grep hash loop proc fib sort wc
+tcl 2.10 4.10 1.51 0.06 1.27 3.76 5.40 0.97
+l 2.10 4.21 1.48 0.08 0.51 3.92 5.76 coredump :(
+
+vs now, late Jan-2008
+
+lang cat grep hash loop proc fib sort wc
+tcl 0.81 0.97 1.13 0.05 0.98 3.45 2.85 1.21
+l 0.82 0.97 1.14 0.05 0.45 3.36 3.11 1.93
+
+Factor better:
+lang cat grep hash loop proc fib sort wc
+tcl 2.6x 4.2x 1.3x wash 1.3x wash 1.9x .8x (whoops)
+l 2.6x 4.2x 1.3x wash wash 1.2x 1.9x NA
+
+And other languages for comparison:
+lang cat grep hash loop proc fib sort wc
+pl 0.36 0.36 0.61 0.07 0.40 3.68 2.15 1.00
+py 0.46 1.50 0.48 0.15 0.23 1.27 2.26 0.49
+rb 0.82 0.73 1.64 0.29 1.13 4.06 4.29 3.09
+
+Amount slower than perl:
+lang cat grep hash loop proc fib sort wc
+tcl/l 2.3x 2.7x 1.9x faster wash faster 1.4x 1.2x
diff --git a/tests/langbench/BEFORE.pcre b/tests/langbench/BEFORE.pcre
new file mode 100644
index 0000000..e62a0d5
--- /dev/null
+++ b/tests/langbench/BEFORE.pcre
@@ -0,0 +1,8 @@
+langbench version 0.6 results:
+lang cat grep hash loop proc fib sort wc
+tcl 0.54 2.61 0.87 0.05 0.91 2.27 2.38 0.80
+tcl 0.53 2.59 0.87 0.05 0.92 2.28 2.36 0.79
+tcl 0.55 2.58 0.87 0.05 0.89 2.32 2.37 0.79
+l 0.56 1.88 0.84 0.04 0.30 2.14 2.64 1.33
+l 0.55 1.87 0.86 0.05 0.30 2.14 2.63 1.30
+l 0.55 1.89 0.85 0.04 0.32 2.15 2.64 1.32
diff --git a/tests/langbench/ChangeLog b/tests/langbench/ChangeLog
new file mode 100644
index 0000000..d8c6cec
--- /dev/null
+++ b/tests/langbench/ChangeLog
@@ -0,0 +1,10 @@
+0.6
+ - Make the grep expr be [^A-Za-z]fopen\(.*\) since that is not
+ trivially optimized.
+ - Add fibonacci benchmark.
+ - Make the procedure calls take more arguments.
+ - add a findtclsh so that if you run this in a tcl source tree
+ under tests/langbench it just works.
+ - Allow setting of each language with RUBY=/build/ruby/ruby
+ (for testing new versions like the ruby with a byte code
+ compiler).
diff --git a/tests/langbench/PERF_LOG b/tests/langbench/PERF_LOG
new file mode 100644
index 0000000..2e8ce52
--- /dev/null
+++ b/tests/langbench/PERF_LOG
@@ -0,0 +1,20 @@
+2.6ghz T61
+
+2008-02-02
+
+lang cat grep hash loop proc fib sort wc
+pl 0.35 0.34 0.62 0.07 0.40 3.65 2.19 1.00
+py 0.45 1.48 0.49 0.15 0.22 1.21 2.15 0.49
+rb 0.82 0.73 1.57 0.28 1.12 3.94 4.28 3.10
+tcl 0.78 0.93 1.11 0.05 0.99 3.54 2.84 1.16
+l 0.79 0.93 1.13 0.05 0.46 3.42 2.98 1.86
+
+2008-04-10
+
+lang cat grep hash loop proc fib sort wc
+pl 0.38 0.36 0.64 0.07 0.42 3.90 2.27 1.04
+py 0.48 1.55 0.51 0.16 0.23 1.26 2.24 0.51
+rb 0.87 0.76 1.63 0.29 1.18 4.17 4.53 3.23
+tcl 0.84 1.05 1.19 0.06 1.06 3.75 2.91 1.23
+l 0.84 1.02 1.22 0.05 0.46 3.66 2.90 1.85
+
diff --git a/tests/langbench/README b/tests/langbench/README
new file mode 100644
index 0000000..f8007ba
--- /dev/null
+++ b/tests/langbench/README
@@ -0,0 +1,56 @@
+langbench is a simplistic set of microbenchmarks designed to see how
+well a scripting language performs at basic operations. The intent is to
+have a set of tests that encourage each language team to optimize their
+language in a way that would benefit the widest possible set of users.
+The version number of this test suite will be 1.0 when there is widespread
+agreement that these are the "right" set of benchmarks, much like lmbench
+was the "right" set of benchmarks for operating systems.
+
+We (BitKeeper Inc) are using it to benchmark our scripting language, you can
+use it for whatever you like.
+
+You may use for langbench any purpose provided that if you use the
+"langbench" name you report all results for all languages like so:
+
+langbench version 0.5 results:
+lang cat grep hash loop proc sort split
+pl 0.85 0.85 1.38 0.24 0.68 4.72 5.13
+py 0.81 2.97 1.03 0.34 0.40 4.37 1.56
+rb 1.81 1.68 4.18 0.53 1.04 8.00 3.66
+tcl 2.02 1.45 2.44 0.13 0.72 7.48 3.93
+l 2.02 1.48 2.43 0.12 0.73 8.11 3.94
+
+langbench version 0.6 results (faster cpu accounts for some diffs):
+lang cat grep hash loop proc fib sort wc
+pl 0.37 0.34 0.62 0.11 0.38 4.35 2.02 1.03
+py 0.38 1.99 0.46 0.18 0.21 1.08 1.83 0.48
+rb 0.84 0.81 1.98 0.31 0.59 2.95 3.33 2.33
+tcl 0.75 2.64 1.09 0.07 0.89 2.65 3.46 0.90
+l 0.71 2.03 1.14 0.07 0.29 2.49 3.88 1.54
+
+with the exception that you may leave off the L language until it is
+widely distributed (defined as apt-get install l just works or is
+included with the tcl package).
+
+Note that for the cat, grep, hash, loop, proc, sort benchmarks the number
+printed is the microseconds for the implied operation, i.e., for cat,
+it is usecs/line, for sort it is the usecs/line to sort and print each
+line, etc.
+
+Test descriptions:
+ cat copy stdin to stdout
+ grep match a regular expression against stdin, print each match
+ hash use each line of stdin as a hash key, value is 1.
+ loop measure the cost of a loop
+ proc measure procedure call cost
+ sort sorts stdin to stdout
+ split [Not used because the semantics are different across langs]
+
+Input data is a million lines of code generated like this:
+
+ for i in 1 2 3 4 5 6 7 8 9 0
+ do cat tcl/generic/*.[ch]
+ done | head -1000000 > DATA
+
+This file and tests are at http://www.bitkeeper.com/lm/langbench.shar
+
diff --git a/tests/langbench/RUN b/tests/langbench/RUN
new file mode 100644
index 0000000..bbb8eaf
--- /dev/null
+++ b/tests/langbench/RUN
@@ -0,0 +1,58 @@
+test X$LANGBENCH = X && {
+ LANGBENCH=.
+ test -d langbench && LANGBENCH=langbench
+}
+test X$TCLSH = X && {
+ test -x gui/bin/tclsh && TCLSH=gui/bin/tclsh
+ test -x ../gui/bin/tclsh && TCLSH=../gui/bin/tclsh
+}
+test X$TCLSH = X && {
+ echo Please set TCLSH
+ exit 1
+}
+test X$PERL = X && PERL=perl
+test X$PYTHON = X && PYTHON=python
+test X$RUBY = X && RUBY=ruby
+test "X$LANGS" = X && LANGS="pl py rb tcl l"
+test "X$TESTS" = X && TESTS="cat grep hash loop proc fib sort wc"
+export TCL_REGEXP_PCRE=1
+echo "langbench version 0.6 results:"
+echo -n "lang "
+for i in $TESTS
+do echo -n "$i "
+done
+echo ""
+for lang in $LANGS
+do
+ case $lang in
+ pl) CMD=$PERL;;
+ py) CMD=$PYTHON;;
+ rb) CMD=$RUBY;;
+ tcl|l) CMD=$TCLSH;;
+ esac
+ N=1
+ test X$RUNS = X || N=$RUNS
+ while (($N > 0))
+ do
+ printf "%-8s" $lang
+ for test in $TESTS
+ do
+ DATA=DATA
+ test $test = wc && DATA=SMALL
+ export LANG_TEST=$test
+ for run in 1 2 3
+ do time $CMD $LANGBENCH/${test}.${lang} $DATA > /dev/null
+ done 2>&1 |
+ perl -e '$min = 1000000;
+ while (<>) {
+ if (/real.*0m(.*)s/) {
+ $min = $1 if $1 < $min;
+ }
+ }
+ printf "%-8.2f", $min;'
+ done
+ printf "\n"
+ N=`expr $N - 1`
+ done
+done
+exit 0
diff --git a/tests/langbench/WEIRD b/tests/langbench/WEIRD
new file mode 100644
index 0000000..b6a2533
--- /dev/null
+++ b/tests/langbench/WEIRD
@@ -0,0 +1,9 @@
+If the regexp is ^$ then the python code gets one more match than the others.
+
+python's split gets the word count wrong:
+
+ wc -w: 3647213
+ perl: 3647213
+ ruby: 3647213
+ tcl: 3647213
+ python: 3647250
diff --git a/tests/langbench/cat.l b/tests/langbench/cat.l
new file mode 100644
index 0000000..ca6ca1c
--- /dev/null
+++ b/tests/langbench/cat.l
@@ -0,0 +1,18 @@
+void
+main(int ac, string av[])
+{
+ string buf;
+ FILE f;
+ int i;
+
+ fconfigure("stdout", buffering:"full", translation:"binary");
+ for (i = 1; i < ac; ++i) {
+ unless (f = open(av[i], "rb")) continue;
+ while (gets(f, &buf) >= 0) {
+ // roughly 40% slower than puts
+ // printf("%s\n", buf);
+ puts(buf);
+ }
+ close(f);
+ }
+}
diff --git a/tests/langbench/cat.pl b/tests/langbench/cat.pl
new file mode 100644
index 0000000..915af0a
--- /dev/null
+++ b/tests/langbench/cat.pl
@@ -0,0 +1,10 @@
+# One could argue this should be
+# while ($foo = <>) { chomp($foo); print $foo . "\n"; }
+# to match what tcl does.
+# That slows it down by a factor of 2.
+foreach $file (@ARGV) {
+ open(FD, $file);
+ while ($buf = <FD>) {
+ print $buf;
+ }
+}
diff --git a/tests/langbench/cat.py b/tests/langbench/cat.py
new file mode 100644
index 0000000..3775fa3
--- /dev/null
+++ b/tests/langbench/cat.py
@@ -0,0 +1,16 @@
+#!/usr/bin/python
+import os
+import sys
+
+def cat(file):
+ f = open(file)
+ for line in f:
+ print line,
+ f.close()
+
+def main():
+ for a in sys.argv:
+ cat(a)
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/langbench/cat.rb b/tests/langbench/cat.rb
new file mode 100644
index 0000000..2eaf834
--- /dev/null
+++ b/tests/langbench/cat.rb
@@ -0,0 +1,3 @@
+while line = gets()
+ print line
+end
diff --git a/tests/langbench/cat.tcl b/tests/langbench/cat.tcl
new file mode 100644
index 0000000..ebf83a5
--- /dev/null
+++ b/tests/langbench/cat.tcl
@@ -0,0 +1,9 @@
+proc cat {file} {
+ set f [open $file rb]
+ while {[gets $f buf] >= 0} { puts $buf }
+ close $f
+}
+fconfigure stdout -buffering full -translation binary
+foreach file $argv {
+ cat $file
+}
diff --git a/tests/langbench/fib.l b/tests/langbench/fib.l
new file mode 100644
index 0000000..dfb1e52
--- /dev/null
+++ b/tests/langbench/fib.l
@@ -0,0 +1,20 @@
+
+int
+fib(int n)
+{
+ if (n < 2) {
+ return (n);
+ } else {
+ return (fib(n - 1) + fib(n - 2));
+ }
+}
+
+void
+main()
+{
+ int i;
+
+ for (i = 0; i <= 30; ++i) {
+ printf("n=%d => %d\n", i, fib(i));
+ }
+}
diff --git a/tests/langbench/fib.pl b/tests/langbench/fib.pl
new file mode 100644
index 0000000..603a989
--- /dev/null
+++ b/tests/langbench/fib.pl
@@ -0,0 +1,11 @@
+sub fib
+{
+ my($n) = @_[0];
+
+ return $n if $n < 2;
+ return &fib($n - 1) + &fib($n - 2);
+}
+
+for ($i = 0; $i <= 30; ++$i) {
+ printf "n=%d => %d\n", $i, &fib($i);
+}
diff --git a/tests/langbench/fib.py b/tests/langbench/fib.py
new file mode 100644
index 0000000..f369a4c
--- /dev/null
+++ b/tests/langbench/fib.py
@@ -0,0 +1,8 @@
+def fib(n):
+ if n < 2:
+ return n
+ else:
+ return fib(n-1) + fib(n-2)
+
+for i in range(30):
+ print "n=%d => %d" % (i, fib(i))
diff --git a/tests/langbench/fib.rb b/tests/langbench/fib.rb
new file mode 100644
index 0000000..225c7bf
--- /dev/null
+++ b/tests/langbench/fib.rb
@@ -0,0 +1,11 @@
+def fib(n)
+ if n < 2
+ n
+ else
+ fib(n-1) + fib(n-2)
+ end
+end
+
+30.times do |i|
+ puts "n=#{i} => #{fib(i)}"
+end
diff --git a/tests/langbench/fib.tcl b/tests/langbench/fib.tcl
new file mode 100644
index 0000000..a107b7d
--- /dev/null
+++ b/tests/langbench/fib.tcl
@@ -0,0 +1,11 @@
+proc fib {n} {
+ # Very bogus we have to do {$n - 1} to get performance.
+ # But if we don't this takes 35 seconds. Tcl has issues.
+ expr {$n < 2 ? 1 : [fib [expr {$n -2}]] + [fib [expr {$n -1}]]}
+}
+
+set i 0
+while {$i <= 30} {
+ puts "n=$i => [fib $i]"
+ incr i
+}
diff --git a/tests/langbench/findtcl b/tests/langbench/findtcl
new file mode 100755
index 0000000..338ab63
--- /dev/null
+++ b/tests/langbench/findtcl
@@ -0,0 +1,26 @@
+#!/bin/sh
+
+test X$TCL = X || {
+ echo $TCL
+ exit 0
+}
+
+# If langbench is in the bk source tree, tcl is at ../gui/tcltk/tcl
+test -d ../gui/tcltk/tcl/generic && {
+ echo ../gui/tcltk/tcl
+ exit 0
+}
+
+# If langbench is in the tcl source tree, it is likely at tests/langbench
+# or tests.
+test -d ../tests -a -d ../generic && {
+ echo ..
+ exit 0
+}
+test -d ../../tests -a -d ../../generic && {
+ echo ../..
+ exit 0
+}
+
+echo "Can't find tcl source tree, set a path to one with TCL" 1>&2
+exit 1
diff --git a/tests/langbench/findtclsh b/tests/langbench/findtclsh
new file mode 100755
index 0000000..e679716
--- /dev/null
+++ b/tests/langbench/findtclsh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+test X$TCLSH = X || {
+ echo $TCLSH
+ exit 0
+}
+
+# If langbench is in the bk source tree, tcl is at ../gui/tcltk/tcl
+test -d ../gui/tcltk/tcl/generic && {
+ if [ -d C:/ ]
+ then echo ../gui/tcltk/tcl/win/tclsh85.exe
+ else echo ../gui/tcltk/tcl/unix/tclsh
+ fi
+ exit 0
+}
+
+# If langbench is in the tcl source tree, it is likely at tests/langbench
+# or tests.
+test -d ../tests -a -d ../generic && {
+ if [ -d C:/ ]
+ then echo ../win/tclsh85.exe
+ else echo ../unix/tclsh
+ fi
+ exit 0
+}
+test -d ../../tests -a -d ../../generic && {
+ if [ -d C:/ ]
+ then echo ../../win/tclsh85.exe
+ else echo ../../unix/tclsh
+ fi
+ exit 0
+}
+
+echo "Can't find tclsh, set a path to one with TCLSH" 1>&2
+exit 1
diff --git a/tests/langbench/grep.l b/tests/langbench/grep.l
new file mode 100644
index 0000000..96c255e
--- /dev/null
+++ b/tests/langbench/grep.l
@@ -0,0 +1,15 @@
+void
+main(int ac, string av[])
+{
+ string buf;
+ int i;
+ FILE f;
+
+ for (i = 1; i < ac; ++i) {
+ f = open(av[i], "rb");
+ while (gets(f, &buf) >= 0) {
+ if (buf =~ /[^A-Za-z]fopen\(.*\)/) puts(buf);
+ }
+ close(f);
+ }
+}
diff --git a/tests/langbench/grep.pl b/tests/langbench/grep.pl
new file mode 100644
index 0000000..9357302
--- /dev/null
+++ b/tests/langbench/grep.pl
@@ -0,0 +1,3 @@
+while (<>) {
+ print if /[^A-Za-z]fopen\(.*\)/;
+}
diff --git a/tests/langbench/grep.py b/tests/langbench/grep.py
new file mode 100644
index 0000000..aa50e96
--- /dev/null
+++ b/tests/langbench/grep.py
@@ -0,0 +1,12 @@
+import os
+import sys
+import re
+
+p = re.compile('[^A-Za-z]fopen\(.*\)')
+for a in sys.argv:
+ f = open(a)
+ for line in f:
+ m = p.search(line)
+ if m:
+ print line,
+ f.close()
diff --git a/tests/langbench/grep.rb b/tests/langbench/grep.rb
new file mode 100644
index 0000000..a13f8fe
--- /dev/null
+++ b/tests/langbench/grep.rb
@@ -0,0 +1,4 @@
+re = Regexp.compile("[^A-Za-z]fopen\\(.*\\)")
+while line = gets()
+ print if re =~ line
+end
diff --git a/tests/langbench/grep.tcl b/tests/langbench/grep.tcl
new file mode 100644
index 0000000..c2ad946
--- /dev/null
+++ b/tests/langbench/grep.tcl
@@ -0,0 +1,12 @@
+proc grep {file} {
+ set f [open $file rb]
+ set buf ""
+ while {[gets $f buf] >= 0} {
+ if {[regexp -- {[^A-Za-z]fopen\(.*\)} $buf]} { puts $buf }
+ }
+ close $f
+}
+fconfigure stdout -translation binary
+foreach file $argv {
+ grep $file
+}
diff --git a/tests/langbench/hash.l b/tests/langbench/hash.l
new file mode 100644
index 0000000..ab10f2e
--- /dev/null
+++ b/tests/langbench/hash.l
@@ -0,0 +1,17 @@
+void
+main(int ac, string av[])
+{
+ int i;
+ string buf;
+ hash h;
+ FILE f;
+
+
+ for (i = 1; i < ac; ++i) {
+ f = open(av[i], "rb");
+ while (gets(f, &buf) >= 0) {
+ h{buf} = 1;
+ }
+ close(f);
+ }
+}
diff --git a/tests/langbench/hash.pl b/tests/langbench/hash.pl
new file mode 100644
index 0000000..46e1b9a
--- /dev/null
+++ b/tests/langbench/hash.pl
@@ -0,0 +1,5 @@
+while (<>) {
+ $hash{$_} = 1;
+}
+open(FD, "/proc/$$/status");
+while (<FD>) { print if /^Vm[RD]/; }
diff --git a/tests/langbench/hash.py b/tests/langbench/hash.py
new file mode 100644
index 0000000..07e8bca
--- /dev/null
+++ b/tests/langbench/hash.py
@@ -0,0 +1,16 @@
+import os
+import sys
+import re
+
+d = {}
+for a in sys.argv:
+ f = open(a)
+ for line in f:
+ d[line] = 1
+ f.close
+p = re.compile("^Vm[RD]")
+f = open("/proc/%d/status" % os.getpid())
+for line in f:
+ m = p.match(line)
+ if m:
+ print line,
diff --git a/tests/langbench/hash.rb b/tests/langbench/hash.rb
new file mode 100644
index 0000000..5b30f3e
--- /dev/null
+++ b/tests/langbench/hash.rb
@@ -0,0 +1,10 @@
+hash = {}
+while line = gets()
+ hash[line] = 1
+end
+
+fd = File.open("/proc/#{$$}/status")
+while $_ = fd.gets
+ print if $_ =~ /^Vm[RD]/
+end
+fd.close
diff --git a/tests/langbench/hash.tcl b/tests/langbench/hash.tcl
new file mode 100644
index 0000000..0b1afa8
--- /dev/null
+++ b/tests/langbench/hash.tcl
@@ -0,0 +1,17 @@
+proc main {} {
+ global argv
+
+ set d [dict create]
+ foreach file $argv {
+ set f [open $file rb]
+ while {[gets $f buf] >= 0} {
+ dict set d $buf 1
+ }
+ close $f
+ }
+}
+main
+set f [open "/proc/[pid]/status"]
+while {[gets $f buf] >= 0} {
+ if {[regexp {^Vm[RD]} $buf]} { puts $buf }
+}
diff --git a/tests/langbench/loop.l b/tests/langbench/loop.l
new file mode 100644
index 0000000..f62ff01
--- /dev/null
+++ b/tests/langbench/loop.l
@@ -0,0 +1,11 @@
+void
+doit(int n)
+{
+ while (n-- > 0);
+}
+
+void
+main()
+{
+ doit(1000000);
+}
diff --git a/tests/langbench/loop.pl b/tests/langbench/loop.pl
new file mode 100644
index 0000000..6f71a23
--- /dev/null
+++ b/tests/langbench/loop.pl
@@ -0,0 +1,2 @@
+$n = 1000000;
+while ($n > 0) { $n--; }
diff --git a/tests/langbench/loop.py b/tests/langbench/loop.py
new file mode 100644
index 0000000..2fb1363
--- /dev/null
+++ b/tests/langbench/loop.py
@@ -0,0 +1,3 @@
+n = 1000000
+while n > 0:
+ n = n - 1
diff --git a/tests/langbench/loop.rb b/tests/langbench/loop.rb
new file mode 100644
index 0000000..f6a3e16
--- /dev/null
+++ b/tests/langbench/loop.rb
@@ -0,0 +1,4 @@
+n = 1000000
+while n > 0
+ n -= 1
+end
diff --git a/tests/langbench/loop.tcl b/tests/langbench/loop.tcl
new file mode 100644
index 0000000..c1de6f7
--- /dev/null
+++ b/tests/langbench/loop.tcl
@@ -0,0 +1,4 @@
+proc doit {n} {
+ while {$n > 0} { incr n -1 }
+}
+doit 1000000
diff --git a/tests/langbench/proc.l b/tests/langbench/proc.l
new file mode 100644
index 0000000..7ac1fe6
--- /dev/null
+++ b/tests/langbench/proc.l
@@ -0,0 +1,20 @@
+int a(int val) { return b(val); }
+int b(int val) { return c(val); }
+int c(int val) { return d(val); }
+int d(int val) { return e(val); }
+int e(int val) { return f(val); }
+int f(int val) { return g(val, 2); }
+int g(int v1, int v2) { return h(v1, v2, 3); }
+int h(int v1, int v2, int v3) { return i(v1, v2, v3, 4); }
+int i(int v1, int v2, int v3, int v4) { return j(v1, v2, v3, v4, 5); }
+int j(int v1, int v2, int v3, int v4, int v5) { return v1 + v2 + v3 + v4 + v5; }
+
+void
+main()
+{
+ int n = 100000; // there are 10 procs, so .1M iterations
+ int x;
+
+ while (n > 0) { x = a(n); n--; }
+ printf("x=%d\n", x);
+}
diff --git a/tests/langbench/proc.pl b/tests/langbench/proc.pl
new file mode 100644
index 0000000..7ae5f2e
--- /dev/null
+++ b/tests/langbench/proc.pl
@@ -0,0 +1,13 @@
+sub a { return &b($_[0]); }
+sub b { return &c($_[0]); }
+sub c { return &d($_[0]); }
+sub d { return &e($_[0]); }
+sub e { return &f($_[0]); }
+sub f { return &g($_[0], 2); }
+sub g { return &h($_[0], $_[1], 3); }
+sub h { return &i($_[0], $_[1], $_[2], 4); }
+sub i { return &j($_[0], $_[1], $_[2], $_[3], 5); }
+sub j { return $_[0] + $_[1] + $_[2] + $_[3] + $_[4]; }
+$n = 100000;
+while ($n > 0) { $x = &a($n); $n--; }
+print "$x\n";
diff --git a/tests/langbench/proc.py b/tests/langbench/proc.py
new file mode 100644
index 0000000..726b9a5
--- /dev/null
+++ b/tests/langbench/proc.py
@@ -0,0 +1,28 @@
+#!/usr/bin/python
+
+def a(val):
+ return b(val)
+def b(val):
+ return c(val)
+def c(val):
+ return d(val)
+def d(val):
+ return e(val)
+def e(val):
+ return f(val)
+def f(val):
+ return g(val, 2)
+def g(v1, v2):
+ return h(v1, v2, 3)
+def h(v1, v2, v3):
+ return i(v1, v2, v3, 4)
+def i(v1, v2, v3, v4):
+ return j(v1, v2, v3, v4, 5)
+def j(v1, v2, v3, v4, v5):
+ return v1 + v2 + v3 + v4 + v5
+
+n = 100000
+while n > 0:
+ x = a(n)
+ n = n - 1
+print "x=%d" % x
diff --git a/tests/langbench/proc.rb b/tests/langbench/proc.rb
new file mode 100644
index 0000000..1c0aae2
--- /dev/null
+++ b/tests/langbench/proc.rb
@@ -0,0 +1,36 @@
+def a(i)
+ return b(i)
+end
+def b(i)
+ return c(i)
+end
+def c(i)
+ return d(i)
+end
+def d(i)
+ return e(i)
+end
+def e(i)
+ return f(i)
+end
+def f(i)
+ return g(i, 2)
+end
+def g(v1, v2)
+ return h(v1, v2, 3)
+end
+def h(v1, v2, v3)
+ return i(v1, v2, v3, 4)
+end
+def i(v1, v2, v3, v4)
+ return j(v1, v2, v3, v4, 5)
+end
+def j(v1, v2, v3, v4, v5)
+ return v1 + v2 + v3 + v4 + v5
+end
+n = 100000;
+while n > 0
+ x = a(n)
+ n -= 1
+end
+print "#{x}\n";
diff --git a/tests/langbench/proc.tcl b/tests/langbench/proc.tcl
new file mode 100644
index 0000000..034190a
--- /dev/null
+++ b/tests/langbench/proc.tcl
@@ -0,0 +1,16 @@
+proc a {val} { return [b $val] }
+proc b {val} { return [c $val] }
+proc c {val} { return [d $val] }
+proc d {val} { return [e $val] }
+proc e {val} { return [f $val] }
+proc f {val} { return [g $val 2] }
+proc g {v1 v2} { return [h $v1 $v2 3] }
+proc h {v1 v2 v3} { return [i $v1 $v2 $v3 4] }
+proc i {v1 v2 v3 v4} { return [j $v1 $v2 $v3 $v4 5] }
+proc j {v1 v2 v3 v4 v5} { return [expr $v1 + $v2 + $v3 + $v4 + $v5] }
+proc main {} {
+ set n 100000
+ while {$n > 0} { set x [a $n]; incr n -1 }
+ puts $x
+}
+main
diff --git a/tests/langbench/sort.l b/tests/langbench/sort.l
new file mode 100644
index 0000000..f36c0e7
--- /dev/null
+++ b/tests/langbench/sort.l
@@ -0,0 +1,19 @@
+void
+main(int ac, string av[])
+{
+ int i;
+ FILE f;
+ string buf;
+ string l[];
+
+ fconfigure("stdout", buffering: "full", translation: "binary");
+ for (i = 1; i < ac; ++i) {
+ f = open(av[i], "rb");
+ while (gets(f, &buf) >= 0) {
+ push(&l, buf);
+ }
+ }
+ foreach (buf in sort(l)) {
+ puts(buf);
+ }
+}
diff --git a/tests/langbench/sort.pl b/tests/langbench/sort.pl
new file mode 100644
index 0000000..be73936
--- /dev/null
+++ b/tests/langbench/sort.pl
@@ -0,0 +1,7 @@
+while (<>) {
+ push(@l, $_);
+}
+
+foreach $_ (sort(@l)) {
+ print;
+}
diff --git a/tests/langbench/sort.py b/tests/langbench/sort.py
new file mode 100644
index 0000000..f36bbc1
--- /dev/null
+++ b/tests/langbench/sort.py
@@ -0,0 +1,13 @@
+import os
+import sys
+import re
+
+l = []
+for a in sys.argv:
+ f = open(a)
+ for line in f:
+ l.append(line)
+ f.close()
+l.sort()
+for line in l:
+ print line,
diff --git a/tests/langbench/sort.rb b/tests/langbench/sort.rb
new file mode 100644
index 0000000..0acbf64
--- /dev/null
+++ b/tests/langbench/sort.rb
@@ -0,0 +1,8 @@
+l = []
+while gets
+ l.push($_)
+end
+
+l.sort.each {|p|
+ print p
+}
diff --git a/tests/langbench/sort.tcl b/tests/langbench/sort.tcl
new file mode 100644
index 0000000..9e353ab
--- /dev/null
+++ b/tests/langbench/sort.tcl
@@ -0,0 +1,20 @@
+proc main {} {
+ global argv
+
+ foreach file $argv {
+ set f [open $file rb]
+
+ # Takes 2.7 seconds/12.3
+ while {[gets $f buf] >= 0} {
+ lappend l $buf
+ }
+ close $f
+ }
+
+ # takes 7.9 seconds/12.3
+ foreach buf [lsort $l] {
+ puts $buf
+ }
+}
+fconfigure stdout -buffering full -translation binary
+main
diff --git a/tests/langbench/wc.l b/tests/langbench/wc.l
new file mode 100644
index 0000000..f24ec07
--- /dev/null
+++ b/tests/langbench/wc.l
@@ -0,0 +1,52 @@
+string []
+wordsplit(string str)
+{
+ string chars[];
+ string list[];
+ string c, word;
+ int i;
+
+ word = "";
+ chars = split(str, "");
+ foreach (c in chars) {
+ if (string("is", "space", c)) {
+ if (length(word) > 0) {
+ push(&list, word);
+ }
+ word = "";
+ } else {
+ append(&word, c);
+ }
+ }
+ if (length(word) > 0) {
+ push(&list, word);
+ }
+ return (list);
+}
+
+int
+doit(string file)
+{
+ FILE f = open(file, "rb");
+ string buf;
+ string words[];
+ int n;
+
+ while (gets(f, &buf) >= 0) {
+ words = wordsplit(buf);
+ n += llength(words);
+ }
+ close(f);
+ return (n);
+}
+
+void
+main(int ac, string av[])
+{
+ int total, i;
+
+ for (i = 1; i < ac; ++i) {
+ total += doit(av[i]);
+ }
+ printf("%d\n", total);
+}
diff --git a/tests/langbench/wc.pl b/tests/langbench/wc.pl
new file mode 100644
index 0000000..0853908
--- /dev/null
+++ b/tests/langbench/wc.pl
@@ -0,0 +1,23 @@
+sub wordsplit
+{
+ chomp($_[0]);
+ @list = ();
+ $word = "";
+ foreach $c (split(//, $_[0])) {
+ if ($c =~ /\s/o) {
+ push(@list, $word) if $word ne "";
+ $word = "";
+ } else {
+ $word .= $c;
+ }
+ }
+ push(@list, $word) if $word ne "";
+ return @list;
+}
+
+$n = 0;
+while (<>) {
+ @words = &wordsplit($_);
+ $n += $#words + 1;
+}
+printf "%d\n", $n;
diff --git a/tests/langbench/wc.py b/tests/langbench/wc.py
new file mode 100644
index 0000000..d2a8b50
--- /dev/null
+++ b/tests/langbench/wc.py
@@ -0,0 +1,30 @@
+#!/usr/bin/python
+import os
+import sys
+
+def wordsplit(line):
+ list = []
+ word = ""
+ for c in line:
+ if c.isspace():
+ if len(word) > 0:
+ list.append(word)
+ word = ""
+ else:
+ word += c
+ if len(word) > 0:
+ list.append(word)
+ return list
+
+def main():
+ n = 0
+ for a in sys.argv[1:]:
+ f = open(a)
+ for line in f:
+ words = wordsplit(line)
+ n += len(words)
+ f.close()
+ print "%d\n" % n
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/langbench/wc.rb b/tests/langbench/wc.rb
new file mode 100644
index 0000000..ef19635
--- /dev/null
+++ b/tests/langbench/wc.rb
@@ -0,0 +1,25 @@
+def wordsplit(line)
+ list = []
+ word = ""
+ line.split('').each do |c|
+ if c =~ /\s/
+ if word.length > 0
+ list << word
+ end
+ word = ""
+ else
+ word += c
+ end
+ end
+ if word.length > 0
+ list << word
+ end
+ return list
+end
+
+n = 0
+while line = gets()
+ words = wordsplit(line)
+ n += words.length
+end
+printf("%d\n", n)
diff --git a/tests/langbench/wc.tcl b/tests/langbench/wc.tcl
new file mode 100644
index 0000000..5dc17aa
--- /dev/null
+++ b/tests/langbench/wc.tcl
@@ -0,0 +1,36 @@
+proc wordsplit {str} {
+ set list {}
+ set word {}
+ foreach char [split $str {}] {
+ if {[string is space $char]} {
+ if {[string length $word] > 0} {
+ lappend list $word
+ }
+ set word {}
+ } else {
+ append word $char
+ }
+ }
+ if {[string length $word] > 0} {
+ lappend list $word
+ }
+ return $list
+}
+
+proc doit {file} {
+ set f [open $file r]
+ fconfigure $f -translation binary
+ set buf ""
+ set n 0
+ while {[gets $f buf] >= 0} {
+ set words [wordsplit $buf]
+ incr n [llength $words]
+ }
+ close $f
+ return $n
+}
+set total 0
+foreach file $argv {
+ incr total [doit $file]
+}
+puts $total
diff --git a/tests/reg.test b/tests/reg.test
index d040632..2f7e923 100644
--- a/tests/reg.test
+++ b/tests/reg.test
@@ -21,6 +21,7 @@ catch [list package require -exact Tcltest [info patchlevel]]
::tcltest::testConstraint testregexp [llength [info commands testregexp]]
::tcltest::testConstraint localeRegexp 0
+::tcltest::testConstraint classicre [string equal [interp regexp {}] classic]
# This file uses some custom procedures, defined below, for regexp regression
# testing. The name of the procedure indicates the general nature of the
@@ -180,7 +181,7 @@ namespace eval RETest {
# Share the generation of the list of test constraints so it is
# done the same on all routes.
proc TestConstraints {flags} {
- set constraints [list testregexp]
+ set constraints [list testregexp classicre]
variable regBug
if {$regBug} {
diff --git a/tests/regexp.test b/tests/regexp.test
index 9fff262..ac6f8a3 100644
--- a/tests/regexp.test
+++ b/tests/regexp.test
@@ -15,7 +15,7 @@ if {"::tcltest" ni [namespace children]} {
package require tcltest 2
namespace import -force ::tcltest::*
}
-
+interp regexp {} pcre
unset -nocomplain foo
testConstraint exec [llength [info commands exec]]
@@ -247,13 +247,13 @@ test regexp-6.2 {regexp errors} {
} {1 {wrong # args: should be "regexp ?-option ...? exp string ?matchVar? ?subMatchVar ...?"}}
test regexp-6.3 {regexp errors} {
list [catch {regexp -gorp a} msg] $msg
-} {1 {bad option "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}}
-test regexp-6.4 {regexp errors} {
- list [catch {regexp a( b} msg] $msg
-} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
-test regexp-6.5 {regexp errors} {
+} {1 {bad option "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, -type, or --}}
+test regexp-6.4 {regexp errors} -body {
list [catch {regexp a( b} msg] $msg
-} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+} -match glob -result {1 {couldn't compile*}}
+test regexp-6.5 {regexp errors} -body {
+ list [catch {regexp a) b} msg] $msg
+} -match glob -result {1 {couldn't compile*}}
test regexp-6.6 {regexp errors} {
list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
} {0 1}
@@ -453,10 +453,10 @@ test regexp-11.4 {regsub errors} {
} {1 {wrong # args: should be "regsub ?-option ...? exp string subSpec ?varName?"}}
test regexp-11.5 {regsub errors} {
list [catch {regsub -gorp a b c} msg] $msg
-} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}}
-test regexp-11.6 {regsub errors} {
+} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, -type, or --}}
+test regexp-11.6 {regsub errors} -body {
list [catch {regsub -nocase a( b c d} msg] $msg
-} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+} -match glob -result {1 {couldn't compile*}}
test regexp-11.7 {regsub errors} -setup {
unset -nocomplain f1
} -body {
diff --git a/tests/regexpComp.test b/tests/regexpComp.test
index 01ef06d..088b73f 100644
--- a/tests/regexpComp.test
+++ b/tests/regexpComp.test
@@ -326,17 +326,17 @@ test regexpComp-6.3 {regexp errors} {
evalInProc {
list [catch {regexp -gorp a} msg] $msg
}
-} {1 {bad option "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, or --}}
-test regexpComp-6.4 {regexp errors} {
+} {1 {bad option "-gorp": must be -all, -about, -indices, -inline, -expanded, -line, -linestop, -lineanchor, -nocase, -start, -type, or --}}
+test regexpComp-6.4 {regexp errors} -body {
evalInProc {
list [catch {regexp a( b} msg] $msg
}
-} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
-test regexpComp-6.5 {regexp errors} {
+} -match glob -result {1 {couldn't compile*}}
+test regexpComp-6.5 {regexp errors} -body {
evalInProc {
- list [catch {regexp a( b} msg] $msg
+ list [catch {regexp a) b} msg] $msg
}
-} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+} -match glob -result {1 {couldn't compile*}}
test regexpComp-6.6 {regexp errors} {
evalInProc {
list [catch {regexp a a f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1 f1} msg] $msg
@@ -587,12 +587,12 @@ test regexpComp-11.5 {regsub errors} {
evalInProc {
list [catch {regsub -gorp a b c} msg] $msg
}
-} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, or --}}
-test regexpComp-11.6 {regsub errors} {
+} {1 {bad option "-gorp": must be -all, -nocase, -expanded, -line, -linestop, -lineanchor, -start, -type, or --}}
+test regexpComp-11.6 {regsub errors} -body {
evalInProc {
list [catch {regsub -nocase a( b c d} msg] $msg
}
-} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+} -match glob -result {1 {couldn't compile*}}
test regexpComp-11.7 {regsub errors} {
evalInProc {
unset -nocomplain f1
@@ -965,12 +965,12 @@ test regexpComp-24.8 {regexp command compiling tests} {
regexp -- $re dogfod
}
} 0
-test regexpComp-24.9 {regexp command compiling tests} {
+test regexpComp-24.9 {regexp command compiling tests} -body {
evalInProc {
set re "("
list [catch {regexp -- $re dogfod} msg] $msg
}
-} {1 {couldn't compile regular expression pattern: parentheses () not balanced}}
+} -match glob -result {1 {couldn't compile*}}
test regexpComp-24.10 {regexp command compiling tests} {
# Bug 1902436 - last * escaped
evalInProc {
diff --git a/tools/installData.tcl b/tools/installData.tcl
index 4b43f1e..25613b7 100644
--- a/tools/installData.tcl
+++ b/tools/installData.tcl
@@ -27,7 +27,8 @@ proc copyDir {d1 d2} {
foreach ftail [glob -directory $d1 -nocomplain -tails *] {
set f [file join $d1 $ftail]
- if {[file isdirectory $f] && [string compare CVS $ftail]} {
+ if {[file isdirectory $f] && [string compare CVS $ftail] &&
+ [string compare SCCS $ftail]} {
copyDir $f [file join $d2 $ftail]
} elseif {[file isfile $f]} {
file copy -force $f [file join $d2 $ftail]
diff --git a/unix/Makefile.in b/unix/Makefile.in
index c90fd16..6b7d8ca 100644
--- a/unix/Makefile.in
+++ b/unix/Makefile.in
@@ -241,7 +241,7 @@ TCL_BUILDTIME_LIBRARY = @TCL_SRC_DIR@/library
ZLIB_DIR = ${COMPAT_DIR}/zlib
ZLIB_INCLUDE = @ZLIB_INCLUDE@
-CC = @CC@
+CC = $(if $(Q), @echo CC $(notdir $<) ; @CC@, @CC@)
#CC = purify -best-effort @CC@ -DPURIFY
# Flags to be passed to installManPage to control how the manpages should be
@@ -271,13 +271,14 @@ VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high --leak-ch
STUB_CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${SHLIB_CFLAGS} \
-I"${BUILD_DIR}" -I${UNIX_DIR} -I${GENERIC_DIR} -I${TOMMATH_DIR} \
-${AC_FLAGS} ${PROTO_FLAGS} ${ENV_FLAGS} ${EXTRA_CFLAGS} @EXTRA_CC_SWITCHES@
-
+${AC_FLAGS} ${PROTO_FLAGS} ${ENV_FLAGS} @PCRE_INCLUDE@ \
+${EXTRA_CFLAGS} @EXTRA_CC_SWITCHES@
CC_SWITCHES = $(STUB_CC_SWITCHES) ${NO_DEPRECATED_FLAGS}
APP_CC_SWITCHES = $(CC_SWITCHES) @EXTRA_APP_CC_SWITCHES@
-LIBS = @TCL_LIBS@
+LIBS = @PCRE_LIBS@ @TCL_LIBS@
+
DEPEND_SWITCHES = ${CFLAGS} -I${UNIX_DIR} -I${GENERIC_DIR} \
${AC_FLAGS} ${PROTO_FLAGS} ${EXTRA_CFLAGS} @EXTRA_CC_SWITCHES@
@@ -313,6 +314,9 @@ GENERIC_OBJS = regcomp.o regexec.o regfree.o regerror.o tclAlloc.o \
OO_OBJS = tclOO.o tclOOBasic.o tclOOCall.o tclOODefineCmds.o tclOOInfo.o \
tclOOMethod.o tclOOStubInit.o
+L_OBJS = Lscanner-pregen.o Lgrammar-pregen.o Lcompile.o Last.o \
+ Ltypecheck.o Lgetopt.o
+
TOMMATH_OBJS = bncore.o bn_reverse.o bn_fast_s_mp_mul_digs.o \
bn_fast_s_mp_sqr.o bn_mp_add.o bn_mp_and.o \
bn_mp_add_d.o bn_mp_clamp.o bn_mp_clear.o bn_mp_clear_multi.o \
@@ -359,7 +363,7 @@ ZLIB_OBJS = Zadler32.o Zcompress.o Zcrc32.o Zdeflate.o Zinfback.o \
TCL_OBJS = ${GENERIC_OBJS} ${UNIX_OBJS} ${NOTIFY_OBJS} ${COMPAT_OBJS} \
${OO_OBJS} @DL_OBJS@ @PLAT_OBJS@
-OBJS = ${TCL_OBJS} ${TOMMATH_OBJS} @DTRACE_OBJ@ @ZLIB_OBJS@
+OBJS = ${TCL_OBJS} ${TOMMATH_OBJS} @DTRACE_OBJ@ @ZLIB_OBJS@ ${L_OBJS}
TCL_DECLS = \
$(GENERIC_DIR)/tcl.decls \
@@ -474,6 +478,19 @@ OO_SRCS = \
$(GENERIC_DIR)/tclOOMethod.c \
$(GENERIC_DIR)/tclOOStubInit.c
+L_HDRS = \
+ $(GENERIC_DIR)/Lcompile.h \
+ $(GENERIC_DIR)/Lgrammar.h \
+ $(GENERIC_DIR)/Last.h
+
+L_SRCS = \
+ $(GENERIC_DIR)/Lscanner.l \
+ $(GENERIC_DIR)/Lgrammar.y \
+ $(GENERIC_DIR)/Lcompile.c \
+ $(GENERIC_DIR)/Ltypecheck.c \
+ $(GENERIC_DIR)/Last.c \
+ $(GENERIC_DIR)/Lgetopt.c
+
STUB_SRCS = \
$(GENERIC_DIR)/tclStubLib.c \
$(GENERIC_DIR)/tclTomMathStubLib.c \
@@ -606,7 +623,7 @@ ZLIB_SRCS = \
# things like "make depend".
SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \
- $(OO_SRCS) $(STUB_SRCS) @PLAT_SRCS@ @ZLIB_SRCS@
+ $(OO_SRCS) $(STUB_SRCS) @PLAT_SRCS@ @ZLIB_SRCS@ ${L_SRCS}
#--------------------------------------------------------------------------
# Start of rules
@@ -614,7 +631,7 @@ SRCS = $(GENERIC_SRCS) $(TOMMATH_SRCS) $(UNIX_SRCS) $(NOTIFY_SRCS) \
all: binaries libraries doc packages
-binaries: ${LIB_FILE} ${TCL_EXE}
+binaries: ${LIB_FILE} ${TCL_EXE} ${TCLTEST_EXE}
libraries:
@@ -711,6 +728,9 @@ tcltest-real:
test: test-tcl test-packages
+l-test l-tests test-l test-L:
+ TCLTEST_SHELL_OPTIONS='-encoding utf-8' $(MAKE) test TESTFLAGS+="-file l-*.test"
+
test-tcl: ${TCLTEST_EXE}
$(SHELL_ENV) ./${TCLTEST_EXE} $(TOP_DIR)/tests/all.tcl $(TESTFLAGS)
@@ -796,8 +816,8 @@ install-binaries: binaries
@echo "Installing $(LIB_FILE) to $(DLL_INSTALL_DIR)/"
@@INSTALL_LIB@
@chmod 555 "$(DLL_INSTALL_DIR)/$(LIB_FILE)"
- @echo "Installing ${TCL_EXE} as $(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}"
- @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)/tclsh$(VERSION)${EXE_SUFFIX}"
+ @echo "Installing ${TCL_EXE} as $(BIN_INSTALL_DIR)/tclsh${EXE_SUFFIX}"
+ @$(INSTALL_PROGRAM) ${TCL_EXE} "$(BIN_INSTALL_DIR)/tclsh${EXE_SUFFIX}"
@echo "Installing tclConfig.sh to $(CONFIG_INSTALL_DIR)/"
@$(INSTALL_DATA) tclConfig.sh "$(CONFIG_INSTALL_DIR)/tclConfig.sh"
@echo "Installing tclooConfig.sh to $(CONFIG_INSTALL_DIR)/"
@@ -1120,7 +1140,7 @@ tclEnv.o: $(GENERIC_DIR)/tclEnv.c
tclEvent.o: $(GENERIC_DIR)/tclEvent.c
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclEvent.c
-tclExecute.o: $(GENERIC_DIR)/tclExecute.c $(COMPILEHDR) $(MATHHDRS) $(NREHDR)
+tclExecute.o: $(GENERIC_DIR)/tclExecute.c $(COMPILEHDR) $(MATHHDRS) $(NREHDR) $(L_HDRS)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclExecute.c
tclFCmd.o: $(GENERIC_DIR)/tclFCmd.c
@@ -1351,6 +1371,33 @@ tclThreadTest.o: $(GENERIC_DIR)/tclThreadTest.c
tclTomMathInterface.o: $(GENERIC_DIR)/tclTomMathInterface.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/tclTomMathInterface.c
+
+Lscanner.c: $(GENERIC_DIR)/Lscanner.l $(L_HDRS) $(GENERIC_DIR)/Lgrammar.c
+ flex -PL_ -o$@ $(GENERIC_DIR)/Lscanner.l
+
+Lscanner-pregen.o: $(L_HDRS) $(GENERIC_DIR)/Lscanner-pregen.c
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/Lscanner-pregen.c
+
+Lgrammar.c: $(GENERIC_DIR)/Lgrammar.y $(L_HDRS)
+ @BISON@ -pL_ -d -o$@ $(GENERIC_DIR)/Lgrammar.y
+
+Lgrammar-pregen.o: $(GENERIC_DIR)/Lgrammar-pregen.c Lcompile.o $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) -fno-strict-aliasing $(GENERIC_DIR)/Lgrammar-pregen.c || \
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/Lgrammar-pregen.c
+
+Lcompile.o: $(GENERIC_DIR)/Lcompile.c $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/Lcompile.c
+
+Ltypecheck.o: $(GENERIC_DIR)/Ltypecheck.c $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/Ltypecheck.c
+
+Lgetopt.o: $(GENERIC_DIR)/Lgetopt.c $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/Lgetopt.c
+
+Last.o: $(GENERIC_DIR)/Last.c $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) $(GENERIC_DIR)/Last.c
+
+
bncore.o: $(TOMMATH_DIR)/bncore.c $(MATHHDRS)
$(CC) -c $(CC_SWITCHES) $(TOMMATH_DIR)/bncore.c
@@ -2113,5 +2160,4 @@ BUILD_HTML = \
.PHONY: packages configure-packages test-packages clean-packages
.PHONY: dist-packages distclean-packages install-packages
-#--------------------------------------------------------------------------
# DO NOT DELETE THIS LINE -- make depend depends on it.
diff --git a/unix/configure b/unix/configure
index 27e147b..03fdbda 100755
--- a/unix/configure
+++ b/unix/configure
@@ -1,81 +1,459 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for tcl 8.6.
+# Generated by GNU Autoconf 2.69 for tcl 8.6.
+#
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
#
-# Copyright (C) 2003 Free Software Foundation, Inc.
# This configure script is free software; the Free Software Foundation
# gives unlimited permission to copy, distribute and modify it.
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
- set -o posix
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
fi
-DUALCASE=1; export DUALCASE # for MKS sh
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
fi
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
PS1='$ '
PS2='> '
PS4='+ '
# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+# Use a proper internal environment variable to ensure we don't fall
+ # into an infinite loop, continuously re-executing ourselves.
+ if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+ _as_can_reexec=no; export _as_can_reexec;
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+ fi
+ # We don't want this to propagate to other subprocesses.
+ { _as_can_reexec=; unset _as_can_reexec;}
+if test "x$CONFIG_SHELL" = x; then
+ as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then :
+ emulate sh
+ NULLCMD=:
+ # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which
+ # is contrary to our usage. Disable this feature.
+ alias -g '\${1+\"\$@\"}'='\"\$@\"'
+ setopt NO_GLOB_SUBST
+else
+ case \`(set -o) 2>/dev/null\` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
+fi
+"
+ as_required="as_fn_return () { (exit \$1); }
+as_fn_success () { as_fn_return 0; }
+as_fn_failure () { as_fn_return 1; }
+as_fn_ret_success () { return 0; }
+as_fn_ret_failure () { return 1; }
+
+exitcode=0
+as_fn_success || { exitcode=1; echo as_fn_success failed.; }
+as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; }
+as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; }
+as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; }
+if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then :
+
+else
+ exitcode=1; echo positional parameters were not saved.
+fi
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
+ as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
+ as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO
+ eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" &&
+ test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1
+test \$(( 1 + 1 )) = 2 || exit 1"
+ if (eval "$as_required") 2>/dev/null; then :
+ as_have_required=yes
+else
+ as_have_required=no
+fi
+ if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then :
+
+else
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+as_found=false
+for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ as_found=:
+ case $as_dir in #(
+ /*)
+ for as_base in sh bash ksh sh5; do
+ # Try only shells that exist, to save several forks.
+ as_shell=$as_dir/$as_base
+ if { test -f "$as_shell" || test -f "$as_shell.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ CONFIG_SHELL=$as_shell as_have_required=yes
+ if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then :
+ break 2
+fi
+fi
+ done;;
+ esac
+ as_found=false
+done
+$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } &&
+ { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then :
+ CONFIG_SHELL=$SHELL as_have_required=yes
+fi; }
+IFS=$as_save_IFS
+
+
+ if test "x$CONFIG_SHELL" != x; then :
+ export CONFIG_SHELL
+ # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+ *v*x* | *x*v* ) as_opts=-vx ;;
+ *v* ) as_opts=-v ;;
+ *x* ) as_opts=-x ;;
+ * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
+fi
+
+ if test x$as_have_required = xno; then :
+ $as_echo "$0: This script requires a shell more modern than all"
+ $as_echo "$0: the shells that I found on your system."
+ if test x${ZSH_VERSION+set} = xset ; then
+ $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should"
+ $as_echo "$0: be upgraded to zsh 4.3.4 or later."
else
- $as_unset $as_var
+ $as_echo "$0: Please tell bug-autoconf@gnu.org about your system,
+$0: including any error possibly output before this
+$0: message. Then install a modern shell, or manually run
+$0: the script under such a shell if you do have one."
fi
-done
+ exit 1
+fi
+fi
+fi
+SHELL=${CONFIG_SHELL-/bin/sh}
+export SHELL
+# Unset more variables known to interfere with behavior of common tools.
+CLICOLOR_FORCE= GREP_OPTIONS=
+unset CLICOLOR_FORCE GREP_OPTIONS
+
+## --------------------- ##
+## M4sh Shell Functions. ##
+## --------------------- ##
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
+ fi
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
as_expr=expr
else
as_expr=false
fi
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
-# Name of the executable.
-as_me=`$as_basename "$0" ||
+as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)$' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
- /^X\/\(\/\/\)$/{ s//\1/; q; }
- /^X\/\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
-
-# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
@@ -83,146 +461,91 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" || {
- # Find who we are. Look in the path if we contain no path at all
- # relative or not.
- case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
- ;;
- esac
- # We did not find ourselves, most probably we were run as `sh COMMAND'
- # in which case we are not to be found in the path.
- if test "x$as_myself" = x; then
- as_myself=$0
- fi
- if test ! -f "$as_myself"; then
- { echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2
- { (exit 1); exit 1; }; }
- fi
- case $CONFIG_SHELL in
- '')
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for as_base in sh bash ksh sh5; do
- case $as_dir in
- /*)
- if ("$as_dir/$as_base" -c '
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
- $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
- $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
- CONFIG_SHELL=$as_dir/$as_base
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$0" ${1+"$@"}
- fi;;
- esac
- done
-done
-;;
- esac
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line before each line; the second 'sed' does the real
- # work. The second script uses 'N' to pair each line-number line
- # with the numbered line, and appends trailing '-' during
- # substitution so that $LINENO is not a special case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
- sed '=' <$as_myself |
+ as_lineno_1=$LINENO as_lineno_1a=$LINENO
+ as_lineno_2=$LINENO as_lineno_2a=$LINENO
+ eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" &&
+ test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || {
+ # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-)
+ sed -n '
+ p
+ /[$]LINENO/=
+ ' <$as_myself |
sed '
+ s/[$]LINENO.*/&-/
+ t lineno
+ b
+ :lineno
N
- s,$,-,
- : loop
- s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
+ :loop
+ s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/
t loop
- s,-$,,
- s,^['$as_cr_digits']*\n,,
+ s/-\n.*//
' >$as_me.lineno &&
- chmod +x $as_me.lineno ||
- { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2
- { (exit 1); exit 1; }; }
+ chmod +x "$as_me.lineno" ||
+ { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; }
+ # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+ # already done that, so ensure we don't try to do so again and fall
+ # in an infinite loop. This has already happened in practice.
+ _as_can_reexec=no; export _as_can_reexec
# Don't try to exec as it changes $[0], causing all sort of problems
# (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensible to this).
- . ./$as_me.lineno
+ # original and so on. Autoconf is especially sensitive to this).
+ . "./$as_me.lineno"
# Exit status is that of the last command.
exit
}
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
- *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T=' ' ;;
- *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
- *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
esac
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
else
- as_expr=false
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- # We could just check for DJGPP; but this test a) works b) is more generic
- # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
- if test -f conf$$.exe; then
- # Don't use ln at all; we don't have any links
- as_ln_s='cp -p'
- else
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
-rm -f conf$$ conf$$.exe conf$$.file
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
+ as_mkdir_p='mkdir -p "$as_dir"'
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
-as_executable_p="test -f"
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -231,38 +554,25 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" $as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1
# Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
# so uname gets run too.
ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q`
-exec 6>&1
-
#
# Initializations.
#
ac_default_prefix=/usr/local
+ac_clean_files=
ac_config_libobj_dir=.
+LIBOBJS=
cross_compiling=no
subdirs=
MFLAGS=
MAKEFLAGS=
-SHELL=${CONFIG_SHELL-/bin/sh}
-
-# Maximum number of lines to put in a shell here document.
-# This variable seems obsolete. It should probably be removed, and
-# only ac_max_sed_lines should be used.
-: ${ac_max_here_lines=38}
# Identity of this package.
PACKAGE_NAME='tcl'
@@ -270,50 +580,218 @@ PACKAGE_TARNAME='tcl'
PACKAGE_VERSION='8.6'
PACKAGE_STRING='tcl 8.6'
PACKAGE_BUGREPORT=''
+PACKAGE_URL=''
# Factoring default headers for most tests.
ac_includes_default="\
#include <stdio.h>
-#if HAVE_SYS_TYPES_H
+#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
-#if HAVE_SYS_STAT_H
+#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
-#if STDC_HEADERS
+#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
-# if HAVE_STDLIB_H
+# ifdef HAVE_STDLIB_H
# include <stdlib.h>
# endif
#endif
-#if HAVE_STRING_H
-# if !STDC_HEADERS && HAVE_MEMORY_H
+#ifdef HAVE_STRING_H
+# if !defined STDC_HEADERS && defined HAVE_MEMORY_H
# include <memory.h>
# endif
# include <string.h>
#endif
-#if HAVE_STRINGS_H
+#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
-#if HAVE_INTTYPES_H
+#ifdef HAVE_INTTYPES_H
# include <inttypes.h>
-#else
-# if HAVE_STDINT_H
-# include <stdint.h>
-# endif
#endif
-#if HAVE_UNISTD_H
+#ifdef HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS MAN_FLAGS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP TCL_THREADS TCLSH_PROG ZLIB_OBJS ZLIB_SRCS ZLIB_INCLUDE RANLIB ac_ct_RANLIB AR ac_ct_AR LIBOBJS TCL_LIBS DL_LIBS DL_OBJS PLAT_OBJS PLAT_SRCS LDAIX_SRC CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING LDFLAGS_DEBUG LDFLAGS_OPTIMIZE CC_SEARCH_FLAGS LD_SEARCH_FLAGS STLIB_LD SHLIB_LD TCL_SHLIB_LD_EXTRAS TK_SHLIB_LD_EXTRAS SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX MAKE_LIB MAKE_STUB_LIB INSTALL_LIB DLL_INSTALL_DIR INSTALL_STUB_LIB CFLAGS_DEFAULT LDFLAGS_DEFAULT DTRACE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL TCL_YEAR PKG_CFG_ARGS TCL_LIB_FILE TCL_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_SRC_DIR CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX TCL_SHARED_BUILD LD_LIBRARY_PATH_VAR TCL_BUILD_LIB_SPEC TCL_LIB_VERSIONS_OK TCL_SHARED_LIB_SUFFIX TCL_UNSHARED_LIB_SUFFIX TCL_HAS_LONGLONG INSTALL_TZDATA DTRACE_SRC DTRACE_HDR DTRACE_OBJ MAKEFILE_SHELL BUILD_DLTEST TCL_PACKAGE_PATH TCL_MODULE_PATH TCL_LIBRARY PRIVATE_INCLUDE_DIR HTML_DIR PACKAGE_DIR EXTRA_CC_SWITCHES EXTRA_APP_CC_SWITCHES EXTRA_INSTALL EXTRA_INSTALL_BINARIES EXTRA_BUILD_HTML EXTRA_TCLSH_LIBS DLTEST_LD DLTEST_SUFFIX'
+ac_subst_vars='DLTEST_SUFFIX
+DLTEST_LD
+EXTRA_TCLSH_LIBS
+EXTRA_BUILD_HTML
+EXTRA_INSTALL_BINARIES
+EXTRA_INSTALL
+EXTRA_APP_CC_SWITCHES
+EXTRA_CC_SWITCHES
+PACKAGE_DIR
+HTML_DIR
+PRIVATE_INCLUDE_DIR
+TCL_LIBRARY
+TCL_MODULE_PATH
+TCL_PACKAGE_PATH
+BUILD_DLTEST
+MAKEFILE_SHELL
+DTRACE_OBJ
+DTRACE_HDR
+DTRACE_SRC
+INSTALL_TZDATA
+TCL_HAS_LONGLONG
+TCL_UNSHARED_LIB_SUFFIX
+TCL_SHARED_LIB_SUFFIX
+TCL_LIB_VERSIONS_OK
+TCL_BUILD_LIB_SPEC
+LD_LIBRARY_PATH_VAR
+TCL_SHARED_BUILD
+CFG_TCL_UNSHARED_LIB_SUFFIX
+CFG_TCL_SHARED_LIB_SUFFIX
+TCL_SRC_DIR
+TCL_BUILD_STUB_LIB_PATH
+TCL_BUILD_STUB_LIB_SPEC
+TCL_INCLUDE_SPEC
+TCL_STUB_LIB_PATH
+TCL_STUB_LIB_SPEC
+TCL_STUB_LIB_FLAG
+TCL_STUB_LIB_FILE
+TCL_LIB_SPEC
+TCL_LIB_FLAG
+TCL_LIB_FILE
+PKG_CFG_ARGS
+TCL_YEAR
+TCL_PATCH_LEVEL
+TCL_MINOR_VERSION
+TCL_MAJOR_VERSION
+TCL_VERSION
+DTRACE
+PCRE_LIBS
+PCRE_INCLUDE
+LDFLAGS_DEFAULT
+CFLAGS_DEFAULT
+INSTALL_STUB_LIB
+DLL_INSTALL_DIR
+INSTALL_LIB
+MAKE_STUB_LIB
+MAKE_LIB
+SHLIB_SUFFIX
+SHLIB_CFLAGS
+SHLIB_LD_LIBS
+TK_SHLIB_LD_EXTRAS
+TCL_SHLIB_LD_EXTRAS
+SHLIB_LD
+STLIB_LD
+LD_SEARCH_FLAGS
+CC_SEARCH_FLAGS
+LDFLAGS_OPTIMIZE
+LDFLAGS_DEBUG
+CFLAGS_WARNING
+CFLAGS_OPTIMIZE
+CFLAGS_DEBUG
+LDAIX_SRC
+PLAT_SRCS
+PLAT_OBJS
+DL_OBJS
+DL_LIBS
+TCL_LIBS
+LIBOBJS
+AR
+RANLIB
+ZLIB_INCLUDE
+ZLIB_SRCS
+ZLIB_OBJS
+TCLSH_PROG
+TCL_THREADS
+EGREP
+GREP
+CPP
+BISON
+OBJEXT
+EXEEXT
+ac_ct_CC
+CPPFLAGS
+LDFLAGS
+CFLAGS
+CC
+MAN_FLAGS
+target_alias
+host_alias
+build_alias
+LIBS
+ECHO_T
+ECHO_N
+ECHO_C
+DEFS
+mandir
+localedir
+libdir
+psdir
+pdfdir
+dvidir
+htmldir
+infodir
+docdir
+oldincludedir
+includedir
+localstatedir
+sharedstatedir
+sysconfdir
+datadir
+datarootdir
+libexecdir
+sbindir
+bindir
+program_transform_name
+prefix
+exec_prefix
+PACKAGE_URL
+PACKAGE_BUGREPORT
+PACKAGE_STRING
+PACKAGE_VERSION
+PACKAGE_TARNAME
+PACKAGE_NAME
+PATH_SEPARATOR
+SHELL'
ac_subst_files=''
+ac_user_opts='
+enable_option_checking
+enable_man_symlinks
+enable_man_compression
+enable_man_suffix
+enable_threads
+with_encoding
+enable_shared
+enable_64bit
+enable_64bit_vis
+enable_rpath
+enable_corefoundation
+enable_load
+enable_symbols
+with_pcre
+enable_pcre
+enable_usleep
+enable_langinfo
+enable_dll_unloading
+with_tzdata
+enable_dtrace
+enable_framework
+'
+ ac_precious_vars='build_alias
+host_alias
+target_alias
+CC
+CFLAGS
+LDFLAGS
+LIBS
+CPPFLAGS
+CPP'
+
# Initialize some variables set by options.
ac_init_help=
ac_init_version=false
+ac_unrecognized_opts=
+ac_unrecognized_sep=
# The variables have the same names as the options, with
# dashes changed to underlines.
cache_file=/dev/null
@@ -336,34 +814,49 @@ x_libraries=NONE
# and all the variables that are supposed to be based on exec_prefix
# by default will actually change.
# Use braces instead of parens because sh, perl, etc. also accept them.
+# (The list follows the same order as the GNU Coding Standards.)
bindir='${exec_prefix}/bin'
sbindir='${exec_prefix}/sbin'
libexecdir='${exec_prefix}/libexec'
-datadir='${prefix}/share'
+datarootdir='${prefix}/share'
+datadir='${datarootdir}'
sysconfdir='${prefix}/etc'
sharedstatedir='${prefix}/com'
localstatedir='${prefix}/var'
-libdir='${exec_prefix}/lib'
includedir='${prefix}/include'
oldincludedir='/usr/include'
-infodir='${prefix}/info'
-mandir='${prefix}/man'
+docdir='${datarootdir}/doc/${PACKAGE_TARNAME}'
+infodir='${datarootdir}/info'
+htmldir='${docdir}'
+dvidir='${docdir}'
+pdfdir='${docdir}'
+psdir='${docdir}'
+libdir='${exec_prefix}/lib'
+localedir='${datarootdir}/locale'
+mandir='${datarootdir}/man'
ac_prev=
+ac_dashdash=
for ac_option
do
# If the previous option needs an argument, assign it.
if test -n "$ac_prev"; then
- eval "$ac_prev=\$ac_option"
+ eval $ac_prev=\$ac_option
ac_prev=
continue
fi
- ac_optarg=`expr "x$ac_option" : 'x[^=]*=\(.*\)'`
+ case $ac_option in
+ *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+ *=) ac_optarg= ;;
+ *) ac_optarg=yes ;;
+ esac
# Accept the important Cygnus configure options, so we can diagnose typos.
- case $ac_option in
+ case $ac_dashdash$ac_option in
+ --)
+ ac_dashdash=yes ;;
-bindir | --bindir | --bindi | --bind | --bin | --bi)
ac_prev=bindir ;;
@@ -385,33 +878,59 @@ do
--config-cache | -C)
cache_file=config.cache ;;
- -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ -datadir | --datadir | --datadi | --datad)
ac_prev=datadir ;;
- -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
- | --da=*)
+ -datadir=* | --datadir=* | --datadi=* | --datad=*)
datadir=$ac_optarg ;;
+ -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \
+ | --dataroo | --dataro | --datar)
+ ac_prev=datarootdir ;;
+ -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \
+ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*)
+ datarootdir=$ac_optarg ;;
+
-disable-* | --disable-*)
- ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
+ ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'`
# Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/-/_/g'`
- eval "enable_$ac_feature=no" ;;
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval enable_$ac_useropt=no ;;
+
+ -docdir | --docdir | --docdi | --doc | --do)
+ ac_prev=docdir ;;
+ -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*)
+ docdir=$ac_optarg ;;
+
+ -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv)
+ ac_prev=dvidir ;;
+ -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*)
+ dvidir=$ac_optarg ;;
-enable-* | --enable-*)
- ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
+ ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- expr "x$ac_feature" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid feature name: $ac_feature" >&2
- { (exit 1); exit 1; }; }
- ac_feature=`echo $ac_feature | sed 's/-/_/g'`
- case $ac_option in
- *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
- *) ac_optarg=yes ;;
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid feature name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"enable_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
esac
- eval "enable_$ac_feature='$ac_optarg'" ;;
+ eval enable_$ac_useropt=\$ac_optarg ;;
-exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
| --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
@@ -438,6 +957,12 @@ do
-host=* | --host=* | --hos=* | --ho=*)
host_alias=$ac_optarg ;;
+ -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht)
+ ac_prev=htmldir ;;
+ -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \
+ | --ht=*)
+ htmldir=$ac_optarg ;;
+
-includedir | --includedir | --includedi | --included | --include \
| --includ | --inclu | --incl | --inc)
ac_prev=includedir ;;
@@ -462,13 +987,16 @@ do
| --libexe=* | --libex=* | --libe=*)
libexecdir=$ac_optarg ;;
+ -localedir | --localedir | --localedi | --localed | --locale)
+ ac_prev=localedir ;;
+ -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*)
+ localedir=$ac_optarg ;;
+
-localstatedir | --localstatedir | --localstatedi | --localstated \
- | --localstate | --localstat | --localsta | --localst \
- | --locals | --local | --loca | --loc | --lo)
+ | --localstate | --localstat | --localsta | --localst | --locals)
ac_prev=localstatedir ;;
-localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
- | --localstate=* | --localstat=* | --localsta=* | --localst=* \
- | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*)
localstatedir=$ac_optarg ;;
-mandir | --mandir | --mandi | --mand | --man | --ma | --m)
@@ -533,6 +1061,16 @@ do
| --progr-tra=* | --program-tr=* | --program-t=*)
program_transform_name=$ac_optarg ;;
+ -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd)
+ ac_prev=pdfdir ;;
+ -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*)
+ pdfdir=$ac_optarg ;;
+
+ -psdir | --psdir | --psdi | --psd | --ps)
+ ac_prev=psdir ;;
+ -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*)
+ psdir=$ac_optarg ;;
+
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
silent=yes ;;
@@ -583,26 +1121,36 @@ do
ac_init_version=: ;;
-with-* | --with-*)
- ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
+ ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'`
# Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package| sed 's/-/_/g'`
- case $ac_option in
- *=*) ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`;;
- *) ac_optarg=yes ;;
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
esac
- eval "with_$ac_package='$ac_optarg'" ;;
+ eval with_$ac_useropt=\$ac_optarg ;;
-without-* | --without-*)
- ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'`
+ ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'`
# Reject names that are not valid shell variable names.
- expr "x$ac_package" : ".*[^-_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid package name: $ac_package" >&2
- { (exit 1); exit 1; }; }
- ac_package=`echo $ac_package | sed 's/-/_/g'`
- eval "with_$ac_package=no" ;;
+ expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
+ as_fn_error $? "invalid package name: $ac_useropt"
+ ac_useropt_orig=$ac_useropt
+ ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'`
+ case $ac_user_opts in
+ *"
+"with_$ac_useropt"
+"*) ;;
+ *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig"
+ ac_unrecognized_sep=', ';;
+ esac
+ eval with_$ac_useropt=no ;;
--x)
# Obsolete; use --with-x.
@@ -622,27 +1170,26 @@ do
| --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
x_libraries=$ac_optarg ;;
- -*) { echo "$as_me: error: unrecognized option: $ac_option
-Try \`$0 --help' for more information." >&2
- { (exit 1); exit 1; }; }
+ -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
;;
*=*)
ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='`
# Reject names that are not valid shell variable names.
- expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null &&
- { echo "$as_me: error: invalid variable name: $ac_envvar" >&2
- { (exit 1); exit 1; }; }
- ac_optarg=`echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"`
- eval "$ac_envvar='$ac_optarg'"
+ case $ac_envvar in #(
+ '' | [0-9]* | *[!_$as_cr_alnum]* )
+ as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
+ esac
+ eval $ac_envvar=\$ac_optarg
export $ac_envvar ;;
*)
# FIXME: should be removed in autoconf 3.0.
- echo "$as_me: WARNING: you should use --build, --host, --target" >&2
+ $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2
expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null &&
- echo "$as_me: WARNING: invalid host type: $ac_option" >&2
- : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+ $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
+ : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
;;
esac
@@ -650,31 +1197,36 @@ done
if test -n "$ac_prev"; then
ac_option=--`echo $ac_prev | sed 's/_/-/g'`
- { echo "$as_me: error: missing argument to $ac_option" >&2
- { (exit 1); exit 1; }; }
+ as_fn_error $? "missing argument to $ac_option"
fi
-# Be sure to have absolute paths.
-for ac_var in exec_prefix prefix
-do
- eval ac_val=$`echo $ac_var`
- case $ac_val in
- [\\/$]* | ?:[\\/]* | NONE | '' ) ;;
- *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
- { (exit 1); exit 1; }; };;
+if test -n "$ac_unrecognized_opts"; then
+ case $enable_option_checking in
+ no) ;;
+ fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
+ *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
esac
-done
+fi
-# Be sure to have absolute paths.
-for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \
- localstatedir libdir includedir oldincludedir infodir mandir
+# Check all directory arguments for consistency.
+for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \
+ datadir sysconfdir sharedstatedir localstatedir includedir \
+ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \
+ libdir localedir mandir
do
- eval ac_val=$`echo $ac_var`
+ eval ac_val=\$$ac_var
+ # Remove trailing slashes.
+ case $ac_val in
+ */ )
+ ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'`
+ eval $ac_var=\$ac_val;;
+ esac
+ # Be sure to have absolute directory names.
case $ac_val in
- [\\/$]* | ?:[\\/]* ) ;;
- *) { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2
- { (exit 1); exit 1; }; };;
+ [\\/$]* | ?:[\\/]* ) continue;;
+ NONE | '' ) case $ac_var in *prefix ) continue;; esac;;
esac
+ as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
done
# There might be people who depend on the old broken behavior: `$host'
@@ -688,8 +1240,6 @@ target=$target_alias
if test "x$host_alias" != x; then
if test "x$build_alias" = x; then
cross_compiling=maybe
- echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
- If a cross compiler is detected then cross compile mode will be used." >&2
elif test "x$build_alias" != "x$host_alias"; then
cross_compiling=yes
fi
@@ -701,74 +1251,72 @@ test -n "$host_alias" && ac_tool_prefix=$host_alias-
test "$silent" = yes && exec 6>/dev/null
+ac_pwd=`pwd` && test -n "$ac_pwd" &&
+ac_ls_di=`ls -di .` &&
+ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
+ as_fn_error $? "working directory cannot be determined"
+test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
+ as_fn_error $? "pwd does not report name of working directory"
+
+
# Find the source files, if location was not specified.
if test -z "$srcdir"; then
ac_srcdir_defaulted=yes
- # Try the directory containing this script, then its parent.
- ac_confdir=`(dirname "$0") 2>/dev/null ||
-$as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$0" : 'X\(//\)[^/]' \| \
- X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$0" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
+ # Try the directory containing this script, then the parent directory.
+ ac_confdir=`$as_dirname -- "$as_myself" ||
+$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_myself" : 'X\(//\)[^/]' \| \
+ X"$as_myself" : 'X\(//\)$' \| \
+ X"$as_myself" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_myself" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
srcdir=$ac_confdir
- if test ! -r $srcdir/$ac_unique_file; then
+ if test ! -r "$srcdir/$ac_unique_file"; then
srcdir=..
fi
else
ac_srcdir_defaulted=no
fi
-if test ! -r $srcdir/$ac_unique_file; then
- if test "$ac_srcdir_defaulted" = yes; then
- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $ac_confdir or .." >&2
- { (exit 1); exit 1; }; }
- else
- { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2
- { (exit 1); exit 1; }; }
- fi
-fi
-(cd $srcdir && test -r ./$ac_unique_file) 2>/dev/null ||
- { echo "$as_me: error: sources are in $srcdir, but \`cd $srcdir' does not work" >&2
- { (exit 1); exit 1; }; }
-srcdir=`echo "$srcdir" | sed 's%\([^\\/]\)[\\/]*$%\1%'`
-ac_env_build_alias_set=${build_alias+set}
-ac_env_build_alias_value=$build_alias
-ac_cv_env_build_alias_set=${build_alias+set}
-ac_cv_env_build_alias_value=$build_alias
-ac_env_host_alias_set=${host_alias+set}
-ac_env_host_alias_value=$host_alias
-ac_cv_env_host_alias_set=${host_alias+set}
-ac_cv_env_host_alias_value=$host_alias
-ac_env_target_alias_set=${target_alias+set}
-ac_env_target_alias_value=$target_alias
-ac_cv_env_target_alias_set=${target_alias+set}
-ac_cv_env_target_alias_value=$target_alias
-ac_env_CC_set=${CC+set}
-ac_env_CC_value=$CC
-ac_cv_env_CC_set=${CC+set}
-ac_cv_env_CC_value=$CC
-ac_env_CFLAGS_set=${CFLAGS+set}
-ac_env_CFLAGS_value=$CFLAGS
-ac_cv_env_CFLAGS_set=${CFLAGS+set}
-ac_cv_env_CFLAGS_value=$CFLAGS
-ac_env_LDFLAGS_set=${LDFLAGS+set}
-ac_env_LDFLAGS_value=$LDFLAGS
-ac_cv_env_LDFLAGS_set=${LDFLAGS+set}
-ac_cv_env_LDFLAGS_value=$LDFLAGS
-ac_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_env_CPPFLAGS_value=$CPPFLAGS
-ac_cv_env_CPPFLAGS_set=${CPPFLAGS+set}
-ac_cv_env_CPPFLAGS_value=$CPPFLAGS
-ac_env_CPP_set=${CPP+set}
-ac_env_CPP_value=$CPP
-ac_cv_env_CPP_set=${CPP+set}
-ac_cv_env_CPP_value=$CPP
+if test ! -r "$srcdir/$ac_unique_file"; then
+ test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
+ as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
+fi
+ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
+ac_abs_confdir=`(
+ cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
+ pwd)`
+# When building in place, set srcdir=.
+if test "$ac_abs_confdir" = "$ac_pwd"; then
+ srcdir=.
+fi
+# Remove unnecessary trailing slashes from srcdir.
+# Double slashes in file names in object file debugging info
+# mess up M-x gdb in Emacs.
+case $srcdir in
+*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;;
+esac
+for ac_var in $ac_precious_vars; do
+ eval ac_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_env_${ac_var}_value=\$${ac_var}
+ eval ac_cv_env_${ac_var}_set=\${${ac_var}+set}
+ eval ac_cv_env_${ac_var}_value=\$${ac_var}
+done
#
# Report the --help message.
@@ -791,20 +1339,17 @@ Configuration:
--help=short display options specific to this package
--help=recursive display the short help of all the included packages
-V, --version display version information and exit
- -q, --quiet, --silent do not print \`checking...' messages
+ -q, --quiet, --silent do not print \`checking ...' messages
--cache-file=FILE cache test results in FILE [disabled]
-C, --config-cache alias for \`--cache-file=config.cache'
-n, --no-create do not create output files
--srcdir=DIR find the sources in DIR [configure dir or \`..']
-_ACEOF
-
- cat <<_ACEOF
Installation directories:
--prefix=PREFIX install architecture-independent files in PREFIX
- [$ac_default_prefix]
+ [$ac_default_prefix]
--exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
- [PREFIX]
+ [PREFIX]
By default, \`make install' will install all the files in
\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify
@@ -814,18 +1359,25 @@ for instance \`--prefix=\$HOME'.
For better control, use the options below.
Fine tuning of the installation directories:
- --bindir=DIR user executables [EPREFIX/bin]
- --sbindir=DIR system admin executables [EPREFIX/sbin]
- --libexecdir=DIR program executables [EPREFIX/libexec]
- --datadir=DIR read-only architecture-independent data [PREFIX/share]
- --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
- --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
- --localstatedir=DIR modifiable single-machine data [PREFIX/var]
- --libdir=DIR object code libraries [EPREFIX/lib]
- --includedir=DIR C header files [PREFIX/include]
- --oldincludedir=DIR C header files for non-gcc [/usr/include]
- --infodir=DIR info documentation [PREFIX/info]
- --mandir=DIR man documentation [PREFIX/man]
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/tcl]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
_ACEOF
cat <<\_ACEOF
@@ -839,6 +1391,7 @@ if test -n "$ac_init_help"; then
cat <<\_ACEOF
Optional Features:
+ --disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--enable-man-symlinks use symlinks for the manpages (default: off)
@@ -857,6 +1410,7 @@ Optional Features:
--enable-load allow dynamic loading and "load" command (default:
on)
--enable-symbols build with debugging symbols (default: off)
+ --enable-pcre whether to enable pcre (default: off)
--enable-usleep use usleep if possible to sleep, otherwise use
Tcl_Sleep (default: on)
--enable-langinfo use nl_langinfo if possible to determine encoding at
@@ -871,6 +1425,7 @@ Optional Packages:
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-encoding encoding for configuration values (default:
iso8859-1)
+ --with-pcre directory containing pcre headers and libraries
--with-tzdata install timezone data (default: autodetect)
Some influential environment variables:
@@ -878,128 +1433,560 @@ Some influential environment variables:
CFLAGS C compiler flags
LDFLAGS linker flags, e.g. -L<lib dir> if you have libraries in a
nonstandard directory <lib dir>
- CPPFLAGS C/C++ preprocessor flags, e.g. -I<include dir> if you have
- headers in a nonstandard directory <include dir>
+ LIBS libraries to pass to the linker, e.g. -l<library>
+ CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
+ you have headers in a nonstandard directory <include dir>
CPP C preprocessor
Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.
+Report bugs to the package provider.
_ACEOF
+ac_status=$?
fi
if test "$ac_init_help" = "recursive"; then
# If there are subdirs, report their specific --help.
- ac_popdir=`pwd`
for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue
- test -d $ac_dir || continue
+ test -d "$ac_dir" ||
+ { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } ||
+ continue
ac_builddir=.
-if test "$ac_dir" != .; then
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A "../" for each directory in $ac_dir_suffix.
- ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
- ac_dir_suffix= ac_top_builddir=
-fi
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
case $srcdir in
- .) # No --srcdir option. We are building in place.
+ .) # We are building in place.
ac_srcdir=.
- if test -z "$ac_top_builddir"; then
- ac_top_srcdir=.
- else
- ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
- fi ;;
- [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir ;;
- *) # Relative path.
- ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
- case "$ac_dir" in
- .) ac_abs_builddir=`pwd`;;
- [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
- *) ac_abs_builddir=`pwd`/"$ac_dir";;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
- case ${ac_top_builddir}. in
- .) ac_abs_top_builddir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
- *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
- case $ac_srcdir in
- .) ac_abs_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
- *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
- case $ac_top_srcdir in
- .) ac_abs_top_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
- *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
- esac;;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
-
- cd $ac_dir
- # Check for guested configure; otherwise get Cygnus style configure.
- if test -f $ac_srcdir/configure.gnu; then
- echo
- $SHELL $ac_srcdir/configure.gnu --help=recursive
- elif test -f $ac_srcdir/configure; then
- echo
- $SHELL $ac_srcdir/configure --help=recursive
- elif test -f $ac_srcdir/configure.ac ||
- test -f $ac_srcdir/configure.in; then
- echo
- $ac_configure --help
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+ cd "$ac_dir" || { ac_status=$?; continue; }
+ # Check for guested configure.
+ if test -f "$ac_srcdir/configure.gnu"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure.gnu" --help=recursive
+ elif test -f "$ac_srcdir/configure"; then
+ echo &&
+ $SHELL "$ac_srcdir/configure" --help=recursive
else
- echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
- fi
- cd $ac_popdir
+ $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2
+ fi || ac_status=$?
+ cd "$ac_pwd" || { ac_status=$?; break; }
done
fi
-test -n "$ac_init_help" && exit 0
+test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
tcl configure 8.6
-generated by GNU Autoconf 2.59
+generated by GNU Autoconf 2.69
-Copyright (C) 2003 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it.
_ACEOF
- exit 0
+ exit
fi
-exec 5>config.log
-cat >&5 <<_ACEOF
+
+## ------------------------ ##
+## Autoconf initialization. ##
+## ------------------------ ##
+
+# ac_fn_c_try_compile LINENO
+# --------------------------
+# Try to compile conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext
+ if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest.$ac_objext; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_compile
+
+# ac_fn_c_try_link LINENO
+# -----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_link ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ rm -f conftest.$ac_objext conftest$ac_exeext
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && {
+ test -z "$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ } && test -s conftest$ac_exeext && {
+ test "$cross_compiling" = yes ||
+ test -x conftest$ac_exeext
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information
+ # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would
+ # interfere with the next link command; also delete a directory that is
+ # left behind by Apple's compiler. We do this before executing the actions.
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_link
+
+# ac_fn_c_try_cpp LINENO
+# ----------------------
+# Try to preprocess conftest.$ac_ext, and return whether this succeeded.
+ac_fn_c_try_cpp ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err
+ ac_status=$?
+ if test -s conftest.err; then
+ grep -v '^ *+' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ mv -f conftest.er1 conftest.err
+ fi
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } > conftest.i && {
+ test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+ test ! -s conftest.err
+ }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=1
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_cpp
+
+# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists, giving a warning if it cannot be compiled using
+# the include files in INCLUDES and setting the cache variable VAR
+# accordingly.
+ac_fn_c_check_header_mongrel ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if eval \${$3+:} false; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+else
+ # Is the header compilable?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5
+$as_echo_n "checking $2 usability... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_header_compiler=yes
+else
+ ac_header_compiler=no
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5
+$as_echo "$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5
+$as_echo_n "checking $2 presence... " >&6; }
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <$2>
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+ ac_header_preproc=yes
+else
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.i conftest.$ac_ext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
+$as_echo "$ac_header_preproc" >&6; }
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #((
+ yes:no: )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5
+$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+ no:yes:* )
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5
+$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5
+$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5
+$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5
+$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5
+$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
+ ;;
+esac
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=\$ac_header_compiler"
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+fi
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_mongrel
+
+# ac_fn_c_try_run LINENO
+# ----------------------
+# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes
+# that executables *can* be run.
+ac_fn_c_try_run ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; } && { ac_try='./conftest$ac_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then :
+ ac_retval=0
+else
+ $as_echo "$as_me: program exited with status $ac_status" >&5
+ $as_echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_retval=$ac_status
+fi
+ rm -rf conftest.dSYM conftest_ipa8_conftest.oo
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+ as_fn_set_status $ac_retval
+
+} # ac_fn_c_try_run
+
+# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES
+# -------------------------------------------------------
+# Tests whether HEADER exists and can be compiled using the include files in
+# INCLUDES, setting the cache variable VAR accordingly.
+ac_fn_c_check_header_compile ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+#include <$2>
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_header_compile
+
+# ac_fn_c_check_func LINENO FUNC VAR
+# ----------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_c_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_func
+
+# ac_fn_c_check_type LINENO TYPE VAR INCLUDES
+# -------------------------------------------
+# Tests whether TYPE exists after having included INCLUDES, setting cache
+# variable VAR accordingly.
+ac_fn_c_check_type ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ eval "$3=no"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof ($2))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$4
+int
+main ()
+{
+if (sizeof (($2)))
+ return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ eval "$3=yes"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_type
+
+# ac_fn_c_check_member LINENO AGGR MEMBER VAR INCLUDES
+# ----------------------------------------------------
+# Tries to find if the field MEMBER exists in type AGGR, after including
+# INCLUDES, setting cache variable VAR accordingly.
+ac_fn_c_check_member ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2.$3" >&5
+$as_echo_n "checking for $2.$3... " >&6; }
+if eval \${$4+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+$5
+int
+main ()
+{
+static $2 ac_aggr;
+if (sizeof ac_aggr.$3)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$4=yes"
+else
+ eval "$4=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$4
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_check_member
+cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
It was created by tcl $as_me 8.6, which was
-generated by GNU Autoconf 2.59. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
_ACEOF
+exec 5>>config.log
{
cat <<_ASUNAME
## --------- ##
@@ -1018,7 +2005,7 @@ uname -v = `(uname -v) 2>/dev/null || echo unknown`
/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown`
/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown`
/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown`
-hostinfo = `(hostinfo) 2>/dev/null || echo unknown`
+/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown`
/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown`
/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown`
/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown`
@@ -1030,8 +2017,9 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- echo "PATH: $as_dir"
-done
+ $as_echo "PATH: $as_dir"
+ done
+IFS=$as_save_IFS
} >&5
@@ -1053,7 +2041,6 @@ _ACEOF
ac_configure_args=
ac_configure_args0=
ac_configure_args1=
-ac_sep=
ac_must_keep_next=false
for ac_pass in 1 2
do
@@ -1064,13 +2051,13 @@ do
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil)
continue ;;
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
- ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *\'*)
+ ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;;
esac
case $ac_pass in
- 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;;
+ 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;;
2)
- ac_configure_args1="$ac_configure_args1 '$ac_arg'"
+ as_fn_append ac_configure_args1 " '$ac_arg'"
if test $ac_must_keep_next = true; then
ac_must_keep_next=false # Got value, back to normal.
else
@@ -1086,104 +2073,115 @@ do
-* ) ac_must_keep_next=true ;;
esac
fi
- ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'"
- # Get rid of the leading space.
- ac_sep=" "
+ as_fn_append ac_configure_args " '$ac_arg'"
;;
esac
done
done
-$as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; }
-$as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; }
+{ ac_configure_args0=; unset ac_configure_args0;}
+{ ac_configure_args1=; unset ac_configure_args1;}
# When interrupted or exit'd, cleanup temporary files, and complete
# config.log. We remove comments because anyway the quotes in there
# would cause problems or look ugly.
-# WARNING: Be sure not to use single quotes in there, as some shells,
-# such as our DU 5.0 friend, will then `close' the trap.
+# WARNING: Use '\'' to represent an apostrophe within the trap.
+# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug.
trap 'exit_status=$?
# Save into config.log some information that might help in debugging.
{
echo
- cat <<\_ASBOX
-## ---------------- ##
+ $as_echo "## ---------------- ##
## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
echo
# The following way of writing the cache mishandles newlines in values,
-{
+(
+ for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
(set) 2>&1 |
- case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
+ case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
sed -n \
- "s/'"'"'/'"'"'\\\\'"'"''"'"'/g;
- s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p"
- ;;
+ "s/'\''/'\''\\\\'\'''\''/g;
+ s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p"
+ ;; #(
*)
- sed -n \
- "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
;;
- esac;
-}
+ esac |
+ sort
+)
echo
- cat <<\_ASBOX
-## ----------------- ##
+ $as_echo "## ----------------- ##
## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
echo
for ac_var in $ac_subst_vars
do
- eval ac_val=$`echo $ac_var`
- echo "$ac_var='"'"'$ac_val'"'"'"
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
done | sort
echo
if test -n "$ac_subst_files"; then
- cat <<\_ASBOX
-## ------------- ##
-## Output files. ##
-## ------------- ##
-_ASBOX
+ $as_echo "## ------------------- ##
+## File substitutions. ##
+## ------------------- ##"
echo
for ac_var in $ac_subst_files
do
- eval ac_val=$`echo $ac_var`
- echo "$ac_var='"'"'$ac_val'"'"'"
+ eval ac_val=\$$ac_var
+ case $ac_val in
+ *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;;
+ esac
+ $as_echo "$ac_var='\''$ac_val'\''"
done | sort
echo
fi
if test -s confdefs.h; then
- cat <<\_ASBOX
-## ----------- ##
+ $as_echo "## ----------- ##
## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
echo
- sed "/^$/d" confdefs.h | sort
+ cat confdefs.h
echo
fi
test "$ac_signal" != 0 &&
- echo "$as_me: caught signal $ac_signal"
- echo "$as_me: exit $exit_status"
+ $as_echo "$as_me: caught signal $ac_signal"
+ $as_echo "$as_me: exit $exit_status"
} >&5
- rm -f core *.core &&
- rm -rf conftest* confdefs* conf$$* $ac_clean_files &&
+ rm -f core *.core core.conftest.* &&
+ rm -f -r conftest* confdefs* conf$$* $ac_clean_files &&
exit $exit_status
- ' 0
+' 0
for ac_signal in 1 2 13 15; do
- trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal
+ trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal
done
ac_signal=0
# confdefs.h avoids OS command line length limits that DEFS can exceed.
-rm -rf conftest* confdefs.h
-# AIX cpp loses on an empty file, so make sure it contains at least a newline.
-echo >confdefs.h
+rm -f -r conftest* confdefs.h
+
+$as_echo "/* confdefs.h */" > confdefs.h
# Predefined preprocessor variables.
@@ -1191,112 +2189,137 @@ cat >>confdefs.h <<_ACEOF
#define PACKAGE_NAME "$PACKAGE_NAME"
_ACEOF
-
cat >>confdefs.h <<_ACEOF
#define PACKAGE_TARNAME "$PACKAGE_TARNAME"
_ACEOF
-
cat >>confdefs.h <<_ACEOF
#define PACKAGE_VERSION "$PACKAGE_VERSION"
_ACEOF
-
cat >>confdefs.h <<_ACEOF
#define PACKAGE_STRING "$PACKAGE_STRING"
_ACEOF
-
cat >>confdefs.h <<_ACEOF
#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT"
_ACEOF
+cat >>confdefs.h <<_ACEOF
+#define PACKAGE_URL "$PACKAGE_URL"
+_ACEOF
+
# Let the site file select an alternate cache file if it wants to.
-# Prefer explicitly selected file to automatically selected ones.
-if test -z "$CONFIG_SITE"; then
- if test "x$prefix" != xNONE; then
- CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
- else
- CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
- fi
+# Prefer an explicitly selected file to automatically selected ones.
+ac_site_file1=NONE
+ac_site_file2=NONE
+if test -n "$CONFIG_SITE"; then
+ # We do not want a PATH search for config.site.
+ case $CONFIG_SITE in #((
+ -*) ac_site_file1=./$CONFIG_SITE;;
+ */*) ac_site_file1=$CONFIG_SITE;;
+ *) ac_site_file1=./$CONFIG_SITE;;
+ esac
+elif test "x$prefix" != xNONE; then
+ ac_site_file1=$prefix/share/config.site
+ ac_site_file2=$prefix/etc/config.site
+else
+ ac_site_file1=$ac_default_prefix/share/config.site
+ ac_site_file2=$ac_default_prefix/etc/config.site
fi
-for ac_site_file in $CONFIG_SITE; do
- if test -r "$ac_site_file"; then
- { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5
-echo "$as_me: loading site script $ac_site_file" >&6;}
+for ac_site_file in "$ac_site_file1" "$ac_site_file2"
+do
+ test "x$ac_site_file" = xNONE && continue
+ if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
+$as_echo "$as_me: loading site script $ac_site_file" >&6;}
sed 's/^/| /' "$ac_site_file" >&5
- . "$ac_site_file"
+ . "$ac_site_file" \
+ || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
fi
done
if test -r "$cache_file"; then
- # Some versions of bash will fail to source /dev/null (special
- # files actually), so we avoid doing that.
- if test -f "$cache_file"; then
- { echo "$as_me:$LINENO: loading cache $cache_file" >&5
-echo "$as_me: loading cache $cache_file" >&6;}
+ # Some versions of bash will fail to source /dev/null (special files
+ # actually), so we avoid doing that. DJGPP emulates it as a regular file.
+ if test /dev/null != "$cache_file" && test -f "$cache_file"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
+$as_echo "$as_me: loading cache $cache_file" >&6;}
case $cache_file in
- [\\/]* | ?:[\\/]* ) . $cache_file;;
- *) . ./$cache_file;;
+ [\\/]* | ?:[\\/]* ) . "$cache_file";;
+ *) . "./$cache_file";;
esac
fi
else
- { echo "$as_me:$LINENO: creating cache $cache_file" >&5
-echo "$as_me: creating cache $cache_file" >&6;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5
+$as_echo "$as_me: creating cache $cache_file" >&6;}
>$cache_file
fi
# Check that the precious variables saved in the cache have kept the same
# value.
ac_cache_corrupted=false
-for ac_var in `(set) 2>&1 |
- sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do
+for ac_var in $ac_precious_vars; do
eval ac_old_set=\$ac_cv_env_${ac_var}_set
eval ac_new_set=\$ac_env_${ac_var}_set
- eval ac_old_val="\$ac_cv_env_${ac_var}_value"
- eval ac_new_val="\$ac_env_${ac_var}_value"
+ eval ac_old_val=\$ac_cv_env_${ac_var}_value
+ eval ac_new_val=\$ac_env_${ac_var}_value
case $ac_old_set,$ac_new_set in
set,)
- { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;}
ac_cache_corrupted=: ;;
,set)
- { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5
-echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5
+$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;}
ac_cache_corrupted=: ;;
,);;
*)
if test "x$ac_old_val" != "x$ac_new_val"; then
- { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5
-echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
- { echo "$as_me:$LINENO: former value: $ac_old_val" >&5
-echo "$as_me: former value: $ac_old_val" >&2;}
- { echo "$as_me:$LINENO: current value: $ac_new_val" >&5
-echo "$as_me: current value: $ac_new_val" >&2;}
- ac_cache_corrupted=:
+ # differences in whitespace do not lead to failure.
+ ac_old_val_w=`echo x $ac_old_val`
+ ac_new_val_w=`echo x $ac_new_val`
+ if test "$ac_old_val_w" != "$ac_new_val_w"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5
+$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;}
+ ac_cache_corrupted=:
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5
+$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;}
+ eval $ac_var=\$ac_old_val
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5
+$as_echo "$as_me: former value: \`$ac_old_val'" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5
+$as_echo "$as_me: current value: \`$ac_new_val'" >&2;}
fi;;
esac
# Pass precious variables to config.status.
if test "$ac_new_set" = set; then
case $ac_new_val in
- *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?\"\']*)
- ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
+ *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;;
*) ac_arg=$ac_var=$ac_new_val ;;
esac
case " $ac_configure_args " in
*" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy.
- *) ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) as_fn_append ac_configure_args " '$ac_arg'" ;;
esac
fi
done
if $ac_cache_corrupted; then
- { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5
-echo "$as_me: error: changes in the environment can compromise the build" >&2;}
- { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5
-echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;}
- { (exit 1); exit 1; }; }
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5
+$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
+ as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
fi
+## -------------------- ##
+## Main body of script. ##
+## -------------------- ##
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
@@ -1309,31 +2332,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
TCL_VERSION=8.6
TCL_MAJOR_VERSION=8
TCL_MINOR_VERSION=6
@@ -1384,62 +2382,60 @@ TCL_SRC_DIR="`cd "$srcdir"/..; pwd`"
#------------------------------------------------------------------------
- echo "$as_me:$LINENO: checking whether to use symlinks for manpages" >&5
-echo $ECHO_N "checking whether to use symlinks for manpages... $ECHO_C" >&6
- # Check whether --enable-man-symlinks or --disable-man-symlinks was given.
-if test "${enable_man_symlinks+set}" = set; then
- enableval="$enable_man_symlinks"
- test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use symlinks for manpages" >&5
+$as_echo_n "checking whether to use symlinks for manpages... " >&6; }
+ # Check whether --enable-man-symlinks was given.
+if test "${enable_man_symlinks+set}" = set; then :
+ enableval=$enable_man_symlinks; test "$enableval" != "no" && MAN_FLAGS="$MAN_FLAGS --symlinks"
else
enableval="no"
-fi;
- echo "$as_me:$LINENO: result: $enableval" >&5
-echo "${ECHO_T}$enableval" >&6
-
- echo "$as_me:$LINENO: checking whether to compress the manpages" >&5
-echo $ECHO_N "checking whether to compress the manpages... $ECHO_C" >&6
- # Check whether --enable-man-compression or --disable-man-compression was given.
-if test "${enable_man_compression+set}" = set; then
- enableval="$enable_man_compression"
- case $enableval in
- yes) { { echo "$as_me:$LINENO: error: missing argument to --enable-man-compression" >&5
-echo "$as_me: error: missing argument to --enable-man-compression" >&2;}
- { (exit 1); exit 1; }; };;
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
+$as_echo "$enableval" >&6; }
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compress the manpages" >&5
+$as_echo_n "checking whether to compress the manpages... " >&6; }
+ # Check whether --enable-man-compression was given.
+if test "${enable_man_compression+set}" = set; then :
+ enableval=$enable_man_compression; case $enableval in
+ yes) as_fn_error $? "missing argument to --enable-man-compression" "$LINENO" 5;;
no) ;;
*) MAN_FLAGS="$MAN_FLAGS --compress $enableval";;
esac
else
enableval="no"
-fi;
- echo "$as_me:$LINENO: result: $enableval" >&5
-echo "${ECHO_T}$enableval" >&6
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
+$as_echo "$enableval" >&6; }
if test "$enableval" != "no"; then
- echo "$as_me:$LINENO: checking for compressed file suffix" >&5
-echo $ECHO_N "checking for compressed file suffix... $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for compressed file suffix" >&5
+$as_echo_n "checking for compressed file suffix... " >&6; }
touch TeST
$enableval TeST
Z=`ls TeST* | sed 's/^....//'`
rm -f TeST*
MAN_FLAGS="$MAN_FLAGS --extension $Z"
- echo "$as_me:$LINENO: result: $Z" >&5
-echo "${ECHO_T}$Z" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $Z" >&5
+$as_echo "$Z" >&6; }
fi
- echo "$as_me:$LINENO: checking whether to add a package name suffix for the manpages" >&5
-echo $ECHO_N "checking whether to add a package name suffix for the manpages... $ECHO_C" >&6
- # Check whether --enable-man-suffix or --disable-man-suffix was given.
-if test "${enable_man_suffix+set}" = set; then
- enableval="$enable_man_suffix"
- case $enableval in
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to add a package name suffix for the manpages" >&5
+$as_echo_n "checking whether to add a package name suffix for the manpages... " >&6; }
+ # Check whether --enable-man-suffix was given.
+if test "${enable_man_suffix+set}" = set; then :
+ enableval=$enable_man_suffix; case $enableval in
yes) enableval="tcl" MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
no) ;;
*) MAN_FLAGS="$MAN_FLAGS --suffix $enableval";;
esac
else
enableval="no"
-fi;
- echo "$as_me:$LINENO: result: $enableval" >&5
-echo "${ECHO_T}$enableval" >&6
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enableval" >&5
+$as_echo "$enableval" >&6; }
@@ -1462,10 +2458,10 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args.
set dummy ${ac_tool_prefix}gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1475,35 +2471,37 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
+
fi
if test -z "$ac_cv_prog_CC"; then
ac_ct_CC=$CC
# Extract the first word of "gcc", so it can be a program name with args.
set dummy gcc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
@@ -1513,39 +2511,50 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="gcc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
- CC=$ac_ct_CC
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
else
CC="$ac_cv_prog_CC"
fi
if test -z "$CC"; then
- if test -n "$ac_tool_prefix"; then
- # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
+ if test -n "$ac_tool_prefix"; then
+ # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args.
set dummy ${ac_tool_prefix}cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1555,77 +2564,37 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="${ac_tool_prefix}cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
-else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
-fi
-
-fi
-if test -z "$ac_cv_prog_CC"; then
- ac_ct_CC=$CC
- # Extract the first word of "cc", so it can be a program name with args.
-set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if test -n "$ac_ct_CC"; then
- ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
- ac_cv_prog_ac_ct_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
- break 2
- fi
-done
-done
-
-fi
-fi
-ac_ct_CC=$ac_cv_prog_ac_ct_CC
-if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
- CC=$ac_ct_CC
-else
- CC="$ac_cv_prog_CC"
-fi
+ fi
fi
if test -z "$CC"; then
# Extract the first word of "cc", so it can be a program name with args.
set dummy cc; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1636,18 +2605,19 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
ac_prog_rejected=yes
continue
fi
ac_cv_prog_CC="cc"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
if test $ac_prog_rejected = yes; then
# We found a bogon in the path, so make sure we never use it.
@@ -1665,24 +2635,25 @@ fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
+
fi
if test -z "$CC"; then
if test -n "$ac_tool_prefix"; then
- for ac_prog in cl
+ for ac_prog in cl.exe
do
# Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
set dummy $ac_tool_prefix$ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$CC"; then
ac_cv_prog_CC="$CC" # Let the user override the test.
@@ -1692,39 +2663,41 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
fi
fi
CC=$ac_cv_prog_CC
if test -n "$CC"; then
- echo "$as_me:$LINENO: result: $CC" >&5
-echo "${ECHO_T}$CC" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5
+$as_echo "$CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
+
test -n "$CC" && break
done
fi
if test -z "$CC"; then
ac_ct_CC=$CC
- for ac_prog in cl
+ for ac_prog in cl.exe
do
# Extract the first word of "$ac_prog", so it can be a program name with args.
set dummy $ac_prog; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_CC"; then
ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test.
@@ -1734,66 +2707,78 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_CC="$ac_prog"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
fi
fi
ac_ct_CC=$ac_cv_prog_ac_ct_CC
if test -n "$ac_ct_CC"; then
- echo "$as_me:$LINENO: result: $ac_ct_CC" >&5
-echo "${ECHO_T}$ac_ct_CC" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5
+$as_echo "$ac_ct_CC" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
+
test -n "$ac_ct_CC" && break
done
- CC=$ac_ct_CC
+ if test "x$ac_ct_CC" = x; then
+ CC=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CC=$ac_ct_CC
+ fi
fi
fi
-test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&5
-echo "$as_me: error: no acceptable C compiler found in \$PATH
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }
# Provide some information about the compiler.
-echo "$as_me:$LINENO:" \
- "checking for C compiler version" >&5
-ac_compiler=`set X $ac_compile; echo $2`
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
- (eval $ac_compiler --version </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -v </dev/null >&5\"") >&5
- (eval $ac_compiler -v </dev/null >&5) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
-{ (eval echo "$as_me:$LINENO: \"$ac_compiler -V </dev/null >&5\"") >&5
- (eval $ac_compiler -V </dev/null >&5) 2>&5
+$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5
+set X $ac_compile
+ac_compiler=$2
+for ac_option in --version -v -V -qversion; do
+ { { ac_try="$ac_compiler $ac_option >&5"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compiler $ac_option >&5") 2>conftest.err
ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }
+ if test -s conftest.err; then
+ sed '10a\
+... rest of stderr output deleted ...
+ 10q' conftest.err >conftest.er1
+ cat conftest.er1 >&5
+ fi
+ rm -f conftest.er1 conftest.err
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+done
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -1805,112 +2790,108 @@ main ()
}
_ACEOF
ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.exe b.out"
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
# Try to create an executable without -o first, disregard a.out.
# It will help us diagnose broken compilers, and finding out an intuition
# of exeext.
-echo "$as_me:$LINENO: checking for C compiler default output file name" >&5
-echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6
-ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
-if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5
- (eval $ac_link_default) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- # Find the output, starting from the most likely. This scheme is
-# not robust to junk in `.', hence go to wildcards (a.*) only as a last
-# resort.
-
-# Be careful to initialize this variable, since it used to be cached.
-# Otherwise an old cache value of `no' led to `EXEEXT = no' in a Makefile.
-ac_cv_exeext=
-# b.out is created by i960 compilers.
-for ac_file in a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
+ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
+
+# The possible output files:
+ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*"
+
+ac_rmfiles=
+for ac_file in $ac_files
+do
+ case $ac_file in
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
+ * ) ac_rmfiles="$ac_rmfiles $ac_file";;
+ esac
+done
+rm -f $ac_rmfiles
+
+if { { ac_try="$ac_link_default"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link_default") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ # Autoconf-2.13 could set the ac_cv_exeext variable to `no'.
+# So ignore a value of `no', otherwise this would lead to `EXEEXT = no'
+# in a Makefile. We should not override ac_cv_exeext if it was cached,
+# so that the user can short-circuit this test for compilers unknown to
+# Autoconf.
+for ac_file in $ac_files ''
do
test -f "$ac_file" || continue
case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj )
- ;;
- conftest.$ac_ext )
- # This is the source file.
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj )
;;
[ab].out )
# We found the default executable, but exeext='' is most
# certainly right.
break;;
*.* )
- ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- # FIXME: I believe we export ac_cv_exeext for Libtool,
- # but it would be cool to find out if it's true. Does anybody
- # maintain Libtool? --akim.
- export ac_cv_exeext
+ if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no;
+ then :; else
+ ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
+ fi
+ # We set ac_cv_exeext here because the later test for it is not
+ # safe: cross compilers may not add the suffix if given an `-o'
+ # argument, so we may need to know it at that point already.
+ # Even if this section looks crufty: it has the advantage of
+ # actually working.
break;;
* )
break;;
esac
done
+test "$ac_cv_exeext" = no && ac_cv_exeext=
+
else
- echo "$as_me: failed program was:" >&5
+ ac_file=''
+fi
+if test -z "$ac_file"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-{ { echo "$as_me:$LINENO: error: C compiler cannot create executables
-See \`config.log' for more details." >&5
-echo "$as_me: error: C compiler cannot create executables
-See \`config.log' for more details." >&2;}
- { (exit 77); exit 77; }; }
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
fi
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
ac_exeext=$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_file" >&5
-echo "${ECHO_T}$ac_file" >&6
-
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether the C compiler works" >&5
-echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6
-# FIXME: These cross compiler hacks should be removed for Autoconf 3.0
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
- if { ac_try='./$ac_file'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- cross_compiling=no
- else
- if test "$cross_compiling" = maybe; then
- cross_compiling=yes
- else
- { { echo "$as_me:$LINENO: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
- fi
- fi
-fi
-echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
-rm -f a.out a.exe conftest$ac_cv_exeext b.out
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
ac_clean_files=$ac_clean_files_save
-# Check the compiler produces executables we can run. If not, either
-# the compiler is broken, or we cross compile.
-echo "$as_me:$LINENO: checking whether we are cross compiling" >&5
-echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6
-echo "$as_me:$LINENO: result: $cross_compiling" >&5
-echo "${ECHO_T}$cross_compiling" >&6
-
-echo "$as_me:$LINENO: checking for suffix of executables" >&5
-echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
+$as_echo_n "checking for suffix of executables... " >&6; }
+if { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
# If both `conftest.exe' and `conftest' are `present' (well, observable)
# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will
# work properly (i.e., refer to `conftest.exe'), while it won't with
@@ -1918,38 +2899,90 @@ if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
for ac_file in conftest.exe conftest conftest.*; do
test -f "$ac_file" || continue
case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;;
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;;
*.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'`
- export ac_cv_exeext
break;;
* ) break;;
esac
done
else
- { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
fi
-
-rm -f conftest$ac_cv_exeext
-echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5
-echo "${ECHO_T}$ac_cv_exeext" >&6
+rm -f conftest conftest$ac_cv_exeext
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
+$as_echo "$ac_cv_exeext" >&6; }
rm -f conftest.$ac_ext
EXEEXT=$ac_cv_exeext
ac_exeext=$EXEEXT
-echo "$as_me:$LINENO: checking for suffix of object files" >&5
-echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6
-if test "${ac_cv_objext+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+ ;
+ return 0;
+}
_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run. If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+ { { ac_try="$ac_link"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_link") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }
+ if { ac_try='./conftest$ac_cv_exeext'
+ { { case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_try") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }; then
+ cross_compiling=no
+ else
+ if test "$cross_compiling" = maybe; then
+ cross_compiling=yes
+ else
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+ fi
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
+$as_echo_n "checking for suffix of object files... " >&6; }
+if ${ac_cv_objext+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -1961,45 +2994,46 @@ main ()
}
_ACEOF
rm -f conftest.o conftest.obj
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; then
- for ac_file in `(ls conftest.o conftest.obj; ls conftest.*) 2>/dev/null`; do
+if { { ac_try="$ac_compile"
+case "(($ac_try" in
+ *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+ *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+ (eval "$ac_compile") 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; then :
+ for ac_file in conftest.o conftest.obj conftest.*; do
+ test -f "$ac_file" || continue;
case $ac_file in
- *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg ) ;;
+ *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;;
*) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'`
break;;
esac
done
else
- echo "$as_me: failed program was:" >&5
+ $as_echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5
-{ { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&5
-echo "$as_me: error: cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
fi
-
rm -f conftest.$ac_cv_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_objext" >&5
-echo "${ECHO_T}$ac_cv_objext" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5
+$as_echo "$ac_cv_objext" >&6; }
OBJEXT=$ac_cv_objext
ac_objext=$OBJEXT
-echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5
-echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6
-if test "${ac_cv_c_compiler_gnu+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5
+$as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
+if ${ac_cv_c_compiler_gnu+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -2013,55 +3047,34 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
ac_compiler_gnu=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_compiler_gnu=no
+ ac_compiler_gnu=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
ac_cv_c_compiler_gnu=$ac_compiler_gnu
fi
-echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5
-echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6
-GCC=`test $ac_compiler_gnu = yes && echo yes`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5
+$as_echo "$ac_cv_c_compiler_gnu" >&6; }
+if test $ac_compiler_gnu = yes; then
+ GCC=yes
+else
+ GCC=
+fi
ac_test_CFLAGS=${CFLAGS+set}
ac_save_CFLAGS=$CFLAGS
-CFLAGS="-g"
-echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5
-echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_g+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5
+$as_echo_n "checking whether $CC accepts -g... " >&6; }
+if ${ac_cv_prog_cc_g+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_save_c_werror_flag=$ac_c_werror_flag
+ ac_c_werror_flag=yes
+ ac_cv_prog_cc_g=no
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -2072,39 +3085,49 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_prog_cc_g=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ CFLAGS=""
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+ ac_c_werror_flag=$ac_save_c_werror_flag
+ CFLAGS="-g"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+int
+main ()
+{
-ac_cv_prog_cc_g=no
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_g=yes
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ ac_c_werror_flag=$ac_save_c_werror_flag
fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_g" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5
+$as_echo "$ac_cv_prog_cc_g" >&6; }
if test "$ac_test_CFLAGS" = set; then
CFLAGS=$ac_save_CFLAGS
elif test $ac_cv_prog_cc_g = yes; then
@@ -2120,23 +3143,18 @@ else
CFLAGS=
fi
fi
-echo "$as_me:$LINENO: checking for $CC option to accept ANSI C" >&5
-echo $ECHO_N "checking for $CC option to accept ANSI C... $ECHO_C" >&6
-if test "${ac_cv_prog_cc_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5
+$as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
+if ${ac_cv_prog_cc_c89+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- ac_cv_prog_cc_stdc=no
+ ac_cv_prog_cc_c89=no
ac_save_CC=$CC
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdarg.h>
#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */
struct buf { int x; };
FILE * (*rcsopen) (struct buf *, struct stat *, int);
@@ -2159,12 +3177,17 @@ static char *f (char * (*g) (char **, int), char **p, ...)
/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has
function prototypes and stuff, but not '\xHH' hex character constants.
These don't provoke an error unfortunately, instead are silently treated
- as 'x'. The following induces an error, until -std1 is added to get
+ as 'x'. The following induces an error, until -std is added to get
proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an
array size at least. It's necessary to write '\x00'==0 to get something
- that's true only with -std1. */
+ that's true only with -std. */
int osf4_cc_array ['\x00' == 0 ? 1 : -1];
+/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters
+ inside strings and character constants. */
+#define FOO(x) 'x'
+int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1];
+
int test (int i, double x);
struct s1 {int (*f) (int a);};
struct s2 {int (*f) (double a);};
@@ -2179,205 +3202,37 @@ return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1];
return 0;
}
_ACEOF
-# Don't try gcc -ansi; that turns off useful extensions and
-# breaks some systems' header files.
-# AIX -qlanglvl=ansi
-# Ultrix and OSF/1 -std1
-# HP-UX 10.20 and later -Ae
-# HP-UX older versions -Aa -D_HPUX_SOURCE
-# SVR4 -Xc -D__EXTENSIONS__
-for ac_arg in "" -qlanglvl=ansi -std1 -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
+for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \
+ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__"
do
CC="$ac_save_CC $ac_arg"
- rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_prog_cc_stdc=$ac_arg
-break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
+ if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_prog_cc_c89=$ac_arg
fi
-rm -f conftest.err conftest.$ac_objext
+rm -f core conftest.err conftest.$ac_objext
+ test "x$ac_cv_prog_cc_c89" != "xno" && break
done
-rm -f conftest.$ac_ext conftest.$ac_objext
+rm -f conftest.$ac_ext
CC=$ac_save_CC
fi
-
-case "x$ac_cv_prog_cc_stdc" in
- x|xno)
- echo "$as_me:$LINENO: result: none needed" >&5
-echo "${ECHO_T}none needed" >&6 ;;
+# AC_CACHE_VAL
+case "x$ac_cv_prog_cc_c89" in
+ x)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5
+$as_echo "none needed" >&6; } ;;
+ xno)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5
+$as_echo "unsupported" >&6; } ;;
*)
- echo "$as_me:$LINENO: result: $ac_cv_prog_cc_stdc" >&5
-echo "${ECHO_T}$ac_cv_prog_cc_stdc" >&6
- CC="$CC $ac_cv_prog_cc_stdc" ;;
+ CC="$CC $ac_cv_prog_cc_c89"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5
+$as_echo "$ac_cv_prog_cc_c89" >&6; } ;;
esac
-
-# Some people use a C++ compiler to compile C. Since we use `exit',
-# in C++ we need to declare it. In case someone uses the same compiler
-# for both compiling C and C++ we need to have the C++ compiler decide
-# the declaration of exit, since it's the most demanding environment.
-cat >conftest.$ac_ext <<_ACEOF
-#ifndef __cplusplus
- choke me
-#endif
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- for ac_declaration in \
- '' \
- 'extern "C" void std::exit (int) throw (); using std::exit;' \
- 'extern "C" void std::exit (int); using std::exit;' \
- 'extern "C" void exit (int) throw ();' \
- 'extern "C" void exit (int);' \
- 'void exit (int);'
-do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-#include <stdlib.h>
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-continue
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_declaration
-int
-main ()
-{
-exit (42);
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if test "x$ac_cv_prog_cc_c89" != xno; then :
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-done
-rm -f conftest*
-if test -n "$ac_declaration"; then
- echo '#ifdef __cplusplus' >>confdefs.h
- echo $ac_declaration >>confdefs.h
- echo '#endif' >>confdefs.h
-fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
ac_ext=c
ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -2385,18 +3240,14 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking for inline" >&5
-echo $ECHO_N "checking for inline... $ECHO_C" >&6
-if test "${ac_cv_c_inline+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for inline" >&5
+$as_echo_n "checking for inline... " >&6; }
+if ${ac_cv_c_inline+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_cv_c_inline=no
for ac_kw in inline __inline__ __inline; do
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifndef __cplusplus
typedef int foo_t;
@@ -2405,41 +3256,16 @@ $ac_kw foo_t foo () {return 0; }
#endif
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_c_inline=$ac_kw; break
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
+if ac_fn_c_try_compile "$LINENO"; then :
+ ac_cv_c_inline=$ac_kw
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ test "$ac_cv_c_inline" != no && break
done
fi
-echo "$as_me:$LINENO: result: $ac_cv_c_inline" >&5
-echo "${ECHO_T}$ac_cv_c_inline" >&6
-
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_inline" >&5
+$as_echo "$ac_cv_c_inline" >&6; }
case $ac_cv_c_inline in
inline | yes) ;;
@@ -2457,6 +3283,57 @@ _ACEOF
esac
+
+ for ac_prog in bison
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_BISON+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$BISON"; then
+ ac_cv_prog_BISON="$BISON" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_BISON="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+BISON=$ac_cv_prog_BISON
+if test -n "$BISON"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BISON" >&5
+$as_echo "$BISON" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$BISON" && break
+done
+test -n "$BISON" || BISON="no"
+
+ export BISON;
+ if test $BISON = "no" ;
+ then
+ as_fn_error $? "Unable to find bison" "$LINENO" 5;
+ fi
+
+
#--------------------------------------------------------------------
# Supply substitutes for missing POSIX header files. Special notes:
# - stdlib.h doesn't define strtol, strtoul, or
@@ -2471,15 +3348,15 @@ ac_cpp='$CPP $CPPFLAGS'
ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
-echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5
+$as_echo_n "checking how to run the C preprocessor... " >&6; }
# On Suns, sometimes $CPP names a directory.
if test -n "$CPP" && test -d "$CPP"; then
CPP=
fi
if test -z "$CPP"; then
- if test "${ac_cv_prog_CPP+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ if ${ac_cv_prog_CPP+:} false; then :
+ $as_echo_n "(cached) " >&6
else
# Double quotes because CPP needs to be expanded
for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
@@ -2493,11 +3370,7 @@ do
# <limits.h> exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifdef __STDC__
# include <limits.h>
@@ -2506,78 +3379,34 @@ cat >>conftest.$ac_ext <<_ACEOF
#endif
Syntax error
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_cpp "$LINENO"; then :
+else
# Broken: fails on valid input.
continue
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
- # OK, works on sane cases. Now check whether non-existent headers
+ # OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <ac_nonexistent.h>
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+if ac_fn_c_try_cpp "$LINENO"; then :
# Broken: success on invalid input.
continue
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
# Passes both tests.
ac_preproc_ok=:
break
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
break
fi
@@ -2589,8 +3418,8 @@ fi
else
ac_cv_prog_CPP=$CPP
fi
-echo "$as_me:$LINENO: result: $CPP" >&5
-echo "${ECHO_T}$CPP" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5
+$as_echo "$CPP" >&6; }
ac_preproc_ok=false
for ac_c_preproc_warn_flag in '' yes
do
@@ -2600,11 +3429,7 @@ do
# <limits.h> exists even on freestanding compilers.
# On the NeXT, cc -E runs the code through the compiler's parser,
# not just through cpp. "Syntax error" is here to catch this case.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifdef __STDC__
# include <limits.h>
@@ -2613,85 +3438,40 @@ cat >>conftest.$ac_ext <<_ACEOF
#endif
Syntax error
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- :
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_cpp "$LINENO"; then :
+else
# Broken: fails on valid input.
continue
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
- # OK, works on sane cases. Now check whether non-existent headers
+ # OK, works on sane cases. Now check whether nonexistent headers
# can be detected and how.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <ac_nonexistent.h>
_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
+if ac_fn_c_try_cpp "$LINENO"; then :
# Broken: success on invalid input.
continue
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
# Passes both tests.
ac_preproc_ok=:
break
fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
done
# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
-if $ac_preproc_ok; then
- :
+rm -f conftest.i conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then :
+
else
- { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&5
-echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." >&2;}
- { (exit 1); exit 1; }; }
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
fi
ac_ext=c
@@ -2701,31 +3481,142 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
ac_compiler_gnu=$ac_cv_c_compiler_gnu
-echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6
-if test "${ac_cv_prog_egrep+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5
+$as_echo_n "checking for grep that handles long lines and -e... " >&6; }
+if ${ac_cv_path_GREP+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- if echo a | (grep -E '(a|b)') >/dev/null 2>&1
- then ac_cv_prog_egrep='grep -E'
- else ac_cv_prog_egrep='egrep'
+ if test -z "$GREP"; then
+ ac_path_GREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in grep ggrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_GREP" || continue
+# Check for GNU ac_path_GREP and select it if it is found.
+ # Check for GNU $ac_path_GREP
+case `"$ac_path_GREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'GREP' >> "conftest.nl"
+ "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_GREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_GREP="$ac_path_GREP"
+ ac_path_GREP_max=$ac_count
fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_GREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_GREP"; then
+ as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_GREP=$GREP
fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
-echo "${ECHO_T}$ac_cv_prog_egrep" >&6
- EGREP=$ac_cv_prog_egrep
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5
+$as_echo "$ac_cv_path_GREP" >&6; }
+ GREP="$ac_cv_path_GREP"
-echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
-if test "${ac_cv_header_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5
+$as_echo_n "checking for egrep... " >&6; }
+if ${ac_cv_path_EGREP+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ if echo a | $GREP -E '(a|b)' >/dev/null 2>&1
+ then ac_cv_path_EGREP="$GREP -E"
+ else
+ if test -z "$EGREP"; then
+ ac_path_EGREP_found=false
+ # Loop through the user's path and test for each of PROGNAME-LIST
+ as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_prog in egrep; do
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
+ as_fn_executable_p "$ac_path_EGREP" || continue
+# Check for GNU ac_path_EGREP and select it if it is found.
+ # Check for GNU $ac_path_EGREP
+case `"$ac_path_EGREP" --version 2>&1` in
+*GNU*)
+ ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;;
+*)
+ ac_count=0
+ $as_echo_n 0123456789 >"conftest.in"
+ while :
+ do
+ cat "conftest.in" "conftest.in" >"conftest.tmp"
+ mv "conftest.tmp" "conftest.in"
+ cp "conftest.in" "conftest.nl"
+ $as_echo 'EGREP' >> "conftest.nl"
+ "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break
+ diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break
+ as_fn_arith $ac_count + 1 && ac_count=$as_val
+ if test $ac_count -gt ${ac_path_EGREP_max-0}; then
+ # Best one so far, save it but keep looking for a better one
+ ac_cv_path_EGREP="$ac_path_EGREP"
+ ac_path_EGREP_max=$ac_count
+ fi
+ # 10*(2^10) chars as input seems more than enough
+ test $ac_count -gt 10 && break
+ done
+ rm -f conftest.in conftest.tmp conftest.nl conftest.out;;
+esac
+
+ $ac_path_EGREP_found && break 3
+ done
+ done
+ done
+IFS=$as_save_IFS
+ if test -z "$ac_cv_path_EGREP"; then
+ as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+ fi
+else
+ ac_cv_path_EGREP=$EGREP
+fi
+
+ fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5
+$as_echo "$ac_cv_path_EGREP" >&6; }
+ EGREP="$ac_cv_path_EGREP"
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5
+$as_echo_n "checking for ANSI C header files... " >&6; }
+if ${ac_cv_header_stdc+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdlib.h>
#include <stdarg.h>
@@ -2740,51 +3631,23 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_header_stdc=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_header_stdc=no
+ ac_cv_header_stdc=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
if test $ac_cv_header_stdc = yes; then
# SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <string.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then
- :
+ $EGREP "memchr" >/dev/null 2>&1; then :
+
else
ac_cv_header_stdc=no
fi
@@ -2794,18 +3657,14 @@ fi
if test $ac_cv_header_stdc = yes; then
# ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdlib.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then
- :
+ $EGREP "free" >/dev/null 2>&1; then :
+
else
ac_cv_header_stdc=no
fi
@@ -2815,16 +3674,13 @@ fi
if test $ac_cv_header_stdc = yes; then
# /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then
+ if test "$cross_compiling" = yes; then :
:
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <ctype.h>
+#include <stdlib.h>
#if ((' ' & 0x0FF) == 0x020)
# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
@@ -2844,109 +3700,39 @@ main ()
for (i = 0; i < 256; i++)
if (XOR (islower (i), ISLOWER (i))
|| toupper (i) != TOUPPER (i))
- exit(2);
- exit (0);
+ return 2;
+ return 0;
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+if ac_fn_c_try_run "$LINENO"; then :
-( exit $ac_status )
-ac_cv_header_stdc=no
+else
+ ac_cv_header_stdc=no
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+
fi
fi
-echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5
+$as_echo "$ac_cv_header_stdc" >&6; }
if test $ac_cv_header_stdc = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
+$as_echo "#define STDC_HEADERS 1" >>confdefs.h
fi
# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_Header=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_Header=no"
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+do :
+ as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
+ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default
+"
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1
_ACEOF
fi
@@ -2955,17 +3741,13 @@ done
- echo "$as_me:$LINENO: checking dirent.h" >&5
-echo $ECHO_N "checking dirent.h... $ECHO_C" >&6
-if test "${tcl_cv_dirent_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking dirent.h" >&5
+$as_echo_n "checking dirent.h... " >&6; }
+if ${tcl_cv_dirent_h+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
#include <dirent.h>
@@ -2995,535 +3777,85 @@ closedir(d);
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_dirent_h=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_dirent_h=no
+ tcl_cv_dirent_h=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_dirent_h" >&5
-echo "${ECHO_T}$tcl_cv_dirent_h" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_dirent_h" >&5
+$as_echo "$tcl_cv_dirent_h" >&6; }
if test $tcl_cv_dirent_h = no; then
-cat >>confdefs.h <<\_ACEOF
-#define NO_DIRENT_H 1
-_ACEOF
+$as_echo "#define NO_DIRENT_H 1" >>confdefs.h
fi
- if test "${ac_cv_header_float_h+set}" = set; then
- echo "$as_me:$LINENO: checking for float.h" >&5
-echo $ECHO_N "checking for float.h... $ECHO_C" >&6
-if test "${ac_cv_header_float_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
-echo "${ECHO_T}$ac_cv_header_float_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking float.h usability" >&5
-echo $ECHO_N "checking float.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <float.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
+ ac_fn_c_check_header_mongrel "$LINENO" "float.h" "ac_cv_header_float_h" "$ac_includes_default"
+if test "x$ac_cv_header_float_h" = xyes; then :
-# Is the header present?
-echo "$as_me:$LINENO: checking float.h presence" >&5
-echo $ECHO_N "checking float.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <float.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: float.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: float.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: float.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: float.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: float.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: float.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: float.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: float.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: float.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: float.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: float.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: float.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: float.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for float.h" >&5
-echo $ECHO_N "checking for float.h... $ECHO_C" >&6
-if test "${ac_cv_header_float_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_float_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_float_h" >&5
-echo "${ECHO_T}$ac_cv_header_float_h" >&6
+$as_echo "#define NO_FLOAT_H 1" >>confdefs.h
fi
-if test $ac_cv_header_float_h = yes; then
- :
-else
-
-cat >>confdefs.h <<\_ACEOF
-#define NO_FLOAT_H 1
-_ACEOF
-fi
+ ac_fn_c_check_header_mongrel "$LINENO" "values.h" "ac_cv_header_values_h" "$ac_includes_default"
+if test "x$ac_cv_header_values_h" = xyes; then :
- if test "${ac_cv_header_values_h+set}" = set; then
- echo "$as_me:$LINENO: checking for values.h" >&5
-echo $ECHO_N "checking for values.h... $ECHO_C" >&6
-if test "${ac_cv_header_values_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
-echo "${ECHO_T}$ac_cv_header_values_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking values.h usability" >&5
-echo $ECHO_N "checking values.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <values.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
+$as_echo "#define NO_VALUES_H 1" >>confdefs.h
-# Is the header present?
-echo "$as_me:$LINENO: checking values.h presence" >&5
-echo $ECHO_N "checking values.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <values.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: values.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: values.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: values.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: values.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: values.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: values.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: values.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: values.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: values.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: values.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: values.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: values.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: values.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for values.h" >&5
-echo $ECHO_N "checking for values.h... $ECHO_C" >&6
-if test "${ac_cv_header_values_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_values_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_values_h" >&5
-echo "${ECHO_T}$ac_cv_header_values_h" >&6
-
-fi
-if test $ac_cv_header_values_h = yes; then
- :
-else
-
-cat >>confdefs.h <<\_ACEOF
-#define NO_VALUES_H 1
-_ACEOF
-
-fi
-
-
- if test "${ac_cv_header_stdlib_h+set}" = set; then
- echo "$as_me:$LINENO: checking for stdlib.h" >&5
-echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
-if test "${ac_cv_header_stdlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking stdlib.h usability" >&5
-echo $ECHO_N "checking stdlib.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <stdlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking stdlib.h presence" >&5
-echo $ECHO_N "checking stdlib.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: stdlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: stdlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: stdlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: stdlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: stdlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: stdlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: stdlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: stdlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: stdlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: stdlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: stdlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: stdlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: stdlib.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for stdlib.h" >&5
-echo $ECHO_N "checking for stdlib.h... $ECHO_C" >&6
-if test "${ac_cv_header_stdlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_stdlib_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_stdlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_stdlib_h" >&6
-fi
-if test $ac_cv_header_stdlib_h = yes; then
+ ac_fn_c_check_header_mongrel "$LINENO" "stdlib.h" "ac_cv_header_stdlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_stdlib_h" = xyes; then :
tcl_ok=1
else
tcl_ok=0
fi
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdlib.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "strtol" >/dev/null 2>&1; then
- :
+ $EGREP "strtol" >/dev/null 2>&1; then :
+
else
tcl_ok=0
fi
rm -f conftest*
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdlib.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "strtoul" >/dev/null 2>&1; then
- :
+ $EGREP "strtoul" >/dev/null 2>&1; then :
+
else
tcl_ok=0
fi
rm -f conftest*
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdlib.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "strtod" >/dev/null 2>&1; then
- :
+ $EGREP "strtod" >/dev/null 2>&1; then :
+
else
tcl_ok=0
fi
@@ -3531,184 +3863,45 @@ rm -f conftest*
if test $tcl_ok = 0; then
-cat >>confdefs.h <<\_ACEOF
-#define NO_STDLIB_H 1
-_ACEOF
+$as_echo "#define NO_STDLIB_H 1" >>confdefs.h
fi
- if test "${ac_cv_header_string_h+set}" = set; then
- echo "$as_me:$LINENO: checking for string.h" >&5
-echo $ECHO_N "checking for string.h... $ECHO_C" >&6
-if test "${ac_cv_header_string_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
-echo "${ECHO_T}$ac_cv_header_string_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking string.h usability" >&5
-echo $ECHO_N "checking string.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <string.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
+ ac_fn_c_check_header_mongrel "$LINENO" "string.h" "ac_cv_header_string_h" "$ac_includes_default"
+if test "x$ac_cv_header_string_h" = xyes; then :
+ tcl_ok=1
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
+ tcl_ok=0
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-# Is the header present?
-echo "$as_me:$LINENO: checking string.h presence" >&5
-echo $ECHO_N "checking string.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <string.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
+ ac_fn_c_check_header_mongrel "$LINENO" "strings.h" "ac_cv_header_strings_h" "$ac_includes_default"
+if test "x$ac_cv_header_strings_h" = xyes; then :
+ $as_echo "#define HAVE_STRINGS_H 1" >>confdefs.h
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: string.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: string.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: string.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: string.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: string.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: string.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: string.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: string.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: string.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: string.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: string.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: string.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: string.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for string.h" >&5
-echo $ECHO_N "checking for string.h... $ECHO_C" >&6
-if test "${ac_cv_header_string_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_string_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_string_h" >&5
-echo "${ECHO_T}$ac_cv_header_string_h" >&6
-
-fi
-if test $ac_cv_header_string_h = yes; then
- tcl_ok=1
-else
- tcl_ok=0
fi
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <string.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "strstr" >/dev/null 2>&1; then
- :
+ $EGREP "strstr" >/dev/null 2>&1; then :
+
else
tcl_ok=0
fi
rm -f conftest*
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <string.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "strerror" >/dev/null 2>&1; then
- :
+ $EGREP "strerror" >/dev/null 2>&1; then :
+
else
tcl_ok=0
fi
@@ -3720,454 +3913,38 @@ rm -f conftest*
if test $tcl_ok = 0; then
-cat >>confdefs.h <<\_ACEOF
-#define NO_STRING_H 1
-_ACEOF
+$as_echo "#define NO_STRING_H 1" >>confdefs.h
fi
- if test "${ac_cv_header_sys_wait_h+set}" = set; then
- echo "$as_me:$LINENO: checking for sys/wait.h" >&5
-echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
-if test "${ac_cv_header_sys_wait_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking sys/wait.h usability" >&5
-echo $ECHO_N "checking sys/wait.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <sys/wait.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking sys/wait.h presence" >&5
-echo $ECHO_N "checking sys/wait.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/wait.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/wait.h" "ac_cv_header_sys_wait_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_wait_h" = xyes; then :
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: sys/wait.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: sys/wait.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: sys/wait.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: sys/wait.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/wait.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: sys/wait.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/wait.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: sys/wait.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: sys/wait.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: sys/wait.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: sys/wait.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for sys/wait.h" >&5
-echo $ECHO_N "checking for sys/wait.h... $ECHO_C" >&6
-if test "${ac_cv_header_sys_wait_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_sys_wait_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_sys_wait_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_wait_h" >&6
-
-fi
-if test $ac_cv_header_sys_wait_h = yes; then
- :
else
-cat >>confdefs.h <<\_ACEOF
-#define NO_SYS_WAIT_H 1
-_ACEOF
+$as_echo "#define NO_SYS_WAIT_H 1" >>confdefs.h
fi
- if test "${ac_cv_header_dlfcn_h+set}" = set; then
- echo "$as_me:$LINENO: checking for dlfcn.h" >&5
-echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
-if test "${ac_cv_header_dlfcn_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
-echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking dlfcn.h usability" >&5
-echo $ECHO_N "checking dlfcn.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <dlfcn.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ ac_fn_c_check_header_mongrel "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default"
+if test "x$ac_cv_header_dlfcn_h" = xyes; then :
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking dlfcn.h presence" >&5
-echo $ECHO_N "checking dlfcn.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <dlfcn.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: dlfcn.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: dlfcn.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: dlfcn.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: dlfcn.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: dlfcn.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: dlfcn.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: dlfcn.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: dlfcn.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: dlfcn.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: dlfcn.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: dlfcn.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for dlfcn.h" >&5
-echo $ECHO_N "checking for dlfcn.h... $ECHO_C" >&6
-if test "${ac_cv_header_dlfcn_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_dlfcn_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_dlfcn_h" >&5
-echo "${ECHO_T}$ac_cv_header_dlfcn_h" >&6
-
-fi
-if test $ac_cv_header_dlfcn_h = yes; then
- :
else
-cat >>confdefs.h <<\_ACEOF
-#define NO_DLFCN_H 1
-_ACEOF
+$as_echo "#define NO_DLFCN_H 1" >>confdefs.h
fi
# OS/390 lacks sys/param.h (and doesn't need it, by chance).
-
-for ac_header in sys/param.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ for ac_header in sys/param.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_param_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_SYS_PARAM_H 1
_ACEOF
fi
@@ -4188,18 +3965,14 @@ done
#------------------------------------------------------------------------
if test -z "$no_pipe" && test -n "$GCC"; then
- echo "$as_me:$LINENO: checking if the compiler understands -pipe" >&5
-echo $ECHO_N "checking if the compiler understands -pipe... $ECHO_C" >&6
-if test "${tcl_cv_cc_pipe+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if the compiler understands -pipe" >&5
+$as_echo_n "checking if the compiler understands -pipe... " >&6; }
+if ${tcl_cv_cc_pipe+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -4210,40 +3983,16 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_cc_pipe=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cc_pipe=no
+ tcl_cv_cc_pipe=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS=$hold_cflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cc_pipe" >&5
-echo "${ECHO_T}$tcl_cv_cc_pipe" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_pipe" >&5
+$as_echo "$tcl_cv_cc_pipe" >&6; }
if test $tcl_cv_cc_pipe = yes; then
CFLAGS="$CFLAGS -pipe"
fi
@@ -4254,13 +4003,13 @@ fi
#------------------------------------------------------------------------
- # Check whether --enable-threads or --disable-threads was given.
-if test "${enable_threads+set}" = set; then
- enableval="$enable_threads"
- tcl_ok=$enableval
+ # Check whether --enable-threads was given.
+if test "${enable_threads+set}" = set; then :
+ enableval=$enable_threads; tcl_ok=$enableval
else
tcl_ok=yes
-fi;
+fi
+
if test "${TCL_THREADS}" = 1; then
tcl_threaded_core=1;
@@ -4271,92 +4020,56 @@ fi;
# USE_THREAD_ALLOC tells us to try the special thread-based
# allocator that significantly reduces lock contention
-cat >>confdefs.h <<\_ACEOF
-#define USE_THREAD_ALLOC 1
-_ACEOF
+$as_echo "#define USE_THREAD_ALLOC 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define _REENTRANT 1
-_ACEOF
+$as_echo "#define _REENTRANT 1" >>confdefs.h
if test "`uname -s`" = "SunOS" ; then
-cat >>confdefs.h <<\_ACEOF
-#define _POSIX_PTHREAD_SEMANTICS 1
-_ACEOF
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
fi
-cat >>confdefs.h <<\_ACEOF
-#define _THREAD_SAFE 1
-_ACEOF
+$as_echo "#define _THREAD_SAFE 1" >>confdefs.h
- echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthread" >&5
-echo $ECHO_N "checking for pthread_mutex_init in -lpthread... $ECHO_C" >&6
-if test "${ac_cv_lib_pthread_pthread_mutex_init+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthread" >&5
+$as_echo_n "checking for pthread_mutex_init in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread_pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lpthread $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char pthread_mutex_init ();
int
main ()
{
-pthread_mutex_init ();
+return pthread_mutex_init ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_pthread_pthread_mutex_init=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_pthread_pthread_mutex_init=no
+ ac_cv_lib_pthread_pthread_mutex_init=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
-echo "${ECHO_T}$ac_cv_lib_pthread_pthread_mutex_init" >&6
-if test $ac_cv_lib_pthread_pthread_mutex_init = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthread_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthread_pthread_mutex_init" = xyes; then :
tcl_ok=yes
else
tcl_ok=no
@@ -4368,71 +4081,43 @@ fi
# defined. We could alternatively do an AC_TRY_COMPILE with
# pthread.h, but that will work with libpthread really doesn't
# exist, like AIX 4.2. [Bug: 4359]
- echo "$as_me:$LINENO: checking for __pthread_mutex_init in -lpthread" >&5
-echo $ECHO_N "checking for __pthread_mutex_init in -lpthread... $ECHO_C" >&6
-if test "${ac_cv_lib_pthread___pthread_mutex_init+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for __pthread_mutex_init in -lpthread" >&5
+$as_echo_n "checking for __pthread_mutex_init in -lpthread... " >&6; }
+if ${ac_cv_lib_pthread___pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lpthread $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char __pthread_mutex_init ();
int
main ()
{
-__pthread_mutex_init ();
+return __pthread_mutex_init ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_pthread___pthread_mutex_init=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_pthread___pthread_mutex_init=no
+ ac_cv_lib_pthread___pthread_mutex_init=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
-echo "${ECHO_T}$ac_cv_lib_pthread___pthread_mutex_init" >&6
-if test $ac_cv_lib_pthread___pthread_mutex_init = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthread___pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthread___pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthread___pthread_mutex_init" = xyes; then :
tcl_ok=yes
else
tcl_ok=no
@@ -4444,71 +4129,43 @@ fi
# The space is needed
THREADS_LIBS=" -lpthread"
else
- echo "$as_me:$LINENO: checking for pthread_mutex_init in -lpthreads" >&5
-echo $ECHO_N "checking for pthread_mutex_init in -lpthreads... $ECHO_C" >&6
-if test "${ac_cv_lib_pthreads_pthread_mutex_init+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lpthreads" >&5
+$as_echo_n "checking for pthread_mutex_init in -lpthreads... " >&6; }
+if ${ac_cv_lib_pthreads_pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lpthreads $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char pthread_mutex_init ();
int
main ()
{
-pthread_mutex_init ();
+return pthread_mutex_init ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_pthreads_pthread_mutex_init=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_pthreads_pthread_mutex_init=no
+ ac_cv_lib_pthreads_pthread_mutex_init=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
-echo "${ECHO_T}$ac_cv_lib_pthreads_pthread_mutex_init" >&6
-if test $ac_cv_lib_pthreads_pthread_mutex_init = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_pthreads_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_pthreads_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_pthreads_pthread_mutex_init" = xyes; then :
tcl_ok=yes
else
tcl_ok=no
@@ -4518,142 +4175,86 @@ fi
# The space is needed
THREADS_LIBS=" -lpthreads"
else
- echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc" >&5
-echo $ECHO_N "checking for pthread_mutex_init in -lc... $ECHO_C" >&6
-if test "${ac_cv_lib_c_pthread_mutex_init+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc" >&5
+$as_echo_n "checking for pthread_mutex_init in -lc... " >&6; }
+if ${ac_cv_lib_c_pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lc $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char pthread_mutex_init ();
int
main ()
{
-pthread_mutex_init ();
+return pthread_mutex_init ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_c_pthread_mutex_init=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_c_pthread_mutex_init=no
+ ac_cv_lib_c_pthread_mutex_init=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_c_pthread_mutex_init" >&5
-echo "${ECHO_T}$ac_cv_lib_c_pthread_mutex_init" >&6
-if test $ac_cv_lib_c_pthread_mutex_init = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_c_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_c_pthread_mutex_init" = xyes; then :
tcl_ok=yes
else
tcl_ok=no
fi
if test "$tcl_ok" = "no"; then
- echo "$as_me:$LINENO: checking for pthread_mutex_init in -lc_r" >&5
-echo $ECHO_N "checking for pthread_mutex_init in -lc_r... $ECHO_C" >&6
-if test "${ac_cv_lib_c_r_pthread_mutex_init+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pthread_mutex_init in -lc_r" >&5
+$as_echo_n "checking for pthread_mutex_init in -lc_r... " >&6; }
+if ${ac_cv_lib_c_r_pthread_mutex_init+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lc_r $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char pthread_mutex_init ();
int
main ()
{
-pthread_mutex_init ();
+return pthread_mutex_init ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_c_r_pthread_mutex_init=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_c_r_pthread_mutex_init=no
+ ac_cv_lib_c_r_pthread_mutex_init=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
-echo "${ECHO_T}$ac_cv_lib_c_r_pthread_mutex_init" >&6
-if test $ac_cv_lib_c_r_pthread_mutex_init = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_c_r_pthread_mutex_init" >&5
+$as_echo "$ac_cv_lib_c_r_pthread_mutex_init" >&6; }
+if test "x$ac_cv_lib_c_r_pthread_mutex_init" = xyes; then :
tcl_ok=yes
else
tcl_ok=no
@@ -4664,8 +4265,8 @@ fi
THREADS_LIBS=" -pthread"
else
TCL_THREADS=0
- { echo "$as_me:$LINENO: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&5
-echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&5
+$as_echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you must disable thread support or edit the LIBS in the Makefile..." >&2;}
fi
fi
fi
@@ -4676,104 +4277,13 @@ echo "$as_me: WARNING: Don't know how to find pthread lib on your system - you m
ac_saved_libs=$LIBS
LIBS="$LIBS $THREADS_LIBS"
-
-
-for ac_func in pthread_attr_setstacksize pthread_atfork
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+ for ac_func in pthread_attr_setstacksize pthread_atfork
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
@@ -4784,24 +4294,22 @@ done
TCL_THREADS=0
fi
# Do checking message here to not mess up interleaved configure output
- echo "$as_me:$LINENO: checking for building with threads" >&5
-echo $ECHO_N "checking for building with threads... $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for building with threads" >&5
+$as_echo_n "checking for building with threads... " >&6; }
if test "${TCL_THREADS}" = 1; then
-cat >>confdefs.h <<\_ACEOF
-#define TCL_THREADS 1
-_ACEOF
+$as_echo "#define TCL_THREADS 1" >>confdefs.h
if test "${tcl_threaded_core}" = 1; then
- echo "$as_me:$LINENO: result: yes (threaded core)" >&5
-echo "${ECHO_T}yes (threaded core)" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (threaded core)" >&5
+$as_echo "yes (threaded core)" >&6; }
else
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
fi
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
@@ -4813,11 +4321,11 @@ echo "${ECHO_T}no" >&6
-# Check whether --with-encoding or --without-encoding was given.
-if test "${with_encoding+set}" = set; then
- withval="$with_encoding"
- with_tcencoding=${withval}
-fi;
+# Check whether --with-encoding was given.
+if test "${with_encoding+set}" = set; then :
+ withval=$with_encoding; with_tcencoding=${withval}
+fi
+
if test x"${with_tcencoding}" != x ; then
@@ -4827,9 +4335,7 @@ _ACEOF
else
-cat >>confdefs.h <<\_ACEOF
-#define TCL_CFGVAL_ENCODING "iso8859-1"
-_ACEOF
+$as_echo "#define TCL_CFGVAL_ENCODING \"iso8859-1\"" >>confdefs.h
fi
@@ -4846,161 +4352,44 @@ _ACEOF
# right (and it must appear before "-lm").
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for sin" >&5
-echo $ECHO_N "checking for sin... $ECHO_C" >&6
-if test "${ac_cv_func_sin+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define sin to an innocuous variant, in case <limits.h> declares sin.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define sin innocuous_sin
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char sin (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef sin
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char sin ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_sin) || defined (__stub___sin)
-choke me
-#else
-char (*f) () = sin;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != sin;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_sin=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_sin=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_sin" >&5
-echo "${ECHO_T}$ac_cv_func_sin" >&6
-if test $ac_cv_func_sin = yes; then
+ ac_fn_c_check_func "$LINENO" "sin" "ac_cv_func_sin"
+if test "x$ac_cv_func_sin" = xyes; then :
MATH_LIBS=""
else
MATH_LIBS="-lm"
fi
- echo "$as_me:$LINENO: checking for main in -lieee" >&5
-echo $ECHO_N "checking for main in -lieee... $ECHO_C" >&6
-if test "${ac_cv_lib_ieee_main+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -lieee" >&5
+$as_echo_n "checking for main in -lieee... " >&6; }
+if ${ac_cv_lib_ieee_main+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lieee $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
-main ();
+return main ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_ieee_main=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_ieee_main=no
+ ac_cv_lib_ieee_main=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_ieee_main" >&5
-echo "${ECHO_T}$ac_cv_lib_ieee_main" >&6
-if test $ac_cv_lib_ieee_main = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ieee_main" >&5
+$as_echo "$ac_cv_lib_ieee_main" >&6; }
+if test "x$ac_cv_lib_ieee_main" = xyes; then :
MATH_LIBS="-lieee $MATH_LIBS"
fi
@@ -5010,211 +4399,45 @@ fi
# needs net/errno.h to define the socket-related error codes.
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for main in -linet" >&5
-echo $ECHO_N "checking for main in -linet... $ECHO_C" >&6
-if test "${ac_cv_lib_inet_main+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for main in -linet" >&5
+$as_echo_n "checking for main in -linet... " >&6; }
+if ${ac_cv_lib_inet_main+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-linet $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
main ()
{
-main ();
+return main ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_inet_main=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_inet_main=no
+ ac_cv_lib_inet_main=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_inet_main" >&5
-echo "${ECHO_T}$ac_cv_lib_inet_main" >&6
-if test $ac_cv_lib_inet_main = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_main" >&5
+$as_echo "$ac_cv_lib_inet_main" >&6; }
+if test "x$ac_cv_lib_inet_main" = xyes; then :
LIBS="$LIBS -linet"
fi
- if test "${ac_cv_header_net_errno_h+set}" = set; then
- echo "$as_me:$LINENO: checking for net/errno.h" >&5
-echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
-if test "${ac_cv_header_net_errno_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
-echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking net/errno.h usability" >&5
-echo $ECHO_N "checking net/errno.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <net/errno.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking net/errno.h presence" >&5
-echo $ECHO_N "checking net/errno.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <net/errno.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: net/errno.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: net/errno.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: net/errno.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: net/errno.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: net/errno.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: net/errno.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: net/errno.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: net/errno.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: net/errno.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: net/errno.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: net/errno.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: net/errno.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: net/errno.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for net/errno.h" >&5
-echo $ECHO_N "checking for net/errno.h... $ECHO_C" >&6
-if test "${ac_cv_header_net_errno_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_net_errno_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_net_errno_h" >&5
-echo "${ECHO_T}$ac_cv_header_net_errno_h" >&6
-
-fi
-if test $ac_cv_header_net_errno_h = yes; then
+ ac_fn_c_check_header_mongrel "$LINENO" "net/errno.h" "ac_cv_header_net_errno_h" "$ac_includes_default"
+if test "x$ac_cv_header_net_errno_h" = xyes; then :
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_NET_ERRNO_H 1
-_ACEOF
+$as_echo "#define HAVE_NET_ERRNO_H 1" >>confdefs.h
fi
@@ -5239,261 +4462,55 @@ fi
#--------------------------------------------------------------------
tcl_checkBoth=0
- echo "$as_me:$LINENO: checking for connect" >&5
-echo $ECHO_N "checking for connect... $ECHO_C" >&6
-if test "${ac_cv_func_connect+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define connect to an innocuous variant, in case <limits.h> declares connect.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define connect innocuous_connect
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char connect (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef connect
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char connect ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_connect) || defined (__stub___connect)
-choke me
-#else
-char (*f) () = connect;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != connect;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_connect=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_connect=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_connect" >&5
-echo "${ECHO_T}$ac_cv_func_connect" >&6
-if test $ac_cv_func_connect = yes; then
+ ac_fn_c_check_func "$LINENO" "connect" "ac_cv_func_connect"
+if test "x$ac_cv_func_connect" = xyes; then :
tcl_checkSocket=0
else
tcl_checkSocket=1
fi
if test "$tcl_checkSocket" = 1; then
- echo "$as_me:$LINENO: checking for setsockopt" >&5
-echo $ECHO_N "checking for setsockopt... $ECHO_C" >&6
-if test "${ac_cv_func_setsockopt+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define setsockopt to an innocuous variant, in case <limits.h> declares setsockopt.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define setsockopt innocuous_setsockopt
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char setsockopt (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef setsockopt
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char setsockopt ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_setsockopt) || defined (__stub___setsockopt)
-choke me
-#else
-char (*f) () = setsockopt;
-#endif
-#ifdef __cplusplus
-}
-#endif
+ ac_fn_c_check_func "$LINENO" "setsockopt" "ac_cv_func_setsockopt"
+if test "x$ac_cv_func_setsockopt" = xyes; then :
-int
-main ()
-{
-return f != setsockopt;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_setsockopt=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_setsockopt=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_setsockopt" >&5
-echo "${ECHO_T}$ac_cv_func_setsockopt" >&6
-if test $ac_cv_func_setsockopt = yes; then
- :
-else
- echo "$as_me:$LINENO: checking for setsockopt in -lsocket" >&5
-echo $ECHO_N "checking for setsockopt in -lsocket... $ECHO_C" >&6
-if test "${ac_cv_lib_socket_setsockopt+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for setsockopt in -lsocket" >&5
+$as_echo_n "checking for setsockopt in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_setsockopt+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lsocket $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char setsockopt ();
int
main ()
{
-setsockopt ();
+return setsockopt ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_socket_setsockopt=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_socket_setsockopt=no
+ ac_cv_lib_socket_setsockopt=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_socket_setsockopt" >&5
-echo "${ECHO_T}$ac_cv_lib_socket_setsockopt" >&6
-if test $ac_cv_lib_socket_setsockopt = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_setsockopt" >&5
+$as_echo "$ac_cv_lib_socket_setsockopt" >&6; }
+if test "x$ac_cv_lib_socket_setsockopt" = xyes; then :
LIBS="$LIBS -lsocket"
else
tcl_checkBoth=1
@@ -5505,281 +4522,131 @@ fi
if test "$tcl_checkBoth" = 1; then
tk_oldLibs=$LIBS
LIBS="$LIBS -lsocket -lnsl"
- echo "$as_me:$LINENO: checking for accept" >&5
-echo $ECHO_N "checking for accept... $ECHO_C" >&6
-if test "${ac_cv_func_accept+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define accept to an innocuous variant, in case <limits.h> declares accept.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define accept innocuous_accept
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char accept (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef accept
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char accept ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_accept) || defined (__stub___accept)
-choke me
-#else
-char (*f) () = accept;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != accept;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_accept=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_accept=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_accept" >&5
-echo "${ECHO_T}$ac_cv_func_accept" >&6
-if test $ac_cv_func_accept = yes; then
+ ac_fn_c_check_func "$LINENO" "accept" "ac_cv_func_accept"
+if test "x$ac_cv_func_accept" = xyes; then :
tcl_checkNsl=0
else
LIBS=$tk_oldLibs
fi
fi
- echo "$as_me:$LINENO: checking for gethostbyname" >&5
-echo $ECHO_N "checking for gethostbyname... $ECHO_C" >&6
-if test "${ac_cv_func_gethostbyname+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ ac_fn_c_check_func "$LINENO" "gethostbyname" "ac_cv_func_gethostbyname"
+if test "x$ac_cv_func_gethostbyname" = xyes; then :
+
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname in -lnsl" >&5
+$as_echo_n "checking for gethostbyname in -lnsl... " >&6; }
+if ${ac_cv_lib_nsl_gethostbyname+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_check_lib_save_LIBS=$LIBS
+LIBS="-lnsl $LIBS"
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Define gethostbyname to an innocuous variant, in case <limits.h> declares gethostbyname.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define gethostbyname innocuous_gethostbyname
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char gethostbyname (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef gethostbyname
-
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
-{
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char gethostbyname ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_gethostbyname) || defined (__stub___gethostbyname)
-choke me
-#else
-char (*f) () = gethostbyname;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
int
main ()
{
-return f != gethostbyname;
+return gethostbyname ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_gethostbyname=yes
+if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_lib_nsl_gethostbyname=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_gethostbyname=no
+ ac_cv_lib_nsl_gethostbyname=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname" >&5
-echo "${ECHO_T}$ac_cv_func_gethostbyname" >&6
-if test $ac_cv_func_gethostbyname = yes; then
- :
-else
- echo "$as_me:$LINENO: checking for gethostbyname in -lnsl" >&5
-echo $ECHO_N "checking for gethostbyname in -lnsl... $ECHO_C" >&6
-if test "${ac_cv_lib_nsl_gethostbyname+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_nsl_gethostbyname" >&5
+$as_echo "$ac_cv_lib_nsl_gethostbyname" >&6; }
+if test "x$ac_cv_lib_nsl_gethostbyname" = xyes; then :
+ LIBS="$LIBS -lnsl"
+fi
+
+fi
+
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing inet_aton" >&5
+$as_echo_n "checking for library containing inet_aton... " >&6; }
+if ${ac_cv_search_inet_aton+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- ac_check_lib_save_LIBS=$LIBS
-LIBS="-lnsl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char gethostbyname ();
+char inet_aton ();
int
main ()
{
-gethostbyname ();
+return inet_aton ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_lib_nsl_gethostbyname=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_nsl_gethostbyname=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-LIBS=$ac_check_lib_save_LIBS
+for ac_lib in '' resolv; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_inet_aton=$ac_res
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_nsl_gethostbyname" >&5
-echo "${ECHO_T}$ac_cv_lib_nsl_gethostbyname" >&6
-if test $ac_cv_lib_nsl_gethostbyname = yes; then
- LIBS="$LIBS -lnsl"
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_inet_aton+:} false; then :
+ break
fi
+done
+if ${ac_cv_search_inet_aton+:} false; then :
+else
+ ac_cv_search_inet_aton=no
fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_inet_aton" >&5
+$as_echo "$ac_cv_search_inet_aton" >&6; }
+ac_res=$ac_cv_search_inet_aton
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+fi
# Add the threads support libraries
LIBS="$LIBS$THREADS_LIBS"
- echo "$as_me:$LINENO: checking how to build libraries" >&5
-echo $ECHO_N "checking how to build libraries... $ECHO_C" >&6
- # Check whether --enable-shared or --disable-shared was given.
-if test "${enable_shared+set}" = set; then
- enableval="$enable_shared"
- tcl_ok=$enableval
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to build libraries" >&5
+$as_echo_n "checking how to build libraries... " >&6; }
+ # Check whether --enable-shared was given.
+if test "${enable_shared+set}" = set; then :
+ enableval=$enable_shared; tcl_ok=$enableval
else
tcl_ok=yes
-fi;
+fi
+
if test "${enable_shared+set}" = set; then
enableval="$enable_shared"
@@ -5789,17 +4656,15 @@ fi;
fi
if test "$tcl_ok" = "yes" ; then
- echo "$as_me:$LINENO: result: shared" >&5
-echo "${ECHO_T}shared" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared" >&5
+$as_echo "shared" >&6; }
SHARED_BUILD=1
else
- echo "$as_me:$LINENO: result: static" >&5
-echo "${ECHO_T}static" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: static" >&5
+$as_echo "static" >&6; }
SHARED_BUILD=0
-cat >>confdefs.h <<\_ACEOF
-#define STATIC_BUILD 1
-_ACEOF
+$as_echo "#define STATIC_BUILD 1" >>confdefs.h
fi
@@ -5811,10 +4676,10 @@ _ACEOF
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for tclsh" >&5
-echo $ECHO_N "checking for tclsh... $ECHO_C" >&6
- if test "${ac_cv_path_tclsh+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for tclsh" >&5
+$as_echo_n "checking for tclsh... " >&6; }
+ if ${ac_cv_path_tclsh+:} false; then :
+ $as_echo_n "(cached) " >&6
else
search_path=`echo ${PATH} | sed -e 's/:/ /g'`
@@ -5835,13 +4700,13 @@ fi
if test -f "$ac_cv_path_tclsh" ; then
TCLSH_PROG="$ac_cv_path_tclsh"
- echo "$as_me:$LINENO: result: $TCLSH_PROG" >&5
-echo "${ECHO_T}$TCLSH_PROG" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_PROG" >&5
+$as_echo "$TCLSH_PROG" >&6; }
else
# It is not an error if an installed version of Tcl can't be located.
TCLSH_PROG=""
- echo "$as_me:$LINENO: result: No tclsh found on PATH" >&5
-echo "${ECHO_T}No tclsh found on PATH" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: No tclsh found on PATH" >&5
+$as_echo "No tclsh found on PATH" >&6; }
fi
@@ -5854,204 +4719,13 @@ fi
#------------------------------------------------------------------------
zlib_ok=yes
-if test "${ac_cv_header_zlib_h+set}" = set; then
- echo "$as_me:$LINENO: checking for zlib.h" >&5
-echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6
-if test "${ac_cv_header_zlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_zlib_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking zlib.h usability" >&5
-echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <zlib.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking zlib.h presence" >&5
-echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <zlib.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default"
+if test "x$ac_cv_header_zlib_h" = xyes; then :
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
+ ac_fn_c_check_type "$LINENO" "gz_header" "ac_cv_type_gz_header" "#include <zlib.h>
+"
+if test "x$ac_cv_type_gz_header" = xyes; then :
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: zlib.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: zlib.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for zlib.h" >&5
-echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6
-if test "${ac_cv_header_zlib_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_zlib_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_zlib_h" >&6
-
-fi
-if test $ac_cv_header_zlib_h = yes; then
-
- echo "$as_me:$LINENO: checking for gz_header" >&5
-echo $ECHO_N "checking for gz_header... $ECHO_C" >&6
-if test "${ac_cv_type_gz_header+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <zlib.h>
-
-int
-main ()
-{
-if ((gz_header *) 0)
- return 0;
-if (sizeof (gz_header))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_gz_header=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_gz_header=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_gz_header" >&5
-echo "${ECHO_T}$ac_cv_type_gz_header" >&6
-if test $ac_cv_type_gz_header = yes; then
- :
else
zlib_ok=no
fi
@@ -6062,131 +4736,61 @@ else
fi
-if test $zlib_ok = yes; then
+if test $zlib_ok = yes; then :
- echo "$as_me:$LINENO: checking for library containing deflateSetHeader" >&5
-echo $ECHO_N "checking for library containing deflateSetHeader... $ECHO_C" >&6
-if test "${ac_cv_search_deflateSetHeader+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflateSetHeader" >&5
+$as_echo_n "checking for library containing deflateSetHeader... " >&6; }
+if ${ac_cv_search_deflateSetHeader+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_func_search_save_LIBS=$LIBS
-ac_cv_search_deflateSetHeader=no
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char deflateSetHeader ();
int
main ()
{
-deflateSetHeader ();
+return deflateSetHeader ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_search_deflateSetHeader="none required"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-if test "$ac_cv_search_deflateSetHeader" = no; then
- for ac_lib in z; do
+for ac_lib in '' z; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
LIBS="-l$ac_lib $ac_func_search_save_LIBS"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_deflateSetHeader=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_deflateSetHeader+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_deflateSetHeader+:} false; then :
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char deflateSetHeader ();
-int
-main ()
-{
-deflateSetHeader ();
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_search_deflateSetHeader="-l$ac_lib"
-break
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- done
+ ac_cv_search_deflateSetHeader=no
fi
+rm conftest.$ac_ext
LIBS=$ac_func_search_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_search_deflateSetHeader" >&5
-echo "${ECHO_T}$ac_cv_search_deflateSetHeader" >&6
-if test "$ac_cv_search_deflateSetHeader" != no; then
- test "$ac_cv_search_deflateSetHeader" = "none required" || LIBS="$ac_cv_search_deflateSetHeader $LIBS"
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflateSetHeader" >&5
+$as_echo "$ac_cv_search_deflateSetHeader" >&6; }
+ac_res=$ac_cv_search_deflateSetHeader
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
else
@@ -6195,8 +4799,7 @@ else
fi
fi
-
-if test $zlib_ok = no; then
+if test $zlib_ok = no; then :
ZLIB_OBJS=\${ZLIB_OBJS}
@@ -6207,10 +4810,7 @@ if test $zlib_ok = no; then
fi
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_ZLIB 1
-_ACEOF
+$as_echo "#define HAVE_ZLIB 1" >>confdefs.h
#--------------------------------------------------------------------
@@ -6222,10 +4822,10 @@ _ACEOF
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args.
set dummy ${ac_tool_prefix}ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$RANLIB"; then
ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test.
@@ -6235,35 +4835,37 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
fi
fi
RANLIB=$ac_cv_prog_RANLIB
if test -n "$RANLIB"; then
- echo "$as_me:$LINENO: result: $RANLIB" >&5
-echo "${ECHO_T}$RANLIB" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5
+$as_echo "$RANLIB" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
+
fi
if test -z "$ac_cv_prog_RANLIB"; then
ac_ct_RANLIB=$RANLIB
# Extract the first word of "ranlib", so it can be a program name with args.
set dummy ranlib; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_RANLIB+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_RANLIB+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_RANLIB"; then
ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test.
@@ -6273,28 +4875,38 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_RANLIB="ranlib"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
- test -z "$ac_cv_prog_ac_ct_RANLIB" && ac_cv_prog_ac_ct_RANLIB=":"
fi
fi
ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB
if test -n "$ac_ct_RANLIB"; then
- echo "$as_me:$LINENO: result: $ac_ct_RANLIB" >&5
-echo "${ECHO_T}$ac_ct_RANLIB" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5
+$as_echo "$ac_ct_RANLIB" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
- RANLIB=$ac_ct_RANLIB
+ if test "x$ac_ct_RANLIB" = x; then
+ RANLIB=":"
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ RANLIB=$ac_ct_RANLIB
+ fi
else
RANLIB="$ac_cv_prog_RANLIB"
fi
@@ -6303,52 +4915,47 @@ fi
# Step 0.a: Enable 64 bit support?
- echo "$as_me:$LINENO: checking if 64bit support is requested" >&5
-echo $ECHO_N "checking if 64bit support is requested... $ECHO_C" >&6
- # Check whether --enable-64bit or --disable-64bit was given.
-if test "${enable_64bit+set}" = set; then
- enableval="$enable_64bit"
- do64bit=$enableval
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit support is requested" >&5
+$as_echo_n "checking if 64bit support is requested... " >&6; }
+ # Check whether --enable-64bit was given.
+if test "${enable_64bit+set}" = set; then :
+ enableval=$enable_64bit; do64bit=$enableval
else
do64bit=no
-fi;
- echo "$as_me:$LINENO: result: $do64bit" >&5
-echo "${ECHO_T}$do64bit" >&6
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bit" >&5
+$as_echo "$do64bit" >&6; }
# Step 0.b: Enable Solaris 64 bit VIS support?
- echo "$as_me:$LINENO: checking if 64bit Sparc VIS support is requested" >&5
-echo $ECHO_N "checking if 64bit Sparc VIS support is requested... $ECHO_C" >&6
- # Check whether --enable-64bit-vis or --disable-64bit-vis was given.
-if test "${enable_64bit_vis+set}" = set; then
- enableval="$enable_64bit_vis"
- do64bitVIS=$enableval
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if 64bit Sparc VIS support is requested" >&5
+$as_echo_n "checking if 64bit Sparc VIS support is requested... " >&6; }
+ # Check whether --enable-64bit-vis was given.
+if test "${enable_64bit_vis+set}" = set; then :
+ enableval=$enable_64bit_vis; do64bitVIS=$enableval
else
do64bitVIS=no
-fi;
- echo "$as_me:$LINENO: result: $do64bitVIS" >&5
-echo "${ECHO_T}$do64bitVIS" >&6
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $do64bitVIS" >&5
+$as_echo "$do64bitVIS" >&6; }
# Force 64bit on with VIS
- if test "$do64bitVIS" = "yes"; then
+ if test "$do64bitVIS" = "yes"; then :
do64bit=yes
fi
-
# Step 0.c: Check if visibility support is available. Do this here so
# that platform specific alternatives can be used below if this fails.
- echo "$as_me:$LINENO: checking if compiler supports visibility \"hidden\"" >&5
-echo $ECHO_N "checking if compiler supports visibility \"hidden\"... $ECHO_C" >&6
-if test "${tcl_cv_cc_visibility_hidden+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler supports visibility \"hidden\"" >&5
+$as_echo_n "checking if compiler supports visibility \"hidden\"... " >&6; }
+if ${tcl_cv_cc_visibility_hidden+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
extern __attribute__((__visibility__("hidden"))) void f(void);
@@ -6361,79 +4968,50 @@ f();
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_cc_visibility_hidden=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cc_visibility_hidden=no
+ tcl_cv_cc_visibility_hidden=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
CFLAGS=$hold_cflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cc_visibility_hidden" >&5
-echo "${ECHO_T}$tcl_cv_cc_visibility_hidden" >&6
- if test $tcl_cv_cc_visibility_hidden = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_visibility_hidden" >&5
+$as_echo "$tcl_cv_cc_visibility_hidden" >&6; }
+ if test $tcl_cv_cc_visibility_hidden = yes; then :
-cat >>confdefs.h <<\_ACEOF
-#define MODULE_SCOPE extern __attribute__((__visibility__("hidden")))
-_ACEOF
+$as_echo "#define MODULE_SCOPE extern __attribute__((__visibility__(\"hidden\")))" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_HIDDEN 1
-_ACEOF
+$as_echo "#define HAVE_HIDDEN 1" >>confdefs.h
fi
-
# Step 0.d: Disable -rpath support?
- echo "$as_me:$LINENO: checking if rpath support is requested" >&5
-echo $ECHO_N "checking if rpath support is requested... $ECHO_C" >&6
- # Check whether --enable-rpath or --disable-rpath was given.
-if test "${enable_rpath+set}" = set; then
- enableval="$enable_rpath"
- doRpath=$enableval
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if rpath support is requested" >&5
+$as_echo_n "checking if rpath support is requested... " >&6; }
+ # Check whether --enable-rpath was given.
+if test "${enable_rpath+set}" = set; then :
+ enableval=$enable_rpath; doRpath=$enableval
else
doRpath=yes
-fi;
- echo "$as_me:$LINENO: result: $doRpath" >&5
-echo "${ECHO_T}$doRpath" >&6
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $doRpath" >&5
+$as_echo "$doRpath" >&6; }
# Step 1: set the variable "system" to hold the name and version number
# for the system.
- echo "$as_me:$LINENO: checking system version" >&5
-echo $ECHO_N "checking system version... $ECHO_C" >&6
-if test "${tcl_cv_sys_version+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5
+$as_echo_n "checking system version... " >&6; }
+if ${tcl_cv_sys_version+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -f /usr/lib/NextStep/software_version; then
@@ -6441,8 +5019,8 @@ else
else
tcl_cv_sys_version=`uname -s`-`uname -r`
if test "$?" -ne 0 ; then
- { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5
-echo "$as_me: WARNING: can't find uname command" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5
+$as_echo "$as_me: WARNING: can't find uname command" >&2;}
tcl_cv_sys_version=unknown
else
# Special check for weird MP-RAS system (uname returns weird
@@ -6458,79 +5036,51 @@ echo "$as_me: WARNING: can't find uname command" >&2;}
fi
fi
-echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5
-echo "${ECHO_T}$tcl_cv_sys_version" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5
+$as_echo "$tcl_cv_sys_version" >&6; }
system=$tcl_cv_sys_version
# Step 2: check for existence of -ldl library. This is needed because
# Linux can use either -ldl or -ldld for dynamic loading.
- echo "$as_me:$LINENO: checking for dlopen in -ldl" >&5
-echo $ECHO_N "checking for dlopen in -ldl... $ECHO_C" >&6
-if test "${ac_cv_lib_dl_dlopen+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5
+$as_echo_n "checking for dlopen in -ldl... " >&6; }
+if ${ac_cv_lib_dl_dlopen+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ldl $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char dlopen ();
int
main ()
{
-dlopen ();
+return dlopen ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_dl_dlopen=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dl_dlopen=no
+ ac_cv_lib_dl_dlopen=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dl_dlopen" >&5
-echo "${ECHO_T}$ac_cv_lib_dl_dlopen" >&6
-if test $ac_cv_lib_dl_dlopen = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5
+$as_echo "$ac_cv_lib_dl_dlopen" >&6; }
+if test "x$ac_cv_lib_dl_dlopen" = xyes; then :
have_dl=yes
else
have_dl=no
@@ -6556,7 +5106,7 @@ fi
ECHO_VERSION='`echo ${VERSION}`'
TCL_LIB_VERSIONS_OK=ok
CFLAGS_DEBUG=-g
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
CFLAGS_OPTIMIZE=-O2
CFLAGS_WARNING="-Wall"
@@ -6567,14 +5117,13 @@ else
CFLAGS_WARNING=""
fi
-
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$AR"; then
ac_cv_prog_AR="$AR" # Let the user override the test.
@@ -6584,35 +5133,37 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_AR="${ac_tool_prefix}ar"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
fi
fi
AR=$ac_cv_prog_AR
if test -n "$AR"; then
- echo "$as_me:$LINENO: result: $AR" >&5
-echo "${ECHO_T}$AR" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5
+$as_echo "$AR" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
+
fi
if test -z "$ac_cv_prog_AR"; then
ac_ct_AR=$AR
# Extract the first word of "ar", so it can be a program name with args.
set dummy ar; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_prog_ac_ct_AR+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_AR+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -n "$ac_ct_AR"; then
ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test.
@@ -6622,27 +5173,38 @@ for as_dir in $PATH
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_prog_ac_ct_AR="ar"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
fi
fi
ac_ct_AR=$ac_cv_prog_ac_ct_AR
if test -n "$ac_ct_AR"; then
- echo "$as_me:$LINENO: result: $ac_ct_AR" >&5
-echo "${ECHO_T}$ac_ct_AR" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5
+$as_echo "$ac_ct_AR" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
- AR=$ac_ct_AR
+ if test "x$ac_ct_AR" = x; then
+ AR=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ AR=$ac_ct_AR
+ fi
else
AR="$ac_cv_prog_AR"
fi
@@ -6652,13 +5214,12 @@ fi
PLAT_OBJS=""
PLAT_SRCS=""
LDAIX_SRC=""
- if test x"${SHLIB_VERSION}" = x; then
+ if test x"${SHLIB_VERSION}" = x; then :
SHLIB_VERSION="1.0"
fi
-
case $system in
AIX-*)
- if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then
+ if test "${TCL_THREADS}" = "1" -a "$GCC" != "yes"; then :
# AIX requires the _r compiler when gcc isn't being used
case "${CC}" in
@@ -6670,11 +5231,10 @@ fi
CC=`echo "$CC" | sed -e 's/^\([^ ]*\)/\1_r/'`
;;
esac
- echo "$as_me:$LINENO: result: Using $CC for compiling with threads" >&5
-echo "${ECHO_T}Using $CC for compiling with threads" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: Using $CC for compiling with threads" >&5
+$as_echo "Using $CC for compiling with threads" >&6; }
fi
-
LIBS="$LIBS -lc"
SHLIB_CFLAGS=""
SHLIB_SUFFIX=".so"
@@ -6687,12 +5247,12 @@ fi
LDAIX_SRC='$(UNIX_DIR)/ldAix'
# Check to enable 64-bit flags for compiler/linker
- if test "$do64bit" = yes; then
+ if test "$do64bit" = yes; then :
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
- { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
-echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
else
@@ -6705,17 +5265,15 @@ else
fi
-
fi
-
- if test "`uname -m`" = ia64; then
+ if test "`uname -m`" = ia64; then :
# AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC
SHLIB_LD="/usr/ccs/bin/ld -G -z text"
# AIX-5 has dl* in libc.so
DL_LIBS=""
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
@@ -6724,12 +5282,11 @@ else
CC_SEARCH_FLAGS='-R${LIB_RUNTIME_DIR}'
fi
-
LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
else
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
SHLIB_LD='${CC} -shared -Wl,-bexpall'
@@ -6739,14 +5296,12 @@ else
LDFLAGS="$LDFLAGS -brtl"
fi
-
SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}"
DL_LIBS="-ldl"
CC_SEARCH_FLAGS='-L${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
fi
-
;;
BeOS*)
SHLIB_CFLAGS="-fPIC"
@@ -6760,71 +5315,43 @@ fi
# -lsocket, even if the network functions are in -lnet which
# is always linked to, for compatibility.
#-----------------------------------------------------------
- echo "$as_me:$LINENO: checking for inet_ntoa in -lbind" >&5
-echo $ECHO_N "checking for inet_ntoa in -lbind... $ECHO_C" >&6
-if test "${ac_cv_lib_bind_inet_ntoa+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lbind" >&5
+$as_echo_n "checking for inet_ntoa in -lbind... " >&6; }
+if ${ac_cv_lib_bind_inet_ntoa+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lbind $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char inet_ntoa ();
int
main ()
{
-inet_ntoa ();
+return inet_ntoa ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_bind_inet_ntoa=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_bind_inet_ntoa=no
+ ac_cv_lib_bind_inet_ntoa=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_bind_inet_ntoa" >&5
-echo "${ECHO_T}$ac_cv_lib_bind_inet_ntoa" >&6
-if test $ac_cv_lib_bind_inet_ntoa = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_bind_inet_ntoa" >&5
+$as_echo "$ac_cv_lib_bind_inet_ntoa" >&6; }
+if test "x$ac_cv_lib_bind_inet_ntoa" = xyes; then :
LIBS="$LIBS -lbind -lsocket"
fi
@@ -6861,16 +5388,12 @@ fi
TCL_NEEDS_EXP_FILE=1
TCL_EXPORT_FILE_SUFFIX='${VERSION}\$\{DBGX\}.dll.a'
SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$@.a"
- echo "$as_me:$LINENO: checking for Cygwin version of gcc" >&5
-echo $ECHO_N "checking for Cygwin version of gcc... $ECHO_C" >&6
-if test "${ac_cv_cygwin+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Cygwin version of gcc" >&5
+$as_echo_n "checking for Cygwin version of gcc... " >&6; }
+if ${ac_cv_cygwin+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifdef __CYGWIN__
@@ -6885,49 +5408,21 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_cygwin=no
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_cygwin=yes
+ ac_cv_cygwin=yes
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_cygwin" >&5
-echo "${ECHO_T}$ac_cv_cygwin" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_cygwin" >&5
+$as_echo "$ac_cv_cygwin" >&6; }
if test "$ac_cv_cygwin" = "no"; then
- { { echo "$as_me:$LINENO: error: ${CC} is not a cygwin compiler." >&5
-echo "$as_me: error: ${CC} is not a cygwin compiler." >&2;}
- { (exit 1); exit 1; }; }
+ as_fn_error $? "${CC} is not a cygwin compiler." "$LINENO" 5
fi
if test "x${TCL_THREADS}" = "x0"; then
- { { echo "$as_me:$LINENO: error: CYGWIN compile is only supported with --enable-threads" >&5
-echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2;}
- { (exit 1); exit 1; }; }
+ as_fn_error $? "CYGWIN compile is only supported with --enable-threads" "$LINENO" 5
fi
do64bit_ok=yes
if test "x${SHARED_BUILD}" = "x1"; then
@@ -6957,71 +5452,43 @@ echo "$as_me: error: CYGWIN compile is only supported with --enable-threads" >&2
SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
DL_OBJS="tclLoadDl.o"
DL_LIBS="-lroot"
- echo "$as_me:$LINENO: checking for inet_ntoa in -lnetwork" >&5
-echo $ECHO_N "checking for inet_ntoa in -lnetwork... $ECHO_C" >&6
-if test "${ac_cv_lib_network_inet_ntoa+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5
+$as_echo_n "checking for inet_ntoa in -lnetwork... " >&6; }
+if ${ac_cv_lib_network_inet_ntoa+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lnetwork $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char inet_ntoa ();
int
main ()
{
-inet_ntoa ();
+return inet_ntoa ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_network_inet_ntoa=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_network_inet_ntoa=no
+ ac_cv_lib_network_inet_ntoa=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_network_inet_ntoa" >&5
-echo "${ECHO_T}$ac_cv_lib_network_inet_ntoa" >&6
-if test $ac_cv_lib_network_inet_ntoa = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_network_inet_ntoa" >&5
+$as_echo "$ac_cv_lib_network_inet_ntoa" >&6; }
+if test "x$ac_cv_lib_network_inet_ntoa" = xyes; then :
LIBS="$LIBS -lnetwork"
fi
@@ -7029,18 +5496,14 @@ fi
HP-UX-*.11.*)
# Use updated header definitions where possible
-cat >>confdefs.h <<\_ACEOF
-#define _XOPEN_SOURCE_EXTENDED 1
-_ACEOF
+$as_echo "#define _XOPEN_SOURCE_EXTENDED 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define _XOPEN_SOURCE 1
-_ACEOF
+$as_echo "#define _XOPEN_SOURCE 1" >>confdefs.h
LIBS="$LIBS -lxnet" # Use the XOPEN network library
- if test "`uname -m`" = ia64; then
+ if test "`uname -m`" = ia64; then :
SHLIB_SUFFIX=".so"
@@ -7049,78 +5512,49 @@ else
SHLIB_SUFFIX=".sl"
fi
-
- echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
-echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ldld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char shl_load ();
int
main ()
{
-shl_load ();
+return shl_load ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_dld_shl_load=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_shl_load=no
+ ac_cv_lib_dld_shl_load=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
-if test $ac_cv_lib_dld_shl_load = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
tcl_ok=yes
else
tcl_ok=no
fi
- if test "$tcl_ok" = yes; then
+ if test "$tcl_ok" = yes; then :
SHLIB_CFLAGS="+z"
SHLIB_LD="ld -b"
@@ -7132,8 +5566,7 @@ fi
LD_LIBRARY_PATH_VAR="SHLIB_PATH"
fi
-
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
SHLIB_LD='${CC} -shared'
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
@@ -7144,30 +5577,28 @@ else
fi
-
# Users may want PA-RISC 1.1/2.0 portable code - needs HP cc
#CFLAGS="$CFLAGS +DAportable"
# Check to enable 64-bit flags for compiler/linker
- if test "$do64bit" = "yes"; then
+ if test "$do64bit" = "yes"; then :
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
case `${CC} -dumpmachine` in
hppa64*)
# 64-bit gcc in use. Fix flags for GNU ld.
do64bit_ok=yes
SHLIB_LD='${CC} -shared'
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
-
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
;;
*)
- { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
-echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;}
;;
esac
@@ -7179,82 +5610,52 @@ else
fi
-
-fi
- ;;
+fi ;;
HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*)
SHLIB_SUFFIX=".sl"
- echo "$as_me:$LINENO: checking for shl_load in -ldld" >&5
-echo $ECHO_N "checking for shl_load in -ldld... $ECHO_C" >&6
-if test "${ac_cv_lib_dld_shl_load+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5
+$as_echo_n "checking for shl_load in -ldld... " >&6; }
+if ${ac_cv_lib_dld_shl_load+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-ldld $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char shl_load ();
int
main ()
{
-shl_load ();
+return shl_load ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_dld_shl_load=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_dld_shl_load=no
+ ac_cv_lib_dld_shl_load=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_dld_shl_load" >&5
-echo "${ECHO_T}$ac_cv_lib_dld_shl_load" >&6
-if test $ac_cv_lib_dld_shl_load = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5
+$as_echo "$ac_cv_lib_dld_shl_load" >&6; }
+if test "x$ac_cv_lib_dld_shl_load" = xyes; then :
tcl_ok=yes
else
tcl_ok=no
fi
- if test "$tcl_ok" = yes; then
+ if test "$tcl_ok" = yes; then :
SHLIB_CFLAGS="+z"
SHLIB_LD="ld -b"
@@ -7266,28 +5667,24 @@ fi
LD_SEARCH_FLAGS='+s +b ${LIB_RUNTIME_DIR}:.'
LD_LIBRARY_PATH_VAR="SHLIB_PATH"
-fi
- ;;
+fi ;;
IRIX-5.*)
SHLIB_CFLAGS=""
SHLIB_LD="ld -shared -rdata_shared"
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
- case $LIBOBJS in
- "mkstemp.$ac_objext" | \
- *" mkstemp.$ac_objext" | \
- "mkstemp.$ac_objext "* | \
+ case " $LIBOBJS " in
*" mkstemp.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
+ ;;
esac
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi
-
;;
IRIX-6.*)
SHLIB_CFLAGS=""
@@ -7295,21 +5692,18 @@ fi
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
- case $LIBOBJS in
- "mkstemp.$ac_objext" | \
- *" mkstemp.$ac_objext" | \
- "mkstemp.$ac_objext "* | \
+ case " $LIBOBJS " in
*" mkstemp.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
+ ;;
esac
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi
-
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
CFLAGS="$CFLAGS -mabi=n32"
LDFLAGS="$LDFLAGS -mabi=n32"
@@ -7328,7 +5722,6 @@ else
LDFLAGS="$LDFLAGS -n32"
fi
-
;;
IRIX64-6.*)
SHLIB_CFLAGS=""
@@ -7336,29 +5729,26 @@ fi
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
- case $LIBOBJS in
- "mkstemp.$ac_objext" | \
- *" mkstemp.$ac_objext" | \
- "mkstemp.$ac_objext "* | \
+ case " $LIBOBJS " in
*" mkstemp.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
+ ;;
esac
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi
-
# Check to enable 64-bit flags for compiler/linker
- if test "$do64bit" = yes; then
+ if test "$do64bit" = yes; then :
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
- { echo "$as_me:$LINENO: WARNING: 64bit mode not supported by gcc" >&5
-echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported by gcc" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported by gcc" >&2;}
else
@@ -7369,9 +5759,7 @@ else
fi
-
fi
-
;;
Linux*|GNU*|NetBSD-Debian)
SHLIB_CFLAGS="-fPIC"
@@ -7387,31 +5775,25 @@ fi
DL_OBJS="tclLoadDl.o"
DL_LIBS="-ldl"
LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
-
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- if test "`uname -m`" = "alpha"; then
+ if test "`uname -m`" = "alpha"; then :
CFLAGS="$CFLAGS -mieee"
fi
+ if test $do64bit = yes; then :
- if test $do64bit = yes; then
-
- echo "$as_me:$LINENO: checking if compiler accepts -m64 flag" >&5
-echo $ECHO_N "checking if compiler accepts -m64 flag... $ECHO_C" >&6
-if test "${tcl_cv_cc_m64+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -m64 flag" >&5
+$as_echo_n "checking if compiler accepts -m64 flag... " >&6; }
+if ${tcl_cv_cc_m64+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -m64"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -7422,62 +5804,35 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_cc_m64=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cc_m64=no
+ tcl_cv_cc_m64=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
CFLAGS=$hold_cflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cc_m64" >&5
-echo "${ECHO_T}$tcl_cv_cc_m64" >&6
- if test $tcl_cv_cc_m64 = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_m64" >&5
+$as_echo "$tcl_cv_cc_m64" >&6; }
+ if test $tcl_cv_cc_m64 = yes; then :
CFLAGS="$CFLAGS -m64"
do64bit_ok=yes
fi
-
fi
-
# The combo of gcc + glibc has a bug related to inlining of
# functions like strtod(). The -fno-builtin flag should address
# this problem but it does not work. The -fno-inline flag is kind
# of overkill but it works. Disable inlining only when one of the
# files in compat/*.c is being linked in.
- if test x"${USE_COMPAT}" != x; then
+ if test x"${USE_COMPAT}" != x; then :
CFLAGS="$CFLAGS -fno-inline"
fi
-
;;
Lynx*)
SHLIB_CFLAGS="-fPIC"
@@ -7487,12 +5842,11 @@ fi
DL_OBJS="tclLoadDl.o"
DL_LIBS="-mshared -ldl"
LD_FLAGS="-Wl,--export-dynamic"
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
-
;;
MP-RAS-02*)
SHLIB_CFLAGS="-K PIC"
@@ -7538,11 +5892,10 @@ fi
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
-
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so.${SHLIB_VERSION}'
LDFLAGS="-Wl,-export-dynamic"
@@ -7559,7 +5912,7 @@ fi
CFLAGS_OPTIMIZE="-O2"
;;
esac
- if test "${TCL_THREADS}" = "1"; then
+ if test "${TCL_THREADS}" = "1"; then :
# On OpenBSD: Compile with -pthread
# Don't link with -lpthread
@@ -7567,7 +5920,6 @@ fi
CFLAGS="$CFLAGS -pthread"
fi
-
# OpenBSD doesn't do version numbers with dots.
UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
TCL_LIB_VERSIONS_OK=nodots
@@ -7580,13 +5932,12 @@ fi
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
LDFLAGS="$LDFLAGS -export-dynamic"
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
-
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- if test "${TCL_THREADS}" = "1"; then
+ if test "${TCL_THREADS}" = "1"; then :
# The -pthread needs to go in the CFLAGS, not LIBS
LIBS=`echo $LIBS | sed s/-pthread//`
@@ -7594,7 +5945,6 @@ fi
LDFLAGS="$LDFLAGS -pthread"
fi
-
;;
FreeBSD-*)
# This configuration from FreeBSD Ports.
@@ -7605,20 +5955,18 @@ fi
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
LDFLAGS=""
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
-
- if test "${TCL_THREADS}" = "1"; then
+ if test "${TCL_THREADS}" = "1"; then :
# The -pthread needs to go in the LDFLAGS, not LIBS
LIBS=`echo $LIBS | sed s/-pthread//`
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
LDFLAGS="$LDFLAGS $PTHREAD_LIBS"
fi
-
case $system in
FreeBSD-3.*)
# Version numbers are dot-stripped by system policy.
@@ -7641,23 +5989,19 @@ fi
CFLAGS="`echo " ${CFLAGS}" | \
awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \
if (!($i~/^(isysroot|mmacosx-version-min)/)) print "-"$i}'`"
- if test $do64bit = yes; then
+ if test $do64bit = yes; then :
case `arch` in
ppc)
- echo "$as_me:$LINENO: checking if compiler accepts -arch ppc64 flag" >&5
-echo $ECHO_N "checking if compiler accepts -arch ppc64 flag... $ECHO_C" >&6
-if test "${tcl_cv_cc_arch_ppc64+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch ppc64 flag" >&5
+$as_echo_n "checking if compiler accepts -arch ppc64 flag... " >&6; }
+if ${tcl_cv_cc_arch_ppc64+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -7668,62 +6012,33 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_cc_arch_ppc64=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cc_arch_ppc64=no
+ tcl_cv_cc_arch_ppc64=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
CFLAGS=$hold_cflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_ppc64" >&5
-echo "${ECHO_T}$tcl_cv_cc_arch_ppc64" >&6
- if test $tcl_cv_cc_arch_ppc64 = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_ppc64" >&5
+$as_echo "$tcl_cv_cc_arch_ppc64" >&6; }
+ if test $tcl_cv_cc_arch_ppc64 = yes; then :
CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5"
do64bit_ok=yes
-fi
-;;
+fi;;
i386)
- echo "$as_me:$LINENO: checking if compiler accepts -arch x86_64 flag" >&5
-echo $ECHO_N "checking if compiler accepts -arch x86_64 flag... $ECHO_C" >&6
-if test "${tcl_cv_cc_arch_x86_64+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if compiler accepts -arch x86_64 flag" >&5
+$as_echo_n "checking if compiler accepts -arch x86_64 flag... " >&6; }
+if ${tcl_cv_cc_arch_x86_64+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_cflags=$CFLAGS
CFLAGS="$CFLAGS -arch x86_64"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -7734,79 +6049,48 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_cc_arch_x86_64=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cc_arch_x86_64=no
+ tcl_cv_cc_arch_x86_64=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
CFLAGS=$hold_cflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cc_arch_x86_64" >&5
-echo "${ECHO_T}$tcl_cv_cc_arch_x86_64" >&6
- if test $tcl_cv_cc_arch_x86_64 = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_arch_x86_64" >&5
+$as_echo "$tcl_cv_cc_arch_x86_64" >&6; }
+ if test $tcl_cv_cc_arch_x86_64 = yes; then :
CFLAGS="$CFLAGS -arch x86_64"
do64bit_ok=yes
-fi
-;;
+fi;;
*)
- { echo "$as_me:$LINENO: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
-echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&5
+$as_echo "$as_me: WARNING: Don't know how enable 64-bit on architecture \`arch\`" >&2;};;
esac
else
# Check for combined 32-bit and 64-bit fat build
if echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \
- && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then
+ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '; then :
fat_32_64=yes
fi
-
fi
-
SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS}'
- echo "$as_me:$LINENO: checking if ld accepts -single_module flag" >&5
-echo $ECHO_N "checking if ld accepts -single_module flag... $ECHO_C" >&6
-if test "${tcl_cv_ld_single_module+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -single_module flag" >&5
+$as_echo_n "checking if ld accepts -single_module flag... " >&6; }
+if ${tcl_cv_ld_single_module+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_ldflags=$LDFLAGS
LDFLAGS="$LDFLAGS -dynamiclib -Wl,-single_module"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -7817,71 +6101,41 @@ int i;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_ld_single_module=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_ld_single_module=no
+ tcl_cv_ld_single_module=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LDFLAGS=$hold_ldflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_ld_single_module" >&5
-echo "${ECHO_T}$tcl_cv_ld_single_module" >&6
- if test $tcl_cv_ld_single_module = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_single_module" >&5
+$as_echo "$tcl_cv_ld_single_module" >&6; }
+ if test $tcl_cv_ld_single_module = yes; then :
SHLIB_LD="${SHLIB_LD} -Wl,-single_module"
fi
-
SHLIB_SUFFIX=".dylib"
DL_OBJS="tclLoadDyld.o"
DL_LIBS=""
# Don't use -prebind when building for Mac OS X 10.4 or later only:
if test "`echo "${MACOSX_DEPLOYMENT_TARGET}" | awk -F '10\\.' '{print int($2)}'`" -lt 4 -a \
- "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then
+ "`echo "${CPPFLAGS}" | awk -F '-mmacosx-version-min=10\\.' '{print int($2)}'`" -lt 4; then :
LDFLAGS="$LDFLAGS -prebind"
fi
-
LDFLAGS="$LDFLAGS -headerpad_max_install_names"
- echo "$as_me:$LINENO: checking if ld accepts -search_paths_first flag" >&5
-echo $ECHO_N "checking if ld accepts -search_paths_first flag... $ECHO_C" >&6
-if test "${tcl_cv_ld_search_paths_first+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if ld accepts -search_paths_first flag" >&5
+$as_echo_n "checking if ld accepts -search_paths_first flag... " >&6; }
+if ${tcl_cv_ld_search_paths_first+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_ldflags=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -7892,88 +6146,58 @@ int i;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_ld_search_paths_first=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_ld_search_paths_first=no
+ tcl_cv_ld_search_paths_first=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LDFLAGS=$hold_ldflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_ld_search_paths_first" >&5
-echo "${ECHO_T}$tcl_cv_ld_search_paths_first" >&6
- if test $tcl_cv_ld_search_paths_first = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_search_paths_first" >&5
+$as_echo "$tcl_cv_ld_search_paths_first" >&6; }
+ if test $tcl_cv_ld_search_paths_first = yes; then :
LDFLAGS="$LDFLAGS -Wl,-search_paths_first"
fi
+ if test "$tcl_cv_cc_visibility_hidden" != yes; then :
- if test "$tcl_cv_cc_visibility_hidden" != yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define MODULE_SCOPE __private_extern__
-_ACEOF
+$as_echo "#define MODULE_SCOPE __private_extern__" >>confdefs.h
fi
-
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH"
-cat >>confdefs.h <<\_ACEOF
-#define MAC_OSX_TCL 1
-_ACEOF
+$as_echo "#define MAC_OSX_TCL 1" >>confdefs.h
PLAT_OBJS='${MAC_OSX_OBJS}'
PLAT_SRCS='${MAC_OSX_SRCS}'
- echo "$as_me:$LINENO: checking whether to use CoreFoundation" >&5
-echo $ECHO_N "checking whether to use CoreFoundation... $ECHO_C" >&6
- # Check whether --enable-corefoundation or --disable-corefoundation was given.
-if test "${enable_corefoundation+set}" = set; then
- enableval="$enable_corefoundation"
- tcl_corefoundation=$enableval
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use CoreFoundation" >&5
+$as_echo_n "checking whether to use CoreFoundation... " >&6; }
+ # Check whether --enable-corefoundation was given.
+if test "${enable_corefoundation+set}" = set; then :
+ enableval=$enable_corefoundation; tcl_corefoundation=$enableval
else
tcl_corefoundation=yes
-fi;
- echo "$as_me:$LINENO: result: $tcl_corefoundation" >&5
-echo "${ECHO_T}$tcl_corefoundation" >&6
- if test $tcl_corefoundation = yes; then
+fi
- echo "$as_me:$LINENO: checking for CoreFoundation.framework" >&5
-echo $ECHO_N "checking for CoreFoundation.framework... $ECHO_C" >&6
-if test "${tcl_cv_lib_corefoundation+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_corefoundation" >&5
+$as_echo "$tcl_corefoundation" >&6; }
+ if test $tcl_corefoundation = yes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for CoreFoundation.framework" >&5
+$as_echo_n "checking for CoreFoundation.framework... " >&6; }
+if ${tcl_cv_lib_corefoundation+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_libs=$LIBS
- if test "$fat_32_64" = yes; then
+ if test "$fat_32_64" = yes; then :
for v in CFLAGS CPPFLAGS LDFLAGS; do
# On Tiger there is no 64-bit CF, so remove 64-bit
@@ -7983,13 +6207,8 @@ else
eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"'
done
fi
-
LIBS="$LIBS -framework CoreFoundation"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <CoreFoundation/CoreFoundation.h>
int
@@ -8000,77 +6219,45 @@ CFBundleRef b = CFBundleGetMainBundle();
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_lib_corefoundation=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_lib_corefoundation=no
+ tcl_cv_lib_corefoundation=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
- if test "$fat_32_64" = yes; then
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ if test "$fat_32_64" = yes; then :
for v in CFLAGS CPPFLAGS LDFLAGS; do
eval $v'="$hold_'$v'"'
done
fi
-
LIBS=$hold_libs
fi
-echo "$as_me:$LINENO: result: $tcl_cv_lib_corefoundation" >&5
-echo "${ECHO_T}$tcl_cv_lib_corefoundation" >&6
- if test $tcl_cv_lib_corefoundation = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation" >&5
+$as_echo "$tcl_cv_lib_corefoundation" >&6; }
+ if test $tcl_cv_lib_corefoundation = yes; then :
LIBS="$LIBS -framework CoreFoundation"
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_COREFOUNDATION 1
-_ACEOF
+$as_echo "#define HAVE_COREFOUNDATION 1" >>confdefs.h
else
tcl_corefoundation=no
fi
+ if test "$fat_32_64" = yes -a $tcl_corefoundation = yes; then :
- if test "$fat_32_64" = yes -a $tcl_corefoundation = yes; then
-
- echo "$as_me:$LINENO: checking for 64-bit CoreFoundation" >&5
-echo $ECHO_N "checking for 64-bit CoreFoundation... $ECHO_C" >&6
-if test "${tcl_cv_lib_corefoundation_64+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit CoreFoundation" >&5
+$as_echo_n "checking for 64-bit CoreFoundation... " >&6; }
+if ${tcl_cv_lib_corefoundation_64+:} false; then :
+ $as_echo_n "(cached) " >&6
else
for v in CFLAGS CPPFLAGS LDFLAGS; do
eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"'
done
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <CoreFoundation/CoreFoundation.h>
int
@@ -8081,60 +6268,31 @@ CFBundleRef b = CFBundleGetMainBundle();
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_lib_corefoundation_64=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_lib_corefoundation_64=no
+ tcl_cv_lib_corefoundation_64=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
for v in CFLAGS CPPFLAGS LDFLAGS; do
eval $v'="$hold_'$v'"'
done
fi
-echo "$as_me:$LINENO: result: $tcl_cv_lib_corefoundation_64" >&5
-echo "${ECHO_T}$tcl_cv_lib_corefoundation_64" >&6
- if test $tcl_cv_lib_corefoundation_64 = no; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_lib_corefoundation_64" >&5
+$as_echo "$tcl_cv_lib_corefoundation_64" >&6; }
+ if test $tcl_cv_lib_corefoundation_64 = no; then :
-cat >>confdefs.h <<\_ACEOF
-#define NO_COREFOUNDATION_64 1
-_ACEOF
+$as_echo "#define NO_COREFOUNDATION_64 1" >>confdefs.h
LDFLAGS="$LDFLAGS -Wl,-no_arch_warnings"
fi
-
fi
-
fi
-
;;
NEXTSTEP-*)
SHLIB_CFLAGS=""
@@ -8150,9 +6308,7 @@ fi
SHLIB_LD_LIBS=""
CFLAGS_OPTIMIZE="" # Optimizer is buggy
-cat >>confdefs.h <<\_ACEOF
-#define _OE_SOCKETS 1
-_ACEOF
+$as_echo "#define _OE_SOCKETS 1" >>confdefs.h
;;
OSF1-1.0|OSF1-1.1|OSF1-1.2)
@@ -8170,14 +6326,13 @@ _ACEOF
OSF1-1.*)
# OSF/1 1.3 from OSF using ELF, and derivatives, including AD2
SHLIB_CFLAGS="-fPIC"
- if test "$SHARED_BUILD" = 1; then
+ if test "$SHARED_BUILD" = 1; then :
SHLIB_LD="ld -shared"
else
SHLIB_LD="ld -non_shared"
fi
-
SHLIB_LD_LIBS=""
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
@@ -8188,7 +6343,7 @@ fi
OSF1-V*)
# Digital OSF/1
SHLIB_CFLAGS=""
- if test "$SHARED_BUILD" = 1; then
+ if test "$SHARED_BUILD" = 1; then :
SHLIB_LD='ld -shared -expect_unresolved "*"'
@@ -8197,30 +6352,27 @@ else
SHLIB_LD='ld -non_shared -expect_unresolved "*"'
fi
-
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS=""
- if test $doRpath = yes; then
+ if test $doRpath = yes; then :
CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}'
fi
-
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
CFLAGS="$CFLAGS -mieee"
else
CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"
fi
-
# see pthread_intro(3) for pthread support on osf1, k.furukawa
- if test "${TCL_THREADS}" = 1; then
+ if test "${TCL_THREADS}" = 1; then :
CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE"
CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64"
LIBS=`echo $LIBS | sed s/-lpthreads//`
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
LIBS="$LIBS -lpthread -lmach -lexc"
@@ -8231,9 +6383,7 @@ else
fi
-
fi
-
;;
QNX-6*)
# QNX RTP
@@ -8252,7 +6402,7 @@ fi
# Note, dlopen is available only on SCO 3.2.5 and greater. However,
# this test works, since "uname -s" was non-standard in 3.2.4 and
# below.
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
SHLIB_CFLAGS="-fPIC -melf"
LDFLAGS="$LDFLAGS -melf -Wl,-Bexport"
@@ -8263,7 +6413,6 @@ else
LDFLAGS="$LDFLAGS -belf -Wl,-Bexport"
fi
-
SHLIB_LD="ld -G"
SHLIB_LD_LIBS=""
SHLIB_SUFFIX=".so"
@@ -8271,6 +6420,7 @@ fi
DL_LIBS=""
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
+ CFLAGS="$CFLAGS -D_SVID3"
;;
SINIX*5.4*)
SHLIB_CFLAGS="-K PIC"
@@ -8308,21 +6458,17 @@ fi
# won't define thread-safe library routines.
-cat >>confdefs.h <<\_ACEOF
-#define _REENTRANT 1
-_ACEOF
+$as_echo "#define _REENTRANT 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define _POSIX_PTHREAD_SEMANTICS 1
-_ACEOF
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
SHLIB_CFLAGS="-KPIC"
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS="-ldl"
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
SHLIB_LD='${CC} -shared'
CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
@@ -8335,37 +6481,32 @@ else
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
fi
-
;;
SunOS-5*)
# Note: If _REENTRANT isn't defined, then Solaris
# won't define thread-safe library routines.
-cat >>confdefs.h <<\_ACEOF
-#define _REENTRANT 1
-_ACEOF
+$as_echo "#define _REENTRANT 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define _POSIX_PTHREAD_SEMANTICS 1
-_ACEOF
+$as_echo "#define _POSIX_PTHREAD_SEMANTICS 1" >>confdefs.h
SHLIB_CFLAGS="-KPIC"
# Check to enable 64-bit flags for compiler/linker
- if test "$do64bit" = yes; then
+ if test "$do64bit" = yes; then :
arch=`isainfo`
- if test "$arch" = "sparcv9 sparc"; then
+ if test "$arch" = "sparcv9 sparc"; then :
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
- if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then
+ if test "`${CC} -dumpversion | awk -F. '{print $1}'`" -lt 3; then :
- { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
-echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC < 3.2 on $system" >&2;}
else
@@ -8376,11 +6517,10 @@ else
fi
-
else
do64bit_ok=yes
- if test "$do64bitVIS" = yes; then
+ if test "$do64bitVIS" = yes; then :
CFLAGS="$CFLAGS -xarch=v9a"
LDFLAGS_ARCH="-xarch=v9a"
@@ -8391,17 +6531,15 @@ else
LDFLAGS_ARCH="-xarch=v9"
fi
-
# Solaris 64 uses this as well
#LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64"
fi
-
else
- if test "$arch" = "amd64 i386"; then
+ if test "$arch" = "amd64 i386"; then :
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
case $system in
SunOS-5.1[1-9]*|SunOS-5.[2-9][0-9]*)
@@ -8409,8 +6547,8 @@ else
CFLAGS="$CFLAGS -m64"
LDFLAGS="$LDFLAGS -m64";;
*)
- { echo "$as_me:$LINENO: WARNING: 64bit mode not supported with GCC on $system" >&5
-echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};;
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported with GCC on $system" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported with GCC on $system" >&2;};;
esac
else
@@ -8427,169 +6565,32 @@ else
fi
-
else
- { echo "$as_me:$LINENO: WARNING: 64bit mode not supported for $arch" >&5
-echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit mode not supported for $arch" >&5
+$as_echo "$as_me: WARNING: 64bit mode not supported for $arch" >&2;}
fi
-
fi
-
fi
-
#--------------------------------------------------------------------
# On Solaris 5.x i386 with the sunpro compiler we need to link
# with sunmath to get floating point rounding control
#--------------------------------------------------------------------
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
use_sunmath=no
else
arch=`isainfo`
- echo "$as_me:$LINENO: checking whether to use -lsunmath for fp rounding control" >&5
-echo $ECHO_N "checking whether to use -lsunmath for fp rounding control... $ECHO_C" >&6
- if test "$arch" = "amd64 i386" -o "$arch" = "i386"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use -lsunmath for fp rounding control" >&5
+$as_echo_n "checking whether to use -lsunmath for fp rounding control... " >&6; }
+ if test "$arch" = "amd64 i386" -o "$arch" = "i386"; then :
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
MATH_LIBS="-lsunmath $MATH_LIBS"
- if test "${ac_cv_header_sunmath_h+set}" = set; then
- echo "$as_me:$LINENO: checking for sunmath.h" >&5
-echo $ECHO_N "checking for sunmath.h... $ECHO_C" >&6
-if test "${ac_cv_header_sunmath_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_sunmath_h" >&5
-echo "${ECHO_T}$ac_cv_header_sunmath_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking sunmath.h usability" >&5
-echo $ECHO_N "checking sunmath.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <sunmath.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking sunmath.h presence" >&5
-echo $ECHO_N "checking sunmath.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sunmath.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: sunmath.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: sunmath.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: sunmath.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: sunmath.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: sunmath.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: sunmath.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: sunmath.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: sunmath.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: sunmath.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: sunmath.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: sunmath.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: sunmath.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: sunmath.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: sunmath.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: sunmath.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: sunmath.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for sunmath.h" >&5
-echo $ECHO_N "checking for sunmath.h... $ECHO_C" >&6
-if test "${ac_cv_header_sunmath_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_sunmath_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_sunmath_h" >&5
-echo "${ECHO_T}$ac_cv_header_sunmath_h" >&6
+ ac_fn_c_check_header_mongrel "$LINENO" "sunmath.h" "ac_cv_header_sunmath_h" "$ac_includes_default"
+if test "x$ac_cv_header_sunmath_h" = xyes; then :
fi
@@ -8598,26 +6599,24 @@ fi
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
use_sunmath=no
fi
-
fi
-
SHLIB_SUFFIX=".so"
DL_OBJS="tclLoadDl.o"
DL_LIBS="-ldl"
- if test "$GCC" = yes; then
+ if test "$GCC" = yes; then :
SHLIB_LD='${CC} -shared'
CC_SEARCH_FLAGS='-Wl,-R,${LIB_RUNTIME_DIR}'
LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
- if test "$do64bit_ok" = yes; then
+ if test "$do64bit_ok" = yes; then :
- if test "$arch" = "sparcv9 sparc"; then
+ if test "$arch" = "sparcv9 sparc"; then :
# We need to specify -static-libgcc or we need to
# add the path to the sparv9 libgcc.
@@ -8628,26 +6627,22 @@ fi
#CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir"
else
- if test "$arch" = "amd64 i386"; then
+ if test "$arch" = "amd64 i386"; then :
SHLIB_LD="$SHLIB_LD -m64 -static-libgcc"
fi
-
fi
-
fi
-
else
- if test "$use_sunmath" = yes; then
+ if test "$use_sunmath" = yes; then :
textmode=textoff
else
textmode=text
fi
-
case $system in
SunOS-5.[1-9][0-9]*|SunOS-5.[7-9])
SHLIB_LD="\${CC} -G -z $textmode \${LDFLAGS}";;
@@ -8658,7 +6653,6 @@ fi
LD_SEARCH_FLAGS='-R ${LIB_RUNTIME_DIR}'
fi
-
;;
UNIX_SV* | UnixWare-5*)
SHLIB_CFLAGS="-KPIC"
@@ -8669,19 +6663,15 @@ fi
DL_LIBS="-ldl"
# Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers
# that don't grok the -Bexport option. Test that it does.
- echo "$as_me:$LINENO: checking for ld accepts -Bexport flag" >&5
-echo $ECHO_N "checking for ld accepts -Bexport flag... $ECHO_C" >&6
-if test "${tcl_cv_ld_Bexport+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld accepts -Bexport flag" >&5
+$as_echo_n "checking for ld accepts -Bexport flag... " >&6; }
+if ${tcl_cv_ld_Bexport+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_ldflags=$LDFLAGS
LDFLAGS="$LDFLAGS -Wl,-Bexport"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -8692,93 +6682,63 @@ int i;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_ld_Bexport=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_ld_Bexport=no
+ tcl_cv_ld_Bexport=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LDFLAGS=$hold_ldflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_ld_Bexport" >&5
-echo "${ECHO_T}$tcl_cv_ld_Bexport" >&6
- if test $tcl_cv_ld_Bexport = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_ld_Bexport" >&5
+$as_echo "$tcl_cv_ld_Bexport" >&6; }
+ if test $tcl_cv_ld_Bexport = yes; then :
LDFLAGS="$LDFLAGS -Wl,-Bexport"
fi
-
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
;;
esac
- if test "$do64bit" = yes -a "$do64bit_ok" = no; then
+ if test "$do64bit" = yes -a "$do64bit_ok" = no; then :
- { echo "$as_me:$LINENO: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
-echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: 64bit support being disabled -- don't know magic for this platform" >&5
+$as_echo "$as_me: WARNING: 64bit support being disabled -- don't know magic for this platform" >&2;}
fi
-
- if test "$do64bit" = yes -a "$do64bit_ok" = yes; then
+ if test "$do64bit" = yes -a "$do64bit_ok" = yes; then :
-cat >>confdefs.h <<\_ACEOF
-#define TCL_CFG_DO64BIT 1
-_ACEOF
+$as_echo "#define TCL_CFG_DO64BIT 1" >>confdefs.h
fi
-
# Step 4: disable dynamic loading if requested via a command-line switch.
- # Check whether --enable-load or --disable-load was given.
-if test "${enable_load+set}" = set; then
- enableval="$enable_load"
- tcl_ok=$enableval
+ # Check whether --enable-load was given.
+if test "${enable_load+set}" = set; then :
+ enableval=$enable_load; tcl_ok=$enableval
else
tcl_ok=yes
-fi;
- if test "$tcl_ok" = no; then
- DL_OBJS=""
fi
+ if test "$tcl_ok" = no; then :
+ DL_OBJS=""
+fi
- if test "x$DL_OBJS" != x; then
+ if test "x$DL_OBJS" != x; then :
BUILD_DLTEST="\$(DLTEST_TARGETS)"
else
- { echo "$as_me:$LINENO: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5
-echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&5
+$as_echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libraries on this system." >&2;}
SHLIB_CFLAGS=""
SHLIB_LD=""
SHLIB_SUFFIX=""
@@ -8790,14 +6750,13 @@ echo "$as_me: WARNING: Can't figure out how to do dynamic loading or shared libr
BUILD_DLTEST=""
fi
-
LDFLAGS="$LDFLAGS $LDFLAGS_ARCH"
# If we're running gcc, then change the C flags for compiling shared
# libraries to the right flags for gcc, instead of those for the
# standard manufacturer compiler.
- if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then
+ if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then :
case $system in
AIX-*) ;;
@@ -8811,35 +6770,29 @@ fi
esac
fi
+ if test "$tcl_cv_cc_visibility_hidden" != yes; then :
- if test "$tcl_cv_cc_visibility_hidden" != yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define MODULE_SCOPE extern
-_ACEOF
+$as_echo "#define MODULE_SCOPE extern" >>confdefs.h
fi
-
- if test "$SHARED_LIB_SUFFIX" = ""; then
+ if test "$SHARED_LIB_SUFFIX" = ""; then :
SHARED_LIB_SUFFIX='${VERSION}${SHLIB_SUFFIX}'
fi
-
- if test "$UNSHARED_LIB_SUFFIX" = ""; then
+ if test "$UNSHARED_LIB_SUFFIX" = ""; then :
UNSHARED_LIB_SUFFIX='${VERSION}.a'
fi
-
DLL_INSTALL_DIR="\$(LIB_INSTALL_DIR)"
- if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then
+ if test "${SHARED_BUILD}" = 1 -a "${SHLIB_SUFFIX}" != ""; then :
LIB_SUFFIX=${SHARED_LIB_SUFFIX}
MAKE_LIB='${SHLIB_LD} -o $@ ${OBJS} ${SHLIB_LD_LIBS} ${TCL_SHLIB_LD_EXTRAS} ${TK_SHLIB_LD_EXTRAS} ${LD_SEARCH_FLAGS}'
- if test "${SHLIB_SUFFIX}" = ".dll"; then
+ if test "${SHLIB_SUFFIX}" = ".dll"; then :
INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(BIN_INSTALL_DIR)/$(LIB_FILE)"'
DLL_INSTALL_DIR="\$(BIN_INSTALL_DIR)"
@@ -8850,12 +6803,11 @@ else
fi
-
else
LIB_SUFFIX=${UNSHARED_LIB_SUFFIX}
- if test "$RANLIB" = ""; then
+ if test "$RANLIB" = ""; then :
MAKE_LIB='$(STLIB_LD) $@ ${OBJS}'
@@ -8864,14 +6816,12 @@ else
MAKE_LIB='${STLIB_LD} $@ ${OBJS} ; ${RANLIB} $@'
fi
-
INSTALL_LIB='$(INSTALL_LIBRARY) $(LIB_FILE) "$(LIB_INSTALL_DIR)/$(LIB_FILE)"'
fi
-
# Stub lib does not depend on shared/static configuration
- if test "$RANLIB" = ""; then
+ if test "$RANLIB" = ""; then :
MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS}'
@@ -8880,33 +6830,27 @@ else
MAKE_STUB_LIB='${STLIB_LD} $@ ${STUB_LIB_OBJS} ; ${RANLIB} $@'
fi
-
INSTALL_STUB_LIB='$(INSTALL_LIBRARY) $(STUB_LIB_FILE) "$(LIB_INSTALL_DIR)/$(STUB_LIB_FILE)"'
# Define TCL_LIBS now that we know what DL_LIBS is.
# The trick here is that we don't want to change the value of TCL_LIBS if
# it is already set when tclConfig.sh had been loaded by Tk.
- if test "x${TCL_LIBS}" = x; then
+ if test "x${TCL_LIBS}" = x; then :
TCL_LIBS="${DL_LIBS} ${LIBS} ${MATH_LIBS}"
fi
-
# See if the compiler supports casting to a union type.
# This is used to stop gcc from printing a compiler
# warning when initializing a union member.
- echo "$as_me:$LINENO: checking for cast to union support" >&5
-echo $ECHO_N "checking for cast to union support... $ECHO_C" >&6
-if test "${tcl_cv_cast_to_union+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for cast to union support" >&5
+$as_echo_n "checking for cast to union support... " >&6; }
+if ${tcl_cv_cast_to_union+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -8920,45 +6864,19 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_cast_to_union=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cast_to_union=no
+ tcl_cv_cast_to_union=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cast_to_union" >&5
-echo "${ECHO_T}$tcl_cv_cast_to_union" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cast_to_union" >&5
+$as_echo "$tcl_cv_cast_to_union" >&6; }
if test "$tcl_cv_cast_to_union" = "yes"; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CAST_TO_UNION 1
-_ACEOF
+$as_echo "#define HAVE_CAST_TO_UNION 1" >>confdefs.h
fi
@@ -9004,84 +6922,78 @@ _ACEOF
- echo "$as_me:$LINENO: checking for build with symbols" >&5
-echo $ECHO_N "checking for build with symbols... $ECHO_C" >&6
- # Check whether --enable-symbols or --disable-symbols was given.
-if test "${enable_symbols+set}" = set; then
- enableval="$enable_symbols"
- tcl_ok=$enableval
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for build with symbols" >&5
+$as_echo_n "checking for build with symbols... " >&6; }
+ # Check whether --enable-symbols was given.
+if test "${enable_symbols+set}" = set; then :
+ enableval=$enable_symbols; tcl_ok=$enableval
else
tcl_ok=no
-fi;
+fi
+
# FIXME: Currently, LDFLAGS_DEFAULT is not used, it should work like CFLAGS_DEFAULT.
DBGX=""
if test "$tcl_ok" = "no"; then
CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
-cat >>confdefs.h <<\_ACEOF
-#define NDEBUG 1
-_ACEOF
+$as_echo "#define NDEBUG 1" >>confdefs.h
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
-cat >>confdefs.h <<\_ACEOF
-#define TCL_CFG_OPTIMIZED 1
-_ACEOF
+$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h
+
+ elif test "$tcl_ok" = "all-with-O2"; then
+ CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
+ LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: all-with-O2 (all debugging but with -O2 optimization)" >&5
+$as_echo "all-with-O2 (all debugging but with -O2 optimization)" >&6; }
+
+$as_echo "#define TCL_CFG_OPTIMIZED 1" >>confdefs.h
else
CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
if test "$tcl_ok" = "yes"; then
- echo "$as_me:$LINENO: result: yes (standard debugging)" >&5
-echo "${ECHO_T}yes (standard debugging)" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes (standard debugging)" >&5
+$as_echo "yes (standard debugging)" >&6; }
fi
fi
- if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+ if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all" -o "$tcl_ok" = "all-with-O2"; then
-cat >>confdefs.h <<\_ACEOF
-#define TCL_MEM_DEBUG 1
-_ACEOF
+$as_echo "#define TCL_MEM_DEBUG 1" >>confdefs.h
fi
- if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then
+ if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all" -o "$tcl_ok" = "all-with-O2"; then
-cat >>confdefs.h <<\_ACEOF
-#define TCL_COMPILE_DEBUG 1
-_ACEOF
+$as_echo "#define TCL_COMPILE_DEBUG 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define TCL_COMPILE_STATS 1
-_ACEOF
+$as_echo "#define TCL_COMPILE_STATS 1" >>confdefs.h
fi
if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
if test "$tcl_ok" = "all"; then
- echo "$as_me:$LINENO: result: enabled symbols mem compile debugging" >&5
-echo "${ECHO_T}enabled symbols mem compile debugging" >&6
- else
- echo "$as_me:$LINENO: result: enabled $tcl_ok debugging" >&5
-echo "${ECHO_T}enabled $tcl_ok debugging" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled symbols mem compile debugging" >&5
+$as_echo "enabled symbols mem compile debugging" >&6; }
+ elif test "$tcl_ok" != "all-with-O2"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled $tcl_ok debugging" >&5
+$as_echo "enabled $tcl_ok debugging" >&6; }
fi
fi
-cat >>confdefs.h <<\_ACEOF
-#define TCL_TOMMATH 1
-_ACEOF
+$as_echo "#define TCL_TOMMATH 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define MP_PREC 4
-_ACEOF
+$as_echo "#define MP_PREC 4" >>confdefs.h
#--------------------------------------------------------------------
@@ -9089,18 +7001,14 @@ _ACEOF
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for required early compiler flags" >&5
-echo $ECHO_N "checking for required early compiler flags... $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for required early compiler flags" >&5
+$as_echo_n "checking for required early compiler flags... " >&6; }
tcl_flags=""
- if test "${tcl_cv_flag__isoc99_source+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ if ${tcl_cv_flag__isoc99_source+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdlib.h>
int
@@ -9111,38 +7019,10 @@ char *p = (char *)strtoll; char *q = (char *)strtoull;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_flag__isoc99_source=no
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define _ISOC99_SOURCE 1
#include <stdlib.h>
@@ -9154,58 +7034,28 @@ char *p = (char *)strtoll; char *q = (char *)strtoull;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_flag__isoc99_source=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_flag__isoc99_source=no
+ tcl_cv_flag__isoc99_source=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
if test "x${tcl_cv_flag__isoc99_source}" = "xyes" ; then
-cat >>confdefs.h <<\_ACEOF
-#define _ISOC99_SOURCE 1
-_ACEOF
+$as_echo "#define _ISOC99_SOURCE 1" >>confdefs.h
tcl_flags="$tcl_flags _ISOC99_SOURCE"
fi
- if test "${tcl_cv_flag__largefile64_source+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ if ${tcl_cv_flag__largefile64_source+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/stat.h>
int
@@ -9216,38 +7066,10 @@ struct stat64 buf; int i = stat64("/", &buf);
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_flag__largefile64_source=no
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define _LARGEFILE64_SOURCE 1
#include <sys/stat.h>
@@ -9259,58 +7081,28 @@ struct stat64 buf; int i = stat64("/", &buf);
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_flag__largefile64_source=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_flag__largefile64_source=no
+ tcl_cv_flag__largefile64_source=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
if test "x${tcl_cv_flag__largefile64_source}" = "xyes" ; then
-cat >>confdefs.h <<\_ACEOF
-#define _LARGEFILE64_SOURCE 1
-_ACEOF
+$as_echo "#define _LARGEFILE64_SOURCE 1" >>confdefs.h
tcl_flags="$tcl_flags _LARGEFILE64_SOURCE"
fi
- if test "${tcl_cv_flag__largefile_source64+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ if ${tcl_cv_flag__largefile_source64+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/stat.h>
int
@@ -9321,38 +7113,10 @@ char *p = (char *)open64;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_flag__largefile_source64=no
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#define _LARGEFILE_SOURCE64 1
#include <sys/stat.h>
@@ -9364,72 +7128,42 @@ char *p = (char *)open64;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_flag__largefile_source64=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_flag__largefile_source64=no
+ tcl_cv_flag__largefile_source64=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
if test "x${tcl_cv_flag__largefile_source64}" = "xyes" ; then
-cat >>confdefs.h <<\_ACEOF
-#define _LARGEFILE_SOURCE64 1
-_ACEOF
+$as_echo "#define _LARGEFILE_SOURCE64 1" >>confdefs.h
tcl_flags="$tcl_flags _LARGEFILE_SOURCE64"
fi
if test "x${tcl_flags}" = "x" ; then
- echo "$as_me:$LINENO: result: none" >&5
-echo "${ECHO_T}none" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5
+$as_echo "none" >&6; }
else
- echo "$as_me:$LINENO: result: ${tcl_flags}" >&5
-echo "${ECHO_T}${tcl_flags}" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_flags}" >&5
+$as_echo "${tcl_flags}" >&6; }
fi
- echo "$as_me:$LINENO: checking for 64-bit integer type" >&5
-echo $ECHO_N "checking for 64-bit integer type... $ECHO_C" >&6
- if test "${tcl_cv_type_64bit+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for 64-bit integer type" >&5
+$as_echo_n "checking for 64-bit integer type... " >&6; }
+ if ${tcl_cv_type_64bit+:} false; then :
+ $as_echo_n "(cached) " >&6
else
tcl_cv_type_64bit=none
# See if the compiler knows natively about __int64
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -9440,44 +7174,16 @@ __int64 value = (__int64) 0;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_type_64bit=__int64
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_type_64bit="long long"
+ tcl_type_64bit="long long"
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
# See if we should use long anyway Note that we substitute in the
# type that is our current guess for a 64-bit type inside this check
# program, so it should be modified only carefully...
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -9490,66 +7196,35 @@ switch (0) {
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_type_64bit=${tcl_type_64bit}
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
if test "${tcl_cv_type_64bit}" = none ; then
-cat >>confdefs.h <<\_ACEOF
-#define TCL_WIDE_INT_IS_LONG 1
-_ACEOF
+$as_echo "#define TCL_WIDE_INT_IS_LONG 1" >>confdefs.h
- echo "$as_me:$LINENO: result: using long" >&5
-echo "${ECHO_T}using long" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: using long" >&5
+$as_echo "using long" >&6; }
else
cat >>confdefs.h <<_ACEOF
#define TCL_WIDE_INT_TYPE ${tcl_cv_type_64bit}
_ACEOF
- echo "$as_me:$LINENO: result: ${tcl_cv_type_64bit}" >&5
-echo "${ECHO_T}${tcl_cv_type_64bit}" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${tcl_cv_type_64bit}" >&5
+$as_echo "${tcl_cv_type_64bit}" >&6; }
# Now check for auxiliary declarations
- echo "$as_me:$LINENO: checking for struct dirent64" >&5
-echo $ECHO_N "checking for struct dirent64... $ECHO_C" >&6
-if test "${tcl_cv_struct_dirent64+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct dirent64" >&5
+$as_echo_n "checking for struct dirent64... " >&6; }
+if ${tcl_cv_struct_dirent64+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
#include <dirent.h>
@@ -9561,58 +7236,28 @@ struct dirent64 p;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_struct_dirent64=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_struct_dirent64=no
+ tcl_cv_struct_dirent64=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_struct_dirent64" >&5
-echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_dirent64" >&5
+$as_echo "$tcl_cv_struct_dirent64" >&6; }
if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRUCT_DIRENT64 1
-_ACEOF
+$as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h
fi
- echo "$as_me:$LINENO: checking for struct stat64" >&5
-echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6
-if test "${tcl_cv_struct_stat64+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat64" >&5
+$as_echo_n "checking for struct stat64... " >&6; }
+if ${tcl_cv_struct_stat64+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/stat.h>
int
@@ -9624,161 +7269,40 @@ struct stat64 p;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_struct_stat64=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_struct_stat64=no
+ tcl_cv_struct_stat64=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_struct_stat64" >&5
-echo "${ECHO_T}$tcl_cv_struct_stat64" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_struct_stat64" >&5
+$as_echo "$tcl_cv_struct_stat64" >&6; }
if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_STRUCT_STAT64 1
-_ACEOF
+$as_echo "#define HAVE_STRUCT_STAT64 1" >>confdefs.h
fi
-
-
-for ac_func in open64 lseek64
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+ for ac_func in open64 lseek64
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
- echo "$as_me:$LINENO: checking for off64_t" >&5
-echo $ECHO_N "checking for off64_t... $ECHO_C" >&6
- if test "${tcl_cv_type_off64_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for off64_t" >&5
+$as_echo_n "checking for off64_t... " >&6; }
+ if ${tcl_cv_type_off64_t+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
int
@@ -9790,51 +7314,25 @@ off64_t offset;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_type_off64_t=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_type_off64_t=no
+ tcl_cv_type_off64_t=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
if test "x${tcl_cv_type_off64_t}" = "xyes" && \
test "x${ac_cv_func_lseek64}" = "xyes" && \
test "x${ac_cv_func_open64}" = "xyes" ; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_TYPE_OFF64_T 1
-_ACEOF
+$as_echo "#define HAVE_TYPE_OFF64_T 1" >>confdefs.h
- echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
fi
@@ -9844,235 +7342,229 @@ echo "${ECHO_T}no" >&6
# Tcl_UniChar strings to memcmp on big-endian systems.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking whether byte ordering is bigendian" >&5
-echo $ECHO_N "checking whether byte ordering is bigendian... $ECHO_C" >&6
-if test "${ac_cv_c_bigendian+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
+$as_echo_n "checking whether byte ordering is bigendian... " >&6; }
+if ${ac_cv_c_bigendian+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- # See if sys/param.h defines the BYTE_ORDER macro.
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ ac_cv_c_bigendian=unknown
+ # See if we're dealing with a universal compiler.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#ifndef __APPLE_CC__
+ not a universal capable compiler
+ #endif
+ typedef int dummy;
+
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ # Check for potential -arch flags. It is not universal unless
+ # there are at least two -arch flags with different values.
+ ac_arch=
+ ac_prev=
+ for ac_word in $CC $CFLAGS $CPPFLAGS $LDFLAGS; do
+ if test -n "$ac_prev"; then
+ case $ac_word in
+ i?86 | x86_64 | ppc | ppc64)
+ if test -z "$ac_arch" || test "$ac_arch" = "$ac_word"; then
+ ac_arch=$ac_word
+ else
+ ac_cv_c_bigendian=universal
+ break
+ fi
+ ;;
+ esac
+ ac_prev=
+ elif test "x$ac_word" = "x-arch"; then
+ ac_prev=arch
+ fi
+ done
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if sys/param.h defines the BYTE_ORDER macro.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
-#include <sys/param.h>
+ #include <sys/param.h>
int
main ()
{
-#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
- bogus endian macros
-#endif
+#if ! (defined BYTE_ORDER && defined BIG_ENDIAN \
+ && defined LITTLE_ENDIAN && BYTE_ORDER && BIG_ENDIAN \
+ && LITTLE_ENDIAN)
+ bogus endian macros
+ #endif
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
# It does; now see whether it defined to BIG_ENDIAN or not.
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
-#include <sys/param.h>
+ #include <sys/param.h>
int
main ()
{
#if BYTE_ORDER != BIG_ENDIAN
- not big endian
-#endif
+ not big endian
+ #endif
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_c_bigendian=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_c_bigendian=no
+ ac_cv_c_bigendian=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # See if <limits.h> defines _LITTLE_ENDIAN or _BIG_ENDIAN (e.g., Solaris).
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <limits.h>
-# It does not; compile a test program.
-if test "$cross_compiling" = yes; then
- # try to guess the endianness by grepping values into an object file
- ac_cv_c_bigendian=unknown
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
+int
+main ()
+{
+#if ! (defined _LITTLE_ENDIAN || defined _BIG_ENDIAN)
+ bogus endian macros
+ #endif
+
+ ;
+ return 0;
+}
_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ # It does; now see whether it defined to _BIG_ENDIAN or not.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-short ascii_mm[] = { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
-short ascii_ii[] = { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
-void _ascii () { char *s = (char *) ascii_mm; s = (char *) ascii_ii; }
-short ebcdic_ii[] = { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
-short ebcdic_mm[] = { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
-void _ebcdic () { char *s = (char *) ebcdic_mm; s = (char *) ebcdic_ii; }
+#include <limits.h>
+
int
main ()
{
- _ascii (); _ebcdic ();
+#ifndef _BIG_ENDIAN
+ not big endian
+ #endif
+
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- if grep BIGenDianSyS conftest.$ac_objext >/dev/null ; then
+if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_c_bigendian=yes
+else
+ ac_cv_c_bigendian=no
fi
-if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
- if test "$ac_cv_c_bigendian" = unknown; then
- ac_cv_c_bigendian=no
- else
- # finding both strings is unlikely to happen, but who knows?
- ac_cv_c_bigendian=unknown
- fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+ fi
+ if test $ac_cv_c_bigendian = unknown; then
+ # Compile a test program.
+ if test "$cross_compiling" = yes; then :
+ # Try to guess by grepping values from an object file.
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+short int ascii_mm[] =
+ { 0x4249, 0x4765, 0x6E44, 0x6961, 0x6E53, 0x7953, 0 };
+ short int ascii_ii[] =
+ { 0x694C, 0x5454, 0x656C, 0x6E45, 0x6944, 0x6E61, 0 };
+ int use_ascii (int i) {
+ return ascii_mm[i] + ascii_ii[i];
+ }
+ short int ebcdic_ii[] =
+ { 0x89D3, 0xE3E3, 0x8593, 0x95C5, 0x89C4, 0x9581, 0 };
+ short int ebcdic_mm[] =
+ { 0xC2C9, 0xC785, 0x95C4, 0x8981, 0x95E2, 0xA8E2, 0 };
+ int use_ebcdic (int i) {
+ return ebcdic_mm[i] + ebcdic_ii[i];
+ }
+ extern int foo;
+int
+main ()
+{
+return use_ascii (foo) == use_ebcdic (foo);
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ if grep BIGenDianSyS conftest.$ac_objext >/dev/null; then
+ ac_cv_c_bigendian=yes
+ fi
+ if grep LiTTleEnDian conftest.$ac_objext >/dev/null ; then
+ if test "$ac_cv_c_bigendian" = unknown; then
+ ac_cv_c_bigendian=no
+ else
+ # finding both strings is unlikely to happen, but who knows?
+ ac_cv_c_bigendian=unknown
+ fi
+ fi
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
+$ac_includes_default
int
main ()
{
- /* Are we little or big endian? From Harbison&Steele. */
- union
- {
- long l;
- char c[sizeof (long)];
- } u;
- u.l = 1;
- exit (u.c[sizeof (long) - 1] == 1);
+
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long int l;
+ char c[sizeof (long int)];
+ } u;
+ u.l = 1;
+ return u.c[sizeof (long int) - 1] == 1;
+
+ ;
+ return 0;
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_run "$LINENO"; then :
ac_cv_c_bigendian=no
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_c_bigendian=yes
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+ ac_cv_c_bigendian=yes
fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+ fi
fi
-echo "$as_me:$LINENO: result: $ac_cv_c_bigendian" >&5
-echo "${ECHO_T}$ac_cv_c_bigendian" >&6
-case $ac_cv_c_bigendian in
- yes)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_bigendian" >&5
+$as_echo "$ac_cv_c_bigendian" >&6; }
+ case $ac_cv_c_bigendian in #(
+ yes)
+ $as_echo "#define WORDS_BIGENDIAN 1" >>confdefs.h
+;; #(
+ no)
+ ;; #(
+ universal)
-cat >>confdefs.h <<\_ACEOF
-#define WORDS_BIGENDIAN 1
-_ACEOF
- ;;
- no)
- ;;
- *)
- { { echo "$as_me:$LINENO: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&5
-echo "$as_me: error: unknown endianness
-presetting ac_cv_c_bigendian=no (or yes) will help" >&2;}
- { (exit 1); exit 1; }; } ;;
-esac
+$as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
+
+ ;; #(
+ *)
+ as_fn_error $? "unknown endianness
+ presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
+ esac
#--------------------------------------------------------------------
@@ -10081,110 +7573,17 @@ esac
#--------------------------------------------------------------------
# Check if Posix compliant getcwd exists, if not we'll use getwd.
-
for ac_func in getcwd
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+do :
+ ac_fn_c_check_func "$LINENO" "getcwd" "ac_cv_func_getcwd"
+if test "x$ac_cv_func_getcwd" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define HAVE_GETCWD 1
_ACEOF
else
-cat >>confdefs.h <<\_ACEOF
-#define USEGETWD 1
-_ACEOF
+$as_echo "#define USEGETWD 1" >>confdefs.h
fi
done
@@ -10192,518 +7591,92 @@ done
# Nb: if getcwd uses popen and pwd(1) (like SunOS 4) we should really
# define USEGETWD even if the posix getcwd exists. Add a test ?
+ac_fn_c_check_func "$LINENO" "mkstemp" "ac_cv_func_mkstemp"
+if test "x$ac_cv_func_mkstemp" = xyes; then :
+ $as_echo "#define HAVE_MKSTEMP 1" >>confdefs.h
-
-
-
-for ac_func in mkstemp opendir strtol waitpid
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ case " $LIBOBJS " in
+ *" mkstemp.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS mkstemp.$ac_objext"
+ ;;
+esac
-eval "$as_ac_var=no"
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+
+ac_fn_c_check_func "$LINENO" "opendir" "ac_cv_func_opendir"
+if test "x$ac_cv_func_opendir" = xyes; then :
+ $as_echo "#define HAVE_OPENDIR 1" >>confdefs.h
else
- case $LIBOBJS in
- "$ac_func.$ac_objext" | \
- *" $ac_func.$ac_objext" | \
- "$ac_func.$ac_objext "* | \
- *" $ac_func.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext" ;;
+ case " $LIBOBJS " in
+ *" opendir.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS opendir.$ac_objext"
+ ;;
esac
fi
-done
+ac_fn_c_check_func "$LINENO" "strtol" "ac_cv_func_strtol"
+if test "x$ac_cv_func_strtol" = xyes; then :
+ $as_echo "#define HAVE_STRTOL 1" >>confdefs.h
-echo "$as_me:$LINENO: checking for strerror" >&5
-echo $ECHO_N "checking for strerror... $ECHO_C" >&6
-if test "${ac_cv_func_strerror+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define strerror to an innocuous variant, in case <limits.h> declares strerror.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strerror innocuous_strerror
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strerror (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+ case " $LIBOBJS " in
+ *" strtol.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS strtol.$ac_objext"
+ ;;
+esac
-#undef strerror
+fi
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strerror ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_strerror) || defined (__stub___strerror)
-choke me
-#else
-char (*f) () = strerror;
-#endif
-#ifdef __cplusplus
-}
-#endif
+ac_fn_c_check_func "$LINENO" "waitpid" "ac_cv_func_waitpid"
+if test "x$ac_cv_func_waitpid" = xyes; then :
+ $as_echo "#define HAVE_WAITPID 1" >>confdefs.h
-int
-main ()
-{
-return f != strerror;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strerror=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ case " $LIBOBJS " in
+ *" waitpid.$ac_objext "* ) ;;
+ *) LIBOBJS="$LIBOBJS waitpid.$ac_objext"
+ ;;
+esac
-ac_cv_func_strerror=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_func_strerror" >&5
-echo "${ECHO_T}$ac_cv_func_strerror" >&6
-if test $ac_cv_func_strerror = yes; then
- :
-else
-cat >>confdefs.h <<\_ACEOF
-#define NO_STRERROR 1
-_ACEOF
-fi
+ac_fn_c_check_func "$LINENO" "strerror" "ac_cv_func_strerror"
+if test "x$ac_cv_func_strerror" = xyes; then :
-echo "$as_me:$LINENO: checking for getwd" >&5
-echo $ECHO_N "checking for getwd... $ECHO_C" >&6
-if test "${ac_cv_func_getwd+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define getwd to an innocuous variant, in case <limits.h> declares getwd.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define getwd innocuous_getwd
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char getwd (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef getwd
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char getwd ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_getwd) || defined (__stub___getwd)
-choke me
-#else
-char (*f) () = getwd;
-#endif
-#ifdef __cplusplus
-}
-#endif
-int
-main ()
-{
-return f != getwd;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_getwd=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+$as_echo "#define NO_STRERROR 1" >>confdefs.h
-ac_cv_func_getwd=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_getwd" >&5
-echo "${ECHO_T}$ac_cv_func_getwd" >&6
-if test $ac_cv_func_getwd = yes; then
- :
-else
-
-cat >>confdefs.h <<\_ACEOF
-#define NO_GETWD 1
-_ACEOF
-fi
+ac_fn_c_check_func "$LINENO" "getwd" "ac_cv_func_getwd"
+if test "x$ac_cv_func_getwd" = xyes; then :
-echo "$as_me:$LINENO: checking for wait3" >&5
-echo $ECHO_N "checking for wait3... $ECHO_C" >&6
-if test "${ac_cv_func_wait3+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define wait3 to an innocuous variant, in case <limits.h> declares wait3.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define wait3 innocuous_wait3
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char wait3 (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef wait3
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char wait3 ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_wait3) || defined (__stub___wait3)
-choke me
-#else
-char (*f) () = wait3;
-#endif
-#ifdef __cplusplus
-}
-#endif
-int
-main ()
-{
-return f != wait3;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_wait3=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+$as_echo "#define NO_GETWD 1" >>confdefs.h
-ac_cv_func_wait3=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_func_wait3" >&5
-echo "${ECHO_T}$ac_cv_func_wait3" >&6
-if test $ac_cv_func_wait3 = yes; then
- :
-else
-cat >>confdefs.h <<\_ACEOF
-#define NO_WAIT3 1
-_ACEOF
+ac_fn_c_check_func "$LINENO" "wait3" "ac_cv_func_wait3"
+if test "x$ac_cv_func_wait3" = xyes; then :
-fi
-
-echo "$as_me:$LINENO: checking for uname" >&5
-echo $ECHO_N "checking for uname... $ECHO_C" >&6
-if test "${ac_cv_func_uname+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define uname to an innocuous variant, in case <limits.h> declares uname.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define uname innocuous_uname
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char uname (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-#undef uname
+$as_echo "#define NO_WAIT3 1" >>confdefs.h
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char uname ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_uname) || defined (__stub___uname)
-choke me
-#else
-char (*f) () = uname;
-#endif
-#ifdef __cplusplus
-}
-#endif
+fi
-int
-main ()
-{
-return f != uname;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_uname=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ac_fn_c_check_func "$LINENO" "uname" "ac_cv_func_uname"
+if test "x$ac_cv_func_uname" = xyes; then :
-ac_cv_func_uname=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_uname" >&5
-echo "${ECHO_T}$ac_cv_func_uname" >&6
-if test $ac_cv_func_uname = yes; then
- :
else
-cat >>confdefs.h <<\_ACEOF
-#define NO_UNAME 1
-_ACEOF
+$as_echo "#define NO_UNAME 1" >>confdefs.h
fi
@@ -10714,209 +7687,25 @@ if test "`uname -s`" = "Darwin" && test "${TCL_THREADS}" = 1 && \
# use it when threads are enabled, c.f. bug # 711232
ac_cv_func_realpath=no
fi
-echo "$as_me:$LINENO: checking for realpath" >&5
-echo $ECHO_N "checking for realpath... $ECHO_C" >&6
-if test "${ac_cv_func_realpath+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define realpath to an innocuous variant, in case <limits.h> declares realpath.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define realpath innocuous_realpath
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char realpath (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath"
+if test "x$ac_cv_func_realpath" = xyes; then :
-#undef realpath
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char realpath ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_realpath) || defined (__stub___realpath)
-choke me
-#else
-char (*f) () = realpath;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != realpath;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_realpath=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_realpath=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_realpath" >&5
-echo "${ECHO_T}$ac_cv_func_realpath" >&6
-if test $ac_cv_func_realpath = yes; then
- :
else
-cat >>confdefs.h <<\_ACEOF
-#define NO_REALPATH 1
-_ACEOF
+$as_echo "#define NO_REALPATH 1" >>confdefs.h
fi
NEED_FAKE_RFC2553=0
-
-
-
-
-for ac_func in getnameinfo getaddrinfo freeaddrinfo gai_strerror
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+ for ac_func in getnameinfo getaddrinfo freeaddrinfo gai_strerror
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
else
@@ -10924,69 +7713,14 @@ else
fi
done
- echo "$as_me:$LINENO: checking for struct addrinfo" >&5
-echo $ECHO_N "checking for struct addrinfo... $ECHO_C" >&6
-if test "${ac_cv_type_struct_addrinfo+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
+ ac_fn_c_check_type "$LINENO" "struct addrinfo" "ac_cv_type_struct_addrinfo" "
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
-
-int
-main ()
-{
-if ((struct addrinfo *) 0)
- return 0;
-if (sizeof (struct addrinfo))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_struct_addrinfo=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_struct_addrinfo=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_struct_addrinfo" >&5
-echo "${ECHO_T}$ac_cv_type_struct_addrinfo" >&6
-if test $ac_cv_type_struct_addrinfo = yes; then
+"
+if test "x$ac_cv_type_struct_addrinfo" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRUCT_ADDRINFO 1
@@ -10996,69 +7730,14 @@ _ACEOF
else
NEED_FAKE_RFC2553=1
fi
-echo "$as_me:$LINENO: checking for struct in6_addr" >&5
-echo $ECHO_N "checking for struct in6_addr... $ECHO_C" >&6
-if test "${ac_cv_type_struct_in6_addr+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
+ac_fn_c_check_type "$LINENO" "struct in6_addr" "ac_cv_type_struct_in6_addr" "
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
-
-int
-main ()
-{
-if ((struct in6_addr *) 0)
- return 0;
-if (sizeof (struct in6_addr))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_struct_in6_addr=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_struct_in6_addr=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_struct_in6_addr" >&5
-echo "${ECHO_T}$ac_cv_type_struct_in6_addr" >&6
-if test $ac_cv_type_struct_in6_addr = yes; then
+"
+if test "x$ac_cv_type_struct_in6_addr" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRUCT_IN6_ADDR 1
@@ -11068,69 +7747,14 @@ _ACEOF
else
NEED_FAKE_RFC2553=1
fi
-echo "$as_me:$LINENO: checking for struct sockaddr_in6" >&5
-echo $ECHO_N "checking for struct sockaddr_in6... $ECHO_C" >&6
-if test "${ac_cv_type_struct_sockaddr_in6+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
+ac_fn_c_check_type "$LINENO" "struct sockaddr_in6" "ac_cv_type_struct_sockaddr_in6" "
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
-
-int
-main ()
-{
-if ((struct sockaddr_in6 *) 0)
- return 0;
-if (sizeof (struct sockaddr_in6))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_struct_sockaddr_in6=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_struct_sockaddr_in6=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_in6" >&5
-echo "${ECHO_T}$ac_cv_type_struct_sockaddr_in6" >&6
-if test $ac_cv_type_struct_sockaddr_in6 = yes; then
+"
+if test "x$ac_cv_type_struct_sockaddr_in6" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRUCT_SOCKADDR_IN6 1
@@ -11140,69 +7764,14 @@ _ACEOF
else
NEED_FAKE_RFC2553=1
fi
-echo "$as_me:$LINENO: checking for struct sockaddr_storage" >&5
-echo $ECHO_N "checking for struct sockaddr_storage... $ECHO_C" >&6
-if test "${ac_cv_type_struct_sockaddr_storage+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-
+ac_fn_c_check_type "$LINENO" "struct sockaddr_storage" "ac_cv_type_struct_sockaddr_storage" "
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
-
-int
-main ()
-{
-if ((struct sockaddr_storage *) 0)
- return 0;
-if (sizeof (struct sockaddr_storage))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_struct_sockaddr_storage=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_struct_sockaddr_storage=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_struct_sockaddr_storage" >&5
-echo "${ECHO_T}$ac_cv_type_struct_sockaddr_storage" >&6
-if test $ac_cv_type_struct_sockaddr_storage = yes; then
+"
+if test "x$ac_cv_type_struct_sockaddr_storage" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRUCT_SOCKADDR_STORAGE 1
@@ -11215,108 +7784,18 @@ fi
if test "x$NEED_FAKE_RFC2553" = "x1"; then
-cat >>confdefs.h <<\_ACEOF
-#define NEED_FAKE_RFC2553 1
-_ACEOF
+$as_echo "#define NEED_FAKE_RFC2553 1" >>confdefs.h
- case $LIBOBJS in
- "fake-rfc2553.$ac_objext" | \
- *" fake-rfc2553.$ac_objext" | \
- "fake-rfc2553.$ac_objext "* | \
+ case " $LIBOBJS " in
*" fake-rfc2553.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS fake-rfc2553.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS fake-rfc2553.$ac_objext"
+ ;;
esac
- echo "$as_me:$LINENO: checking for strlcpy" >&5
-echo $ECHO_N "checking for strlcpy... $ECHO_C" >&6
-if test "${ac_cv_func_strlcpy+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define strlcpy to an innocuous variant, in case <limits.h> declares strlcpy.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strlcpy innocuous_strlcpy
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strlcpy (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
+ ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
+if test "x$ac_cv_func_strlcpy" = xyes; then :
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef strlcpy
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strlcpy ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_strlcpy) || defined (__stub___strlcpy)
-choke me
-#else
-char (*f) () = strlcpy;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != strlcpy;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strlcpy=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_strlcpy=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_func_strlcpy" >&5
-echo "${ECHO_T}$ac_cv_func_strlcpy" >&6
fi
@@ -11326,109 +7805,16 @@ fi
#--------------------------------------------------------------------
if test "${TCL_THREADS}" = 1; then
- echo "$as_me:$LINENO: checking for getpwuid_r" >&5
-echo $ECHO_N "checking for getpwuid_r... $ECHO_C" >&6
-if test "${ac_cv_func_getpwuid_r+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define getpwuid_r to an innocuous variant, in case <limits.h> declares getpwuid_r.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define getpwuid_r innocuous_getpwuid_r
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char getpwuid_r (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef getpwuid_r
+ ac_fn_c_check_func "$LINENO" "getpwuid_r" "ac_cv_func_getpwuid_r"
+if test "x$ac_cv_func_getpwuid_r" = xyes; then :
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char getpwuid_r ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_getpwuid_r) || defined (__stub___getpwuid_r)
-choke me
-#else
-char (*f) () = getpwuid_r;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != getpwuid_r;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_getpwuid_r=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_getpwuid_r=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_getpwuid_r" >&5
-echo "${ECHO_T}$ac_cv_func_getpwuid_r" >&6
-if test $ac_cv_func_getpwuid_r = yes; then
-
- echo "$as_me:$LINENO: checking for getpwuid_r with 5 args" >&5
-echo $ECHO_N "checking for getpwuid_r with 5 args... $ECHO_C" >&6
-if test "${tcl_cv_api_getpwuid_r_5+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwuid_r with 5 args" >&5
+$as_echo_n "checking for getpwuid_r with 5 args... " >&6; }
+if ${tcl_cv_api_getpwuid_r_5+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
@@ -11449,58 +7835,28 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_getpwuid_r_5=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_getpwuid_r_5=no
+ tcl_cv_api_getpwuid_r_5=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_getpwuid_r_5" >&5
-echo "${ECHO_T}$tcl_cv_api_getpwuid_r_5" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwuid_r_5" >&5
+$as_echo "$tcl_cv_api_getpwuid_r_5" >&6; }
tcl_ok=$tcl_cv_api_getpwuid_r_5
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETPWUID_R_5 1
-_ACEOF
+$as_echo "#define HAVE_GETPWUID_R_5 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for getpwuid_r with 4 args" >&5
-echo $ECHO_N "checking for getpwuid_r with 4 args... $ECHO_C" >&6
-if test "${tcl_cv_api_getpwuid_r_4+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwuid_r with 4 args" >&5
+$as_echo_n "checking for getpwuid_r with 4 args... " >&6; }
+if ${tcl_cv_api_getpwuid_r_4+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
@@ -11521,161 +7877,40 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_getpwuid_r_4=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_getpwuid_r_4=no
+ tcl_cv_api_getpwuid_r_4=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_getpwuid_r_4" >&5
-echo "${ECHO_T}$tcl_cv_api_getpwuid_r_4" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwuid_r_4" >&5
+$as_echo "$tcl_cv_api_getpwuid_r_4" >&6; }
tcl_ok=$tcl_cv_api_getpwuid_r_4
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETPWUID_R_4 1
-_ACEOF
+$as_echo "#define HAVE_GETPWUID_R_4 1" >>confdefs.h
fi
fi
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETPWUID_R 1
-_ACEOF
+$as_echo "#define HAVE_GETPWUID_R 1" >>confdefs.h
fi
fi
- echo "$as_me:$LINENO: checking for getpwnam_r" >&5
-echo $ECHO_N "checking for getpwnam_r... $ECHO_C" >&6
-if test "${ac_cv_func_getpwnam_r+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define getpwnam_r to an innocuous variant, in case <limits.h> declares getpwnam_r.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define getpwnam_r innocuous_getpwnam_r
+ ac_fn_c_check_func "$LINENO" "getpwnam_r" "ac_cv_func_getpwnam_r"
+if test "x$ac_cv_func_getpwnam_r" = xyes; then :
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char getpwnam_r (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef getpwnam_r
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char getpwnam_r ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_getpwnam_r) || defined (__stub___getpwnam_r)
-choke me
-#else
-char (*f) () = getpwnam_r;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != getpwnam_r;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_getpwnam_r=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwnam_r with 5 args" >&5
+$as_echo_n "checking for getpwnam_r with 5 args... " >&6; }
+if ${tcl_cv_api_getpwnam_r_5+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_func_getpwnam_r=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_getpwnam_r" >&5
-echo "${ECHO_T}$ac_cv_func_getpwnam_r" >&6
-if test $ac_cv_func_getpwnam_r = yes; then
-
- echo "$as_me:$LINENO: checking for getpwnam_r with 5 args" >&5
-echo $ECHO_N "checking for getpwnam_r with 5 args... $ECHO_C" >&6
-if test "${tcl_cv_api_getpwnam_r_5+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
@@ -11696,58 +7931,28 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_getpwnam_r_5=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_getpwnam_r_5=no
+ tcl_cv_api_getpwnam_r_5=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_getpwnam_r_5" >&5
-echo "${ECHO_T}$tcl_cv_api_getpwnam_r_5" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwnam_r_5" >&5
+$as_echo "$tcl_cv_api_getpwnam_r_5" >&6; }
tcl_ok=$tcl_cv_api_getpwnam_r_5
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETPWNAM_R_5 1
-_ACEOF
+$as_echo "#define HAVE_GETPWNAM_R_5 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for getpwnam_r with 4 args" >&5
-echo $ECHO_N "checking for getpwnam_r with 4 args... $ECHO_C" >&6
-if test "${tcl_cv_api_getpwnam_r_4+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getpwnam_r with 4 args" >&5
+$as_echo_n "checking for getpwnam_r with 4 args... " >&6; }
+if ${tcl_cv_api_getpwnam_r_4+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
@@ -11768,161 +7973,40 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_getpwnam_r_4=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_getpwnam_r_4=no
+ tcl_cv_api_getpwnam_r_4=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_getpwnam_r_4" >&5
-echo "${ECHO_T}$tcl_cv_api_getpwnam_r_4" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getpwnam_r_4" >&5
+$as_echo "$tcl_cv_api_getpwnam_r_4" >&6; }
tcl_ok=$tcl_cv_api_getpwnam_r_4
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETPWNAM_R_4 1
-_ACEOF
+$as_echo "#define HAVE_GETPWNAM_R_4 1" >>confdefs.h
fi
fi
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETPWNAM_R 1
-_ACEOF
+$as_echo "#define HAVE_GETPWNAM_R 1" >>confdefs.h
fi
fi
- echo "$as_me:$LINENO: checking for getgrgid_r" >&5
-echo $ECHO_N "checking for getgrgid_r... $ECHO_C" >&6
-if test "${ac_cv_func_getgrgid_r+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define getgrgid_r to an innocuous variant, in case <limits.h> declares getgrgid_r.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define getgrgid_r innocuous_getgrgid_r
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char getgrgid_r (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef getgrgid_r
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char getgrgid_r ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_getgrgid_r) || defined (__stub___getgrgid_r)
-choke me
-#else
-char (*f) () = getgrgid_r;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != getgrgid_r;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_getgrgid_r=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_getgrgid_r=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_getgrgid_r" >&5
-echo "${ECHO_T}$ac_cv_func_getgrgid_r" >&6
-if test $ac_cv_func_getgrgid_r = yes; then
+ ac_fn_c_check_func "$LINENO" "getgrgid_r" "ac_cv_func_getgrgid_r"
+if test "x$ac_cv_func_getgrgid_r" = xyes; then :
- echo "$as_me:$LINENO: checking for getgrgid_r with 5 args" >&5
-echo $ECHO_N "checking for getgrgid_r with 5 args... $ECHO_C" >&6
-if test "${tcl_cv_api_getgrgid_r_5+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrgid_r with 5 args" >&5
+$as_echo_n "checking for getgrgid_r with 5 args... " >&6; }
+if ${tcl_cv_api_getgrgid_r_5+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
@@ -11943,58 +8027,28 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_getgrgid_r_5=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_getgrgid_r_5=no
+ tcl_cv_api_getgrgid_r_5=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_getgrgid_r_5" >&5
-echo "${ECHO_T}$tcl_cv_api_getgrgid_r_5" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrgid_r_5" >&5
+$as_echo "$tcl_cv_api_getgrgid_r_5" >&6; }
tcl_ok=$tcl_cv_api_getgrgid_r_5
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETGRGID_R_5 1
-_ACEOF
+$as_echo "#define HAVE_GETGRGID_R_5 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for getgrgid_r with 4 args" >&5
-echo $ECHO_N "checking for getgrgid_r with 4 args... $ECHO_C" >&6
-if test "${tcl_cv_api_getgrgid_r_4+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrgid_r with 4 args" >&5
+$as_echo_n "checking for getgrgid_r with 4 args... " >&6; }
+if ${tcl_cv_api_getgrgid_r_4+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
@@ -12015,161 +8069,40 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_getgrgid_r_4=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_getgrgid_r_4=no
+ tcl_cv_api_getgrgid_r_4=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_getgrgid_r_4" >&5
-echo "${ECHO_T}$tcl_cv_api_getgrgid_r_4" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrgid_r_4" >&5
+$as_echo "$tcl_cv_api_getgrgid_r_4" >&6; }
tcl_ok=$tcl_cv_api_getgrgid_r_4
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETGRGID_R_4 1
-_ACEOF
+$as_echo "#define HAVE_GETGRGID_R_4 1" >>confdefs.h
fi
fi
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETGRGID_R 1
-_ACEOF
+$as_echo "#define HAVE_GETGRGID_R 1" >>confdefs.h
fi
fi
- echo "$as_me:$LINENO: checking for getgrnam_r" >&5
-echo $ECHO_N "checking for getgrnam_r... $ECHO_C" >&6
-if test "${ac_cv_func_getgrnam_r+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define getgrnam_r to an innocuous variant, in case <limits.h> declares getgrnam_r.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define getgrnam_r innocuous_getgrnam_r
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char getgrnam_r (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+ ac_fn_c_check_func "$LINENO" "getgrnam_r" "ac_cv_func_getgrnam_r"
+if test "x$ac_cv_func_getgrnam_r" = xyes; then :
-#undef getgrnam_r
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char getgrnam_r ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_getgrnam_r) || defined (__stub___getgrnam_r)
-choke me
-#else
-char (*f) () = getgrnam_r;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != getgrnam_r;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_getgrnam_r=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrnam_r with 5 args" >&5
+$as_echo_n "checking for getgrnam_r with 5 args... " >&6; }
+if ${tcl_cv_api_getgrnam_r_5+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_getgrnam_r=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_getgrnam_r" >&5
-echo "${ECHO_T}$ac_cv_func_getgrnam_r" >&6
-if test $ac_cv_func_getgrnam_r = yes; then
- echo "$as_me:$LINENO: checking for getgrnam_r with 5 args" >&5
-echo $ECHO_N "checking for getgrnam_r with 5 args... $ECHO_C" >&6
-if test "${tcl_cv_api_getgrnam_r_5+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
@@ -12190,58 +8123,28 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_getgrnam_r_5=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_getgrnam_r_5=no
+ tcl_cv_api_getgrnam_r_5=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_getgrnam_r_5" >&5
-echo "${ECHO_T}$tcl_cv_api_getgrnam_r_5" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrnam_r_5" >&5
+$as_echo "$tcl_cv_api_getgrnam_r_5" >&6; }
tcl_ok=$tcl_cv_api_getgrnam_r_5
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETGRNAM_R_5 1
-_ACEOF
+$as_echo "#define HAVE_GETGRNAM_R_5 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for getgrnam_r with 4 args" >&5
-echo $ECHO_N "checking for getgrnam_r with 4 args... $ECHO_C" >&6
-if test "${tcl_cv_api_getgrnam_r_4+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for getgrnam_r with 4 args" >&5
+$as_echo_n "checking for getgrnam_r with 4 args... " >&6; }
+if ${tcl_cv_api_getgrnam_r_4+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
@@ -12262,53 +8165,25 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_getgrnam_r_4=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_getgrnam_r_4=no
+ tcl_cv_api_getgrnam_r_4=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_getgrnam_r_4" >&5
-echo "${ECHO_T}$tcl_cv_api_getgrnam_r_4" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_getgrnam_r_4" >&5
+$as_echo "$tcl_cv_api_getgrnam_r_4" >&6; }
tcl_ok=$tcl_cv_api_getgrnam_r_4
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETGRNAM_R_4 1
-_ACEOF
+$as_echo "#define HAVE_GETGRNAM_R_4 1" >>confdefs.h
fi
fi
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETGRNAM_R 1
-_ACEOF
+$as_echo "#define HAVE_GETGRNAM_R 1" >>confdefs.h
fi
@@ -12320,14 +8195,10 @@ fi
# are actually MT-safe as they always return pointers
# from TSD instead of static storage.
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_MTSAFE_GETHOSTBYNAME 1
-_ACEOF
+$as_echo "#define HAVE_MTSAFE_GETHOSTBYNAME 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_MTSAFE_GETHOSTBYADDR 1
-_ACEOF
+$as_echo "#define HAVE_MTSAFE_GETHOSTBYADDR 1" >>confdefs.h
elif test "`uname -s`" = "HP-UX" && \
@@ -12336,120 +8207,23 @@ _ACEOF
# are actually MT-safe as they always return pointers
# from TSD instead of static storage.
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_MTSAFE_GETHOSTBYNAME 1
-_ACEOF
+$as_echo "#define HAVE_MTSAFE_GETHOSTBYNAME 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_MTSAFE_GETHOSTBYADDR 1
-_ACEOF
+$as_echo "#define HAVE_MTSAFE_GETHOSTBYADDR 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for gethostbyname_r" >&5
-echo $ECHO_N "checking for gethostbyname_r... $ECHO_C" >&6
-if test "${ac_cv_func_gethostbyname_r+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define gethostbyname_r to an innocuous variant, in case <limits.h> declares gethostbyname_r.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define gethostbyname_r innocuous_gethostbyname_r
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char gethostbyname_r (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef gethostbyname_r
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char gethostbyname_r ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_gethostbyname_r) || defined (__stub___gethostbyname_r)
-choke me
-#else
-char (*f) () = gethostbyname_r;
-#endif
-#ifdef __cplusplus
-}
-#endif
+ ac_fn_c_check_func "$LINENO" "gethostbyname_r" "ac_cv_func_gethostbyname_r"
+if test "x$ac_cv_func_gethostbyname_r" = xyes; then :
-int
-main ()
-{
-return f != gethostbyname_r;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_gethostbyname_r=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_gethostbyname_r=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyname_r" >&5
-echo "${ECHO_T}$ac_cv_func_gethostbyname_r" >&6
-if test $ac_cv_func_gethostbyname_r = yes; then
-
- echo "$as_me:$LINENO: checking for gethostbyname_r with 6 args" >&5
-echo $ECHO_N "checking for gethostbyname_r with 6 args... $ECHO_C" >&6
-if test "${tcl_cv_api_gethostbyname_r_6+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r with 6 args" >&5
+$as_echo_n "checking for gethostbyname_r with 6 args... " >&6; }
+if ${tcl_cv_api_gethostbyname_r_6+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <netdb.h>
@@ -12470,58 +8244,28 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_gethostbyname_r_6=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_gethostbyname_r_6=no
+ tcl_cv_api_gethostbyname_r_6=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyname_r_6" >&5
-echo "${ECHO_T}$tcl_cv_api_gethostbyname_r_6" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyname_r_6" >&5
+$as_echo "$tcl_cv_api_gethostbyname_r_6" >&6; }
tcl_ok=$tcl_cv_api_gethostbyname_r_6
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETHOSTBYNAME_R_6 1
-_ACEOF
+$as_echo "#define HAVE_GETHOSTBYNAME_R_6 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for gethostbyname_r with 5 args" >&5
-echo $ECHO_N "checking for gethostbyname_r with 5 args... $ECHO_C" >&6
-if test "${tcl_cv_api_gethostbyname_r_5+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r with 5 args" >&5
+$as_echo_n "checking for gethostbyname_r with 5 args... " >&6; }
+if ${tcl_cv_api_gethostbyname_r_5+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <netdb.h>
@@ -12542,58 +8286,28 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_gethostbyname_r_5=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_gethostbyname_r_5=no
+ tcl_cv_api_gethostbyname_r_5=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyname_r_5" >&5
-echo "${ECHO_T}$tcl_cv_api_gethostbyname_r_5" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyname_r_5" >&5
+$as_echo "$tcl_cv_api_gethostbyname_r_5" >&6; }
tcl_ok=$tcl_cv_api_gethostbyname_r_5
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETHOSTBYNAME_R_5 1
-_ACEOF
+$as_echo "#define HAVE_GETHOSTBYNAME_R_5 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for gethostbyname_r with 3 args" >&5
-echo $ECHO_N "checking for gethostbyname_r with 3 args... $ECHO_C" >&6
-if test "${tcl_cv_api_gethostbyname_r_3+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyname_r with 3 args" >&5
+$as_echo_n "checking for gethostbyname_r with 3 args... " >&6; }
+if ${tcl_cv_api_gethostbyname_r_3+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <netdb.h>
@@ -12612,162 +8326,41 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_gethostbyname_r_3=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_gethostbyname_r_3=no
+ tcl_cv_api_gethostbyname_r_3=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyname_r_3" >&5
-echo "${ECHO_T}$tcl_cv_api_gethostbyname_r_3" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyname_r_3" >&5
+$as_echo "$tcl_cv_api_gethostbyname_r_3" >&6; }
tcl_ok=$tcl_cv_api_gethostbyname_r_3
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETHOSTBYNAME_R_3 1
-_ACEOF
+$as_echo "#define HAVE_GETHOSTBYNAME_R_3 1" >>confdefs.h
fi
fi
fi
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETHOSTBYNAME_R 1
-_ACEOF
+$as_echo "#define HAVE_GETHOSTBYNAME_R 1" >>confdefs.h
fi
fi
- echo "$as_me:$LINENO: checking for gethostbyaddr_r" >&5
-echo $ECHO_N "checking for gethostbyaddr_r... $ECHO_C" >&6
-if test "${ac_cv_func_gethostbyaddr_r+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define gethostbyaddr_r to an innocuous variant, in case <limits.h> declares gethostbyaddr_r.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define gethostbyaddr_r innocuous_gethostbyaddr_r
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char gethostbyaddr_r (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef gethostbyaddr_r
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char gethostbyaddr_r ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_gethostbyaddr_r) || defined (__stub___gethostbyaddr_r)
-choke me
-#else
-char (*f) () = gethostbyaddr_r;
-#endif
-#ifdef __cplusplus
-}
-#endif
+ ac_fn_c_check_func "$LINENO" "gethostbyaddr_r" "ac_cv_func_gethostbyaddr_r"
+if test "x$ac_cv_func_gethostbyaddr_r" = xyes; then :
-int
-main ()
-{
-return f != gethostbyaddr_r;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_gethostbyaddr_r=yes
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr_r with 7 args" >&5
+$as_echo_n "checking for gethostbyaddr_r with 7 args... " >&6; }
+if ${tcl_cv_api_gethostbyaddr_r_7+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-ac_cv_func_gethostbyaddr_r=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_gethostbyaddr_r" >&5
-echo "${ECHO_T}$ac_cv_func_gethostbyaddr_r" >&6
-if test $ac_cv_func_gethostbyaddr_r = yes; then
-
- echo "$as_me:$LINENO: checking for gethostbyaddr_r with 7 args" >&5
-echo $ECHO_N "checking for gethostbyaddr_r with 7 args... $ECHO_C" >&6
-if test "${tcl_cv_api_gethostbyaddr_r_7+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <netdb.h>
@@ -12791,58 +8384,28 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_gethostbyaddr_r_7=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_gethostbyaddr_r_7=no
+ tcl_cv_api_gethostbyaddr_r_7=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyaddr_r_7" >&5
-echo "${ECHO_T}$tcl_cv_api_gethostbyaddr_r_7" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyaddr_r_7" >&5
+$as_echo "$tcl_cv_api_gethostbyaddr_r_7" >&6; }
tcl_ok=$tcl_cv_api_gethostbyaddr_r_7
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETHOSTBYADDR_R_7 1
-_ACEOF
+$as_echo "#define HAVE_GETHOSTBYADDR_R_7 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for gethostbyaddr_r with 8 args" >&5
-echo $ECHO_N "checking for gethostbyaddr_r with 8 args... $ECHO_C" >&6
-if test "${tcl_cv_api_gethostbyaddr_r_8+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for gethostbyaddr_r with 8 args" >&5
+$as_echo_n "checking for gethostbyaddr_r with 8 args... " >&6; }
+if ${tcl_cv_api_gethostbyaddr_r_8+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <netdb.h>
@@ -12866,53 +8429,25 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_api_gethostbyaddr_r_8=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_gethostbyaddr_r_8=no
+ tcl_cv_api_gethostbyaddr_r_8=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_gethostbyaddr_r_8" >&5
-echo "${ECHO_T}$tcl_cv_api_gethostbyaddr_r_8" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_gethostbyaddr_r_8" >&5
+$as_echo "$tcl_cv_api_gethostbyaddr_r_8" >&6; }
tcl_ok=$tcl_cv_api_gethostbyaddr_r_8
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETHOSTBYADDR_R_8 1
-_ACEOF
+$as_echo "#define HAVE_GETHOSTBYADDR_R_8 1" >>confdefs.h
fi
fi
if test "$tcl_ok" = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_GETHOSTBYADDR_R 1
-_ACEOF
+$as_echo "#define HAVE_GETHOSTBYADDR_R 1" >>confdefs.h
fi
@@ -12930,450 +8465,36 @@ fi
# sys/modem.h is needed on HP-UX.
#---------------------------------------------------------------------------
-
for ac_header in termios.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "termios.h" "ac_cv_header_termios_h" "$ac_includes_default"
+if test "x$ac_cv_header_termios_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_TERMIOS_H 1
_ACEOF
fi
done
-
for ac_header in sys/ioctl.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_ioctl_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_SYS_IOCTL_H 1
_ACEOF
fi
done
-
for ac_header in sys/modem.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/modem.h" "ac_cv_header_sys_modem_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_modem_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_SYS_MODEM_H 1
_ACEOF
fi
@@ -13391,17 +8512,13 @@ done
# special flag.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for fd_set in sys/types" >&5
-echo $ECHO_N "checking for fd_set in sys/types... $ECHO_C" >&6
-if test "${tcl_cv_type_fd_set+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fd_set in sys/types" >&5
+$as_echo_n "checking for fd_set in sys/types... " >&6; }
+if ${tcl_cv_type_fd_set+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
int
@@ -13412,58 +8529,30 @@ fd_set readMask, writeMask;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_type_fd_set=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_type_fd_set=no
+ tcl_cv_type_fd_set=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_type_fd_set" >&5
-echo "${ECHO_T}$tcl_cv_type_fd_set" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_type_fd_set" >&5
+$as_echo "$tcl_cv_type_fd_set" >&6; }
tcl_ok=$tcl_cv_type_fd_set
if test $tcl_ok = no; then
- echo "$as_me:$LINENO: checking for fd_mask in sys/select" >&5
-echo $ECHO_N "checking for fd_mask in sys/select... $ECHO_C" >&6
-if test "${tcl_cv_grep_fd_mask+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fd_mask in sys/select" >&5
+$as_echo_n "checking for fd_mask in sys/select... " >&6; }
+if ${tcl_cv_grep_fd_mask+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/select.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "fd_mask" >/dev/null 2>&1; then
+ $EGREP "fd_mask" >/dev/null 2>&1; then :
tcl_cv_grep_fd_mask=present
else
tcl_cv_grep_fd_mask=missing
@@ -13471,22 +8560,18 @@ fi
rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $tcl_cv_grep_fd_mask" >&5
-echo "${ECHO_T}$tcl_cv_grep_fd_mask" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_grep_fd_mask" >&5
+$as_echo "$tcl_cv_grep_fd_mask" >&6; }
if test $tcl_cv_grep_fd_mask = present; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_SYS_SELECT_H 1
-_ACEOF
+$as_echo "#define HAVE_SYS_SELECT_H 1" >>confdefs.h
tcl_ok=yes
fi
fi
if test $tcl_ok = no; then
-cat >>confdefs.h <<\_ACEOF
-#define NO_FD_SET 1
-_ACEOF
+$as_echo "#define NO_FD_SET 1" >>confdefs.h
fi
@@ -13495,166 +8580,24 @@ fi
#------------------------------------------------------------------------------
-
-for ac_header in sys/time.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ for ac_header in sys/time.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/time.h" "ac_cv_header_sys_time_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_time_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_SYS_TIME_H 1
_ACEOF
fi
done
- echo "$as_me:$LINENO: checking whether time.h and sys/time.h may both be included" >&5
-echo $ECHO_N "checking whether time.h and sys/time.h may both be included... $ECHO_C" >&6
-if test "${ac_cv_header_time+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether time.h and sys/time.h may both be included" >&5
+$as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
+if ${ac_cv_header_time+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
#include <sys/time.h>
@@ -13669,164 +8612,42 @@ return 0;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_header_time=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_header_time=no
+ ac_cv_header_time=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_header_time" >&5
-echo "${ECHO_T}$ac_cv_header_time" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_time" >&5
+$as_echo "$ac_cv_header_time" >&6; }
if test $ac_cv_header_time = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define TIME_WITH_SYS_TIME 1
-_ACEOF
+$as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h
fi
-
-
-
-for ac_func in gmtime_r localtime_r mktime
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+ for ac_func in gmtime_r localtime_r mktime
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
done
- echo "$as_me:$LINENO: checking tm_tzadj in struct tm" >&5
-echo $ECHO_N "checking tm_tzadj in struct tm... $ECHO_C" >&6
-if test "${tcl_cv_member_tm_tzadj+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking tm_tzadj in struct tm" >&5
+$as_echo_n "checking tm_tzadj in struct tm... " >&6; }
+if ${tcl_cv_member_tm_tzadj+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <time.h>
int
@@ -13837,58 +8658,28 @@ struct tm tm; tm.tm_tzadj;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_member_tm_tzadj=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_member_tm_tzadj=no
+ tcl_cv_member_tm_tzadj=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_member_tm_tzadj" >&5
-echo "${ECHO_T}$tcl_cv_member_tm_tzadj" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_member_tm_tzadj" >&5
+$as_echo "$tcl_cv_member_tm_tzadj" >&6; }
if test $tcl_cv_member_tm_tzadj = yes ; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_TM_TZADJ 1
-_ACEOF
+$as_echo "#define HAVE_TM_TZADJ 1" >>confdefs.h
fi
- echo "$as_me:$LINENO: checking tm_gmtoff in struct tm" >&5
-echo $ECHO_N "checking tm_gmtoff in struct tm... $ECHO_C" >&6
-if test "${tcl_cv_member_tm_gmtoff+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking tm_gmtoff in struct tm" >&5
+$as_echo_n "checking tm_gmtoff in struct tm... " >&6; }
+if ${tcl_cv_member_tm_gmtoff+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <time.h>
int
@@ -13899,44 +8690,18 @@ struct tm tm; tm.tm_gmtoff;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_member_tm_gmtoff=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_member_tm_gmtoff=no
+ tcl_cv_member_tm_gmtoff=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_member_tm_gmtoff" >&5
-echo "${ECHO_T}$tcl_cv_member_tm_gmtoff" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_member_tm_gmtoff" >&5
+$as_echo "$tcl_cv_member_tm_gmtoff" >&6; }
if test $tcl_cv_member_tm_gmtoff = yes ; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_TM_GMTOFF 1
-_ACEOF
+$as_echo "#define HAVE_TM_GMTOFF 1" >>confdefs.h
fi
@@ -13944,17 +8709,13 @@ _ACEOF
# Its important to include time.h in this check, as some systems
# (like convex) have timezone functions, etc.
#
- echo "$as_me:$LINENO: checking long timezone variable" >&5
-echo $ECHO_N "checking long timezone variable... $ECHO_C" >&6
-if test "${tcl_cv_timezone_long+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking long timezone variable" >&5
+$as_echo_n "checking long timezone variable... " >&6; }
+if ${tcl_cv_timezone_long+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <time.h>
int
@@ -13967,60 +8728,30 @@ extern long timezone;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_timezone_long=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_timezone_long=no
+ tcl_cv_timezone_long=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_timezone_long" >&5
-echo "${ECHO_T}$tcl_cv_timezone_long" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_timezone_long" >&5
+$as_echo "$tcl_cv_timezone_long" >&6; }
if test $tcl_cv_timezone_long = yes ; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_TIMEZONE_VAR 1
-_ACEOF
+$as_echo "#define HAVE_TIMEZONE_VAR 1" >>confdefs.h
else
#
# On some systems (eg IRIX 6.2), timezone is a time_t and not a long.
#
- echo "$as_me:$LINENO: checking time_t timezone variable" >&5
-echo $ECHO_N "checking time_t timezone variable... $ECHO_C" >&6
-if test "${tcl_cv_timezone_time+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking time_t timezone variable" >&5
+$as_echo_n "checking time_t timezone variable... " >&6; }
+if ${tcl_cv_timezone_time+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <time.h>
int
@@ -14033,49 +8764,144 @@ extern time_t timezone;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_timezone_time=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_timezone_time=no
+ tcl_cv_timezone_time=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_timezone_time" >&5
-echo "${ECHO_T}$tcl_cv_timezone_time" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_timezone_time" >&5
+$as_echo "$tcl_cv_timezone_time" >&6; }
if test $tcl_cv_timezone_time = yes ; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_TIMEZONE_VAR 1
-_ACEOF
+$as_echo "#define HAVE_TIMEZONE_VAR 1" >>confdefs.h
fi
fi
+#------------------------------------------------------------------------------
+# Check if we want to use pcre
+#------------------------------------------------------------------------------
+
+
+
+# Check whether --with-pcre was given.
+if test "${with_pcre+set}" = set; then :
+ withval=$with_pcre; with_pcre=${withval}
+fi
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for PCRE configuration" >&5
+$as_echo_n "checking for PCRE configuration... " >&6; }
+
+ if ${ac_cv_c_pcre+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+
+ PCRE_CONFIG="pcre-config"
+ # First check to see if --with-pcre was specified.
+ if test x"${with_pcre}" != x ; then
+ if test -f "${with_pcre}/include/pcre.h" -a \
+ \( -f "${with_pcre}/lib/libpcre.so" -o \
+ -f "${with_pcre}/lib/libpcre.a" \); then
+ ac_cv_c_pcre=`(cd ${with_pcre}; pwd)`
+ PCRE_INCLUDE="-I${ac_cv_c_pcre}/include"
+ PCRE_LIBS="-L${ac_cv_c_pcre}/lib -lpcre"
+ PCRE_CONFIG="${ac_cv_c_pcre}/bin/pcre-config"
+ else
+ as_fn_error $? "${with_pcre} directory doesn't contain pcre header and/or library" "$LINENO" 5
+ fi
+ fi
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ # Try pcre-config if it exists
+ ac_cv_c_pcre=`${PCRE_CONFIG} --prefix 2>/dev/null`
+ if test "$?" -eq 0; then
+ PCRE_INCLUDE=`${PCRE_CONFIG} --cflags 2>/dev/null`
+ PCRE_LIBS=`${PCRE_CONFIG} --libs 2>/dev/null`
+ fi
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_pcre}" = x ; then
+ for i in \
+ `ls -d ${exec_prefix} 2>/dev/null` \
+ `ls -d ${prefix} 2>/dev/null` \
+ `ls -d /usr/local 2>/dev/null` \
+ `ls -d /usr/contrib 2>/dev/null` \
+ `ls -d /usr 2>/dev/null` \
+ ; do
+ if test -f "${i}/include/pcre.h" -a \
+ \( -f "${i}/lib/libpcre.so" -o \
+ -f "${i}/lib/libpcre.a" \); then
+ ac_cv_c_pcre=`(cd $i; pwd)`
+ PCRE_INCLUDE="-I${ac_cv_c_pcre}/include"
+ PCRE_LIBS="-L${ac_cv_c_pcre}/lib -lpcre"
+ break
+ fi
+ done
+ fi
+
+fi
+
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ as_fn_error $? "Can't find PCRE configuration" "$LINENO" 5
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: found PCRE configuration at ${ac_cv_c_pcre}" >&5
+$as_echo "found PCRE configuration at ${ac_cv_c_pcre}" >&6; }
+ fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable pcre in Tcl" >&5
+$as_echo_n "checking whether to enable pcre in Tcl... " >&6; }
+ # Check whether --enable-pcre was given.
+if test "${enable_pcre+set}" = set; then :
+ enableval=$enable_pcre; enable_pcre=$enableval
+else
+ enable_pcre=no
+fi
+
+
+ if test "${enable_pcre+set}" = set; then
+ enableval="$enable_pcre"
+ enable_pcre=$enableval
+ else
+ enable_pcre=yes
+ fi
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: pcre configuration not found" >&5
+$as_echo "pcre configuration not found" >&6; }
+ else
+ if test "$enable_pcre" = "default" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: pcre default" >&5
+$as_echo "pcre default" >&6; }
+
+$as_echo "#define USE_DEFAULT_PCRE 1" >>confdefs.h
+
+
+$as_echo "#define HAVE_PCRE 1" >>confdefs.h
+
+ elif test "$enable_pcre" = "yes" ; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: pcre enabled" >&5
+$as_echo "pcre enabled" >&6; }
+
+$as_echo "#define HAVE_PCRE 1" >>confdefs.h
+
+ else
+ PCRE_INCLUDE=
+ PCRE_LIBS=
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no pcre" >&5
+$as_echo "no pcre" >&6; }
+ fi
+ fi
+
+
#--------------------------------------------------------------------
# Some systems (e.g., IRIX 4.0.5) lack some fields in struct stat. But
# we might be able to use fstatfs instead. Some systems (OpenBSD?) also
@@ -14083,108 +8909,8 @@ _ACEOF
#--------------------------------------------------------------------
if test "$ac_cv_cygwin" != "yes"; then
- echo "$as_me:$LINENO: checking for struct stat.st_blocks" >&5
-echo $ECHO_N "checking for struct stat.st_blocks... $ECHO_C" >&6
-if test "${ac_cv_member_struct_stat_st_blocks+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static struct stat ac_aggr;
-if (ac_aggr.st_blocks)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_member_struct_stat_st_blocks=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static struct stat ac_aggr;
-if (sizeof ac_aggr.st_blocks)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_member_struct_stat_st_blocks=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_member_struct_stat_st_blocks=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blocks" >&5
-echo "${ECHO_T}$ac_cv_member_struct_stat_st_blocks" >&6
-if test $ac_cv_member_struct_stat_st_blocks = yes; then
+ ac_fn_c_check_member "$LINENO" "struct stat" "st_blocks" "ac_cv_member_struct_stat_st_blocks" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_blocks" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRUCT_STAT_ST_BLOCKS 1
@@ -14192,108 +8918,8 @@ _ACEOF
fi
-echo "$as_me:$LINENO: checking for struct stat.st_blksize" >&5
-echo $ECHO_N "checking for struct stat.st_blksize... $ECHO_C" >&6
-if test "${ac_cv_member_struct_stat_st_blksize+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static struct stat ac_aggr;
-if (ac_aggr.st_blksize)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_member_struct_stat_st_blksize=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-static struct stat ac_aggr;
-if (sizeof ac_aggr.st_blksize)
-return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_member_struct_stat_st_blksize=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_member_struct_stat_st_blksize=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_member_struct_stat_st_blksize" >&5
-echo "${ECHO_T}$ac_cv_member_struct_stat_st_blksize" >&6
-if test $ac_cv_member_struct_stat_st_blksize = yes; then
+ac_fn_c_check_member "$LINENO" "struct stat" "st_blksize" "ac_cv_member_struct_stat_st_blksize" "$ac_includes_default"
+if test "x$ac_cv_member_struct_stat_st_blksize" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
@@ -14303,63 +8929,8 @@ _ACEOF
fi
fi
-echo "$as_me:$LINENO: checking for blkcnt_t" >&5
-echo $ECHO_N "checking for blkcnt_t... $ECHO_C" >&6
-if test "${ac_cv_type_blkcnt_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-if ((blkcnt_t *) 0)
- return 0;
-if (sizeof (blkcnt_t))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_blkcnt_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_blkcnt_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_blkcnt_t" >&5
-echo "${ECHO_T}$ac_cv_type_blkcnt_t" >&6
-if test $ac_cv_type_blkcnt_t = yes; then
+ac_fn_c_check_type "$LINENO" "blkcnt_t" "ac_cv_type_blkcnt_t" "$ac_includes_default"
+if test "x$ac_cv_type_blkcnt_t" = xyes; then :
cat >>confdefs.h <<_ACEOF
#define HAVE_BLKCNT_T 1
@@ -14368,103 +8939,12 @@ _ACEOF
fi
-echo "$as_me:$LINENO: checking for fstatfs" >&5
-echo $ECHO_N "checking for fstatfs... $ECHO_C" >&6
-if test "${ac_cv_func_fstatfs+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define fstatfs to an innocuous variant, in case <limits.h> declares fstatfs.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define fstatfs innocuous_fstatfs
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char fstatfs (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef fstatfs
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char fstatfs ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_fstatfs) || defined (__stub___fstatfs)
-choke me
-#else
-char (*f) () = fstatfs;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != fstatfs;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_fstatfs=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ac_fn_c_check_func "$LINENO" "fstatfs" "ac_cv_func_fstatfs"
+if test "x$ac_cv_func_fstatfs" = xyes; then :
-ac_cv_func_fstatfs=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_fstatfs" >&5
-echo "${ECHO_T}$ac_cv_func_fstatfs" >&6
-if test $ac_cv_func_fstatfs = yes; then
- :
else
-cat >>confdefs.h <<\_ACEOF
-#define NO_FSTATFS 1
-_ACEOF
+$as_echo "#define NO_FSTATFS 1" >>confdefs.h
fi
@@ -14474,19 +8954,15 @@ fi
# checks it and add memcmp.o to LIBOBJS if needed
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for working memcmp" >&5
-echo $ECHO_N "checking for working memcmp... $ECHO_C" >&6
-if test "${ac_cv_func_memcmp_working+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for working memcmp" >&5
+$as_echo_n "checking for working memcmp... " >&6; }
+if ${ac_cv_func_memcmp_working+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- if test "$cross_compiling" = yes; then
+ if test "$cross_compiling" = yes; then :
ac_cv_func_memcmp_working=no
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
int
@@ -14494,9 +8970,9 @@ main ()
{
/* Some versions of memcmp are not 8-bit clean. */
- char c0 = 0x40, c1 = 0x80, c2 = 0x81;
+ char c0 = '\100', c1 = '\200', c2 = '\201';
if (memcmp(&c0, &c2, 1) >= 0 || memcmp(&c1, &c2, 1) >= 0)
- exit (1);
+ return 1;
/* The Next x86 OpenStep bug shows up only when comparing 16 bytes
or more and with at least one buffer not starting on a 4-byte boundary.
@@ -14512,46 +8988,31 @@ main ()
strcpy (a, "--------01111111");
strcpy (b, "--------10000000");
if (memcmp (a, b, 16) >= 0)
- exit (1);
+ return 1;
}
- exit (0);
+ return 0;
}
;
return 0;
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_run "$LINENO"; then :
ac_cv_func_memcmp_working=yes
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_func_memcmp_working=no
+ ac_cv_func_memcmp_working=no
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+
fi
-echo "$as_me:$LINENO: result: $ac_cv_func_memcmp_working" >&5
-echo "${ECHO_T}$ac_cv_func_memcmp_working" >&6
-test $ac_cv_func_memcmp_working = no && case $LIBOBJS in
- "memcmp.$ac_objext" | \
- *" memcmp.$ac_objext" | \
- "memcmp.$ac_objext "* | \
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_memcmp_working" >&5
+$as_echo "$ac_cv_func_memcmp_working" >&6; }
+test $ac_cv_func_memcmp_working = no && case " $LIBOBJS " in
*" memcmp.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS memcmp.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS memcmp.$ac_objext"
+ ;;
esac
@@ -14562,109 +9023,16 @@ esac
# compat/string.h}
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for memmove" >&5
-echo $ECHO_N "checking for memmove... $ECHO_C" >&6
-if test "${ac_cv_func_memmove+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define memmove to an innocuous variant, in case <limits.h> declares memmove.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define memmove innocuous_memmove
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char memmove (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef memmove
+ac_fn_c_check_func "$LINENO" "memmove" "ac_cv_func_memmove"
+if test "x$ac_cv_func_memmove" = xyes; then :
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char memmove ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_memmove) || defined (__stub___memmove)
-choke me
-#else
-char (*f) () = memmove;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != memmove;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_memmove=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_memmove=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_memmove" >&5
-echo "${ECHO_T}$ac_cv_func_memmove" >&6
-if test $ac_cv_func_memmove = yes; then
- :
else
-cat >>confdefs.h <<\_ACEOF
-#define NO_MEMMOVE 1
-_ACEOF
+$as_echo "#define NO_MEMMOVE 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define NO_STRING_H 1
-_ACEOF
+$as_echo "#define NO_STRING_H 1" >>confdefs.h
fi
@@ -14675,147 +9043,41 @@ fi
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for strstr" >&5
-echo $ECHO_N "checking for strstr... $ECHO_C" >&6
-if test "${ac_cv_func_strstr+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define strstr to an innocuous variant, in case <limits.h> declares strstr.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strstr innocuous_strstr
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strstr (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef strstr
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strstr ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_strstr) || defined (__stub___strstr)
-choke me
-#else
-char (*f) () = strstr;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != strstr;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strstr=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_strstr=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_strstr" >&5
-echo "${ECHO_T}$ac_cv_func_strstr" >&6
-if test $ac_cv_func_strstr = yes; then
+ ac_fn_c_check_func "$LINENO" "strstr" "ac_cv_func_strstr"
+if test "x$ac_cv_func_strstr" = xyes; then :
tcl_ok=1
else
tcl_ok=0
fi
if test "$tcl_ok" = 1; then
- echo "$as_me:$LINENO: checking proper strstr implementation" >&5
-echo $ECHO_N "checking proper strstr implementation... $ECHO_C" >&6
-if test "${tcl_cv_strstr_unbroken+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strstr implementation" >&5
+$as_echo_n "checking proper strstr implementation... " >&6; }
+if ${tcl_cv_strstr_unbroken+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- if test "$cross_compiling" = yes; then
+ if test "$cross_compiling" = yes; then :
tcl_cv_strstr_unbroken=unknown
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int main() {
extern int strstr();
exit(strstr("\0test", "test") ? 1 : 0);
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_run "$LINENO"; then :
tcl_cv_strstr_unbroken=ok
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-tcl_cv_strstr_unbroken=broken
+ tcl_cv_strstr_unbroken=broken
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+
fi
-echo "$as_me:$LINENO: result: $tcl_cv_strstr_unbroken" >&5
-echo "${ECHO_T}$tcl_cv_strstr_unbroken" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strstr_unbroken" >&5
+$as_echo "$tcl_cv_strstr_unbroken" >&6; }
if test "$tcl_cv_strstr_unbroken" = "ok"; then
tcl_ok=1
else
@@ -14823,12 +9085,10 @@ echo "${ECHO_T}$tcl_cv_strstr_unbroken" >&6
fi
fi
if test "$tcl_ok" = 0; then
- case $LIBOBJS in
- "strstr.$ac_objext" | \
- *" strstr.$ac_objext" | \
- "strstr.$ac_objext "* | \
+ case " $LIBOBJS " in
*" strstr.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS strstr.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS strstr.$ac_objext"
+ ;;
esac
USE_COMPAT=1
@@ -14842,116 +9102,23 @@ esac
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for strtoul" >&5
-echo $ECHO_N "checking for strtoul... $ECHO_C" >&6
-if test "${ac_cv_func_strtoul+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define strtoul to an innocuous variant, in case <limits.h> declares strtoul.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strtoul innocuous_strtoul
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strtoul (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef strtoul
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strtoul ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_strtoul) || defined (__stub___strtoul)
-choke me
-#else
-char (*f) () = strtoul;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != strtoul;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strtoul=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_strtoul=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_strtoul" >&5
-echo "${ECHO_T}$ac_cv_func_strtoul" >&6
-if test $ac_cv_func_strtoul = yes; then
+ ac_fn_c_check_func "$LINENO" "strtoul" "ac_cv_func_strtoul"
+if test "x$ac_cv_func_strtoul" = xyes; then :
tcl_ok=1
else
tcl_ok=0
fi
if test "$tcl_ok" = 1; then
- echo "$as_me:$LINENO: checking proper strtoul implementation" >&5
-echo $ECHO_N "checking proper strtoul implementation... $ECHO_C" >&6
-if test "${tcl_cv_strtoul_unbroken+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strtoul implementation" >&5
+$as_echo_n "checking proper strtoul implementation... " >&6; }
+if ${tcl_cv_strtoul_unbroken+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- if test "$cross_compiling" = yes; then
+ if test "$cross_compiling" = yes; then :
tcl_cv_strtoul_unbroken=unknown
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int main() {
extern int strtoul();
@@ -14959,31 +9126,18 @@ int main() {
exit(strtoul(string,&term,0) != 0 || term != string+1);
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_run "$LINENO"; then :
tcl_cv_strtoul_unbroken=ok
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-tcl_cv_strtoul_unbroken=broken
+ tcl_cv_strtoul_unbroken=broken
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+
fi
-echo "$as_me:$LINENO: result: $tcl_cv_strtoul_unbroken" >&5
-echo "${ECHO_T}$tcl_cv_strtoul_unbroken" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtoul_unbroken" >&5
+$as_echo "$tcl_cv_strtoul_unbroken" >&6; }
if test "$tcl_cv_strtoul_unbroken" = "ok"; then
tcl_ok=1
else
@@ -14991,12 +9145,10 @@ echo "${ECHO_T}$tcl_cv_strtoul_unbroken" >&6
fi
fi
if test "$tcl_ok" = 0; then
- case $LIBOBJS in
- "strtoul.$ac_objext" | \
- *" strtoul.$ac_objext" | \
- "strtoul.$ac_objext "* | \
+ case " $LIBOBJS " in
*" strtoul.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS strtoul.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS strtoul.$ac_objext"
+ ;;
esac
USE_COMPAT=1
@@ -15009,116 +9161,23 @@ esac
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for strtod" >&5
-echo $ECHO_N "checking for strtod... $ECHO_C" >&6
-if test "${ac_cv_func_strtod+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define strtod to an innocuous variant, in case <limits.h> declares strtod.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strtod innocuous_strtod
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strtod (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef strtod
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strtod ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_strtod) || defined (__stub___strtod)
-choke me
-#else
-char (*f) () = strtod;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != strtod;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strtod=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_strtod=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5
-echo "${ECHO_T}$ac_cv_func_strtod" >&6
-if test $ac_cv_func_strtod = yes; then
+ ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod"
+if test "x$ac_cv_func_strtod" = xyes; then :
tcl_ok=1
else
tcl_ok=0
fi
if test "$tcl_ok" = 1; then
- echo "$as_me:$LINENO: checking proper strtod implementation" >&5
-echo $ECHO_N "checking proper strtod implementation... $ECHO_C" >&6
-if test "${tcl_cv_strtod_unbroken+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking proper strtod implementation" >&5
+$as_echo_n "checking proper strtod implementation... " >&6; }
+if ${tcl_cv_strtod_unbroken+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- if test "$cross_compiling" = yes; then
+ if test "$cross_compiling" = yes; then :
tcl_cv_strtod_unbroken=unknown
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int main() {
extern double strtod();
@@ -15126,31 +9185,18 @@ int main() {
exit(strtod(string,&term) != 69 || term != string+4);
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_run "$LINENO"; then :
tcl_cv_strtod_unbroken=ok
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-tcl_cv_strtod_unbroken=broken
+ tcl_cv_strtod_unbroken=broken
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+
fi
-echo "$as_me:$LINENO: result: $tcl_cv_strtod_unbroken" >&5
-echo "${ECHO_T}$tcl_cv_strtod_unbroken" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtod_unbroken" >&5
+$as_echo "$tcl_cv_strtod_unbroken" >&6; }
if test "$tcl_cv_strtod_unbroken" = "ok"; then
tcl_ok=1
else
@@ -15158,12 +9204,10 @@ echo "${ECHO_T}$tcl_cv_strtod_unbroken" >&6
fi
fi
if test "$tcl_ok" = 0; then
- case $LIBOBJS in
- "strtod.$ac_objext" | \
- *" strtod.$ac_objext" | \
- "strtod.$ac_objext "* | \
+ case " $LIBOBJS " in
*" strtod.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS strtod.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS strtod.$ac_objext"
+ ;;
esac
USE_COMPAT=1
@@ -15178,117 +9222,24 @@ esac
#--------------------------------------------------------------------
- echo "$as_me:$LINENO: checking for strtod" >&5
-echo $ECHO_N "checking for strtod... $ECHO_C" >&6
-if test "${ac_cv_func_strtod+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define strtod to an innocuous variant, in case <limits.h> declares strtod.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strtod innocuous_strtod
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strtod (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef strtod
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strtod ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_strtod) || defined (__stub___strtod)
-choke me
-#else
-char (*f) () = strtod;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != strtod;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strtod=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_strtod=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5
-echo "${ECHO_T}$ac_cv_func_strtod" >&6
-if test $ac_cv_func_strtod = yes; then
+ ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod"
+if test "x$ac_cv_func_strtod" = xyes; then :
tcl_strtod=1
else
tcl_strtod=0
fi
if test "$tcl_strtod" = 1; then
- echo "$as_me:$LINENO: checking for Solaris2.4/Tru64 strtod bugs" >&5
-echo $ECHO_N "checking for Solaris2.4/Tru64 strtod bugs... $ECHO_C" >&6
-if test "${tcl_cv_strtod_buggy+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Solaris2.4/Tru64 strtod bugs" >&5
+$as_echo_n "checking for Solaris2.4/Tru64 strtod bugs... " >&6; }
+if ${tcl_cv_strtod_buggy+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- if test "$cross_compiling" = yes; then
+ if test "$cross_compiling" = yes; then :
tcl_cv_strtod_buggy=buggy
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
extern double strtod();
@@ -15311,45 +9262,28 @@ cat >>conftest.$ac_ext <<_ACEOF
exit(0);
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_run "$LINENO"; then :
tcl_cv_strtod_buggy=ok
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-tcl_cv_strtod_buggy=buggy
+ tcl_cv_strtod_buggy=buggy
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+
fi
-echo "$as_me:$LINENO: result: $tcl_cv_strtod_buggy" >&5
-echo "${ECHO_T}$tcl_cv_strtod_buggy" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtod_buggy" >&5
+$as_echo "$tcl_cv_strtod_buggy" >&6; }
if test "$tcl_cv_strtod_buggy" = buggy; then
- case $LIBOBJS in
- "fixstrtod.$ac_objext" | \
- *" fixstrtod.$ac_objext" | \
- "fixstrtod.$ac_objext "* | \
+ case " $LIBOBJS " in
*" fixstrtod.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext"
+ ;;
esac
USE_COMPAT=1
-cat >>confdefs.h <<\_ACEOF
-#define strtod fixstrtod
-_ACEOF
+$as_echo "#define strtod fixstrtod" >>confdefs.h
fi
fi
@@ -15360,64 +9294,9 @@ _ACEOF
# they don't exist.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for mode_t" >&5
-echo $ECHO_N "checking for mode_t... $ECHO_C" >&6
-if test "${ac_cv_type_mode_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-if ((mode_t *) 0)
- return 0;
-if (sizeof (mode_t))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_mode_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
+if test "x$ac_cv_type_mode_t" = xyes; then :
-ac_cv_type_mode_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_mode_t" >&5
-echo "${ECHO_T}$ac_cv_type_mode_t" >&6
-if test $ac_cv_type_mode_t = yes; then
- :
else
cat >>confdefs.h <<_ACEOF
@@ -15426,64 +9305,9 @@ _ACEOF
fi
-echo "$as_me:$LINENO: checking for pid_t" >&5
-echo $ECHO_N "checking for pid_t... $ECHO_C" >&6
-if test "${ac_cv_type_pid_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-if ((pid_t *) 0)
- return 0;
-if (sizeof (pid_t))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_pid_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
+if test "x$ac_cv_type_pid_t" = xyes; then :
-ac_cv_type_pid_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_pid_t" >&5
-echo "${ECHO_T}$ac_cv_type_pid_t" >&6
-if test $ac_cv_type_pid_t = yes; then
- :
else
cat >>confdefs.h <<_ACEOF
@@ -15492,88 +9316,29 @@ _ACEOF
fi
-echo "$as_me:$LINENO: checking for size_t" >&5
-echo $ECHO_N "checking for size_t... $ECHO_C" >&6
-if test "${ac_cv_type_size_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-if ((size_t *) 0)
- return 0;
-if (sizeof (size_t))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_size_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
+if test "x$ac_cv_type_size_t" = xyes; then :
-ac_cv_type_size_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_size_t" >&5
-echo "${ECHO_T}$ac_cv_type_size_t" >&6
-if test $ac_cv_type_size_t = yes; then
- :
else
cat >>confdefs.h <<_ACEOF
-#define size_t unsigned
+#define size_t unsigned int
_ACEOF
fi
-echo "$as_me:$LINENO: checking for uid_t in sys/types.h" >&5
-echo $ECHO_N "checking for uid_t in sys/types.h... $ECHO_C" >&6
-if test "${ac_cv_type_uid_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for uid_t in sys/types.h" >&5
+$as_echo_n "checking for uid_t in sys/types.h... " >&6; }
+if ${ac_cv_type_uid_t+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "uid_t" >/dev/null 2>&1; then
+ $EGREP "uid_t" >/dev/null 2>&1; then :
ac_cv_type_uid_t=yes
else
ac_cv_type_uid_t=no
@@ -15581,33 +9346,25 @@ fi
rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_uid_t" >&5
-echo "${ECHO_T}$ac_cv_type_uid_t" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_type_uid_t" >&5
+$as_echo "$ac_cv_type_uid_t" >&6; }
if test $ac_cv_type_uid_t = no; then
-cat >>confdefs.h <<\_ACEOF
-#define uid_t int
-_ACEOF
+$as_echo "#define uid_t int" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define gid_t int
-_ACEOF
+$as_echo "#define gid_t int" >>confdefs.h
fi
-echo "$as_me:$LINENO: checking for socklen_t" >&5
-echo $ECHO_N "checking for socklen_t... $ECHO_C" >&6
-if test "${tcl_cv_type_socklen_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for socklen_t" >&5
+$as_echo_n "checking for socklen_t... " >&6; }
+if ${tcl_cv_type_socklen_t+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
@@ -15623,172 +9380,103 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_type_socklen_t=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_type_socklen_t=no
+ tcl_cv_type_socklen_t=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_type_socklen_t" >&5
-echo "${ECHO_T}$tcl_cv_type_socklen_t" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_type_socklen_t" >&5
+$as_echo "$tcl_cv_type_socklen_t" >&6; }
if test $tcl_cv_type_socklen_t = no; then
-cat >>confdefs.h <<\_ACEOF
-#define socklen_t int
-_ACEOF
+$as_echo "#define socklen_t int" >>confdefs.h
fi
-echo "$as_me:$LINENO: checking for intptr_t" >&5
-echo $ECHO_N "checking for intptr_t... $ECHO_C" >&6
-if test "${ac_cv_type_intptr_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+# check for SHUT_RD and SHUT_WR being enums vs defines
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for SHUT_RD/SHUT_WR" >&5
+$as_echo_n "checking for SHUT_RD/SHUT_WR... " >&6; }
+if ${tcl_cv_type_shutrd+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-$ac_includes_default
+
+ #include <sys/socket.h>
+
int
main ()
{
-if ((intptr_t *) 0)
- return 0;
-if (sizeof (intptr_t))
- return 0;
+
+ int foo = SHUT_RD;
+ int bar = SHUT_WR;
+
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_intptr_t=yes
+if ac_fn_c_try_compile "$LINENO"; then :
+ tcl_cv_type_shutrd=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_intptr_t=no
+ tcl_cv_type_shutrd=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_type_intptr_t" >&5
-echo "${ECHO_T}$ac_cv_type_intptr_t" >&6
-if test $ac_cv_type_intptr_t = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_type_shutrd" >&5
+$as_echo "$tcl_cv_type_shutrd" >&6; }
+if test $tcl_cv_type_shutrd = no; then
+$as_echo "#define SHUT_RD 0" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_INTPTR_T 1
-_ACEOF
+
+$as_echo "#define SHUT_WR 1" >>confdefs.h
+
+fi
+
+ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_intptr_t" = xyes; then :
+
+
+$as_echo "#define HAVE_INTPTR_T 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for pointer-size signed integer type" >&5
-echo $ECHO_N "checking for pointer-size signed integer type... $ECHO_C" >&6
-if test "${tcl_cv_intptr_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size signed integer type" >&5
+$as_echo_n "checking for pointer-size signed integer type... " >&6; }
+if ${tcl_cv_intptr_t+:} false; then :
+ $as_echo_n "(cached) " >&6
else
for tcl_cv_intptr_t in "int" "long" "long long" none; do
if test "$tcl_cv_intptr_t" != none; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_intptr_t))];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_ok=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_ok=no
+ tcl_ok=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
test "$tcl_ok" = yes && break; fi
done
fi
-echo "$as_me:$LINENO: result: $tcl_cv_intptr_t" >&5
-echo "${ECHO_T}$tcl_cv_intptr_t" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_intptr_t" >&5
+$as_echo "$tcl_cv_intptr_t" >&6; }
if test "$tcl_cv_intptr_t" != none; then
cat >>confdefs.h <<_ACEOF
@@ -15799,132 +9487,48 @@ _ACEOF
fi
-echo "$as_me:$LINENO: checking for uintptr_t" >&5
-echo $ECHO_N "checking for uintptr_t... $ECHO_C" >&6
-if test "${ac_cv_type_uintptr_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-int
-main ()
-{
-if ((uintptr_t *) 0)
- return 0;
-if (sizeof (uintptr_t))
- return 0;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_type_uintptr_t=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_type_uintptr_t=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_type_uintptr_t" >&5
-echo "${ECHO_T}$ac_cv_type_uintptr_t" >&6
-if test $ac_cv_type_uintptr_t = yes; then
+ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default"
+if test "x$ac_cv_type_uintptr_t" = xyes; then :
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_UINTPTR_T 1
-_ACEOF
+$as_echo "#define HAVE_UINTPTR_T 1" >>confdefs.h
else
- echo "$as_me:$LINENO: checking for pointer-size unsigned integer type" >&5
-echo $ECHO_N "checking for pointer-size unsigned integer type... $ECHO_C" >&6
-if test "${tcl_cv_uintptr_t+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for pointer-size unsigned integer type" >&5
+$as_echo_n "checking for pointer-size unsigned integer type... " >&6; }
+if ${tcl_cv_uintptr_t+:} false; then :
+ $as_echo_n "(cached) " >&6
else
for tcl_cv_uintptr_t in "unsigned int" "unsigned long" "unsigned long long" \
none; do
if test "$tcl_cv_uintptr_t" != none; then
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
static int test_array [1 - 2 * !(sizeof (void *) <= sizeof ($tcl_cv_uintptr_t))];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_ok=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_ok=no
+ tcl_ok=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
test "$tcl_ok" = yes && break; fi
done
fi
-echo "$as_me:$LINENO: result: $tcl_cv_uintptr_t" >&5
-echo "${ECHO_T}$tcl_cv_uintptr_t" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_uintptr_t" >&5
+$as_echo "$tcl_cv_uintptr_t" >&6; }
if test "$tcl_cv_uintptr_t" != none; then
cat >>confdefs.h <<_ACEOF
@@ -15943,107 +9547,205 @@ fi
# provided. This version only works with V7-style directories.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for opendir" >&5
-echo $ECHO_N "checking for opendir... $ECHO_C" >&6
-if test "${ac_cv_func_opendir+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ac_fn_c_check_func "$LINENO" "opendir" "ac_cv_func_opendir"
+if test "x$ac_cv_func_opendir" = xyes; then :
+
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+
+$as_echo "#define USE_DIRENT2_H 1" >>confdefs.h
+
+fi
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
+ as_ac_Header=`$as_echo "ac_cv_header_dirent_$ac_hdr" | $as_tr_sh`
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_hdr that defines DIR" >&5
+$as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
+if eval \${$as_ac_Header+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Define opendir to an innocuous variant, in case <limits.h> declares opendir.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define opendir innocuous_opendir
+#include <sys/types.h>
+#include <$ac_hdr>
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char opendir (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
+int
+main ()
+{
+if ((DIR *) 0)
+return 0;
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+ eval "$as_ac_Header=yes"
+else
+ eval "$as_ac_Header=no"
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+eval ac_res=\$$as_ac_Header
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_hdr" | $as_tr_cpp` 1
+_ACEOF
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+ac_header_dirent=$ac_hdr; break
+fi
-#undef opendir
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
-{
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char opendir ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_opendir) || defined (__stub___opendir)
-choke me
-#else
-char (*f) () = opendir;
-#endif
-#ifdef __cplusplus
+int
+main ()
+{
+return opendir ();
+ ;
+ return 0;
}
-#endif
+_ACEOF
+for ac_lib in '' dir; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
+else
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
+fi
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing opendir" >&5
+$as_echo_n "checking for library containing opendir... " >&6; }
+if ${ac_cv_search_opendir+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char opendir ();
int
main ()
{
-return f != opendir;
+return opendir ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_opendir=yes
+for ac_lib in '' x; do
+ if test -z "$ac_lib"; then
+ ac_res="none required"
+ else
+ ac_res=-l$ac_lib
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ fi
+ if ac_fn_c_try_link "$LINENO"; then :
+ ac_cv_search_opendir=$ac_res
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext
+ if ${ac_cv_search_opendir+:} false; then :
+ break
+fi
+done
+if ${ac_cv_search_opendir+:} false; then :
+
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ ac_cv_search_opendir=no
+fi
+rm conftest.$ac_ext
+LIBS=$ac_func_search_save_LIBS
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_opendir" >&5
+$as_echo "$ac_cv_search_opendir" >&6; }
+ac_res=$ac_cv_search_opendir
+if test "$ac_res" != no; then :
+ test "$ac_res" = "none required" || LIBS="$ac_res $LIBS"
-ac_cv_func_opendir=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+
fi
-echo "$as_me:$LINENO: result: $ac_cv_func_opendir" >&5
-echo "${ECHO_T}$ac_cv_func_opendir" >&6
-if test $ac_cv_func_opendir = yes; then
- :
-else
-cat >>confdefs.h <<\_ACEOF
-#define USE_DIRENT2_H 1
+
+
+ ac_fn_c_check_member "$LINENO" "struct dirent" "d_type" "ac_cv_member_struct_dirent_d_type" "
+#include <sys/types.h>
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+#else
+# define dirent direct
+# ifdef HAVE_SYS_NDIR_H
+# include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+# include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+# include <ndir.h>
+# endif
+#endif
+
+"
+if test "x$ac_cv_member_struct_dirent_d_type" = xyes; then :
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_STRUCT_DIRENT_D_TYPE 1
_ACEOF
+
fi
+
#--------------------------------------------------------------------
# The check below checks whether <sys/wait.h> defines the type
# "union wait" correctly. It's needed because of weirdness in
@@ -16052,17 +9754,13 @@ fi
# the trick.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking union wait" >&5
-echo $ECHO_N "checking union wait... $ECHO_C" >&6
-if test "${tcl_cv_union_wait+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking union wait" >&5
+$as_echo_n "checking union wait... " >&6; }
+if ${tcl_cv_union_wait+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/types.h>
#include <sys/wait.h>
@@ -16078,45 +9776,19 @@ WIFEXITED(x); /* Generates compiler error if WIFEXITED
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_union_wait=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_union_wait=no
+ tcl_cv_union_wait=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_union_wait" >&5
-echo "${ECHO_T}$tcl_cv_union_wait" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_union_wait" >&5
+$as_echo "$tcl_cv_union_wait" >&6; }
if test $tcl_cv_union_wait = no; then
-cat >>confdefs.h <<\_ACEOF
-#define NO_UNION_WAIT 1
-_ACEOF
+$as_echo "#define NO_UNION_WAIT 1" >>confdefs.h
fi
@@ -16126,168 +9798,51 @@ fi
# under Sequent Dynix it's in -linet.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for strncasecmp" >&5
-echo $ECHO_N "checking for strncasecmp... $ECHO_C" >&6
-if test "${ac_cv_func_strncasecmp+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define strncasecmp to an innocuous variant, in case <limits.h> declares strncasecmp.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define strncasecmp innocuous_strncasecmp
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char strncasecmp (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef strncasecmp
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char strncasecmp ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_strncasecmp) || defined (__stub___strncasecmp)
-choke me
-#else
-char (*f) () = strncasecmp;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != strncasecmp;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_strncasecmp=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_func_strncasecmp=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_strncasecmp" >&5
-echo "${ECHO_T}$ac_cv_func_strncasecmp" >&6
-if test $ac_cv_func_strncasecmp = yes; then
+ac_fn_c_check_func "$LINENO" "strncasecmp" "ac_cv_func_strncasecmp"
+if test "x$ac_cv_func_strncasecmp" = xyes; then :
tcl_ok=1
else
tcl_ok=0
fi
if test "$tcl_ok" = 0; then
- echo "$as_me:$LINENO: checking for strncasecmp in -lsocket" >&5
-echo $ECHO_N "checking for strncasecmp in -lsocket... $ECHO_C" >&6
-if test "${ac_cv_lib_socket_strncasecmp+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strncasecmp in -lsocket" >&5
+$as_echo_n "checking for strncasecmp in -lsocket... " >&6; }
+if ${ac_cv_lib_socket_strncasecmp+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-lsocket $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char strncasecmp ();
int
main ()
{
-strncasecmp ();
+return strncasecmp ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_socket_strncasecmp=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_socket_strncasecmp=no
+ ac_cv_lib_socket_strncasecmp=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_socket_strncasecmp" >&5
-echo "${ECHO_T}$ac_cv_lib_socket_strncasecmp" >&6
-if test $ac_cv_lib_socket_strncasecmp = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_socket_strncasecmp" >&5
+$as_echo "$ac_cv_lib_socket_strncasecmp" >&6; }
+if test "x$ac_cv_lib_socket_strncasecmp" = xyes; then :
tcl_ok=1
else
tcl_ok=0
@@ -16295,71 +9850,43 @@ fi
fi
if test "$tcl_ok" = 0; then
- echo "$as_me:$LINENO: checking for strncasecmp in -linet" >&5
-echo $ECHO_N "checking for strncasecmp in -linet... $ECHO_C" >&6
-if test "${ac_cv_lib_inet_strncasecmp+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for strncasecmp in -linet" >&5
+$as_echo_n "checking for strncasecmp in -linet... " >&6; }
+if ${ac_cv_lib_inet_strncasecmp+:} false; then :
+ $as_echo_n "(cached) " >&6
else
ac_check_lib_save_LIBS=$LIBS
LIBS="-linet $LIBS"
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
-/* Override any gcc2 internal prototype to avoid an error. */
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
char strncasecmp ();
int
main ()
{
-strncasecmp ();
+return strncasecmp ();
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
ac_cv_lib_inet_strncasecmp=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_lib_inet_strncasecmp=no
+ ac_cv_lib_inet_strncasecmp=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
LIBS=$ac_check_lib_save_LIBS
fi
-echo "$as_me:$LINENO: result: $ac_cv_lib_inet_strncasecmp" >&5
-echo "${ECHO_T}$ac_cv_lib_inet_strncasecmp" >&6
-if test $ac_cv_lib_inet_strncasecmp = yes; then
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_inet_strncasecmp" >&5
+$as_echo "$ac_cv_lib_inet_strncasecmp" >&6; }
+if test "x$ac_cv_lib_inet_strncasecmp" = xyes; then :
tcl_ok=1
else
tcl_ok=0
@@ -16367,12 +9894,10 @@ fi
fi
if test "$tcl_ok" = 0; then
- case $LIBOBJS in
- "strncasecmp.$ac_objext" | \
- *" strncasecmp.$ac_objext" | \
- "strncasecmp.$ac_objext "* | \
+ case " $LIBOBJS " in
*" strncasecmp.$ac_objext "* ) ;;
- *) LIBOBJS="$LIBOBJS strncasecmp.$ac_objext" ;;
+ *) LIBOBJS="$LIBOBJS strncasecmp.$ac_objext"
+ ;;
esac
USE_COMPAT=1
@@ -16387,125 +9912,30 @@ fi
# declare it.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for gettimeofday" >&5
-echo $ECHO_N "checking for gettimeofday... $ECHO_C" >&6
-if test "${ac_cv_func_gettimeofday+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define gettimeofday to an innocuous variant, in case <limits.h> declares gettimeofday.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define gettimeofday innocuous_gettimeofday
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char gettimeofday (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef gettimeofday
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char gettimeofday ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_gettimeofday) || defined (__stub___gettimeofday)
-choke me
-#else
-char (*f) () = gettimeofday;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != gettimeofday;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_func_gettimeofday=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+ac_fn_c_check_func "$LINENO" "gettimeofday" "ac_cv_func_gettimeofday"
+if test "x$ac_cv_func_gettimeofday" = xyes; then :
-ac_cv_func_gettimeofday=no
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: $ac_cv_func_gettimeofday" >&5
-echo "${ECHO_T}$ac_cv_func_gettimeofday" >&6
-if test $ac_cv_func_gettimeofday = yes; then
- :
else
-cat >>confdefs.h <<\_ACEOF
-#define NO_GETTOD 1
-_ACEOF
+$as_echo "#define NO_GETTOD 1" >>confdefs.h
fi
-echo "$as_me:$LINENO: checking for gettimeofday declaration" >&5
-echo $ECHO_N "checking for gettimeofday declaration... $ECHO_C" >&6
-if test "${tcl_cv_grep_gettimeofday+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gettimeofday declaration" >&5
+$as_echo_n "checking for gettimeofday declaration... " >&6; }
+if ${tcl_cv_grep_gettimeofday+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/time.h>
_ACEOF
if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "gettimeofday" >/dev/null 2>&1; then
+ $EGREP "gettimeofday" >/dev/null 2>&1; then :
tcl_cv_grep_gettimeofday=present
else
tcl_cv_grep_gettimeofday=missing
@@ -16513,13 +9943,11 @@ fi
rm -f conftest*
fi
-echo "$as_me:$LINENO: result: $tcl_cv_grep_gettimeofday" >&5
-echo "${ECHO_T}$tcl_cv_grep_gettimeofday" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_grep_gettimeofday" >&5
+$as_echo "$tcl_cv_grep_gettimeofday" >&6; }
if test $tcl_cv_grep_gettimeofday = missing ; then
-cat >>confdefs.h <<\_ACEOF
-#define GETTOD_NOT_DECLARED 1
-_ACEOF
+$as_echo "#define GETTOD_NOT_DECLARED 1" >>confdefs.h
fi
@@ -16529,80 +9957,46 @@ fi
# properly generate sign-extended ints from character values.
#--------------------------------------------------------------------
-
-echo "$as_me:$LINENO: checking whether char is unsigned" >&5
-echo $ECHO_N "checking whether char is unsigned... $ECHO_C" >&6
-if test "${ac_cv_c_char_unsigned+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether char is unsigned" >&5
+$as_echo_n "checking whether char is unsigned... " >&6; }
+if ${ac_cv_c_char_unsigned+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
$ac_includes_default
int
main ()
{
static int test_array [1 - 2 * !(((char) -1) < 0)];
-test_array [0] = 0
+test_array [0] = 0;
+return test_array [0];
;
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
ac_cv_c_char_unsigned=no
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_c_char_unsigned=yes
+ ac_cv_c_char_unsigned=yes
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $ac_cv_c_char_unsigned" >&5
-echo "${ECHO_T}$ac_cv_c_char_unsigned" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_char_unsigned" >&5
+$as_echo "$ac_cv_c_char_unsigned" >&6; }
if test $ac_cv_c_char_unsigned = yes && test "$GCC" != yes; then
- cat >>confdefs.h <<\_ACEOF
-#define __CHAR_UNSIGNED__ 1
-_ACEOF
+ $as_echo "#define __CHAR_UNSIGNED__ 1" >>confdefs.h
fi
-echo "$as_me:$LINENO: checking signed char declarations" >&5
-echo $ECHO_N "checking signed char declarations... $ECHO_C" >&6
-if test "${tcl_cv_char_signed+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking signed char declarations" >&5
+$as_echo_n "checking signed char declarations... " >&6; }
+if ${tcl_cv_char_signed+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -16616,44 +10010,18 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_char_signed=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_char_signed=no
+ tcl_cv_char_signed=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_char_signed" >&5
-echo "${ECHO_T}$tcl_cv_char_signed" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_char_signed" >&5
+$as_echo "$tcl_cv_char_signed" >&6; }
if test $tcl_cv_char_signed = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_SIGNED_CHAR 1
-_ACEOF
+$as_echo "#define HAVE_SIGNED_CHAR 1" >>confdefs.h
fi
@@ -16661,20 +10029,16 @@ fi
# Does putenv() copy or not? We need to know to avoid memory leaks.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for a putenv() that copies the buffer" >&5
-echo $ECHO_N "checking for a putenv() that copies the buffer... $ECHO_C" >&6
-if test "${tcl_cv_putenv_copy+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a putenv() that copies the buffer" >&5
+$as_echo_n "checking for a putenv() that copies the buffer... " >&6; }
+if ${tcl_cv_putenv_copy+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- if test "$cross_compiling" = yes; then
+ if test "$cross_compiling" = yes; then :
tcl_cv_putenv_copy=no
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <stdlib.h>
@@ -16696,36 +10060,21 @@ cat >>conftest.$ac_ext <<_ACEOF
}
_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_run "$LINENO"; then :
tcl_cv_putenv_copy=no
else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-tcl_cv_putenv_copy=yes
+ tcl_cv_putenv_copy=yes
fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+ conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+
fi
-echo "$as_me:$LINENO: result: $tcl_cv_putenv_copy" >&5
-echo "${ECHO_T}$tcl_cv_putenv_copy" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_putenv_copy" >&5
+$as_echo "$tcl_cv_putenv_copy" >&6; }
if test $tcl_cv_putenv_copy = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_PUTENV_THAT_COPIES 1
-_ACEOF
+$as_echo "#define HAVE_PUTENV_THAT_COPIES 1" >>confdefs.h
fi
@@ -16734,154 +10083,18 @@ fi
#--------------------------------------------------------------------
- # Check whether --enable-usleep or --disable-usleep was given.
-if test "${enable_usleep+set}" = set; then
- enableval="$enable_usleep"
- usleep_ok=$enableval
+ # Check whether --enable-usleep was given.
+if test "${enable_usleep+set}" = set; then :
+ enableval=$enable_usleep; usleep_ok=$enableval
else
usleep_ok=yes
-fi;
-
- HAVE_USLEEP=0
- if test "$usleep_ok" = "yes"; then
- if test "${ac_cv_header_unistd_h+set}" = set; then
- echo "$as_me:$LINENO: checking for unistd.h" >&5
-echo $ECHO_N "checking for unistd.h... $ECHO_C" >&6
-if test "${ac_cv_header_unistd_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
fi
-echo "$as_me:$LINENO: result: $ac_cv_header_unistd_h" >&5
-echo "${ECHO_T}$ac_cv_header_unistd_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking unistd.h usability" >&5
-echo $ECHO_N "checking unistd.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <unistd.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-# Is the header present?
-echo "$as_me:$LINENO: checking unistd.h presence" >&5
-echo $ECHO_N "checking unistd.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <unistd.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: unistd.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: unistd.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: unistd.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: unistd.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: unistd.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: unistd.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: unistd.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: unistd.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: unistd.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: unistd.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: unistd.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: unistd.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: unistd.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: unistd.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: unistd.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: unistd.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for unistd.h" >&5
-echo $ECHO_N "checking for unistd.h... $ECHO_C" >&6
-if test "${ac_cv_header_unistd_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_unistd_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_unistd_h" >&5
-echo "${ECHO_T}$ac_cv_header_unistd_h" >&6
-
-fi
-if test $ac_cv_header_unistd_h = yes; then
+ HAVE_USLEEP=0
+ if test "$usleep_ok" = "yes"; then
+ ac_fn_c_check_header_mongrel "$LINENO" "unistd.h" "ac_cv_header_unistd_h" "$ac_includes_default"
+if test "x$ac_cv_header_unistd_h" = xyes; then :
usleep_ok=yes
else
usleep_ok=no
@@ -16889,18 +10102,14 @@ fi
fi
- echo "$as_me:$LINENO: checking whether to use usleep" >&5
-echo $ECHO_N "checking whether to use usleep... $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use usleep" >&5
+$as_echo_n "checking whether to use usleep... " >&6; }
if test "$usleep_ok" = "yes"; then
- if test "${tcl_cv_usleep_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ if ${tcl_cv_usleep_h+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <unistd.h>
int
@@ -16911,50 +10120,24 @@ usleep(0);
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_usleep_h=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_usleep_h=no
+ tcl_cv_usleep_h=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
- echo "$as_me:$LINENO: result: $tcl_cv_usleep_h" >&5
-echo "${ECHO_T}$tcl_cv_usleep_h" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_usleep_h" >&5
+$as_echo "$tcl_cv_usleep_h" >&6; }
if test $tcl_cv_usleep_h = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_USLEEP 1
-_ACEOF
+$as_echo "#define HAVE_USLEEP 1" >>confdefs.h
fi
else
- echo "$as_me:$LINENO: result: $usleep_ok" >&5
-echo "${ECHO_T}$usleep_ok" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $usleep_ok" >&5
+$as_echo "$usleep_ok" >&6; }
fi
@@ -16963,154 +10146,18 @@ echo "${ECHO_T}$usleep_ok" >&6
#--------------------------------------------------------------------
- # Check whether --enable-langinfo or --disable-langinfo was given.
-if test "${enable_langinfo+set}" = set; then
- enableval="$enable_langinfo"
- langinfo_ok=$enableval
+ # Check whether --enable-langinfo was given.
+if test "${enable_langinfo+set}" = set; then :
+ enableval=$enable_langinfo; langinfo_ok=$enableval
else
langinfo_ok=yes
-fi;
-
- HAVE_LANGINFO=0
- if test "$langinfo_ok" = "yes"; then
- if test "${ac_cv_header_langinfo_h+set}" = set; then
- echo "$as_me:$LINENO: checking for langinfo.h" >&5
-echo $ECHO_N "checking for langinfo.h... $ECHO_C" >&6
-if test "${ac_cv_header_langinfo_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_langinfo_h" >&5
-echo "${ECHO_T}$ac_cv_header_langinfo_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking langinfo.h usability" >&5
-echo $ECHO_N "checking langinfo.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <langinfo.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-# Is the header present?
-echo "$as_me:$LINENO: checking langinfo.h presence" >&5
-echo $ECHO_N "checking langinfo.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <langinfo.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: langinfo.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: langinfo.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: langinfo.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: langinfo.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: langinfo.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: langinfo.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: langinfo.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: langinfo.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: langinfo.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: langinfo.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: langinfo.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: langinfo.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: langinfo.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: langinfo.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: langinfo.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: langinfo.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for langinfo.h" >&5
-echo $ECHO_N "checking for langinfo.h... $ECHO_C" >&6
-if test "${ac_cv_header_langinfo_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_langinfo_h=$ac_header_preproc
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_langinfo_h" >&5
-echo "${ECHO_T}$ac_cv_header_langinfo_h" >&6
-fi
-if test $ac_cv_header_langinfo_h = yes; then
+ HAVE_LANGINFO=0
+ if test "$langinfo_ok" = "yes"; then
+ ac_fn_c_check_header_mongrel "$LINENO" "langinfo.h" "ac_cv_header_langinfo_h" "$ac_includes_default"
+if test "x$ac_cv_header_langinfo_h" = xyes; then :
langinfo_ok=yes
else
langinfo_ok=no
@@ -17118,18 +10165,14 @@ fi
fi
- echo "$as_me:$LINENO: checking whether to use nl_langinfo" >&5
-echo $ECHO_N "checking whether to use nl_langinfo... $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use nl_langinfo" >&5
+$as_echo_n "checking whether to use nl_langinfo... " >&6; }
if test "$langinfo_ok" = "yes"; then
- if test "${tcl_cv_langinfo_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ if ${tcl_cv_langinfo_h+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <langinfo.h>
int
@@ -17140,50 +10183,24 @@ nl_langinfo(CODESET);
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_langinfo_h=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_langinfo_h=no
+ tcl_cv_langinfo_h=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
fi
- echo "$as_me:$LINENO: result: $tcl_cv_langinfo_h" >&5
-echo "${ECHO_T}$tcl_cv_langinfo_h" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_langinfo_h" >&5
+$as_echo "$tcl_cv_langinfo_h" >&6; }
if test $tcl_cv_langinfo_h = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_LANGINFO 1
-_ACEOF
+$as_echo "#define HAVE_LANGINFO 1" >>confdefs.h
fi
else
- echo "$as_me:$LINENO: result: $langinfo_ok" >&5
-echo "${ECHO_T}$langinfo_ok" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $langinfo_ok" >&5
+$as_echo "$langinfo_ok" >&6; }
fi
@@ -17191,104 +10208,13 @@ echo "${ECHO_T}$langinfo_ok" >&6
# Check for support of chflags and mkstemps functions
#--------------------------------------------------------------------
-
-
for ac_func in chflags mkstemps
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
_ACEOF
fi
@@ -17299,17 +10225,13 @@ done
# Check for support of isnan() function or macro
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking isnan" >&5
-echo $ECHO_N "checking isnan... $ECHO_C" >&6
-if test "${tcl_cv_isnan+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking isnan" >&5
+$as_echo_n "checking isnan... " >&6; }
+if ${tcl_cv_isnan+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <math.h>
int
@@ -17322,655 +10244,90 @@ isnan(0.0); /* Generates an error if isnan is missing */
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_isnan=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_isnan=no
+ tcl_cv_isnan=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_isnan" >&5
-echo "${ECHO_T}$tcl_cv_isnan" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_isnan" >&5
+$as_echo "$tcl_cv_isnan" >&6; }
if test $tcl_cv_isnan = no; then
-cat >>confdefs.h <<\_ACEOF
-#define NO_ISNAN 1
-_ACEOF
+$as_echo "#define NO_ISNAN 1" >>confdefs.h
fi
#--------------------------------------------------------------------
-# Darwin specific API checks and defines
+# Work around apparent fork() problem on netbsd 4.
#--------------------------------------------------------------------
-if test "`uname -s`" = "Darwin" ; then
-
-for ac_func in getattrlist
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+if test "`uname -s`" = "NetBSD" ; then
-#undef $ac_func
+$as_echo "#define USE_VFORK 1" >>confdefs.h
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
+fi
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+#--------------------------------------------------------------------
+# Darwin specific API checks and defines
+#--------------------------------------------------------------------
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+if test "`uname -s`" = "Darwin" ; then
+ for ac_func in getattrlist
+do :
+ ac_fn_c_check_func "$LINENO" "getattrlist" "ac_cv_func_getattrlist"
+if test "x$ac_cv_func_getattrlist" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define HAVE_GETATTRLIST 1
_ACEOF
fi
done
-
-for ac_header in copyfile.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ for ac_header in copyfile.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "copyfile.h" "ac_cv_header_copyfile_h" "$ac_includes_default"
+if test "x$ac_cv_header_copyfile_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_COPYFILE_H 1
_ACEOF
fi
done
-
-for ac_func in copyfile
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+ for ac_func in copyfile
+do :
+ ac_fn_c_check_func "$LINENO" "copyfile" "ac_cv_func_copyfile"
+if test "x$ac_cv_func_copyfile" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define HAVE_COPYFILE 1
_ACEOF
fi
done
if test $tcl_corefoundation = yes; then
-
-for ac_header in libkern/OSAtomic.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ for ac_header in libkern/OSAtomic.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "libkern/OSAtomic.h" "ac_cv_header_libkern_OSAtomic_h" "$ac_includes_default"
+if test "x$ac_cv_header_libkern_OSAtomic_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_LIBKERN_OSATOMIC_H 1
_ACEOF
fi
done
-
-for ac_func in OSSpinLockLock
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6
-if eval "test \"\${$as_ac_var+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
- For example, HP-UX 11i <limits.h> declares gettimeofday. */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
- which can conflict with char $ac_func (); below.
- Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
- <limits.h> exists even on freestanding compilers. */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any gcc2 internal prototype to avoid an error. */
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-/* We use char because int might match the return type of a gcc2
- builtin and then its argument prototype would still apply. */
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
- to always fail with ENOSYS. Some functions are actually named
- something starting with __ and the normal name is an alias. */
-#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
-choke me
-#else
-char (*f) () = $ac_func;
-#endif
-#ifdef __cplusplus
-}
-#endif
-
-int
-main ()
-{
-return f != $ac_func;
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_var=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_var=no"
-fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_var'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_var'}'`" >&6
-if test `eval echo '${'$as_ac_var'}'` = yes; then
+ for ac_func in OSSpinLockLock
+do :
+ ac_fn_c_check_func "$LINENO" "OSSpinLockLock" "ac_cv_func_OSSpinLockLock"
+if test "x$ac_cv_func_OSSpinLockLock" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+#define HAVE_OSSPINLOCKLOCK 1
_ACEOF
fi
@@ -17978,169 +10335,23 @@ done
fi
-cat >>confdefs.h <<\_ACEOF
-#define USE_VFORK 1
-_ACEOF
+$as_echo "#define USE_VFORK 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define TCL_DEFAULT_ENCODING "utf-8"
-_ACEOF
+$as_echo "#define TCL_DEFAULT_ENCODING \"utf-8\"" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define TCL_LOAD_FROM_MEMORY 1
-_ACEOF
+$as_echo "#define TCL_LOAD_FROM_MEMORY 1" >>confdefs.h
-cat >>confdefs.h <<\_ACEOF
-#define TCL_WIDE_CLICKS 1
-_ACEOF
-
-
-for ac_header in AvailabilityMacros.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+$as_echo "#define TCL_WIDE_CLICKS 1" >>confdefs.h
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ for ac_header in AvailabilityMacros.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "AvailabilityMacros.h" "ac_cv_header_AvailabilityMacros_h" "$ac_includes_default"
+if test "x$ac_cv_header_AvailabilityMacros_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_AVAILABILITYMACROS_H 1
_ACEOF
fi
@@ -18148,18 +10359,14 @@ fi
done
if test "$ac_cv_header_AvailabilityMacros_h" = yes; then
- echo "$as_me:$LINENO: checking if weak import is available" >&5
-echo $ECHO_N "checking if weak import is available... $ECHO_C" >&6
-if test "${tcl_cv_cc_weak_import+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if weak import is available" >&5
+$as_echo_n "checking if weak import is available... " >&6; }
+if ${tcl_cv_cc_weak_import+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
@@ -18179,60 +10386,30 @@ rand();
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_cc_weak_import=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cc_weak_import=no
+ tcl_cv_cc_weak_import=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
CFLAGS=$hold_cflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cc_weak_import" >&5
-echo "${ECHO_T}$tcl_cv_cc_weak_import" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_weak_import" >&5
+$as_echo "$tcl_cv_cc_weak_import" >&6; }
if test $tcl_cv_cc_weak_import = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_WEAK_IMPORT 1
-_ACEOF
+$as_echo "#define HAVE_WEAK_IMPORT 1" >>confdefs.h
fi
- echo "$as_me:$LINENO: checking if Darwin SUSv3 extensions are available" >&5
-echo $ECHO_N "checking if Darwin SUSv3 extensions are available... $ECHO_C" >&6
-if test "${tcl_cv_cc_darwin_c_source+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking if Darwin SUSv3 extensions are available" >&5
+$as_echo_n "checking if Darwin SUSv3 extensions are available... " >&6; }
+if ${tcl_cv_cc_darwin_c_source+:} false; then :
+ $as_echo_n "(cached) " >&6
else
hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror"
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#ifdef __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__
@@ -18253,45 +10430,19 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_compile "$LINENO"; then :
tcl_cv_cc_darwin_c_source=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cc_darwin_c_source=no
+ tcl_cv_cc_darwin_c_source=no
fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
CFLAGS=$hold_cflags
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cc_darwin_c_source" >&5
-echo "${ECHO_T}$tcl_cv_cc_darwin_c_source" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cc_darwin_c_source" >&5
+$as_echo "$tcl_cv_cc_darwin_c_source" >&6; }
if test $tcl_cv_cc_darwin_c_source = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define _DARWIN_C_SOURCE 1
-_ACEOF
+$as_echo "#define _DARWIN_C_SOURCE 1" >>confdefs.h
fi
fi
@@ -18307,17 +10458,13 @@ fi
# Check for support of fts functions (readdir replacement)
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for fts" >&5
-echo $ECHO_N "checking for fts... $ECHO_C" >&6
-if test "${tcl_cv_api_fts+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fts" >&5
+$as_echo_n "checking for fts... " >&6; }
+if ${tcl_cv_api_fts+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
#include <sys/param.h>
@@ -18336,45 +10483,19 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_api_fts=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_api_fts=no
+ tcl_cv_api_fts=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_api_fts" >&5
-echo "${ECHO_T}$tcl_cv_api_fts" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_api_fts" >&5
+$as_echo "$tcl_cv_api_fts" >&6; }
if test $tcl_cv_api_fts = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_FTS 1
-_ACEOF
+$as_echo "#define HAVE_FTS 1" >>confdefs.h
fi
@@ -18385,300 +10506,24 @@ fi
#--------------------------------------------------------------------
-
-for ac_header in sys/ioctl.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ for ac_header in sys/ioctl.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/ioctl.h" "ac_cv_header_sys_ioctl_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_ioctl_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_SYS_IOCTL_H 1
_ACEOF
fi
done
-
-for ac_header in sys/filio.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking $ac_header presence" >&5
-echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <$ac_header>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
-echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- eval "$as_ac_Header=\$ac_header_preproc"
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-
-fi
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ for ac_header in sys/filio.h
+do :
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/filio.h" "ac_cv_header_sys_filio_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_filio_h" = xyes; then :
cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+#define HAVE_SYS_FILIO_H 1
_ACEOF
fi
@@ -18686,10 +10531,10 @@ fi
done
- echo "$as_me:$LINENO: checking system version" >&5
-echo $ECHO_N "checking system version... $ECHO_C" >&6
-if test "${tcl_cv_sys_version+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking system version" >&5
+$as_echo_n "checking system version... " >&6; }
+if ${tcl_cv_sys_version+:} false; then :
+ $as_echo_n "(cached) " >&6
else
if test -f /usr/lib/NextStep/software_version; then
@@ -18697,8 +10542,8 @@ else
else
tcl_cv_sys_version=`uname -s`-`uname -r`
if test "$?" -ne 0 ; then
- { echo "$as_me:$LINENO: WARNING: can't find uname command" >&5
-echo "$as_me: WARNING: can't find uname command" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: can't find uname command" >&5
+$as_echo "$as_me: WARNING: can't find uname command" >&2;}
tcl_cv_sys_version=unknown
else
# Special check for weird MP-RAS system (uname returns weird
@@ -18714,58 +10559,52 @@ echo "$as_me: WARNING: can't find uname command" >&2;}
fi
fi
-echo "$as_me:$LINENO: result: $tcl_cv_sys_version" >&5
-echo "${ECHO_T}$tcl_cv_sys_version" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_sys_version" >&5
+$as_echo "$tcl_cv_sys_version" >&6; }
system=$tcl_cv_sys_version
- echo "$as_me:$LINENO: checking FIONBIO vs. O_NONBLOCK for nonblocking I/O" >&5
-echo $ECHO_N "checking FIONBIO vs. O_NONBLOCK for nonblocking I/O... $ECHO_C" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking FIONBIO vs. O_NONBLOCK for nonblocking I/O" >&5
+$as_echo_n "checking FIONBIO vs. O_NONBLOCK for nonblocking I/O... " >&6; }
case $system in
OSF*)
-cat >>confdefs.h <<\_ACEOF
-#define USE_FIONBIO 1
-_ACEOF
+$as_echo "#define USE_FIONBIO 1" >>confdefs.h
- echo "$as_me:$LINENO: result: FIONBIO" >&5
-echo "${ECHO_T}FIONBIO" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: FIONBIO" >&5
+$as_echo "FIONBIO" >&6; }
;;
SunOS-4*)
-cat >>confdefs.h <<\_ACEOF
-#define USE_FIONBIO 1
-_ACEOF
+$as_echo "#define USE_FIONBIO 1" >>confdefs.h
- echo "$as_me:$LINENO: result: FIONBIO" >&5
-echo "${ECHO_T}FIONBIO" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: FIONBIO" >&5
+$as_echo "FIONBIO" >&6; }
;;
*)
- echo "$as_me:$LINENO: result: O_NONBLOCK" >&5
-echo "${ECHO_T}O_NONBLOCK" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: O_NONBLOCK" >&5
+$as_echo "O_NONBLOCK" >&6; }
;;
esac
#------------------------------------------------------------------------
-echo "$as_me:$LINENO: checking whether to use dll unloading" >&5
-echo $ECHO_N "checking whether to use dll unloading... $ECHO_C" >&6
-# Check whether --enable-dll-unloading or --disable-dll-unloading was given.
-if test "${enable_dll_unloading+set}" = set; then
- enableval="$enable_dll_unloading"
- tcl_ok=$enableval
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use dll unloading" >&5
+$as_echo_n "checking whether to use dll unloading... " >&6; }
+# Check whether --enable-dll-unloading was given.
+if test "${enable_dll_unloading+set}" = set; then :
+ enableval=$enable_dll_unloading; tcl_ok=$enableval
else
tcl_ok=yes
-fi;
+fi
+
if test $tcl_ok = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define TCL_UNLOAD_DLLS 1
-_ACEOF
+$as_echo "#define TCL_UNLOAD_DLLS 1" >>confdefs.h
fi
-echo "$as_me:$LINENO: result: $tcl_ok" >&5
-echo "${ECHO_T}$tcl_ok" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_ok" >&5
+$as_echo "$tcl_ok" >&6; }
#------------------------------------------------------------------------
# Check whether the timezone data is supplied by the OS or has
@@ -18773,31 +10612,31 @@ echo "${ECHO_T}$tcl_ok" >&6
# be overriden on the configure command line either way.
#------------------------------------------------------------------------
-echo "$as_me:$LINENO: checking for timezone data" >&5
-echo $ECHO_N "checking for timezone data... $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for timezone data" >&5
+$as_echo_n "checking for timezone data... " >&6; }
-# Check whether --with-tzdata or --without-tzdata was given.
-if test "${with_tzdata+set}" = set; then
- withval="$with_tzdata"
- tcl_ok=$withval
+# Check whether --with-tzdata was given.
+if test "${with_tzdata+set}" = set; then :
+ withval=$with_tzdata; tcl_ok=$withval
else
tcl_ok=auto
-fi;
+fi
+
#
# Any directories that get added here must also be added to the
# search path in ::tcl::clock::Initialize (library/clock.tcl).
#
case $tcl_ok in
no)
- echo "$as_me:$LINENO: result: supplied by OS vendor" >&5
-echo "${ECHO_T}supplied by OS vendor" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: supplied by OS vendor" >&5
+$as_echo "supplied by OS vendor" >&6; }
;;
yes)
# nothing to do here
;;
auto*)
- if test "${tcl_cv_dir_zoneinfo+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+ if ${tcl_cv_dir_zoneinfo+:} false; then :
+ $as_echo_n "(cached) " >&6
else
for dir in /usr/share/zoneinfo \
@@ -18814,22 +10653,20 @@ fi
if test -n "$tcl_cv_dir_zoneinfo"; then
tcl_ok=no
- echo "$as_me:$LINENO: result: $dir" >&5
-echo "${ECHO_T}$dir" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $dir" >&5
+$as_echo "$dir" >&6; }
else
tcl_ok=yes
fi
;;
*)
- { { echo "$as_me:$LINENO: error: invalid argument: $tcl_ok" >&5
-echo "$as_me: error: invalid argument: $tcl_ok" >&2;}
- { (exit 1); exit 1; }; }
+ as_fn_error $? "invalid argument: $tcl_ok" "$LINENO" 5
;;
esac
if test $tcl_ok = yes
then
- echo "$as_me:$LINENO: result: supplied by Tcl" >&5
-echo "${ECHO_T}supplied by Tcl" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: supplied by Tcl" >&5
+$as_echo "supplied by Tcl" >&6; }
INSTALL_TZDATA=install-tzdata
fi
@@ -18837,152 +10674,16 @@ fi
# DTrace support
#--------------------------------------------------------------------
-# Check whether --enable-dtrace or --disable-dtrace was given.
-if test "${enable_dtrace+set}" = set; then
- enableval="$enable_dtrace"
- tcl_ok=$enableval
+# Check whether --enable-dtrace was given.
+if test "${enable_dtrace+set}" = set; then :
+ enableval=$enable_dtrace; tcl_ok=$enableval
else
tcl_ok=no
-fi;
-if test $tcl_ok = yes; then
- if test "${ac_cv_header_sys_sdt_h+set}" = set; then
- echo "$as_me:$LINENO: checking for sys/sdt.h" >&5
-echo $ECHO_N "checking for sys/sdt.h... $ECHO_C" >&6
-if test "${ac_cv_header_sys_sdt_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_sys_sdt_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_sdt_h" >&6
-else
- # Is the header compilable?
-echo "$as_me:$LINENO: checking sys/sdt.h usability" >&5
-echo $ECHO_N "checking sys/sdt.h usability... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-#include <sys/sdt.h>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_header_compiler=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_header_compiler=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
-echo "${ECHO_T}$ac_header_compiler" >&6
-
-# Is the header present?
-echo "$as_me:$LINENO: checking sys/sdt.h presence" >&5
-echo $ECHO_N "checking sys/sdt.h presence... $ECHO_C" >&6
-cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <sys/sdt.h>
-_ACEOF
-if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
- (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } >/dev/null; then
- if test -s conftest.err; then
- ac_cpp_err=$ac_c_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
- else
- ac_cpp_err=
- fi
-else
- ac_cpp_err=yes
-fi
-if test -z "$ac_cpp_err"; then
- ac_header_preproc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
- ac_header_preproc=no
-fi
-rm -f conftest.err conftest.$ac_ext
-echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
-echo "${ECHO_T}$ac_header_preproc" >&6
-
-# So? What about this header?
-case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
- yes:no: )
- { echo "$as_me:$LINENO: WARNING: sys/sdt.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: sys/sdt.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/sdt.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: sys/sdt.h: proceeding with the compiler's result" >&2;}
- ac_header_preproc=yes
- ;;
- no:yes:* )
- { echo "$as_me:$LINENO: WARNING: sys/sdt.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: sys/sdt.h: present but cannot be compiled" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/sdt.h: check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: sys/sdt.h: check for missing prerequisite headers?" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/sdt.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: sys/sdt.h: see the Autoconf documentation" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/sdt.h: section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: sys/sdt.h: section \"Present But Cannot Be Compiled\"" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/sdt.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: sys/sdt.h: proceeding with the preprocessor's result" >&2;}
- { echo "$as_me:$LINENO: WARNING: sys/sdt.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: sys/sdt.h: in the future, the compiler will take precedence" >&2;}
- (
- cat <<\_ASBOX
-## ------------------------------ ##
-## Report this to the tcl lists. ##
-## ------------------------------ ##
-_ASBOX
- ) |
- sed "s/^/$as_me: WARNING: /" >&2
- ;;
-esac
-echo "$as_me:$LINENO: checking for sys/sdt.h" >&5
-echo $ECHO_N "checking for sys/sdt.h... $ECHO_C" >&6
-if test "${ac_cv_header_sys_sdt_h+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- ac_cv_header_sys_sdt_h=$ac_header_preproc
fi
-echo "$as_me:$LINENO: result: $ac_cv_header_sys_sdt_h" >&5
-echo "${ECHO_T}$ac_cv_header_sys_sdt_h" >&6
-fi
-if test $ac_cv_header_sys_sdt_h = yes; then
+if test $tcl_ok = yes; then
+ ac_fn_c_check_header_mongrel "$LINENO" "sys/sdt.h" "ac_cv_header_sys_sdt_h" "$ac_includes_default"
+if test "x$ac_cv_header_sys_sdt_h" = xyes; then :
tcl_ok=yes
else
tcl_ok=no
@@ -18993,10 +10694,10 @@ fi
if test $tcl_ok = yes; then
# Extract the first word of "dtrace", so it can be a program name with args.
set dummy dtrace; ac_word=$2
-echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
-if test "${ac_cv_path_DTRACE+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_path_DTRACE+:} false; then :
+ $as_echo_n "(cached) " >&6
else
case $DTRACE in
[\\/]* | ?:[\\/]*)
@@ -19009,38 +10710,37 @@ for as_dir in $as_dummy
do
IFS=$as_save_IFS
test -z "$as_dir" && as_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
ac_cv_path_DTRACE="$as_dir/$ac_word$ac_exec_ext"
- echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
break 2
fi
done
-done
+ done
+IFS=$as_save_IFS
;;
esac
fi
DTRACE=$ac_cv_path_DTRACE
-
if test -n "$DTRACE"; then
- echo "$as_me:$LINENO: result: $DTRACE" >&5
-echo "${ECHO_T}$DTRACE" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DTRACE" >&5
+$as_echo "$DTRACE" >&6; }
else
- echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
fi
+
test -z "$ac_cv_path_DTRACE" && tcl_ok=no
fi
-echo "$as_me:$LINENO: checking whether to enable DTrace support" >&5
-echo $ECHO_N "checking whether to enable DTrace support... $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable DTrace support" >&5
+$as_echo_n "checking whether to enable DTrace support... " >&6; }
MAKEFILE_SHELL='/bin/sh'
if test $tcl_ok = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define USE_DTRACE 1
-_ACEOF
+$as_echo "#define USE_DTRACE 1" >>confdefs.h
DTRACE_SRC="\${DTRACE_SRC}"
DTRACE_HDR="\${DTRACE_HDR}"
@@ -19058,24 +10758,20 @@ _ACEOF
fi
fi
fi
-echo "$as_me:$LINENO: result: $tcl_ok" >&5
-echo "${ECHO_T}$tcl_ok" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_ok" >&5
+$as_echo "$tcl_ok" >&6; }
#--------------------------------------------------------------------
# The check below checks whether the cpuid instruction is usable.
#--------------------------------------------------------------------
-echo "$as_me:$LINENO: checking whether the cpuid instruction is usable" >&5
-echo $ECHO_N "checking whether the cpuid instruction is usable... $ECHO_C" >&6
-if test "${tcl_cv_cpuid+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the cpuid instruction is usable" >&5
+$as_echo_n "checking whether the cpuid instruction is usable... " >&6; }
+if ${tcl_cv_cpuid+:} false; then :
+ $as_echo_n "(cached) " >&6
else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
int
@@ -19094,45 +10790,19 @@ main ()
return 0;
}
_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_c_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
+if ac_fn_c_try_link "$LINENO"; then :
tcl_cv_cpuid=yes
else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-tcl_cv_cpuid=no
+ tcl_cv_cpuid=no
fi
-rm -f conftest.err conftest.$ac_objext \
- conftest$ac_exeext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
fi
-echo "$as_me:$LINENO: result: $tcl_cv_cpuid" >&5
-echo "${ECHO_T}$tcl_cv_cpuid" >&6
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_cpuid" >&5
+$as_echo "$tcl_cv_cpuid" >&6; }
if test $tcl_cv_cpuid = yes; then
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_CPUID 1
-_ACEOF
+$as_echo "#define HAVE_CPUID 1" >>confdefs.h
fi
@@ -19163,38 +10833,38 @@ HTML_DIR='$(DISTDIR)/html'
if test "`uname -s`" = "Darwin" ; then
if test "`uname -s`" = "Darwin" ; then
- echo "$as_me:$LINENO: checking how to package libraries" >&5
-echo $ECHO_N "checking how to package libraries... $ECHO_C" >&6
- # Check whether --enable-framework or --disable-framework was given.
-if test "${enable_framework+set}" = set; then
- enableval="$enable_framework"
- enable_framework=$enableval
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to package libraries" >&5
+$as_echo_n "checking how to package libraries... " >&6; }
+ # Check whether --enable-framework was given.
+if test "${enable_framework+set}" = set; then :
+ enableval=$enable_framework; enable_framework=$enableval
else
enable_framework=no
-fi;
+fi
+
if test $enable_framework = yes; then
if test $SHARED_BUILD = 0; then
- { echo "$as_me:$LINENO: WARNING: Frameworks can only be built if --enable-shared is yes" >&5
-echo "$as_me: WARNING: Frameworks can only be built if --enable-shared is yes" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be built if --enable-shared is yes" >&5
+$as_echo "$as_me: WARNING: Frameworks can only be built if --enable-shared is yes" >&2;}
enable_framework=no
fi
if test $tcl_corefoundation = no; then
- { echo "$as_me:$LINENO: WARNING: Frameworks can only be used when CoreFoundation is available" >&5
-echo "$as_me: WARNING: Frameworks can only be used when CoreFoundation is available" >&2;}
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Frameworks can only be used when CoreFoundation is available" >&5
+$as_echo "$as_me: WARNING: Frameworks can only be used when CoreFoundation is available" >&2;}
enable_framework=no
fi
fi
if test $enable_framework = yes; then
- echo "$as_me:$LINENO: result: framework" >&5
-echo "${ECHO_T}framework" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: framework" >&5
+$as_echo "framework" >&6; }
FRAMEWORK_BUILD=1
else
if test $SHARED_BUILD = 1; then
- echo "$as_me:$LINENO: result: shared library" >&5
-echo "${ECHO_T}shared library" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: shared library" >&5
+$as_echo "shared library" >&6; }
else
- echo "$as_me:$LINENO: result: static library" >&5
-echo "${ECHO_T}static library" >&6
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: static library" >&5
+$as_echo "static library" >&6; }
fi
FRAMEWORK_BUILD=0
fi
@@ -19206,20 +10876,18 @@ echo "${ECHO_T}static library" >&6
TCL_SHLIB_LD_EXTRAS="${TCL_SHLIB_LD_EXTRAS}"' -sectcreate __TEXT __info_plist Tcl-Info.plist'
EXTRA_TCLSH_LIBS='-sectcreate __TEXT __info_plist Tclsh-Info.plist'
EXTRA_APP_CC_SWITCHES='-mdynamic-no-pic'
- ac_config_files="$ac_config_files Tcl-Info.plist:../macosx/Tcl-Info.plist.in Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in"
+ ac_config_files="$ac_config_files Tcl-Info.plist:../macosx/Tcl-Info.plist.in Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in"
TCL_YEAR="`date +%Y`"
fi
if test "$FRAMEWORK_BUILD" = "1" ; then
-cat >>confdefs.h <<\_ACEOF
-#define TCL_FRAMEWORK 1
-_ACEOF
+$as_echo "#define TCL_FRAMEWORK 1" >>confdefs.h
# Construct a fake local framework structure to make linking with
# '-framework Tcl' and running of tcltest work
- ac_config_commands="$ac_config_commands Tcl.framework"
+ ac_config_commands="$ac_config_commands Tcl.framework"
LD_LIBRARY_PATH_VAR="DYLD_FRAMEWORK_PATH"
# default install directory for bundled packages
@@ -19379,7 +11047,7 @@ TCL_SHARED_BUILD=${SHARED_BUILD}
- ac_config_files="$ac_config_files Makefile:../unix/Makefile.in dltest/Makefile:../unix/dltest/Makefile.in tclConfig.sh:../unix/tclConfig.sh.in tcl.pc:../unix/tcl.pc.in"
+ac_config_files="$ac_config_files Makefile:../unix/Makefile.in dltest/Makefile:../unix/dltest/Makefile.in tclConfig.sh:../unix/tclConfig.sh.in tcl.pc:../unix/tcl.pc.in"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -19399,39 +11067,70 @@ _ACEOF
# The following way of writing the cache mishandles newlines in values,
# but we know of no workaround that is simple, portable, and efficient.
-# So, don't put newlines in cache variables' values.
+# So, we kill variables containing newlines.
# Ultrix sh set writes to stderr and can't be redirected directly,
# and sets the high bit in the cache file unless we assign to the vars.
-{
+(
+ for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do
+ eval ac_val=\$$ac_var
+ case $ac_val in #(
+ *${as_nl}*)
+ case $ac_var in #(
+ *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5
+$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;
+ esac
+ case $ac_var in #(
+ _ | IFS | as_nl) ;; #(
+ BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #(
+ *) { eval $ac_var=; unset $ac_var;} ;;
+ esac ;;
+ esac
+ done
+
(set) 2>&1 |
- case `(ac_space=' '; set | grep ac_space) 2>&1` in
- *ac_space=\ *)
- # `set' does not quote correctly, so add quotes (double-quote
- # substitution turns \\\\ into \\, and sed turns \\ into \).
+ case $as_nl`(ac_space=' '; set) 2>&1` in #(
+ *${as_nl}ac_space=\ *)
+ # `set' does not quote correctly, so add quotes: double-quote
+ # substitution turns \\\\ into \\, and sed turns \\ into \.
sed -n \
"s/'/'\\\\''/g;
s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p"
- ;;
+ ;; #(
*)
# `set' quotes correctly as required by POSIX, so do not add quotes.
- sed -n \
- "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p"
+ sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p"
;;
- esac;
-} |
+ esac |
+ sort
+) |
sed '
+ /^ac_cv_env_/b end
t clear
- : clear
+ :clear
s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/
t end
- /^ac_cv_env/!s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
- : end' >>confcache
-if diff $cache_file confcache >/dev/null 2>&1; then :; else
- if test -w $cache_file; then
- test "x$cache_file" != "x/dev/null" && echo "updating cache $cache_file"
- cat confcache >$cache_file
+ s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/
+ :end' >>confcache
+if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
+ if test -w "$cache_file"; then
+ if test "x$cache_file" != "x/dev/null"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
+$as_echo "$as_me: updating cache $cache_file" >&6;}
+ if test ! -f "$cache_file" || test -h "$cache_file"; then
+ cat confcache >"$cache_file"
+ else
+ case $cache_file in #(
+ */* | ?:*)
+ mv -f confcache "$cache_file"$$ &&
+ mv -f "$cache_file"$$ "$cache_file" ;; #(
+ *)
+ mv -f confcache "$cache_file" ;;
+ esac
+ fi
+ fi
else
- echo "not updating unwritable cache $cache_file"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5
+$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;}
fi
fi
rm -f confcache
@@ -19440,63 +11139,56 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix
# Let make expand exec_prefix.
test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
-# trailing colons and then remove the whole line if VPATH becomes empty
-# (actually we leave an empty line to preserve line numbers).
-if test "x$srcdir" = x.; then
- ac_vpsub='/^[ ]*VPATH[ ]*=/{
-s/:*\$(srcdir):*/:/;
-s/:*\${srcdir}:*/:/;
-s/:*@srcdir@:*/:/;
-s/^\([^=]*=[ ]*\):*/\1/;
-s/:*$//;
-s/^[^=]*=[ ]*$//;
-}'
-fi
-
# Transform confdefs.h into DEFS.
# Protect against shell expansion while executing Makefile rules.
# Protect against Makefile macro expansion.
#
# If the first sed substitution is executed (which looks for macros that
-# take arguments), then we branch to the quote section. Otherwise,
+# take arguments), then branch to the quote section. Otherwise,
# look for a macro that doesn't take arguments.
-cat >confdef2opt.sed <<\_ACEOF
+ac_script='
+:mline
+/\\$/{
+ N
+ s,\\\n,,
+ b mline
+}
t clear
-: clear
-s,^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\),-D\1=\2,g
+:clear
+s/^[ ]*#[ ]*define[ ][ ]*\([^ (][^ (]*([^)]*)\)[ ]*\(.*\)/-D\1=\2/g
t quote
-s,^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\),-D\1=\2,g
+s/^[ ]*#[ ]*define[ ][ ]*\([^ ][^ ]*\)[ ]*\(.*\)/-D\1=\2/g
t quote
-d
-: quote
-s,[ `~#$^&*(){}\\|;'"<>?],\\&,g
-s,\[,\\&,g
-s,\],\\&,g
-s,\$,$$,g
-p
-_ACEOF
-# We use echo to avoid assuming a particular line-breaking character.
-# The extra dot is to prevent the shell from consuming trailing
-# line-breaks from the sub-command output. A line-break within
-# single-quotes doesn't work because, if this script is created in a
-# platform that uses two characters for line-breaks (e.g., DOS), tr
-# would break.
-ac_LF_and_DOT=`echo; echo .`
-DEFS=`sed -n -f confdef2opt.sed confdefs.h | tr "$ac_LF_and_DOT" ' .'`
-rm -f confdef2opt.sed
+b any
+:quote
+s/[ `~#$^&*(){}\\|;'\''"<>?]/\\&/g
+s/\[/\\&/g
+s/\]/\\&/g
+s/\$/$$/g
+H
+:any
+${
+ g
+ s/^\n//
+ s/\n/ /g
+ p
+}
+'
+DEFS=`sed -n "$ac_script" confdefs.h`
CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""
-: ${CONFIG_STATUS=./config.status}
+
+: "${CONFIG_STATUS=./config.status}"
+ac_write_fail=0
ac_clean_files_save=$ac_clean_files
ac_clean_files="$ac_clean_files $CONFIG_STATUS"
-{ echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5
-echo "$as_me: creating $CONFIG_STATUS" >&6;}
-cat >$CONFIG_STATUS <<_ACEOF
+{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5
+$as_echo "$as_me: creating $CONFIG_STATUS" >&6;}
+as_write_fail=0
+cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1
#! $SHELL
# Generated by $as_me.
# Run this file to recreate the current configuration.
@@ -19506,81 +11198,253 @@ cat >$CONFIG_STATUS <<_ACEOF
debug=false
ac_cs_recheck=false
ac_cs_silent=false
-SHELL=\${CONFIG_SHELL-$SHELL}
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-## --------------------- ##
-## M4sh Initialization. ##
-## --------------------- ##
-
-# Be Bourne compatible
-if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then
+SHELL=\${CONFIG_SHELL-$SHELL}
+export SHELL
+_ASEOF
+cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1
+## -------------------- ##
+## M4sh Initialization. ##
+## -------------------- ##
+
+# Be more Bourne compatible
+DUALCASE=1; export DUALCASE # for MKS sh
+if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then :
emulate sh
NULLCMD=:
- # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which
+ # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which
# is contrary to our usage. Disable this feature.
alias -g '${1+"$@"}'='"$@"'
-elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then
- set -o posix
+ setopt NO_GLOB_SUBST
+else
+ case `(set -o) 2>/dev/null` in #(
+ *posix*) :
+ set -o posix ;; #(
+ *) :
+ ;;
+esac
fi
-DUALCASE=1; export DUALCASE # for MKS sh
-# Support unset when possible.
-if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then
- as_unset=unset
-else
- as_unset=false
+
+as_nl='
+'
+export as_nl
+# Printing a long string crashes Solaris 7 /usr/bin/printf.
+as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\'
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo
+as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo
+# Prefer a ksh shell builtin over an external printf program on Solaris,
+# but without wasting forks for bash or zsh.
+if test -z "$BASH_VERSION$ZSH_VERSION" \
+ && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='print -r --'
+ as_echo_n='print -rn --'
+elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then
+ as_echo='printf %s\n'
+ as_echo_n='printf %s'
+else
+ if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then
+ as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"'
+ as_echo_n='/usr/ucb/echo -n'
+ else
+ as_echo_body='eval expr "X$1" : "X\\(.*\\)"'
+ as_echo_n_body='eval
+ arg=$1;
+ case $arg in #(
+ *"$as_nl"*)
+ expr "X$arg" : "X\\(.*\\)$as_nl";
+ arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;;
+ esac;
+ expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl"
+ '
+ export as_echo_n_body
+ as_echo_n='sh -c $as_echo_n_body as_echo'
+ fi
+ export as_echo_body
+ as_echo='sh -c $as_echo_body as_echo'
+fi
+
+# The user is always right.
+if test "${PATH_SEPARATOR+set}" != set; then
+ PATH_SEPARATOR=:
+ (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
+ (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
+ PATH_SEPARATOR=';'
+ }
fi
-# Work around bugs in pre-3.0 UWIN ksh.
-$as_unset ENV MAIL MAILPATH
+# IFS
+# We need space, tab and new line, in precisely that order. Quoting is
+# there to prevent editors from complaining about space-tab.
+# (If _AS_PATH_WALK were called with IFS unset, it would disable word
+# splitting by setting IFS to empty value.)
+IFS=" "" $as_nl"
+
+# Find who we are. Look in the path if we contain no directory separator.
+as_myself=
+case $0 in #((
+ *[\\/]* ) as_myself=$0 ;;
+ *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
+ done
+IFS=$as_save_IFS
+
+ ;;
+esac
+# We did not find ourselves, most probably we were run as `sh COMMAND'
+# in which case we are not to be found in the path.
+if test "x$as_myself" = x; then
+ as_myself=$0
+fi
+if test ! -f "$as_myself"; then
+ $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2
+ exit 1
+fi
+
+# Unset variables that we do not need and which cause bugs (e.g. in
+# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1"
+# suppresses any "Segmentation fault" message there. '((' could
+# trigger a bug in pdksh 5.2.14.
+for as_var in BASH_ENV ENV MAIL MAILPATH
+do eval test x\${$as_var+set} = xset \
+ && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || :
+done
PS1='$ '
PS2='> '
PS4='+ '
# NLS nuisances.
-for as_var in \
- LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \
- LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \
- LC_TELEPHONE LC_TIME
-do
- if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then
- eval $as_var=C; export $as_var
- else
- $as_unset $as_var
+LC_ALL=C
+export LC_ALL
+LANGUAGE=C
+export LANGUAGE
+
+# CDPATH.
+(unset CDPATH) >/dev/null 2>&1 && unset CDPATH
+
+
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
+# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
+# provided, also output the error to LOG_FD, referencing LINENO. Then exit the
+# script with STATUS, using 1 if that was 0.
+as_fn_error ()
+{
+ as_status=$1; test $as_status -eq 0 && as_status=1
+ if test "$4"; then
+ as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
fi
-done
+ $as_echo "$as_me: error: $2" >&2
+ as_fn_exit $as_status
+} # as_fn_error
+
+
+# as_fn_set_status STATUS
+# -----------------------
+# Set $? to STATUS, without forking.
+as_fn_set_status ()
+{
+ return $1
+} # as_fn_set_status
+
+# as_fn_exit STATUS
+# -----------------
+# Exit the shell with STATUS, even in a "trap 0" or "set -e" context.
+as_fn_exit ()
+{
+ set +e
+ as_fn_set_status $1
+ exit $1
+} # as_fn_exit
+
+# as_fn_unset VAR
+# ---------------
+# Portably unset VAR.
+as_fn_unset ()
+{
+ { eval $1=; unset $1;}
+}
+as_unset=as_fn_unset
+# as_fn_append VAR VALUE
+# ----------------------
+# Append the text in VALUE to the end of the definition contained in VAR. Take
+# advantage of any shell optimizations that allow amortized linear growth over
+# repeated appends, instead of the typical quadratic growth present in naive
+# implementations.
+if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then :
+ eval 'as_fn_append ()
+ {
+ eval $1+=\$2
+ }'
+else
+ as_fn_append ()
+ {
+ eval $1=\$$1\$2
+ }
+fi # as_fn_append
+
+# as_fn_arith ARG...
+# ------------------
+# Perform arithmetic evaluation on the ARGs, and store the result in the
+# global $as_val. Take advantage of shells that can avoid forks. The arguments
+# must be portable across $(()) and expr.
+if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then :
+ eval 'as_fn_arith ()
+ {
+ as_val=$(( $* ))
+ }'
+else
+ as_fn_arith ()
+ {
+ as_val=`expr "$@" || test $? -eq 1`
+ }
+fi # as_fn_arith
+
-# Required to use basename.
-if expr a : '\(a\)' >/dev/null 2>&1; then
+if expr a : '\(a\)' >/dev/null 2>&1 &&
+ test "X`expr 00001 : '.*\(...\)'`" = X001; then
as_expr=expr
else
as_expr=false
fi
-if (basename /) >/dev/null 2>&1 && test "X`basename / 2>&1`" = "X/"; then
+if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then
as_basename=basename
else
as_basename=false
fi
+if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then
+ as_dirname=dirname
+else
+ as_dirname=false
+fi
-# Name of the executable.
-as_me=`$as_basename "$0" ||
+as_me=`$as_basename -- "$0" ||
$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \
X"$0" : 'X\(//\)$' \| \
- X"$0" : 'X\(/\)$' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X/"$0" |
- sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/; q; }
- /^X\/\(\/\/\)$/{ s//\1/; q; }
- /^X\/\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
-
+ X"$0" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X/"$0" |
+ sed '/^.*\/\([^/][^/]*\)\/*$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\/\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
-# PATH needs CR, and LINENO needs CR and PATH.
# Avoid depending upon Character Ranges.
as_cr_letters='abcdefghijklmnopqrstuvwxyz'
as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
@@ -19588,148 +11452,111 @@ as_cr_Letters=$as_cr_letters$as_cr_LETTERS
as_cr_digits='0123456789'
as_cr_alnum=$as_cr_Letters$as_cr_digits
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" || {
- # Find who we are. Look in the path if we contain no path at all
- # relative or not.
- case $0 in
- *[\\/]* ) as_myself=$0 ;;
- *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break
-done
-
- ;;
- esac
- # We did not find ourselves, most probably we were run as `sh COMMAND'
- # in which case we are not to be found in the path.
- if test "x$as_myself" = x; then
- as_myself=$0
- fi
- if test ! -f "$as_myself"; then
- { { echo "$as_me:$LINENO: error: cannot find myself; rerun with an absolute path" >&5
-echo "$as_me: error: cannot find myself; rerun with an absolute path" >&2;}
- { (exit 1); exit 1; }; }
- fi
- case $CONFIG_SHELL in
- '')
- as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH
-do
- IFS=$as_save_IFS
- test -z "$as_dir" && as_dir=.
- for as_base in sh bash ksh sh5; do
- case $as_dir in
- /*)
- if ("$as_dir/$as_base" -c '
- as_lineno_1=$LINENO
- as_lineno_2=$LINENO
- as_lineno_3=`(expr $as_lineno_1 + 1) 2>/dev/null`
- test "x$as_lineno_1" != "x$as_lineno_2" &&
- test "x$as_lineno_3" = "x$as_lineno_2" ') 2>/dev/null; then
- $as_unset BASH_ENV || test "${BASH_ENV+set}" != set || { BASH_ENV=; export BASH_ENV; }
- $as_unset ENV || test "${ENV+set}" != set || { ENV=; export ENV; }
- CONFIG_SHELL=$as_dir/$as_base
- export CONFIG_SHELL
- exec "$CONFIG_SHELL" "$0" ${1+"$@"}
- fi;;
- esac
- done
-done
-;;
- esac
-
- # Create $as_me.lineno as a copy of $as_myself, but with $LINENO
- # uniformly replaced by the line number. The first 'sed' inserts a
- # line-number line before each line; the second 'sed' does the real
- # work. The second script uses 'N' to pair each line-number line
- # with the numbered line, and appends trailing '-' during
- # substitution so that $LINENO is not a special case at line end.
- # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the
- # second 'sed' script. Blame Lee E. McMahon for sed's syntax. :-)
- sed '=' <$as_myself |
- sed '
- N
- s,$,-,
- : loop
- s,^\(['$as_cr_digits']*\)\(.*\)[$]LINENO\([^'$as_cr_alnum'_]\),\1\2\1\3,
- t loop
- s,-$,,
- s,^['$as_cr_digits']*\n,,
- ' >$as_me.lineno &&
- chmod +x $as_me.lineno ||
- { { echo "$as_me:$LINENO: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&5
-echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2;}
- { (exit 1); exit 1; }; }
-
- # Don't try to exec as it changes $[0], causing all sort of problems
- # (the dirname of $[0] is not the place where we might find the
- # original and so on. Autoconf is especially sensible to this).
- . ./$as_me.lineno
- # Exit status is that of the last command.
- exit
-}
-
-
-case `echo "testing\c"; echo 1,2,3`,`echo -n testing; echo 1,2,3` in
- *c*,-n*) ECHO_N= ECHO_C='
-' ECHO_T=' ' ;;
- *c*,* ) ECHO_N=-n ECHO_C= ECHO_T= ;;
- *) ECHO_N= ECHO_C='\c' ECHO_T= ;;
+ECHO_C= ECHO_N= ECHO_T=
+case `echo -n x` in #(((((
+-n*)
+ case `echo 'xy\c'` in
+ *c*) ECHO_T=' ';; # ECHO_T is single tab character.
+ xy) ECHO_C='\c';;
+ *) echo `echo ksh88 bug on AIX 6.1` > /dev/null
+ ECHO_T=' ';;
+ esac;;
+*)
+ ECHO_N='-n';;
esac
-if expr a : '\(a\)' >/dev/null 2>&1; then
- as_expr=expr
+rm -f conf$$ conf$$.exe conf$$.file
+if test -d conf$$.dir; then
+ rm -f conf$$.dir/conf$$.file
else
- as_expr=false
+ rm -f conf$$.dir
+ mkdir conf$$.dir 2>/dev/null
fi
-
-rm -f conf$$ conf$$.exe conf$$.file
-echo >conf$$.file
-if ln -s conf$$.file conf$$ 2>/dev/null; then
- # We could just check for DJGPP; but this test a) works b) is more generic
- # and c) will remain valid once DJGPP supports symlinks (DJGPP 2.04).
- if test -f conf$$.exe; then
- # Don't use ln at all; we don't have any links
- as_ln_s='cp -p'
- else
+if (echo >conf$$.file) 2>/dev/null; then
+ if ln -s conf$$.file conf$$ 2>/dev/null; then
as_ln_s='ln -s'
+ # ... but there are two gotchas:
+ # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail.
+ # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
+ # In both cases, we have to default to `cp -pR'.
+ ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
+ as_ln_s='cp -pR'
+ elif ln conf$$.file conf$$ 2>/dev/null; then
+ as_ln_s=ln
+ else
+ as_ln_s='cp -pR'
fi
-elif ln conf$$.file conf$$ 2>/dev/null; then
- as_ln_s=ln
else
- as_ln_s='cp -p'
+ as_ln_s='cp -pR'
fi
-rm -f conf$$ conf$$.exe conf$$.file
+rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file
+rmdir conf$$.dir 2>/dev/null
+
+
+# as_fn_mkdir_p
+# -------------
+# Create "$as_dir" as a directory, including parents if necessary.
+as_fn_mkdir_p ()
+{
+ case $as_dir in #(
+ -*) as_dir=./$as_dir;;
+ esac
+ test -d "$as_dir" || eval $as_mkdir_p || {
+ as_dirs=
+ while :; do
+ case $as_dir in #(
+ *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'(
+ *) as_qdir=$as_dir;;
+ esac
+ as_dirs="'$as_qdir' $as_dirs"
+ as_dir=`$as_dirname -- "$as_dir" ||
+$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
+ X"$as_dir" : 'X\(//\)[^/]' \| \
+ X"$as_dir" : 'X\(//\)$' \| \
+ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$as_dir" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ test -d "$as_dir" && break
+ done
+ test -z "$as_dirs" || eval "mkdir $as_dirs"
+ } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"
+
+
+} # as_fn_mkdir_p
if mkdir -p . 2>/dev/null; then
- as_mkdir_p=:
+ as_mkdir_p='mkdir -p "$as_dir"'
else
test -d ./-p && rmdir ./-p
as_mkdir_p=false
fi
-as_executable_p="test -f"
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+ test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p
# Sed expression to map a string onto a valid CPP name.
as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
@@ -19738,31 +11565,20 @@ as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'"
as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"
-# IFS
-# We need space, tab and new line, in precisely that order.
-as_nl='
-'
-IFS=" $as_nl"
-
-# CDPATH.
-$as_unset CDPATH
-
exec 6>&1
-
-# Open the log real soon, to keep \$[0] and so on meaningful, and to
+## ----------------------------------- ##
+## Main body of $CONFIG_STATUS script. ##
+## ----------------------------------- ##
+_ASEOF
+test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# Save the log message, to keep $0 and so on meaningful, and to
# report actual input values of CONFIG_FILES etc. instead of their
-# values after options handling. Logging --version etc. is OK.
-exec 5>>config.log
-{
- echo
- sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
-## Running $as_me. ##
-_ASBOX
-} >&5
-cat >&5 <<_CSEOF
-
+# values after options handling.
+ac_log="
This file was extended by tcl $as_me 8.6, which was
-generated by GNU Autoconf 2.59. Invocation command line was
+generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
CONFIG_HEADERS = $CONFIG_HEADERS
@@ -19770,43 +11586,41 @@ generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_COMMANDS = $CONFIG_COMMANDS
$ $0 $@
-_CSEOF
-echo "on `(hostname || uname -n) 2>/dev/null | sed 1q`" >&5
-echo >&5
+on `(hostname || uname -n) 2>/dev/null | sed 1q`
+"
+
_ACEOF
-# Files that config.status was made for.
-if test -n "$ac_config_files"; then
- echo "config_files=\"$ac_config_files\"" >>$CONFIG_STATUS
-fi
+case $ac_config_files in *"
+"*) set x $ac_config_files; shift; ac_config_files=$*;;
+esac
-if test -n "$ac_config_headers"; then
- echo "config_headers=\"$ac_config_headers\"" >>$CONFIG_STATUS
-fi
-if test -n "$ac_config_links"; then
- echo "config_links=\"$ac_config_links\"" >>$CONFIG_STATUS
-fi
-if test -n "$ac_config_commands"; then
- echo "config_commands=\"$ac_config_commands\"" >>$CONFIG_STATUS
-fi
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+# Files that config.status was made for.
+config_files="$ac_config_files"
+config_commands="$ac_config_commands"
-cat >>$CONFIG_STATUS <<\_ACEOF
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
ac_cs_usage="\
-\`$as_me' instantiates files from templates according to the
-current configuration.
+\`$as_me' instantiates files and other configuration actions
+from templates according to the current configuration. Unless the files
+and actions are specified as TAGs, all are instantiated by default.
-Usage: $0 [OPTIONS] [FILE]...
+Usage: $0 [OPTION]... [TAG]...
-h, --help print this help, then exit
- -V, --version print version number, then exit
- -q, --quiet do not print progress messages
+ -V, --version print version number and configuration settings, then exit
+ --config print configuration, then exit
+ -q, --quiet, --silent
+ do not print progress messages
-d, --debug don't remove temporary files
--recheck update $as_me by reconfiguring in the same conditions
- --file=FILE[:TEMPLATE]
- instantiate the configuration file FILE
+ --file=FILE[:TEMPLATE]
+ instantiate the configuration file FILE
Configuration files:
$config_files
@@ -19814,83 +11628,78 @@ $config_files
Configuration commands:
$config_commands
-Report bugs to <bug-autoconf@gnu.org>."
-_ACEOF
+Report bugs to the package provider."
-cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
tcl config.status 8.6
-configured by $0, generated by GNU Autoconf 2.59,
- with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
+configured by $0, generated by GNU Autoconf 2.69,
+ with options \\"\$ac_cs_config\\"
-Copyright (C) 2003 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
This config.status script is free software; the Free Software Foundation
gives unlimited permission to copy, distribute and modify it."
-srcdir=$srcdir
+
+ac_pwd='$ac_pwd'
+srcdir='$srcdir'
+test -n "\$AWK" || AWK=awk
_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-# If no file are specified by the user, then we need to provide default
-# value. By we need to know if files were specified by the user.
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# The default lists apply if the user does not specify any file.
ac_need_defaults=:
while test $# != 0
do
case $1 in
- --*=*)
- ac_option=`expr "x$1" : 'x\([^=]*\)='`
- ac_optarg=`expr "x$1" : 'x[^=]*=\(.*\)'`
+ --*=?*)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'`
ac_shift=:
;;
- -*)
+ --*=)
+ ac_option=`expr "X$1" : 'X\([^=]*\)='`
+ ac_optarg=
+ ac_shift=:
+ ;;
+ *)
ac_option=$1
ac_optarg=$2
ac_shift=shift
;;
- *) # This is not an option, so the user has probably given explicit
- # arguments.
- ac_option=$1
- ac_need_defaults=false;;
esac
case $ac_option in
# Handling of the options.
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
ac_cs_recheck=: ;;
- --version | --vers* | -V )
- echo "$ac_cs_version"; exit 0 ;;
- --he | --h)
- # Conflict between --help and --header
- { { echo "$as_me:$LINENO: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: ambiguous option: $1
-Try \`$0 --help' for more information." >&2;}
- { (exit 1); exit 1; }; };;
- --help | --hel | -h )
- echo "$ac_cs_usage"; exit 0 ;;
- --debug | --d* | -d )
+ --version | --versio | --versi | --vers | --ver | --ve | --v | -V )
+ $as_echo "$ac_cs_version"; exit ;;
+ --config | --confi | --conf | --con | --co | --c )
+ $as_echo "$ac_cs_config"; exit ;;
+ --debug | --debu | --deb | --de | --d | -d )
debug=: ;;
--file | --fil | --fi | --f )
$ac_shift
- CONFIG_FILES="$CONFIG_FILES $ac_optarg"
- ac_need_defaults=false;;
- --header | --heade | --head | --hea )
- $ac_shift
- CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg"
+ case $ac_optarg in
+ *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+ '') as_fn_error $? "missing file argument" ;;
+ esac
+ as_fn_append CONFIG_FILES " '$ac_optarg'"
ac_need_defaults=false;;
+ --he | --h | --help | --hel | -h )
+ $as_echo "$ac_cs_usage"; exit ;;
-q | -quiet | --quiet | --quie | --qui | --qu | --q \
| -silent | --silent | --silen | --sile | --sil | --si | --s)
ac_cs_silent=: ;;
# This is an error.
- -*) { { echo "$as_me:$LINENO: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&5
-echo "$as_me: error: unrecognized option: $1
-Try \`$0 --help' for more information." >&2;}
- { (exit 1); exit 1; }; } ;;
+ -*) as_fn_error $? "unrecognized option: \`$1'
+Try \`$0 --help' for more information." ;;
- *) ac_config_targets="$ac_config_targets $1" ;;
+ *) as_fn_append ac_config_targets " $1"
+ ac_need_defaults=false ;;
esac
shift
@@ -19904,43 +11713,55 @@ if $ac_cs_silent; then
fi
_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
if \$ac_cs_recheck; then
- echo "running $SHELL $0 " $ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6
- exec $SHELL $0 $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+ shift
+ \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6
+ CONFIG_SHELL='$SHELL'
+ export CONFIG_SHELL
+ exec "\$@"
fi
_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+exec 5>>config.log
+{
+ echo
+ sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX
+## Running $as_me. ##
+_ASBOX
+ $as_echo "$ac_log"
+} >&5
-cat >>$CONFIG_STATUS <<_ACEOF
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
#
-# INIT-COMMANDS section.
+# INIT-COMMANDS
#
-
VERSION=${TCL_VERSION}
_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-
-cat >>$CONFIG_STATUS <<\_ACEOF
+# Handling of arguments.
for ac_config_target in $ac_config_targets
do
- case "$ac_config_target" in
- # Handling of arguments.
- "Tcl-Info.plist" ) CONFIG_FILES="$CONFIG_FILES Tcl-Info.plist:../macosx/Tcl-Info.plist.in" ;;
- "Tclsh-Info.plist" ) CONFIG_FILES="$CONFIG_FILES Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" ;;
- "Makefile" ) CONFIG_FILES="$CONFIG_FILES Makefile:../unix/Makefile.in" ;;
- "dltest/Makefile" ) CONFIG_FILES="$CONFIG_FILES dltest/Makefile:../unix/dltest/Makefile.in" ;;
- "tclConfig.sh" ) CONFIG_FILES="$CONFIG_FILES tclConfig.sh:../unix/tclConfig.sh.in" ;;
- "tcl.pc" ) CONFIG_FILES="$CONFIG_FILES tcl.pc:../unix/tcl.pc.in" ;;
- "Tcl.framework" ) CONFIG_COMMANDS="$CONFIG_COMMANDS Tcl.framework" ;;
- *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
-echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
- { (exit 1); exit 1; }; };;
+ case $ac_config_target in
+ "Tcl-Info.plist") CONFIG_FILES="$CONFIG_FILES Tcl-Info.plist:../macosx/Tcl-Info.plist.in" ;;
+ "Tclsh-Info.plist") CONFIG_FILES="$CONFIG_FILES Tclsh-Info.plist:../macosx/Tclsh-Info.plist.in" ;;
+ "Tcl.framework") CONFIG_COMMANDS="$CONFIG_COMMANDS Tcl.framework" ;;
+ "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile:../unix/Makefile.in" ;;
+ "dltest/Makefile") CONFIG_FILES="$CONFIG_FILES dltest/Makefile:../unix/dltest/Makefile.in" ;;
+ "tclConfig.sh") CONFIG_FILES="$CONFIG_FILES tclConfig.sh:../unix/tclConfig.sh.in" ;;
+ "tcl.pc") CONFIG_FILES="$CONFIG_FILES tcl.pc:../unix/tcl.pc.in" ;;
+
+ *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
esac
done
+
# If the user did not use the arguments to specify the items to instantiate,
# then the envvar interface is used. Set only those that are not.
# We use the long form for the default assignment because of an extremely
@@ -19951,533 +11772,427 @@ if $ac_need_defaults; then
fi
# Have a temporary directory for convenience. Make it in the build tree
-# simply because there is no reason to put it here, and in addition,
+# simply because there is no reason against having it here, and in addition,
# creating and moving files from /tmp can sometimes cause problems.
-# Create a temporary directory, and hook for its removal unless debugging.
+# Hook for its removal unless debugging.
+# Note that there is a small window in which the directory will not be cleaned:
+# after its creation but before its name has been assigned to `$tmp'.
$debug ||
{
- trap 'exit_status=$?; rm -rf $tmp && exit $exit_status' 0
- trap '{ (exit 1); exit 1; }' 1 2 13 15
+ tmp= ac_tmp=
+ trap 'exit_status=$?
+ : "${ac_tmp:=$tmp}"
+ { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
+' 0
+ trap 'as_fn_exit 1' 1 2 13 15
}
-
# Create a (secure) tmp directory for tmp files.
{
- tmp=`(umask 077 && mktemp -d -q "./confstatXXXXXX") 2>/dev/null` &&
- test -n "$tmp" && test -d "$tmp"
+ tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
+ test -d "$tmp"
} ||
{
- tmp=./confstat$$-$RANDOM
- (umask 077 && mkdir $tmp)
-} ||
+ tmp=./conf$$-$RANDOM
+ (umask 077 && mkdir "$tmp")
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp
+
+# Set up the scripts for CONFIG_FILES section.
+# No need to generate them if there are no CONFIG_FILES.
+# This happens for instance with `./config.status config.h'.
+if test -n "$CONFIG_FILES"; then
+
+
+ac_cr=`echo X | tr X '\015'`
+# On cygwin, bash can eat \r inside `` if the user requested igncr.
+# But we know of no other shell where ac_cr would be empty at this
+# point, so we can use a bashism as a fallback.
+if test "x$ac_cr" = x; then
+ eval ac_cr=\$\'\\r\'
+fi
+ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
+if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
+ ac_cs_awk_cr='\\r'
+else
+ ac_cs_awk_cr=$ac_cr
+fi
+
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
+_ACEOF
+
+
{
- echo "$me: cannot create a temporary directory in ." >&2
- { (exit 1); exit 1; }
+ echo "cat >conf$$subs.awk <<_ACEOF" &&
+ echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' &&
+ echo "_ACEOF"
+} >conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+ . ./conf$$subs.sh ||
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+
+ ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X`
+ if test $ac_delim_n = $ac_delim_num; then
+ break
+ elif $ac_last_try; then
+ as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ else
+ ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+ fi
+done
+rm -f conf$$subs.sh
+
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
+_ACEOF
+sed -n '
+h
+s/^/S["/; s/!.*/"]=/
+p
+g
+s/^[^!]*!//
+:repl
+t repl
+s/'"$ac_delim"'$//
+t delim
+:nl
+h
+s/\(.\{148\}\)..*/\1/
+t more1
+s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/
+p
+n
+b repl
+:more1
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t nl
+:delim
+h
+s/\(.\{148\}\)..*/\1/
+t more2
+s/["\\]/\\&/g; s/^/"/; s/$/"/
+p
+b
+:more2
+s/["\\]/\\&/g; s/^/"/; s/$/"\\/
+p
+g
+s/.\{148\}//
+t delim
+' <conf$$subs.awk | sed '
+/^[^""]/{
+ N
+ s/\n//
+}
+' >>$CONFIG_STATUS || ac_write_fail=1
+rm -f conf$$subs.awk
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+_ACAWK
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
+ for (key in S) S_is_set[key] = 1
+ FS = ""
+
+}
+{
+ line = $ 0
+ nfields = split(line, field, "@")
+ substed = 0
+ len = length(field[1])
+ for (i = 2; i < nfields; i++) {
+ key = field[i]
+ keylen = length(key)
+ if (S_is_set[key]) {
+ value = S[key]
+ line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3)
+ len += length(value) + length(field[++i])
+ substed = 1
+ } else
+ len += 1 + keylen
+ }
+
+ print line
}
+_ACAWK
+_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then
+ sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g"
+else
+ cat
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+ || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
+# trailing colons and then remove the whole line if VPATH becomes empty
+# (actually we leave an empty line to preserve line numbers).
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{
+h
+s///
+s/^/:/
+s/[ ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
+s/:*$//
+x
+s/\(=[ ]*\).*/\1/
+G
+s/\n//
+s/^[^=]*=[ ]*$//
+}'
+fi
-#
-# CONFIG_FILES section.
-#
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+fi # test -n "$CONFIG_FILES"
-# No need to generate the scripts if there are no CONFIG_FILES.
-# This happens for instance when ./config.status config.h
-if test -n "\$CONFIG_FILES"; then
- # Protect against being on the right side of a sed subst in config.status.
- sed 's/,@/@@/; s/@,/@@/; s/,;t t\$/@;t t/; /@;t t\$/s/[\\\\&,]/\\\\&/g;
- s/@@/,@/; s/@@/@,/; s/@;t t\$/,;t t/' >\$tmp/subs.sed <<\\CEOF
-s,@SHELL@,$SHELL,;t t
-s,@PATH_SEPARATOR@,$PATH_SEPARATOR,;t t
-s,@PACKAGE_NAME@,$PACKAGE_NAME,;t t
-s,@PACKAGE_TARNAME@,$PACKAGE_TARNAME,;t t
-s,@PACKAGE_VERSION@,$PACKAGE_VERSION,;t t
-s,@PACKAGE_STRING@,$PACKAGE_STRING,;t t
-s,@PACKAGE_BUGREPORT@,$PACKAGE_BUGREPORT,;t t
-s,@exec_prefix@,$exec_prefix,;t t
-s,@prefix@,$prefix,;t t
-s,@program_transform_name@,$program_transform_name,;t t
-s,@bindir@,$bindir,;t t
-s,@sbindir@,$sbindir,;t t
-s,@libexecdir@,$libexecdir,;t t
-s,@datadir@,$datadir,;t t
-s,@sysconfdir@,$sysconfdir,;t t
-s,@sharedstatedir@,$sharedstatedir,;t t
-s,@localstatedir@,$localstatedir,;t t
-s,@libdir@,$libdir,;t t
-s,@includedir@,$includedir,;t t
-s,@oldincludedir@,$oldincludedir,;t t
-s,@infodir@,$infodir,;t t
-s,@mandir@,$mandir,;t t
-s,@build_alias@,$build_alias,;t t
-s,@host_alias@,$host_alias,;t t
-s,@target_alias@,$target_alias,;t t
-s,@DEFS@,$DEFS,;t t
-s,@ECHO_C@,$ECHO_C,;t t
-s,@ECHO_N@,$ECHO_N,;t t
-s,@ECHO_T@,$ECHO_T,;t t
-s,@LIBS@,$LIBS,;t t
-s,@MAN_FLAGS@,$MAN_FLAGS,;t t
-s,@CC@,$CC,;t t
-s,@CFLAGS@,$CFLAGS,;t t
-s,@LDFLAGS@,$LDFLAGS,;t t
-s,@CPPFLAGS@,$CPPFLAGS,;t t
-s,@ac_ct_CC@,$ac_ct_CC,;t t
-s,@EXEEXT@,$EXEEXT,;t t
-s,@OBJEXT@,$OBJEXT,;t t
-s,@CPP@,$CPP,;t t
-s,@EGREP@,$EGREP,;t t
-s,@TCL_THREADS@,$TCL_THREADS,;t t
-s,@TCLSH_PROG@,$TCLSH_PROG,;t t
-s,@ZLIB_OBJS@,$ZLIB_OBJS,;t t
-s,@ZLIB_SRCS@,$ZLIB_SRCS,;t t
-s,@ZLIB_INCLUDE@,$ZLIB_INCLUDE,;t t
-s,@RANLIB@,$RANLIB,;t t
-s,@ac_ct_RANLIB@,$ac_ct_RANLIB,;t t
-s,@AR@,$AR,;t t
-s,@ac_ct_AR@,$ac_ct_AR,;t t
-s,@LIBOBJS@,$LIBOBJS,;t t
-s,@TCL_LIBS@,$TCL_LIBS,;t t
-s,@DL_LIBS@,$DL_LIBS,;t t
-s,@DL_OBJS@,$DL_OBJS,;t t
-s,@PLAT_OBJS@,$PLAT_OBJS,;t t
-s,@PLAT_SRCS@,$PLAT_SRCS,;t t
-s,@LDAIX_SRC@,$LDAIX_SRC,;t t
-s,@CFLAGS_DEBUG@,$CFLAGS_DEBUG,;t t
-s,@CFLAGS_OPTIMIZE@,$CFLAGS_OPTIMIZE,;t t
-s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t
-s,@LDFLAGS_DEBUG@,$LDFLAGS_DEBUG,;t t
-s,@LDFLAGS_OPTIMIZE@,$LDFLAGS_OPTIMIZE,;t t
-s,@CC_SEARCH_FLAGS@,$CC_SEARCH_FLAGS,;t t
-s,@LD_SEARCH_FLAGS@,$LD_SEARCH_FLAGS,;t t
-s,@STLIB_LD@,$STLIB_LD,;t t
-s,@SHLIB_LD@,$SHLIB_LD,;t t
-s,@TCL_SHLIB_LD_EXTRAS@,$TCL_SHLIB_LD_EXTRAS,;t t
-s,@TK_SHLIB_LD_EXTRAS@,$TK_SHLIB_LD_EXTRAS,;t t
-s,@SHLIB_LD_LIBS@,$SHLIB_LD_LIBS,;t t
-s,@SHLIB_CFLAGS@,$SHLIB_CFLAGS,;t t
-s,@SHLIB_SUFFIX@,$SHLIB_SUFFIX,;t t
-s,@MAKE_LIB@,$MAKE_LIB,;t t
-s,@MAKE_STUB_LIB@,$MAKE_STUB_LIB,;t t
-s,@INSTALL_LIB@,$INSTALL_LIB,;t t
-s,@DLL_INSTALL_DIR@,$DLL_INSTALL_DIR,;t t
-s,@INSTALL_STUB_LIB@,$INSTALL_STUB_LIB,;t t
-s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t
-s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t
-s,@DTRACE@,$DTRACE,;t t
-s,@TCL_VERSION@,$TCL_VERSION,;t t
-s,@TCL_MAJOR_VERSION@,$TCL_MAJOR_VERSION,;t t
-s,@TCL_MINOR_VERSION@,$TCL_MINOR_VERSION,;t t
-s,@TCL_PATCH_LEVEL@,$TCL_PATCH_LEVEL,;t t
-s,@TCL_YEAR@,$TCL_YEAR,;t t
-s,@PKG_CFG_ARGS@,$PKG_CFG_ARGS,;t t
-s,@TCL_LIB_FILE@,$TCL_LIB_FILE,;t t
-s,@TCL_LIB_FLAG@,$TCL_LIB_FLAG,;t t
-s,@TCL_LIB_SPEC@,$TCL_LIB_SPEC,;t t
-s,@TCL_STUB_LIB_FILE@,$TCL_STUB_LIB_FILE,;t t
-s,@TCL_STUB_LIB_FLAG@,$TCL_STUB_LIB_FLAG,;t t
-s,@TCL_STUB_LIB_SPEC@,$TCL_STUB_LIB_SPEC,;t t
-s,@TCL_STUB_LIB_PATH@,$TCL_STUB_LIB_PATH,;t t
-s,@TCL_INCLUDE_SPEC@,$TCL_INCLUDE_SPEC,;t t
-s,@TCL_BUILD_STUB_LIB_SPEC@,$TCL_BUILD_STUB_LIB_SPEC,;t t
-s,@TCL_BUILD_STUB_LIB_PATH@,$TCL_BUILD_STUB_LIB_PATH,;t t
-s,@TCL_SRC_DIR@,$TCL_SRC_DIR,;t t
-s,@CFG_TCL_SHARED_LIB_SUFFIX@,$CFG_TCL_SHARED_LIB_SUFFIX,;t t
-s,@CFG_TCL_UNSHARED_LIB_SUFFIX@,$CFG_TCL_UNSHARED_LIB_SUFFIX,;t t
-s,@TCL_SHARED_BUILD@,$TCL_SHARED_BUILD,;t t
-s,@LD_LIBRARY_PATH_VAR@,$LD_LIBRARY_PATH_VAR,;t t
-s,@TCL_BUILD_LIB_SPEC@,$TCL_BUILD_LIB_SPEC,;t t
-s,@TCL_LIB_VERSIONS_OK@,$TCL_LIB_VERSIONS_OK,;t t
-s,@TCL_SHARED_LIB_SUFFIX@,$TCL_SHARED_LIB_SUFFIX,;t t
-s,@TCL_UNSHARED_LIB_SUFFIX@,$TCL_UNSHARED_LIB_SUFFIX,;t t
-s,@TCL_HAS_LONGLONG@,$TCL_HAS_LONGLONG,;t t
-s,@INSTALL_TZDATA@,$INSTALL_TZDATA,;t t
-s,@DTRACE_SRC@,$DTRACE_SRC,;t t
-s,@DTRACE_HDR@,$DTRACE_HDR,;t t
-s,@DTRACE_OBJ@,$DTRACE_OBJ,;t t
-s,@MAKEFILE_SHELL@,$MAKEFILE_SHELL,;t t
-s,@BUILD_DLTEST@,$BUILD_DLTEST,;t t
-s,@TCL_PACKAGE_PATH@,$TCL_PACKAGE_PATH,;t t
-s,@TCL_MODULE_PATH@,$TCL_MODULE_PATH,;t t
-s,@TCL_LIBRARY@,$TCL_LIBRARY,;t t
-s,@PRIVATE_INCLUDE_DIR@,$PRIVATE_INCLUDE_DIR,;t t
-s,@HTML_DIR@,$HTML_DIR,;t t
-s,@PACKAGE_DIR@,$PACKAGE_DIR,;t t
-s,@EXTRA_CC_SWITCHES@,$EXTRA_CC_SWITCHES,;t t
-s,@EXTRA_APP_CC_SWITCHES@,$EXTRA_APP_CC_SWITCHES,;t t
-s,@EXTRA_INSTALL@,$EXTRA_INSTALL,;t t
-s,@EXTRA_INSTALL_BINARIES@,$EXTRA_INSTALL_BINARIES,;t t
-s,@EXTRA_BUILD_HTML@,$EXTRA_BUILD_HTML,;t t
-s,@EXTRA_TCLSH_LIBS@,$EXTRA_TCLSH_LIBS,;t t
-s,@DLTEST_LD@,$DLTEST_LD,;t t
-s,@DLTEST_SUFFIX@,$DLTEST_SUFFIX,;t t
-CEOF
-_ACEOF
+eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS"
+shift
+for ac_tag
+do
+ case $ac_tag in
+ :[FHLC]) ac_mode=$ac_tag; continue;;
+ esac
+ case $ac_mode$ac_tag in
+ :[FHL]*:*);;
+ :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
+ :[FH]-) ac_tag=-:-;;
+ :[FH]*) ac_tag=$ac_tag:$ac_tag.in;;
+ esac
+ ac_save_IFS=$IFS
+ IFS=:
+ set x $ac_tag
+ IFS=$ac_save_IFS
+ shift
+ ac_file=$1
+ shift
- cat >>$CONFIG_STATUS <<\_ACEOF
- # Split the substitutions into bite-sized pieces for seds with
- # small command number limits, like on Digital OSF/1 and HP-UX.
- ac_max_sed_lines=48
- ac_sed_frag=1 # Number of current file.
- ac_beg=1 # First line for current file.
- ac_end=$ac_max_sed_lines # Line after last line for current file.
- ac_more_lines=:
- ac_sed_cmds=
- while $ac_more_lines; do
- if test $ac_beg -gt 1; then
- sed "1,${ac_beg}d; ${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
- else
- sed "${ac_end}q" $tmp/subs.sed >$tmp/subs.frag
- fi
- if test ! -s $tmp/subs.frag; then
- ac_more_lines=false
- else
- # The purpose of the label and of the branching condition is to
- # speed up the sed processing (if there are no `@' at all, there
- # is no need to browse any of the substitutions).
- # These are the two extra sed commands mentioned above.
- (echo ':t
- /@[a-zA-Z_][a-zA-Z_0-9]*@/!b' && cat $tmp/subs.frag) >$tmp/subs-$ac_sed_frag.sed
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds="sed -f $tmp/subs-$ac_sed_frag.sed"
- else
- ac_sed_cmds="$ac_sed_cmds | sed -f $tmp/subs-$ac_sed_frag.sed"
- fi
- ac_sed_frag=`expr $ac_sed_frag + 1`
- ac_beg=$ac_end
- ac_end=`expr $ac_end + $ac_max_sed_lines`
+ case $ac_mode in
+ :L) ac_source=$1;;
+ :[FH])
+ ac_file_inputs=
+ for ac_f
+ do
+ case $ac_f in
+ -) ac_f="$ac_tmp/stdin";;
+ *) # Look for the file first in the build tree, then in the source tree
+ # (if the path is not absolute). The absolute path cannot be DOS-style,
+ # because $ac_f cannot contain `:'.
+ test -f "$ac_f" ||
+ case $ac_f in
+ [\\/$]*) false;;
+ *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";;
+ esac ||
+ as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+ esac
+ case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac
+ as_fn_append ac_file_inputs " '$ac_f'"
+ done
+
+ # Let's still pretend it is `configure' which instantiates (i.e., don't
+ # use $as_me), people would be surprised to read:
+ # /* config.h. Generated by config.status. */
+ configure_input='Generated from '`
+ $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g'
+ `' by configure.'
+ if test x"$ac_file" != x-; then
+ configure_input="$ac_file. $configure_input"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5
+$as_echo "$as_me: creating $ac_file" >&6;}
fi
- done
- if test -z "$ac_sed_cmds"; then
- ac_sed_cmds=cat
- fi
-fi # test -n "$CONFIG_FILES"
+ # Neutralize special characters interpreted by sed in replacement strings.
+ case $configure_input in #(
+ *\&* | *\|* | *\\* )
+ ac_sed_conf_input=`$as_echo "$configure_input" |
+ sed 's/[\\\\&|]/\\\\&/g'`;; #(
+ *) ac_sed_conf_input=$configure_input;;
+ esac
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-for ac_file in : $CONFIG_FILES; do test "x$ac_file" = x: && continue
- # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
- case $ac_file in
- - | *:- | *:-:* ) # input from stdin
- cat >$tmp/stdin
- ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
- *:* ) ac_file_in=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_file=`echo "$ac_file" | sed 's,:.*,,'` ;;
- * ) ac_file_in=$ac_file.in ;;
+ case $ac_tag in
+ *:-:* | *:-) cat >"$ac_tmp/stdin" \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
+ esac
+ ;;
esac
- # Compute @srcdir@, @top_srcdir@, and @INSTALL@ for subdirectories.
- ac_dir=`(dirname "$ac_file") 2>/dev/null ||
+ ac_dir=`$as_dirname -- "$ac_file" ||
$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
X"$ac_file" : 'X\(//\)[^/]' \| \
X"$ac_file" : 'X\(//\)$' \| \
- X"$ac_file" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$ac_file" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
- { if $as_mkdir_p; then
- mkdir -p "$ac_dir"
- else
- as_dir="$ac_dir"
- as_dirs=
- while test ! -d "$as_dir"; do
- as_dirs="$as_dir $as_dirs"
- as_dir=`(dirname "$as_dir") 2>/dev/null ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
- done
- test ! -n "$as_dirs" || mkdir $as_dirs
- fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
- { (exit 1); exit 1; }; }; }
-
+ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null ||
+$as_echo X"$ac_file" |
+ sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)[^/].*/{
+ s//\1/
+ q
+ }
+ /^X\(\/\/\)$/{
+ s//\1/
+ q
+ }
+ /^X\(\/\).*/{
+ s//\1/
+ q
+ }
+ s/.*/./; q'`
+ as_dir="$ac_dir"; as_fn_mkdir_p
ac_builddir=.
-if test "$ac_dir" != .; then
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A "../" for each directory in $ac_dir_suffix.
- ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
- ac_dir_suffix= ac_top_builddir=
-fi
+case "$ac_dir" in
+.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;;
+*)
+ ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'`
+ # A ".." for each directory in $ac_dir_suffix.
+ ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'`
+ case $ac_top_builddir_sub in
+ "") ac_top_builddir_sub=. ac_top_build_prefix= ;;
+ *) ac_top_build_prefix=$ac_top_builddir_sub/ ;;
+ esac ;;
+esac
+ac_abs_top_builddir=$ac_pwd
+ac_abs_builddir=$ac_pwd$ac_dir_suffix
+# for backward compatibility:
+ac_top_builddir=$ac_top_build_prefix
case $srcdir in
- .) # No --srcdir option. We are building in place.
+ .) # We are building in place.
ac_srcdir=.
- if test -z "$ac_top_builddir"; then
- ac_top_srcdir=.
- else
- ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
- fi ;;
- [\\/]* | ?:[\\/]* ) # Absolute path.
+ ac_top_srcdir=$ac_top_builddir_sub
+ ac_abs_top_srcdir=$ac_pwd ;;
+ [\\/]* | ?:[\\/]* ) # Absolute name.
ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir ;;
- *) # Relative path.
- ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
- case "$ac_dir" in
- .) ac_abs_builddir=`pwd`;;
- [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
- *) ac_abs_builddir=`pwd`/"$ac_dir";;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
- case ${ac_top_builddir}. in
- .) ac_abs_top_builddir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
- *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
- case $ac_srcdir in
- .) ac_abs_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
- *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
- esac;;
+ ac_top_srcdir=$srcdir
+ ac_abs_top_srcdir=$srcdir ;;
+ *) # Relative name.
+ ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix
+ ac_top_srcdir=$ac_top_build_prefix$srcdir
+ ac_abs_top_srcdir=$ac_pwd/$srcdir ;;
esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
- case $ac_top_srcdir in
- .) ac_abs_top_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
- *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
- esac;;
+ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix
+
+
+ case $ac_mode in
+ :F)
+ #
+ # CONFIG_FILE
+ #
+
+_ACEOF
+
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
+# If the template does not know about datarootdir, expand it.
+# FIXME: This hack should be removed a few years after 2.60.
+ac_datarootdir_hack=; ac_datarootdir_seen=
+ac_sed_dataroot='
+/datarootdir/ {
+ p
+ q
+}
+/@datadir@/p
+/@docdir@/p
+/@infodir@/p
+/@localedir@/p
+/@mandir@/p'
+case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in
+*datarootdir*) ac_datarootdir_seen=yes;;
+*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*)
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5
+$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;}
+_ACEOF
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ ac_datarootdir_hack='
+ s&@datadir@&$datadir&g
+ s&@docdir@&$docdir&g
+ s&@infodir@&$infodir&g
+ s&@localedir@&$localedir&g
+ s&@mandir@&$mandir&g
+ s&\\\${datarootdir}&$datarootdir&g' ;;
esac
-
-
-
- if test x"$ac_file" != x-; then
- { echo "$as_me:$LINENO: creating $ac_file" >&5
-echo "$as_me: creating $ac_file" >&6;}
- rm -f "$ac_file"
- fi
- # Let's still pretend it is `configure' which instantiates (i.e., don't
- # use $as_me), people would be surprised to read:
- # /* config.h. Generated by config.status. */
- if test x"$ac_file" = x-; then
- configure_input=
- else
- configure_input="$ac_file. "
- fi
- configure_input=$configure_input"Generated from `echo $ac_file_in |
- sed 's,.*/,,'` by configure."
-
- # First look for the input files in the build tree, otherwise in the
- # src tree.
- ac_file_inputs=`IFS=:
- for f in $ac_file_in; do
- case $f in
- -) echo $tmp/stdin ;;
- [\\/$]*)
- # Absolute (can't be DOS-style, as IFS=:)
- test -f "$f" || { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
- { (exit 1); exit 1; }; }
- echo "$f";;
- *) # Relative
- if test -f "$f"; then
- # Build tree
- echo "$f"
- elif test -f "$srcdir/$f"; then
- # Source tree
- echo "$srcdir/$f"
- else
- # /dev/null tree
- { { echo "$as_me:$LINENO: error: cannot find input file: $f" >&5
-echo "$as_me: error: cannot find input file: $f" >&2;}
- { (exit 1); exit 1; }; }
- fi;;
- esac
- done` || { (exit 1); exit 1; }
_ACEOF
-cat >>$CONFIG_STATUS <<_ACEOF
- sed "$ac_vpsub
+
+# Neutralize VPATH when `$srcdir' = `.'.
+# Shell code in configure.ac might set extrasub.
+# FIXME: do we really want to maintain this feature?
+cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_sed_extra="$ac_vpsub
$extrasub
_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
+cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
:t
/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
-s,@configure_input@,$configure_input,;t t
-s,@srcdir@,$ac_srcdir,;t t
-s,@abs_srcdir@,$ac_abs_srcdir,;t t
-s,@top_srcdir@,$ac_top_srcdir,;t t
-s,@abs_top_srcdir@,$ac_abs_top_srcdir,;t t
-s,@builddir@,$ac_builddir,;t t
-s,@abs_builddir@,$ac_abs_builddir,;t t
-s,@top_builddir@,$ac_top_builddir,;t t
-s,@abs_top_builddir@,$ac_abs_top_builddir,;t t
-" $ac_file_inputs | (eval "$ac_sed_cmds") >$tmp/out
- rm -f $tmp/stdin
- if test x"$ac_file" != x-; then
- mv $tmp/out $ac_file
- else
- cat $tmp/out
- rm -f $tmp/out
- fi
-
-done
-_ACEOF
-cat >>$CONFIG_STATUS <<\_ACEOF
-
-#
-# CONFIG_COMMANDS section.
-#
-for ac_file in : $CONFIG_COMMANDS; do test "x$ac_file" = x: && continue
- ac_dest=`echo "$ac_file" | sed 's,:.*,,'`
- ac_source=`echo "$ac_file" | sed 's,[^:]*:,,'`
- ac_dir=`(dirname "$ac_dest") 2>/dev/null ||
-$as_expr X"$ac_dest" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$ac_dest" : 'X\(//\)[^/]' \| \
- X"$ac_dest" : 'X\(//\)$' \| \
- X"$ac_dest" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$ac_dest" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
- { if $as_mkdir_p; then
- mkdir -p "$ac_dir"
- else
- as_dir="$ac_dir"
- as_dirs=
- while test ! -d "$as_dir"; do
- as_dirs="$as_dir $as_dirs"
- as_dir=`(dirname "$as_dir") 2>/dev/null ||
-$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
- X"$as_dir" : 'X\(//\)[^/]' \| \
- X"$as_dir" : 'X\(//\)$' \| \
- X"$as_dir" : 'X\(/\)' \| \
- . : '\(.\)' 2>/dev/null ||
-echo X"$as_dir" |
- sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; }
- /^X\(\/\/\)[^/].*/{ s//\1/; q; }
- /^X\(\/\/\)$/{ s//\1/; q; }
- /^X\(\/\).*/{ s//\1/; q; }
- s/.*/./; q'`
- done
- test ! -n "$as_dirs" || mkdir $as_dirs
- fi || { { echo "$as_me:$LINENO: error: cannot create directory \"$ac_dir\"" >&5
-echo "$as_me: error: cannot create directory \"$ac_dir\"" >&2;}
- { (exit 1); exit 1; }; }; }
-
- ac_builddir=.
-
-if test "$ac_dir" != .; then
- ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'`
- # A "../" for each directory in $ac_dir_suffix.
- ac_top_builddir=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,../,g'`
-else
- ac_dir_suffix= ac_top_builddir=
-fi
+s|@configure_input@|$ac_sed_conf_input|;t t
+s&@top_builddir@&$ac_top_builddir_sub&;t t
+s&@top_build_prefix@&$ac_top_build_prefix&;t t
+s&@srcdir@&$ac_srcdir&;t t
+s&@abs_srcdir@&$ac_abs_srcdir&;t t
+s&@top_srcdir@&$ac_top_srcdir&;t t
+s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t
+s&@builddir@&$ac_builddir&;t t
+s&@abs_builddir@&$ac_abs_builddir&;t t
+s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
+$ac_datarootdir_hack
+"
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+ >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+
+test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
+ { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+ { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \
+ "$ac_tmp/out"`; test -z "$ac_out"; } &&
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&5
+$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
+which seems to be undefined. Please make sure it is defined" >&2;}
+
+ rm -f "$ac_tmp/stdin"
+ case $ac_file in
+ -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+ *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
+ esac \
+ || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+ ;;
-case $srcdir in
- .) # No --srcdir option. We are building in place.
- ac_srcdir=.
- if test -z "$ac_top_builddir"; then
- ac_top_srcdir=.
- else
- ac_top_srcdir=`echo $ac_top_builddir | sed 's,/$,,'`
- fi ;;
- [\\/]* | ?:[\\/]* ) # Absolute path.
- ac_srcdir=$srcdir$ac_dir_suffix;
- ac_top_srcdir=$srcdir ;;
- *) # Relative path.
- ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix
- ac_top_srcdir=$ac_top_builddir$srcdir ;;
-esac
-# Do not use `cd foo && pwd` to compute absolute paths, because
-# the directories may not exist.
-case `pwd` in
-.) ac_abs_builddir="$ac_dir";;
-*)
- case "$ac_dir" in
- .) ac_abs_builddir=`pwd`;;
- [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";;
- *) ac_abs_builddir=`pwd`/"$ac_dir";;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_builddir=${ac_top_builddir}.;;
-*)
- case ${ac_top_builddir}. in
- .) ac_abs_top_builddir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;;
- *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_srcdir=$ac_srcdir;;
-*)
- case $ac_srcdir in
- .) ac_abs_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;;
- *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;;
- esac;;
-esac
-case $ac_abs_builddir in
-.) ac_abs_top_srcdir=$ac_top_srcdir;;
-*)
- case $ac_top_srcdir in
- .) ac_abs_top_srcdir=$ac_abs_builddir;;
- [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;;
- *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;;
- esac;;
-esac
+ :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5
+$as_echo "$as_me: executing $ac_file commands" >&6;}
+ ;;
+ esac
- { echo "$as_me:$LINENO: executing $ac_dest commands" >&5
-echo "$as_me: executing $ac_dest commands" >&6;}
- case $ac_dest in
- Tcl.framework ) n=Tcl &&
+ case $ac_file$ac_mode in
+ "Tcl.framework":C) n=Tcl &&
f=$n.framework && v=Versions/$VERSION &&
rm -rf $f && mkdir -p $f/$v/Resources &&
ln -s $v/$n $v/Resources $f && ln -s ../../../$n $f/$v &&
ln -s ../../../../$n-Info.plist $f/$v/Resources/Info.plist &&
unset n f v
;;
+
esac
-done
-_ACEOF
+done # for ac_tag
-cat >>$CONFIG_STATUS <<\_ACEOF
-{ (exit 0); exit 0; }
+as_fn_exit 0
_ACEOF
-chmod +x $CONFIG_STATUS
ac_clean_files=$ac_clean_files_save
+test $ac_write_fail = 0 ||
+ as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5
+
# configure is writing to config.log, and then calls config.status.
# config.status does its own redirection, appending to config.log.
@@ -20497,7 +12212,11 @@ if test "$no_create" != yes; then
exec 5>>config.log
# Use ||, not &&, to avoid exiting from the if with $? = 1, which
# would make configure fail if this is the last instruction.
- $ac_cs_success || { (exit 1); exit 1; }
+ $ac_cs_success || as_fn_exit 1
+fi
+if test -n "$ac_unrecognized_opts" && test "$enable_option_checking" != no; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: unrecognized options: $ac_unrecognized_opts" >&5
+$as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2;}
fi
diff --git a/unix/configure.in b/unix/configure.in
index ce68391..a3802e1 100644
--- a/unix/configure.in
+++ b/unix/configure.in
@@ -86,6 +86,7 @@ fi
AC_PROG_CC
AC_C_INLINE
+AC_PROG_BISON
#--------------------------------------------------------------------
# Supply substitutes for missing POSIX header files. Special notes:
# - stdlib.h doesn't define strtol, strtoul, or
@@ -136,6 +137,7 @@ SC_TCL_CFG_ENCODING
#--------------------------------------------------------------------
SC_TCL_LINK_LIBS
+AC_SEARCH_LIBS(inet_aton, resolv)
# Add the threads support libraries
LIBS="$LIBS$THREADS_LIBS"
@@ -307,6 +309,12 @@ fi
SC_TIME_HANDLER
+#------------------------------------------------------------------------------
+# Check if we want to use pcre
+#------------------------------------------------------------------------------
+
+SC_ENABLE_PCRE
+
#--------------------------------------------------------------------
# Some systems (e.g., IRIX 4.0.5) lack some fields in struct stat. But
# we might be able to use fstatfs instead. Some systems (OpenBSD?) also
@@ -399,6 +407,19 @@ if test $tcl_cv_type_socklen_t = no; then
AC_DEFINE(socklen_t, int, [Define as int if socklen_t is not available])
fi
+# check for SHUT_RD and SHUT_WR being enums vs defines
+AC_CACHE_CHECK([for SHUT_RD/SHUT_WR], tcl_cv_type_shutrd, [
+ AC_TRY_COMPILE([
+ #include <sys/socket.h>
+ ],[
+ int foo = SHUT_RD;
+ int bar = SHUT_WR;
+ ],[tcl_cv_type_shutrd=yes],[tcl_cv_type_shutrd=no])])
+if test $tcl_cv_type_shutrd = no; then
+ AC_DEFINE(SHUT_RD, 0, [SHUT_RD not found, define as 0])
+ AC_DEFINE(SHUT_WR, 1, [SHUT_WR not found, define as 1])
+fi
+
AC_CHECK_TYPE([intptr_t], [
AC_DEFINE([HAVE_INTPTR_T], 1, [Do we have the intptr_t type?])], [
AC_CACHE_CHECK([for pointer-size signed integer type], tcl_cv_intptr_t, [
@@ -440,6 +461,8 @@ AC_CHECK_TYPE([uintptr_t], [
AC_CHECK_FUNC(opendir, , [AC_DEFINE(USE_DIRENT2_H, 1, [May we include <dirent2.h>?])])
+AC_STRUCT_DIRENT_D_TYPE
+
#--------------------------------------------------------------------
# The check below checks whether <sys/wait.h> defines the type
# "union wait" correctly. It's needed because of weirdness in
@@ -575,6 +598,14 @@ if test $tcl_cv_isnan = no; then
fi
#--------------------------------------------------------------------
+# Work around apparent fork() problem on netbsd 4.
+#--------------------------------------------------------------------
+
+if test "`uname -s`" = "NetBSD" ; then
+ AC_DEFINE(USE_VFORK, 1, [Should we use vfork() instead of fork()?])
+fi
+
+#--------------------------------------------------------------------
# Darwin specific API checks and defines
#--------------------------------------------------------------------
diff --git a/unix/tcl.m4 b/unix/tcl.m4
index 83c3fb1..3f1554a 100644
--- a/unix/tcl.m4
+++ b/unix/tcl.m4
@@ -499,6 +499,132 @@ AC_DEFUN([SC_BUILD_TCLSH], [
])
#------------------------------------------------------------------------
+# SC_WITH_PCRE --
+#
+# Finds the PCRE header and library files for use with Tcl
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-pcre=/path/to/pcre
+#
+# Sets the following vars:
+# PCRE_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([SC_WITH_PCRE], [
+ AC_ARG_WITH(pcre,
+ AC_HELP_STRING([--with-pcre],
+ [directory containing pcre headers and libraries]),
+ [with_pcre=${withval}])
+ AC_MSG_CHECKING([for PCRE configuration])
+
+ AC_CACHE_VAL(ac_cv_c_pcre,[
+ PCRE_CONFIG="pcre-config"
+ # First check to see if --with-pcre was specified.
+ if test x"${with_pcre}" != x ; then
+ if test -f "${with_pcre}/include/pcre.h" -a \
+ \( -f "${with_pcre}/lib/libpcre.so" -o \
+ -f "${with_pcre}/lib/libpcre.a" \); then
+ ac_cv_c_pcre=`(cd ${with_pcre}; pwd)`
+ PCRE_INCLUDE="-I${ac_cv_c_pcre}/include"
+ PCRE_LIBS="-L${ac_cv_c_pcre}/lib -lpcre"
+ PCRE_CONFIG="${ac_cv_c_pcre}/bin/pcre-config"
+ else
+ AC_MSG_ERROR([${with_pcre} directory doesn't contain pcre header and/or library])
+ fi
+ fi
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ # Try pcre-config if it exists
+ ac_cv_c_pcre=`${PCRE_CONFIG} --prefix 2>/dev/null`
+ if test "$?" -eq 0; then
+ PCRE_INCLUDE=`${PCRE_CONFIG} --cflags 2>/dev/null`
+ PCRE_LIBS=`${PCRE_CONFIG} --libs 2>/dev/null`
+ fi
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_pcre}" = x ; then
+ for i in \
+ `ls -d ${exec_prefix} 2>/dev/null` \
+ `ls -d ${prefix} 2>/dev/null` \
+ `ls -d /usr/local 2>/dev/null` \
+ `ls -d /usr/contrib 2>/dev/null` \
+ `ls -d /usr 2>/dev/null` \
+ ; do
+ if test -f "${i}/include/pcre.h" -a \
+ \( -f "${i}/lib/libpcre.so" -o \
+ -f "${i}/lib/libpcre.a" \); then
+ ac_cv_c_pcre=`(cd $i; pwd)`
+ PCRE_INCLUDE="-I${ac_cv_c_pcre}/include"
+ PCRE_LIBS="-L${ac_cv_c_pcre}/lib -lpcre"
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ AC_MSG_ERROR([Can't find PCRE configuration])
+ else
+ AC_MSG_RESULT([found PCRE configuration at ${ac_cv_c_pcre}])
+ fi
+ AC_SUBST([PCRE_INCLUDE])
+ AC_SUBST([PCRE_LIBS])
+])
+
+#------------------------------------------------------------------------
+# SC_ENABLE_PCRE --
+#
+# Allows the use of PCRE in Tcl as default
+#
+# Arguments:
+# none
+#
+# Results:
+# Adds the following arguments to configure:
+# --enable-pcre=yes|no|default
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([SC_ENABLE_PCRE], [
+ AC_REQUIRE([SC_WITH_PCRE])
+ AC_MSG_CHECKING([whether to enable pcre in Tcl])
+ AC_ARG_ENABLE(pcre,
+ AC_HELP_STRING([--enable-pcre],
+ [whether to enable pcre (default: off)]),
+ [enable_pcre=$enableval], [enable_pcre=no])
+
+ if test "${enable_pcre+set}" = set; then
+ enableval="$enable_pcre"
+ enable_pcre=$enableval
+ else
+ enable_pcre=yes
+ fi
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ AC_MSG_RESULT([pcre configuration not found])
+ else
+ if test "$enable_pcre" = "default" ; then
+ AC_MSG_RESULT([pcre default])
+ AC_DEFINE(USE_DEFAULT_PCRE, 1, [Use PCRE as default RE?])
+ AC_DEFINE(HAVE_PCRE, 1, [Do we enable PCRE interfaces?])
+ elif test "$enable_pcre" = "yes" ; then
+ AC_MSG_RESULT([pcre enabled])
+ AC_DEFINE(HAVE_PCRE, 1, [Do we enable PCRE interfaces?])
+ else
+ PCRE_INCLUDE=
+ PCRE_LIBS=
+ AC_MSG_RESULT([no pcre])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
# SC_ENABLE_SHARED --
#
# Allows the building of shared libraries
@@ -744,6 +870,11 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
AC_DEFINE(NDEBUG, 1, [Is no debugging enabled?])
AC_MSG_RESULT([no])
AC_DEFINE(TCL_CFG_OPTIMIZED, 1, [Is this an optimized build?])
+ elif test "$tcl_ok" = "all-with-O2"; then
+ CFLAGS_DEFAULT='$(CFLAGS_OPTIMIZE)'
+ LDFLAGS_DEFAULT='$(LDFLAGS_OPTIMIZE)'
+ AC_MSG_RESULT([all-with-O2 (all debugging but with -O2 optimization)])
+ AC_DEFINE(TCL_CFG_OPTIMIZED, 1, [Is this an optimized build?])
else
CFLAGS_DEFAULT='$(CFLAGS_DEBUG)'
LDFLAGS_DEFAULT='$(LDFLAGS_DEBUG)'
@@ -754,12 +885,12 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
AC_SUBST(CFLAGS_DEFAULT)
AC_SUBST(LDFLAGS_DEFAULT)
- if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then
+ if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all" -o "$tcl_ok" = "all-with-O2"; then
AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?])
fi
ifelse($1,bccdebug,dnl Only enable 'compile' for the Tcl core itself
- if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all"; then
+ if test "$tcl_ok" = "compile" -o "$tcl_ok" = "all" -o "$tcl_ok" = "all-with-O2"; then
AC_DEFINE(TCL_COMPILE_DEBUG, 1, [Is bytecode debugging enabled?])
AC_DEFINE(TCL_COMPILE_STATS, 1, [Are bytecode statistics enabled?])
fi)
@@ -767,7 +898,7 @@ AC_DEFUN([SC_ENABLE_SYMBOLS], [
if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then
if test "$tcl_ok" = "all"; then
AC_MSG_RESULT([enabled symbols mem ]ifelse($1,bccdebug,[compile ])[debugging])
- else
+ elif test "$tcl_ok" != "all-with-O2"; then
AC_MSG_RESULT([enabled $tcl_ok debugging])
fi
fi
@@ -1841,6 +1972,7 @@ AC_DEFUN([SC_CONFIG_CFLAGS], [
DL_LIBS=""
CC_SEARCH_FLAGS=""
LD_SEARCH_FLAGS=""
+ CFLAGS="$CFLAGS -D_SVID3"
;;
SINIX*5.4*)
SHLIB_CFLAGS="-K PIC"
@@ -2245,6 +2377,7 @@ closedir(d);
AC_DEFINE(NO_STDLIB_H, 1, [Do we have <stdlib.h>?])
fi
AC_CHECK_HEADER(string.h, tcl_ok=1, tcl_ok=0)
+ AC_CHECK_HEADER(strings.h, [AC_DEFINE(HAVE_STRINGS_H)], )
AC_EGREP_HEADER(strstr, string.h, , tcl_ok=0)
AC_EGREP_HEADER(strerror, string.h, , tcl_ok=0)
@@ -3175,6 +3308,18 @@ if test "x$NEED_FAKE_RFC2553" = "x1"; then
AC_CHECK_FUNC(strlcpy)
fi
])
+
+AC_DEFUN([AC_PROG_BISON],[
+ AC_CHECK_PROGS(BISON,[bison],no)
+ export BISON;
+ if test $BISON = "no" ;
+ then
+ AC_MSG_ERROR([Unable to find bison]);
+ fi
+ AC_SUBST(BISON)
+])
+
+
# Local Variables:
# mode: autoconf
# End:
diff --git a/unix/tclUnixPort.h b/unix/tclUnixPort.h
index 2728957..9835d39 100644
--- a/unix/tclUnixPort.h
+++ b/unix/tclUnixPort.h
@@ -443,6 +443,15 @@ extern int gettimeofday(struct timeval *tp,
/*
*---------------------------------------------------------------------------
+ * Make sure that _SC_GETGR_R_SIZE_MAX is defined.
+ *---------------------------------------------------------------------------
+ */
+#if !defined(_SC_GETGR_R_SIZE_MAX)
+#define _SC_GETGR_R_SIZE_MAX 1024
+#endif
+
+/*
+ *---------------------------------------------------------------------------
* The following macro defines the type of the mask arguments to select:
*---------------------------------------------------------------------------
*/
diff --git a/win/Makefile.in b/win/Makefile.in
index 132721a..740cc9a 100644
--- a/win/Makefile.in
+++ b/win/Makefile.in
@@ -151,7 +151,7 @@ ZLIB_DLL_FILE = zlib1.dll
SHARED_LIBRARIES = $(TCL_DLL_FILE) @ZLIB_DLL_FILE@
STATIC_LIBRARIES = $(TCL_LIB_FILE)
-TCLSH = tclsh$(VER)${EXESUFFIX}
+TCLSH = tclsh${EXESUFFIX}
CAT32 = cat32$(EXEEXT)
MAN2TCL = man2tcl$(EXEEXT)
@@ -171,7 +171,7 @@ VPATH = $(GENERIC_DIR):$(TOMMATH_DIR):$(WIN_DIR):$(COMPAT_DIR):$(ZLIB_DIR)
AR = @AR@
RANLIB = @RANLIB@
-CC = @CC@
+CC = $(if $(Q), @echo CC $(notdir $<) ; @CC@, @CC@)
RC = @RC@
RES = @RES@
AC_FLAGS = @EXTRA_CFLAGS@ @DEFS@
@@ -188,7 +188,7 @@ SHLIB_LD = @SHLIB_LD@
SHLIB_LD_LIBS = @SHLIB_LD_LIBS@
SHLIB_CFLAGS = @SHLIB_CFLAGS@
SHLIB_SUFFIX = @SHLIB_SUFFIX@
-LIBS = @LIBS@ $(shell $(CYGPATH) '@ZLIB_LIBS@')
+LIBS = @LIBS@ @PCRE_LIBS@ @ZLIB_LIBS@
RMDIR = rm -rf
MKDIR = mkdir -p
@@ -199,7 +199,7 @@ COPY = cp
CC_SWITCHES = ${CFLAGS} ${CFLAGS_WARNING} ${TCL_SHLIB_CFLAGS} \
-I"${ZLIB_DIR_NATIVE}" -I"${GENERIC_DIR_NATIVE}" -DTCL_TOMMATH \
-DMP_PREC=4 -I"${TOMMATH_DIR_NATIVE}" -I"${WIN_DIR_NATIVE}" \
-${AC_FLAGS} ${COMPILE_DEBUG_FLAGS} ${NO_DEPRECATED_FLAGS}
+@PCRE_INCLUDE@ ${AC_FLAGS} ${COMPILE_DEBUG_FLAGS} ${NO_DEPRECATED_FLAGS}
CC_OBJNAME = @CC_OBJNAME@
CC_EXENAME = @CC_EXENAME@
@@ -304,6 +304,13 @@ GENERIC_OBJS = \
tclVar.$(OBJEXT) \
tclZlib.$(OBJEXT)
+L_OBJS = Lscanner-pregen.$(OBJEXT) \
+ Lgrammar-pregen.$(OBJEXT) \
+ Lcompile.$(OBJEXT) \
+ Last.$(OBJEXT) \
+ Ltypecheck.$(OBJEXT) \
+ Lgetopt.$(OBJEXT)
+
TOMMATH_OBJS = \
bncore.${OBJEXT} \
bn_reverse.${OBJEXT} \
@@ -371,6 +378,18 @@ TOMMATH_OBJS = \
bn_s_mp_sub.${OBJEXT}
+L_HDRS = \
+ $(GENERIC_DIR)/Lcompile.h \
+ $(GENERIC_DIR)/Lgrammar.h \
+ $(GENERIC_DIR)/Last.h
+
+L_SRCS = \
+ $(GENERIC_DIR)/Lscanner.l \
+ $(GENERIC_DIR)/Lgrammar.y \
+ $(GENERIC_DIR)/Lcompile.c \
+ $(GENERIC_DIR)/Last.c \
+ $(GENERIC_DIR)/Lgetopt.c
+
WIN_OBJS = \
tclWin32Dll.$(OBJEXT) \
tclWinChan.$(OBJEXT) \
@@ -411,7 +430,7 @@ ZLIB_OBJS = \
uncompr.$(OBJEXT) \
zutil.$(OBJEXT)
-TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@
+TCL_OBJS = ${GENERIC_OBJS} $(TOMMATH_OBJS) ${WIN_OBJS} @ZLIB_OBJS@ $(L_OBJS)
TCL_DOCS = "$(ROOT_DIR_NATIVE)"/doc/*.[13n]
@@ -529,6 +548,27 @@ tclTomMathStubLib.${OBJEXT}: tclTomMathStubLib.c
tclOOStubLib.${OBJEXT}: tclOOStubLib.c
$(CC) -c $(CC_SWITCHES) -DSTATIC_BUILD @DEPARG@ $(CC_OBJNAME)
+Lscanner.c: $(GENERIC_DIR)/Lscanner.l $(L_HDRS) $(GENERIC_DIR)/Lgrammar.c
+ flex -PL_ -o$@ $(GENERIC_DIR)/Lscanner.l
+
+Lscanner-pregen.$(OBJEXT): $(GENERIC_DIR)/Lscanner-pregen.c $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) -DBUILD_tcl @DEPARG@ $(GENERIC_DIR)/Lscanner-pregen.c
+
+Lgrammar.c: $(GENERIC_DIR)/Lgrammar.y $(L_HDRS)
+ @BISON@ -pL_ -d -o$@ $(GENERIC_DIR)/Lgrammar.y
+
+Lgrammar-pregen.$(OBJEXT): $(GENERIC_DIR)/Lgrammar-pregen.c Lcompile.$(OBJEXT) $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) -DBUILD_tcl @DEPARG@ $(GENERIC_DIR)/Lgrammar-pregen.c
+
+Lcompile.$(OBJEXT): $(GENERIC_DIR)/Lcompile.c $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) -DBUILD_tcl @DEPARG@ $(GENERIC_DIR)/Lcompile.c
+
+Lgetopt.$(OBJEXT): $(GENERIC_DIR)/Lgetopt.c $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) -DBUILD_tcl @DEPARG@ $(GENERIC_DIR)/Lgetopt.c
+
+Last.$(OBJEXT): $(GENERIC_DIR)/Last.c $(L_HDRS)
+ $(CC) -c $(CC_SWITCHES) -DBUILD_tcl @DEPARG@ $(GENERIC_DIR)/Last.c
+
# Implicit rule for all object files that will end up in the Tcl library
%.${OBJEXT}: %.c
@@ -544,7 +584,7 @@ tclOOStubLib.${OBJEXT}: tclOOStubLib.c
# the .c file.
gendate:
- bison --output-file=$(GENERIC_DIR)/tclDate.c \
+ @BISON@ --output-file=$(GENERIC_DIR)/tclDate.c \
--name-prefix=TclDate \
--no-lines \
$(GENERIC_DIR)/tclGetDate.y
@@ -640,7 +680,7 @@ install-libraries: libraries install-tzdata install-msgs
$(COPY) "$$i" "$(INCLUDE_INSTALL_DIR)"; \
done;
@echo "Installing library files to $(SCRIPT_INSTALL_DIR)";
- @for i in $(ROOT_DIR)/library/*.tcl $(ROOT_DIR)/library/tclIndex; \
+ @for i in $(ROOT_DIR)/library/*.tcl $(ROOT_DIR)/library/tclIndex ; \
do \
$(COPY) "$$i" "$(SCRIPT_INSTALL_DIR)"; \
done;
@@ -713,6 +753,9 @@ test-tcl: binaries $(TCLSH) $(CAT32) $(TEST_DLL_FILE)
package ifneeded dde 1.4.0 [list load [file normalize ${DDE_DLL_FILE}] dde]; \
package ifneeded registry 1.3.1 [list load [file normalize ${REG_DLL_FILE}] registry]" | ./$(CAT32)
+l-test l-tests test-l test-L:
+ TCLTEST_SHELL_OPTIONS='-encoding utf-8' $(MAKE) test TESTFLAGS+="-file l-*.test"
+
# Useful target to launch a built tclsh with the proper path,...
runtest: binaries $(TCLSH) $(TEST_DLL_FILE)
@TCL_LIBRARY="$(LIBRARY_DIR)"; export TCL_LIBRARY; \
@@ -864,6 +907,7 @@ html-tcl: $(TCLSH)
html-tk: $(TCLSH)
$(MAKE) shell SCRIPT="$(TOOL_DIR)/tcltk-man2html.tcl --htmldir=$(HTML_INSTALL_DIR) --srcdir=$(ROOT_DIR)/.. $(BUILD_HTML_FLAGS) --tk"
+FORCE:
#
# The list of all the targets that do not correspond to real files. This stops
diff --git a/win/configure b/win/configure
index 4ce23f9..63d8b61 100755
--- a/win/configure
+++ b/win/configure
@@ -309,7 +309,7 @@ ac_includes_default="\
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING ZLIB_DLL_FILE ZLIB_LIBS ZLIB_OBJS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCL_WIN_VERSION MACHINE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL PKG_CFG_ARGS TCL_EXE TCL_LIB_FILE TCL_LIB_FLAG TCL_STATIC_LIB_FILE TCL_STATIC_LIB_FLAG TCL_IMPORT_LIB_FILE TCL_IMPORT_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_DLL_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX CFG_TCL_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TCL_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TCL_BUILD_LIB_SPEC TCL_LD_SEARCH_FLAGS TCL_NEEDS_EXP_FILE TCL_BUILD_EXP_FILE TCL_EXP_FILE TCL_LIB_VERSIONS_OK TCL_PACKAGE_PATH TCL_DDE_VERSION TCL_DDE_MAJOR_VERSION TCL_DDE_MINOR_VERSION TCL_REG_VERSION TCL_REG_MAJOR_VERSION TCL_REG_MINOR_VERSION RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP EGREP BISON AR ac_ct_AR RANLIB ac_ct_RANLIB RC ac_ct_RC SET_MAKE TCL_THREADS CYGPATH CELIB_DIR DL_LIBS CFLAGS_DEBUG CFLAGS_OPTIMIZE CFLAGS_WARNING ZLIB_DLL_FILE ZLIB_LIBS ZLIB_OBJS PCRE_INCLUDE PCRE_LIBS CFLAGS_DEFAULT LDFLAGS_DEFAULT VC_MANIFEST_EMBED_DLL VC_MANIFEST_EMBED_EXE TCL_WIN_VERSION MACHINE TCL_VERSION TCL_MAJOR_VERSION TCL_MINOR_VERSION TCL_PATCH_LEVEL PKG_CFG_ARGS TCL_EXE TCL_LIB_FILE TCL_LIB_FLAG TCL_STATIC_LIB_FILE TCL_STATIC_LIB_FLAG TCL_IMPORT_LIB_FILE TCL_IMPORT_LIB_FLAG TCL_LIB_SPEC TCL_STUB_LIB_FILE TCL_STUB_LIB_FLAG TCL_STUB_LIB_SPEC TCL_STUB_LIB_PATH TCL_INCLUDE_SPEC TCL_BUILD_STUB_LIB_SPEC TCL_BUILD_STUB_LIB_PATH TCL_DLL_FILE TCL_SRC_DIR TCL_BIN_DIR TCL_DBGX CFG_TCL_SHARED_LIB_SUFFIX CFG_TCL_UNSHARED_LIB_SUFFIX CFG_TCL_EXPORT_FILE_SUFFIX EXTRA_CFLAGS DEPARG CC_OBJNAME CC_EXENAME LDFLAGS_DEBUG LDFLAGS_OPTIMIZE LDFLAGS_CONSOLE LDFLAGS_WINDOW STLIB_LD SHLIB_LD SHLIB_LD_LIBS SHLIB_CFLAGS SHLIB_SUFFIX TCL_SHARED_BUILD LIBS_GUI DLLSUFFIX LIBPREFIX LIBSUFFIX EXESUFFIX LIBRARIES MAKE_LIB MAKE_STUB_LIB POST_MAKE_LIB MAKE_DLL MAKE_EXE TCL_BUILD_LIB_SPEC TCL_LD_SEARCH_FLAGS TCL_NEEDS_EXP_FILE TCL_BUILD_EXP_FILE TCL_EXP_FILE TCL_LIB_VERSIONS_OK TCL_PACKAGE_PATH TCL_DDE_VERSION TCL_DDE_MAJOR_VERSION TCL_DDE_MINOR_VERSION TCL_REG_VERSION TCL_REG_MAJOR_VERSION TCL_REG_MINOR_VERSION RC_OUT RC_TYPE RC_INCLUDE RC_DEFINE RC_DEFINES RES LIBOBJS LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
@@ -844,6 +844,7 @@ Optional Features:
--enable-shared build and link with shared libraries (default: on)
--enable-64bit enable 64bit support (where applicable)
--enable-wince enable Win/CE support (where applicable)
+ --enable-pcre whether to enable pcre (default: off)
--enable-symbols build with debugging symbols (default: off)
--enable-embedded-manifest
embed manifest if possible (default: yes)
@@ -853,6 +854,7 @@ Optional Packages:
--without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
--with-encoding encoding for configuration values
--with-celib=DIR use Windows/CE support library from DIR
+ --with-pcre directory containing pcre headers and libraries
Some influential environment variables:
CC C compiler command
@@ -2773,6 +2775,57 @@ _ACEOF
fi
+ for ac_prog in bison
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6
+if test "${ac_cv_prog_BISON+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if test -n "$BISON"; then
+ ac_cv_prog_BISON="$BISON" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if $as_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_BISON="$ac_prog"
+ echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+done
+
+fi
+fi
+BISON=$ac_cv_prog_BISON
+if test -n "$BISON"; then
+ echo "$as_me:$LINENO: result: $BISON" >&5
+echo "${ECHO_T}$BISON" >&6
+else
+ echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6
+fi
+
+ test -n "$BISON" && break
+done
+test -n "$BISON" || BISON="no"
+
+ export BISON;
+ if test $BISON = "no" ;
+ then
+ { { echo "$as_me:$LINENO: error: Unable to find bison" >&5
+echo "$as_me: error: Unable to find bison" >&2;}
+ { (exit 1); exit 1; }; };
+ fi
+
+
+
if test -n "$ac_tool_prefix"; then
# Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args.
set dummy ${ac_tool_prefix}ar; ac_word=$2
@@ -4972,6 +5025,147 @@ _ACEOF
fi
+#------------------------------------------------------------------------------
+# Check if we want to use pcre
+#------------------------------------------------------------------------------
+
+
+
+# Check whether --with-pcre or --without-pcre was given.
+if test "${with_pcre+set}" = set; then
+ withval="$with_pcre"
+ with_pcre=${withval}
+fi;
+ echo "$as_me:$LINENO: checking for PCRE configuration" >&5
+echo $ECHO_N "checking for PCRE configuration... $ECHO_C" >&6
+
+ if test "${ac_cv_c_pcre+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+ PCRE_CONFIG="pcre-config"
+ # First check to see if --with-pcre was specified.
+ if test x"${with_pcre}" != x ; then
+ if test -f "${with_pcre}/include/pcre.h" -a \
+ \( -f "${with_pcre}/lib/libpcre.so" -o \
+ -f "${with_pcre}/lib/libpcre.a" \); then
+ ac_cv_c_pcre=`(cd ${with_pcre}; pwd)`
+ PCRE_INCLUDE="-I${ac_cv_c_pcre}/include"
+ PCRE_LIBS="-L${ac_cv_c_pcre}/lib -lpcre"
+ PCRE_CONFIG="${ac_cv_c_pcre}/bin/pcre-config"
+ else
+ { { echo "$as_me:$LINENO: error: ${with_pcre} directory doesn't contain pcre header and/or library" >&5
+echo "$as_me: error: ${with_pcre} directory doesn't contain pcre header and/or library" >&2;}
+ { (exit 1); exit 1; }; }
+ fi
+ fi
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ # Try pcre-config if it exists
+ ac_cv_c_pcre=`${PCRE_CONFIG} --prefix 2>/dev/null`
+ if test "$?" -eq 0; then
+ PCRE_INCLUDE=`${PCRE_CONFIG} --cflags 2>/dev/null`
+ PCRE_LIBS=`${PCRE_CONFIG} --libs 2>/dev/null`
+ fi
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_pcre}" = x ; then
+ for i in \
+ `ls -d ${exec_prefix} 2>/dev/null` \
+ `ls -d ${prefix} 2>/dev/null` \
+ `ls -d /usr/local 2>/dev/null` \
+ `ls -d /usr/contrib 2>/dev/null` \
+ `ls -d /usr 2>/dev/null` \
+ ; do
+ if test -f "${i}/include/pcre.h" -a \
+ \( -f "${i}/lib/libpcre.so" -o \
+ -f "${i}/lib/libpcre.a" \); then
+ ac_cv_c_pcre=`(cd $i; pwd)`
+ PCRE_INCLUDE="-I${ac_cv_c_pcre}/include"
+ PCRE_LIBS="-L${ac_cv_c_pcre}/lib -lpcre"
+ break
+ fi
+ done
+ fi
+
+fi
+
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ { { echo "$as_me:$LINENO: error: Can't find PCRE configuration" >&5
+echo "$as_me: error: Can't find PCRE configuration" >&2;}
+ { (exit 1); exit 1; }; }
+ else
+ echo "$as_me:$LINENO: result: found PCRE configuration at ${ac_cv_c_pcre}" >&5
+echo "${ECHO_T}found PCRE configuration at ${ac_cv_c_pcre}" >&6
+ fi
+
+
+
+
+
+ echo "$as_me:$LINENO: checking whether to enable pcre in Tcl" >&5
+echo $ECHO_N "checking whether to enable pcre in Tcl... $ECHO_C" >&6
+ # Check whether --enable-pcre or --disable-pcre was given.
+if test "${enable_pcre+set}" = set; then
+ enableval="$enable_pcre"
+ enable_pcre=$enableval
+else
+ enable_pcre=no
+fi;
+
+ if test "${enable_pcre+set}" = set; then
+ enableval="$enable_pcre"
+ enable_pcre=$enableval
+ else
+ enable_pcre=yes
+ fi
+
+ if test x"${ac_cv_c_pcre}" = x -a x"${PCRE_INCLUDE}" = x -a x"${PCRE_LIBS}" = x ; then
+ echo "$as_me:$LINENO: result: pcre configuration not found" >&5
+echo "${ECHO_T}pcre configuration not found" >&6
+ else
+ if test "$enable_pcre" = "default" ; then
+ echo "$as_me:$LINENO: result: pcre default" >&5
+echo "${ECHO_T}pcre default" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define USE_DEFAULT_PCRE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PCRE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define PCRE_STATIC 1
+_ACEOF
+
+ elif test "$enable_pcre" = "yes" ; then
+ echo "$as_me:$LINENO: result: pcre enabled" >&5
+echo "${ECHO_T}pcre enabled" >&6
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_PCRE 1
+_ACEOF
+
+
+cat >>confdefs.h <<\_ACEOF
+#define PCRE_STATIC 1
+_ACEOF
+
+ else
+ PCRE_INCLUDE=
+ PCRE_LIBS=
+ echo "$as_me:$LINENO: result: no pcre" >&5
+echo "${ECHO_T}no pcre" >&6
+ fi
+ fi
+
+
#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option. This macro depends on C flags, and should be called
@@ -5124,19 +5318,19 @@ TCL_SHARED_LIB_SUFFIX="\${NODOT_VERSION}${DLLSUFFIX}"
TCL_UNSHARED_LIB_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
TCL_EXPORT_FILE_SUFFIX="\${NODOT_VERSION}${LIBSUFFIX}"
-eval "TCL_SRC_DIR=\"`cd $srcdir/..; pwd`\""
+eval "TCL_SRC_DIR=\"`cd $srcdir/..; $CYGPATH $(pwd)`\""
eval "TCL_DLL_FILE=tcl${VER}${DLLSUFFIX}"
eval "TCL_STUB_LIB_FILE=\"${LIBPREFIX}tclstub${VER}${LIBSUFFIX}\""
eval "TCL_STUB_LIB_FLAG=\"-ltclstub${VER}${LIBFLAGSUFFIX}\""
-eval "TCL_BUILD_STUB_LIB_SPEC=\"-L`pwd` ${TCL_STUB_LIB_FLAG}\""
+eval "TCL_BUILD_STUB_LIB_SPEC=\"-L`$CYGPATH $(pwd)` ${TCL_STUB_LIB_FLAG}\""
eval "TCL_STUB_LIB_SPEC=\"-L${libdir} ${TCL_STUB_LIB_FLAG}\""
-eval "TCL_BUILD_STUB_LIB_PATH=\"`pwd`/${TCL_STUB_LIB_FILE}\""
+eval "TCL_BUILD_STUB_LIB_PATH=\"`$CYGPATH $(pwd)`/${TCL_STUB_LIB_FILE}\""
eval "TCL_STUB_LIB_PATH=\"${libdir}/${TCL_STUB_LIB_FILE}\""
eval "TCL_LIB_FILE=\"${LIBPREFIX}tcl${VER}${LIBSUFFIX}\""
-eval "TCL_BUILD_LIB_SPEC=\"-L`pwd` -ltcl${VER}${FLAGSUFFIX}\""
+eval "TCL_BUILD_LIB_SPEC=\"-L`$CYGPATH $(pwd)` -ltcl${VER}${FLAGSUFFIX}\""
eval "TCL_LIB_SPEC=\"-L${libdir} -ltcl${VER}${FLAGSUFFIX}\""
# Install time header dir can be set via --includedir
@@ -5938,6 +6132,7 @@ s,@EXEEXT@,$EXEEXT,;t t
s,@OBJEXT@,$OBJEXT,;t t
s,@CPP@,$CPP,;t t
s,@EGREP@,$EGREP,;t t
+s,@BISON@,$BISON,;t t
s,@AR@,$AR,;t t
s,@ac_ct_AR@,$ac_ct_AR,;t t
s,@RANLIB@,$RANLIB,;t t
@@ -5955,6 +6150,8 @@ s,@CFLAGS_WARNING@,$CFLAGS_WARNING,;t t
s,@ZLIB_DLL_FILE@,$ZLIB_DLL_FILE,;t t
s,@ZLIB_LIBS@,$ZLIB_LIBS,;t t
s,@ZLIB_OBJS@,$ZLIB_OBJS,;t t
+s,@PCRE_INCLUDE@,$PCRE_INCLUDE,;t t
+s,@PCRE_LIBS@,$PCRE_LIBS,;t t
s,@CFLAGS_DEFAULT@,$CFLAGS_DEFAULT,;t t
s,@LDFLAGS_DEFAULT@,$LDFLAGS_DEFAULT,;t t
s,@VC_MANIFEST_EMBED_DLL@,$VC_MANIFEST_EMBED_DLL,;t t
diff --git a/win/configure.in b/win/configure.in
index 9e9df90..7f88089 100644
--- a/win/configure.in
+++ b/win/configure.in
@@ -60,6 +60,7 @@ fi
AC_PROG_CC
AC_C_INLINE
AC_HEADER_STDC
+AC_PROG_BISON
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib)
@@ -260,6 +261,12 @@ if test "$tcl_cv_findex_enums" = "no"; then
[Defined when enums are missing from winbase.h])
fi
+#------------------------------------------------------------------------------
+# Check if we want to use pcre
+#------------------------------------------------------------------------------
+
+SC_ENABLE_PCRE
+
#--------------------------------------------------------------------
# Set the default compiler switches based on the --enable-symbols
# option. This macro depends on C flags, and should be called
diff --git a/win/tcl.m4 b/win/tcl.m4
index db86f6c..6f2e93c 100644
--- a/win/tcl.m4
+++ b/win/tcl.m4
@@ -339,6 +339,134 @@ AC_DEFUN([SC_LOAD_TKCONFIG], [
])
#------------------------------------------------------------------------
+# SC_WITH_PCRE --
+#
+# Finds the PCRE header and library files for use with Tcl
+#
+# Arguments:
+# none
+#
+# Results:
+#
+# Adds the following arguments to configure:
+# --with-pcre=/path/to/pcre
+#
+# Sets the following vars:
+# PCRE_DIR
+#------------------------------------------------------------------------
+
+AC_DEFUN([SC_WITH_PCRE], [
+ AC_ARG_WITH(pcre,
+ AC_HELP_STRING([--with-pcre],
+ [directory containing pcre headers and libraries]),
+ [with_pcre=${withval}])
+ AC_MSG_CHECKING([for PCRE configuration])
+
+ AC_CACHE_VAL(ac_cv_c_pcre,[
+ PCRE_CONFIG="pcre-config"
+ # First check to see if --with-pcre was specified.
+ if test x"${with_pcre}" != x ; then
+ if test -f "${with_pcre}/include/pcre.h" -a \
+ \( -f "${with_pcre}/lib/libpcre.so" -o \
+ -f "${with_pcre}/lib/libpcre.a" \); then
+ ac_cv_c_pcre=`(cd ${with_pcre}; pwd)`
+ PCRE_INCLUDE="-I${ac_cv_c_pcre}/include"
+ PCRE_LIBS="-L${ac_cv_c_pcre}/lib -lpcre"
+ PCRE_CONFIG="${ac_cv_c_pcre}/bin/pcre-config"
+ else
+ AC_MSG_ERROR([${with_pcre} directory doesn't contain pcre header and/or library])
+ fi
+ fi
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ # Try pcre-config if it exists
+ ac_cv_c_pcre=`${PCRE_CONFIG} --prefix 2>/dev/null`
+ if test "$?" -eq 0; then
+ PCRE_INCLUDE=`${PCRE_CONFIG} --cflags 2>/dev/null`
+ PCRE_LIBS=`${PCRE_CONFIG} --libs 2>/dev/null`
+ fi
+ fi
+
+ # check in a few common install locations
+ if test x"${ac_cv_c_pcre}" = x ; then
+ for i in \
+ `ls -d ${exec_prefix} 2>/dev/null` \
+ `ls -d ${prefix} 2>/dev/null` \
+ `ls -d /usr/local 2>/dev/null` \
+ `ls -d /usr/contrib 2>/dev/null` \
+ `ls -d /usr 2>/dev/null` \
+ ; do
+ if test -f "${i}/include/pcre.h" -a \
+ \( -f "${i}/lib/libpcre.so" -o \
+ -f "${i}/lib/libpcre.a" \); then
+ ac_cv_c_pcre=`(cd $i; pwd)`
+ PCRE_INCLUDE="-I${ac_cv_c_pcre}/include"
+ PCRE_LIBS="-L${ac_cv_c_pcre}/lib -lpcre"
+ break
+ fi
+ done
+ fi
+ ])
+
+ if test x"${ac_cv_c_pcre}" = x ; then
+ AC_MSG_ERROR([Can't find PCRE configuration])
+ else
+ AC_MSG_RESULT([found PCRE configuration at ${ac_cv_c_pcre}])
+ fi
+ AC_SUBST([PCRE_INCLUDE])
+ AC_SUBST([PCRE_LIBS])
+])
+
+#------------------------------------------------------------------------
+# SC_ENABLE_PCRE --
+#
+# Allows the use of PCRE in Tcl as default
+#
+# Arguments:
+# none
+#
+# Results:
+# Adds the following arguments to configure:
+# --enable-pcre=yes|no|default
+#
+#------------------------------------------------------------------------
+
+AC_DEFUN([SC_ENABLE_PCRE], [
+ AC_REQUIRE([SC_WITH_PCRE])
+ AC_MSG_CHECKING([whether to enable pcre in Tcl])
+ AC_ARG_ENABLE(pcre,
+ AC_HELP_STRING([--enable-pcre],
+ [whether to enable pcre (default: off)]),
+ [enable_pcre=$enableval], [enable_pcre=no])
+
+ if test "${enable_pcre+set}" = set; then
+ enableval="$enable_pcre"
+ enable_pcre=$enableval
+ else
+ enable_pcre=yes
+ fi
+
+ if test x"${ac_cv_c_pcre}" = x -a x"${PCRE_INCLUDE}" = x -a x"${PCRE_LIBS}" = x ; then
+ AC_MSG_RESULT([pcre configuration not found])
+ else
+ if test "$enable_pcre" = "default" ; then
+ AC_MSG_RESULT([pcre default])
+ AC_DEFINE(USE_DEFAULT_PCRE, 1, [Use PCRE as default RE?])
+ AC_DEFINE(HAVE_PCRE, 1, [Do we enable PCRE interfaces?])
+ AC_DEFINE(PCRE_STATIC, 1, [Statically compile PCRE])
+ elif test "$enable_pcre" = "yes" ; then
+ AC_MSG_RESULT([pcre enabled])
+ AC_DEFINE(HAVE_PCRE, 1, [Do we enable PCRE interfaces?])
+ AC_DEFINE(PCRE_STATIC, 1, [Statically compile PCRE])
+ else
+ PCRE_INCLUDE=
+ PCRE_LIBS=
+ AC_MSG_RESULT([no pcre])
+ fi
+ fi
+])
+
+#------------------------------------------------------------------------
# SC_ENABLE_SHARED --
#
# Allows the building of shared libraries
@@ -1300,3 +1428,13 @@ print("manifest needed")
AC_SUBST(VC_MANIFEST_EMBED_DLL)
AC_SUBST(VC_MANIFEST_EMBED_EXE)
])
+
+AC_DEFUN([AC_PROG_BISON],[
+ AC_CHECK_PROGS(BISON,[bison],no)
+ export BISON;
+ if test $BISON = "no" ;
+ then
+ AC_MSG_ERROR([Unable to find bison]);
+ fi
+ AC_SUBST(BISON)
+])
diff --git a/win/tclWinPort.h b/win/tclWinPort.h
index ca6b2bf..5f28b31 100644
--- a/win/tclWinPort.h
+++ b/win/tclWinPort.h
@@ -93,6 +93,10 @@ typedef DWORD_PTR * PDWORD_PTR;
#include <signal.h>
#include <limits.h>
+#ifdef __MINGW32__
+#include <stdint.h>
+#endif
+
#ifndef __GNUC__
# define strncasecmp _strnicmp
# define strcasecmp _stricmp
@@ -531,7 +535,6 @@ typedef DWORD_PTR * PDWORD_PTR;
/* This type is not defined in the Windows headers */
#define socklen_t int
-
/*
* The following macros have trivial definitions, allowing generic code to
* address platform-specific issues.
diff --git a/win/tclWinSock.c b/win/tclWinSock.c
index a022ed5..49ebdbb 100644
--- a/win/tclWinSock.c
+++ b/win/tclWinSock.c
@@ -54,6 +54,12 @@
# pragma comment (lib, "ws2_32")
#endif
+#ifdef __MINGW32__
+/* For compiling under earlier versions of mingw which omitted this. */
+const struct in6_addr in6addr_any = {{ IN6ADDR_ANY_INIT }};
+const struct in6_addr in6addr_loopback = {{ IN6ADDR_LOOPBACK_INIT }};
+#endif
+
/*
* Support for control over sockets' KEEPALIVE and NODELAY behavior is
* currently disabled.