Rename default to default_function, for compatibility with GNU awk. (For cross-compiling out-of-tree kernel modules, for example.)

#!/usr/bin/awk -f

#-
# Copyright (c) 1992, 1993
#        The Regents of the University of California.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 4. Neither the name of the University nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# From @(#)vnode_if.sh        8.1 (Berkeley) 6/10/93
# From @(#)makedevops.sh 1.1 1998/06/14 13:53:12 dfr Exp $
# From @(#)makedevops.sh ?.? 1998/10/05
# From src/sys/kern/makedevops.pl,v 1.12 1999/11/22 14:40:04 n_hibma Exp
# From src/sys/kern/makeobjops.pl,v 1.8 2001/11/16 02:02:42 joe Exp
#
# $FreeBSD$

#
#   Script to produce kobj front-end sugar.
#

function usage ()
{
	print "usage: makeobjops.awk <srcfile.m> [-d] [-p] [-l <nr>] [-c|-h]";
	print "where -c   produce only .c files";
	print "      -h   produce only .h files";
	print "      -p   use the path component in the source file for destination dir";
	print "      -l   set line width for output files [80]";
	print "      -d   switch on debugging";
	exit 1;
}

function warn (msg)
{
	print "makeobjops.awk:", msg > "/dev/stderr";
}

function warnsrc (msg)
{
	warn(src ":" lineno ": " msg);
}

function debug (msg)
{
	if (opt_d)
		warn(msg);
}

function die (msg)
{
	warn(msg);
	exit 1;
}

#   These are just for convenience ...
function printc(s) {if (opt_c) print s > ctmpfilename;}
function printh(s) {if (opt_h) print s > htmpfilename;}

#
#   If a line exceeds maxlength, split it into multiple
#   lines at commas.  Subsequent lines are indented by
#   the specified number of spaces.
#
#   In other words:  Lines are split by replacing ", "
#   by ",\n" plus indent spaces.
#

function format_line (line, maxlength, indent)
{
	rline = "";

	while (length(line) > maxlength) {
		#
		#   Find the rightmost ", " so that the part
		#   to the left of it is just within maxlength.
		#   If there is none, give up and leave it as-is.
		#
		if (!match(substr(line, 1, maxlength + 1), /^.*, /))
			break;
		rline = rline substr(line, 1, RLENGTH - 1) "\n";
		line = sprintf("%*s", indent, "") substr(line, RLENGTH + 1);
	}
	return rline line;
}

#
#   Join an array into a string.
#

function join (separator, array, num)
{
	_result = ""
	if (num) {
		while (num > 1)
			_result = separator array[num--] _result;
		_result = array[1] _result;
	}
	return _result;
}

#
#   Execute a system command and report if it failed.
#

function system_check (cmd)
{
	if ((rc = system(cmd)))
		warn(cmd " failed (" rc ")");
}

#
#   Handle "INTERFACE" line.
#

function handle_interface ()
{
	intname = $2;
	sub(/;$/, "", intname);
	if (intname !~ /^[a-z_][a-z0-9_]*$/) {
		debug($0);
		warnsrc("Invalid interface name '" intname "', use [a-z_][a-z0-9_]*");
		error = 1;
		return;
	}
	if (!/;[ 	]*$/)
		warnsrc("Semicolon missing at end of line, no problem");

	debug("Interface " intname);

	printh("#ifndef _" intname "_if_h_");
	printh("#define _" intname "_if_h_\n");
	printc("#include \"" intname "_if.h\"\n");
}

#
# Pass doc comments through to the C file
#
function handle_doc ()
{
	doc = ""
	while (!/\*\//) {
		doc = doc $0 "\n";
		getline < src;
		lineno++;
	}
	doc = doc $0 "\n";
	return doc;
}

#
#   Handle "CODE" and "HEADER" sections.
#   Returns the code as-is.
#

function handle_code ()
{
	code = "\n";
	getline < src;
	indent = $0;
	sub(/[^	 ].*$/, "", indent);	# find the indent used
	while (!/^}/) {
		sub("^" indent, "");	# remove the indent
		code = code $0 "\n";
		getline < src;
		lineno++;;
	}
	return code;
}

#
#   Handle "METHOD" and "STATICMETHOD" sections.
#

function handle_method (static, doc)
{
	#
	#   Get the return type and function name and delete that from
	#   the line. What is left is the possibly first function argument
	#   if it is on the same line.
	#
	if (!intname) {
		warnsrc("No interface name defined");
		error = 1;
		return;
	}
	sub(/^[^ 	]+[ 	]+/, "");
	ret = $0;
	sub(/[ 	]*\{.*$/, "", ret);
	name = ret;
	sub(/^.*[ 	]/, "", name);	# last element is name of method
	sub(/[ 	]+[^ 	]+$/, "", ret);	# return type
	debug("Method: name=" name " return type=" ret);

	sub(/^[^\{]*\{[	 ]*/, "");

	if (!name || !ret) {
		debug($0);
		warnsrc("Invalid method specification");
		error = 1;
		return;
	}

	if (name !~ /^[a-z_][a-z_0-9]*$/) {
		warnsrc("Invalid method name '" name "', use [a-z_][a-z0-9_]*");
		error = 1;
		return;
	}

	if (methods[name]) {
		warnsrc("Duplicate method name");
		error = 1;
		return;
	}
	methods[name] = name;

	line = $0;
	while (line !~ /\}/ && (getline < src) > 0) {
		line = line " " $0;
		lineno++
	}

	default_function = "";
	if (!match(line, /\};?/)) {
		warnsrc("Premature end of file");
		error = 1;
		return;
	}
	extra = substr(line, RSTART + RLENGTH);
	if (extra ~ /[	 ]*DEFAULT[ 	]*[a-zA-Z_][a-zA-Z_0-9]*[ 	]*;/) {
		default_function = extra;
		sub(/.*DEFAULT[	 ]*/, "", default_function);
		sub(/[; 	]+.*$/, "", default_function);
	}
	else if (extra && opt_d) {
		#   Warn about garbage at end of line.
		warnsrc("Ignored '" extra "'");
	}
	sub(/\};?.*$/, "", line);

	#
	#   Create a list of variables without the types prepended.
	#
	sub(/^[	 ]+/, "", line);	# remove leading ...
	sub(/[ 	]+$/, "", line);	# ... and trailing whitespace
	gsub(/[	 ]+/, " ", line);	# remove double spaces

	num_arguments = split(line, arguments, / *; */) - 1;
	delete varnames;		# list of varnames
	num_varnames = 0;
	for (i = 1; i <= num_arguments; i++) {
		if (!arguments[i])
			continue;	# skip argument if argument is empty
		num_ar = split(arguments[i], ar, /[* 	]+/);
		if (num_ar < 2) {	# only 1 word in argument?
			warnsrc("no type for '" arguments[i] "'");
			error = 1;
			return;
		}
		#   Last element is name of variable.
		varnames[++num_varnames] = ar[num_ar];
	}

	argument_list = join(", ", arguments, num_arguments);
	varname_list = join(", ", varnames, num_varnames);

	if (opt_d) {
		warn("Arguments: " argument_list);
		warn("Varnames: " varname_list);
	}

	mname = intname "_" name;	# method name
	umname = toupper(mname);	# uppercase method name

	firstvar = varnames[1];

	if (default_function == "")
		default_function = "kobj_error_method";

	# the method description
	printh("/** @brief Unique descriptor for the " umname "() method */");
	printh("extern struct kobjop_desc " mname "_desc;");
	# the method typedef
	printh("/** @brief A function implementing the " umname "() method */");
	prototype = "typedef " ret " " mname "_t(";
	printh(format_line(prototype argument_list ");",
	    line_width, length(prototype)));

	# Print out the method desc
	printc("struct kobj_method " mname "_method_default = {");
	printc("\t&" mname "_desc, (kobjop_t) " default_function);
	printc("};\n");

	printc("struct kobjop_desc " mname "_desc = {");
	printc("\t0, &" mname "_method_default");
	printc("};\n");

	# Print out the method itself
	printh(doc);
	if (0) {		# haven't chosen the format yet
		printh("static __inline " ret " " umname "(" varname_list ")");
		printh("\t" join(";\n\t", arguments, num_arguments) ";");
	}
	else {
		prototype = "static __inline " ret " " umname "(";
		printh(format_line(prototype argument_list ")",
		    line_width, length(prototype)));
	}
	printh("{");
	printh("\tkobjop_t _m;");
	if (!static)
		firstvar = "((kobj_t)" firstvar ")";
	printh("\tKOBJOPLOOKUP(" firstvar "->ops," mname ");");
	retrn =  (ret != "void") ? "return " : "";
	printh("\t" retrn "((" mname "_t *) _m)(" varname_list ");");
	printh("}\n");
}

#
#   Begin of the main program.
#

BEGIN {

line_width = 80;
gerror = 0;

#
#   Process the command line.
#

num_files = 0;

for (i = 1; i < ARGC; i++) {
	if (ARGV[i] ~ /^-/) {
		#
		#   awk doesn't have getopt(), so we have to do it ourselves.
		#   This is a bit clumsy, but it works.
		#
		for (j = 2; j <= length(ARGV[i]); j++) {
			o = substr(ARGV[i], j, 1);
			if	(o == "c")	opt_c = 1;
			else if	(o == "h")	opt_h = 1;
			else if	(o == "p")	opt_p = 1;
			else if	(o == "d")	opt_d = 1;
			else if	(o == "l") {
				if (length(ARGV[i]) > j) {
					opt_l = substr(ARGV[i], j + 1);
					break;
				}
				else {
					if (++i < ARGC)
						opt_l = ARGV[i];
					else
						usage();
				}
			}
			else
				usage();
		}
	}
	else if (ARGV[i] ~ /\.m$/)
		filenames[num_files++] = ARGV[i];
	else
		usage();
}

if (!num_files || !(opt_c || opt_h))
	usage();

if (opt_p)
	debug("Will produce files in original not in current directory");

if (opt_l) {
	if (opt_l !~ /^[0-9]+$/ || opt_l < 1)
		die("Invalid line width '" opt_l "'");
	line_width = opt_l;
	debug("Line width set to " line_width);
}

for (i = 0; i < num_files; i++)
	debug("Filename: " filenames[i]);

for (file_i = 0; file_i < num_files; file_i++) {
	src = filenames[file_i];
	cfilename = hfilename = src;
	sub(/\.m$/, ".c", cfilename);
	sub(/\.m$/, ".h", hfilename);
	if (!opt_p) {
		sub(/^.*\//, "", cfilename);
		sub(/^.*\//, "", hfilename);
	}

	debug("Processing from " src " to " cfilename " / " hfilename);

	ctmpfilename = cfilename ".tmp";
	htmpfilename = hfilename ".tmp";

	common_head = \
	    "/*\n" \
	    " * This file is produced automatically.\n" \
	    " * Do not modify anything in here by hand.\n" \
	    " *\n" \
	    " * Created from source file\n" \
	    " *   " src "\n" \
	    " * with\n" \
	    " *   makeobjops.awk\n" \
	    " *\n" \
	    " * See the source file for legal information\n" \
	    " */\n";

	printc(common_head "\n" \
	    "#include <sys/param.h>\n" \
	    "#include <sys/queue.h>\n" \
	    "#include <sys/kernel.h>\n" \
	    "#include <sys/kobj.h>");

	printh(common_head);

	delete methods;		# clear list of methods
	intname = "";
	lineno = 0;
	error = 0;		# to signal clean up and gerror setting
	lastdoc = "";

	while (!error && (getline < src) > 0) {
		lineno++;

		#
		#   Take special notice of include directives.
		#
		if (/^#[ 	]*include[ 	]+["<][^">]+[">]/) {
			incld = $0;
			sub(/^#[ 	]*include[ 	]+/, "", incld);
			debug("Included file: " incld);
			printc("#include " incld);
		}

		sub(/#.*/, "");		# remove comments
		sub(/^[	 ]+/, "");	# remove leading ...
		sub(/[ 	]+$/, "");	# ... and trailing whitespace

		if (/^$/) {		# skip empty lines
		}
		else if (/^\/\*\*/)
			lastdoc = handle_doc();
		else if (/^INTERFACE[ 	]+[^ 	;]*[ 	]*;?[ 	]*$/) {
			printh(lastdoc);
			lastdoc = "";
			handle_interface();
		} else if (/^CODE[ 	]*{$/)
			printc(handle_code());
		else if (/^HEADER[	 ]*{$/)
			printh(handle_code());
		else if (/^METHOD/) {
			handle_method(0, lastdoc);
			lastdoc = "";
		} else if (/^STATICMETHOD/) {
			handle_method(1, lastdoc);
			lastdoc = "";
		} else {
			debug($0);
			warnsrc("Invalid line encountered");
			error = 1;
		}
	}

	#
	#   Print the final '#endif' in the header file.
	#
	printh("#endif /* _" intname "_if_h_ */");

	close (ctmpfilename);
	close (htmpfilename);

	if (error) {
		warn("Output skipped");
		system_check("rm -f " ctmpfilename " " htmpfilename);
		gerror = 1;
	}
	else {
		if (opt_c)
			system_check("mv -f " ctmpfilename " " cfilename);
		if (opt_h)
			system_check("mv -f " htmpfilename " " hfilename);
	}
}

exit gerror;

}

#!/usr/bin/awk -f

#-
# Copyright (c) 1992, 1993
#        The Regents of the University of California.  All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# 1. Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright
#    notice, this list of conditions and the following disclaimer in the
#    documentation and/or other materials provided with the distribution.
# 4. Neither the name of the University nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
# From @(#)vnode_if.sh        8.1 (Berkeley) 6/10/93
# From @(#)makedevops.sh 1.1 1998/06/14 13:53:12 dfr Exp $
# From @(#)makedevops.sh ?.? 1998/10/05
# From src/sys/kern/makedevops.pl,v 1.12 1999/11/22 14:40:04 n_hibma Exp
# From src/sys/kern/makeobjops.pl,v 1.8 2001/11/16 02:02:42 joe Exp
#
# $FreeBSD$

#
#   Script to produce kobj front-end sugar.
#

function usage ()
{
	print "usage: makeobjops.awk <srcfile.m> [-d] [-p] [-l <nr>] [-c|-h]";
	print "where -c   produce only .c files";
	print "      -h   produce only .h files";
	print "      -p   use the path component in the source file for destination dir";
	print "      -l   set line width for output files [80]";
	print "      -d   switch on debugging";
	exit 1;
}

function warn (msg)
{
	print "makeobjops.awk:", msg > "/dev/stderr";
}

function warnsrc (msg)
{
	warn(src ":" lineno ": " msg);
}

function debug (msg)
{
	if (opt_d)
		warn(msg);
}

function die (msg)
{
	warn(msg);
	exit 1;
}

#   These are just for convenience ...
function printc(s) {if (opt_c) print s > ctmpfilename;}
function printh(s) {if (opt_h) print s > htmpfilename;}

#
#   If a line exceeds maxlength, split it into multiple
#   lines at commas.  Subsequent lines are indented by
#   the specified number of spaces.
#
#   In other words:  Lines are split by replacing ", "
#   by ",\n" plus indent spaces.
#

function format_line (line, maxlength, indent)
{
	rline = "";

	while (length(line) > maxlength) {
		#
		#   Find the rightmost ", " so that the part
		#   to the left of it is just within maxlength.
		#   If there is none, give up and leave it as-is.
		#
		if (!match(substr(line, 1, maxlength + 1), /^.*, /))
			break;
		rline = rline substr(line, 1, RLENGTH - 1) "\n";
		line = sprintf("%*s", indent, "") substr(line, RLENGTH + 1);
	}
	return rline line;
}

#
#   Join an array into a string.
#

function join (separator, array, num)
{
	_result = ""
	if (num) {
		while (num > 1)
			_result = separator array[num--] _result;
		_result = array[1] _result;
	}
	return _result;
}

#
#   Execute a system command and report if it failed.
#

function system_check (cmd)
{
	if ((rc = system(cmd)))
		warn(cmd " failed (" rc ")");
}

#
#   Handle "INTERFACE" line.
#

function handle_interface ()
{
	intname = $2;
	sub(/;$/, "", intname);
	if (intname !~ /^[a-z_][a-z0-9_]*$/) {
		debug($0);
		warnsrc("Invalid interface name '" intname "', use [a-z_][a-z0-9_]*");
		error = 1;
		return;
	}
	if (!/;[ 	]*$/)
		warnsrc("Semicolon missing at end of line, no problem");

	debug("Interface " intname);

	printh("#ifndef _" intname "_if_h_");
	printh("#define _" intname "_if_h_\n");
	printc("#include \"" intname "_if.h\"\n");
}

#
# Pass doc comments through to the C file
#
function handle_doc ()
{
	doc = ""
	while (!/\*\//) {
		doc = doc $0 "\n";
		getline < src;
		lineno++;
	}
	doc = doc $0 "\n";
	return doc;
}

#
#   Handle "CODE" and "HEADER" sections.
#   Returns the code as-is.
#

function handle_code ()
{
	code = "\n";
	getline < src;
	indent = $0;
	sub(/[^	 ].*$/, "", indent);	# find the indent used
	while (!/^}/) {
		sub("^" indent, "");	# remove the indent
		code = code $0 "\n";
		getline < src;
		lineno++;;
	}
	return code;
}

#
#   Handle "METHOD" and "STATICMETHOD" sections.
#

function handle_method (static, doc)
{
	#
	#   Get the return type and function name and delete that from
	#   the line. What is left is the possibly first function argument
	#   if it is on the same line.
	#
	if (!intname) {
		warnsrc("No interface name defined");
		error = 1;
		return;
	}
	sub(/^[^ 	]+[ 	]+/, "");
	ret = $0;
	sub(/[ 	]*\{.*$/, "", ret);
	name = ret;
	sub(/^.*[ 	]/, "", name);	# last element is name of method
	sub(/[ 	]+[^ 	]+$/, "", ret);	# return type
	debug("Method: name=" name " return type=" ret);

	sub(/^[^\{]*\{[	 ]*/, "");

	if (!name || !ret) {
		debug($0);
		warnsrc("Invalid method specification");
		error = 1;
		return;
	}

	if (name !~ /^[a-z_][a-z_0-9]*$/) {
		warnsrc("Invalid method name '" name "', use [a-z_][a-z0-9_]*");
		error = 1;
		return;
	}

	if (methods[name]) {
		warnsrc("Duplicate method name");
		error = 1;
		return;
	}
	methods[name] = name;

	line = $0;
	while (line !~ /\}/ && (getline < src) > 0) {
		line = line " " $0;
		lineno++
	}

	default = "";
	if (!match(line, /\};?/)) {
		warnsrc("Premature end of file");
		error = 1;
		return;
	}
	extra = substr(line, RSTART + RLENGTH);
	if (extra ~ /[	 ]*DEFAULT[ 	]*[a-zA-Z_][a-zA-Z_0-9]*[ 	]*;/) {
		default = extra;
		sub(/.*DEFAULT[	 ]*/, "", default);
		sub(/[; 	]+.*$/, "", default);
	}
	else if (extra && opt_d) {
		#   Warn about garbage at end of line.
		warnsrc("Ignored '" extra "'");
	}
	sub(/\};?.*$/, "", line);

	#
	#   Create a list of variables without the types prepended.
	#
	sub(/^[	 ]+/, "", line);	# remove leading ...
	sub(/[ 	]+$/, "", line);	# ... and trailing whitespace
	gsub(/[	 ]+/, " ", line);	# remove double spaces

	num_arguments = split(line, arguments, / *; */) - 1;
	delete varnames;		# list of varnames
	num_varnames = 0;
	for (i = 1; i <= num_arguments; i++) {
		if (!arguments[i])
			continue;	# skip argument if argument is empty
		num_ar = split(arguments[i], ar, /[* 	]+/);
		if (num_ar < 2) {	# only 1 word in argument?
			warnsrc("no type for '" arguments[i] "'");
			error = 1;
			return;
		}
		#   Last element is name of variable.
		varnames[++num_varnames] = ar[num_ar];
	}

	argument_list = join(", ", arguments, num_arguments);
	varname_list = join(", ", varnames, num_varnames);

	if (opt_d) {
		warn("Arguments: " argument_list);
		warn("Varnames: " varname_list);
	}

	mname = intname "_" name;	# method name
	umname = toupper(mname);	# uppercase method name

	firstvar = varnames[1];

	if (default == "")
		default = "kobj_error_method";

	# the method description
	printh("/** @brief Unique descriptor for the " umname "() method */");
	printh("extern struct kobjop_desc " mname "_desc;");
	# the method typedef
	printh("/** @brief A function implementing the " umname "() method */");
	prototype = "typedef " ret " " mname "_t(";
	printh(format_line(prototype argument_list ");",
	    line_width, length(prototype)));

	# Print out the method desc
	printc("struct kobj_method " mname "_method_default = {");
	printc("\t&" mname "_desc, (kobjop_t) " default);
	printc("};\n");

	printc("struct kobjop_desc " mname "_desc = {");
	printc("\t0, &" mname "_method_default");
	printc("};\n");

	# Print out the method itself
	printh(doc);
	if (0) {		# haven't chosen the format yet
		printh("static __inline " ret " " umname "(" varname_list ")");
		printh("\t" join(";\n\t", arguments, num_arguments) ";");
	}
	else {
		prototype = "static __inline " ret " " umname "(";
		printh(format_line(prototype argument_list ")",
		    line_width, length(prototype)));
	}
	printh("{");
	printh("\tkobjop_t _m;");
	if (!static)
		firstvar = "((kobj_t)" firstvar ")";
	printh("\tKOBJOPLOOKUP(" firstvar "->ops," mname ");");
	retrn =  (ret != "void") ? "return " : "";
	printh("\t" retrn "((" mname "_t *) _m)(" varname_list ");");
	printh("}\n");
}

#
#   Begin of the main program.
#

BEGIN {

line_width = 80;
gerror = 0;

#
#   Process the command line.
#

num_files = 0;

for (i = 1; i < ARGC; i++) {
	if (ARGV[i] ~ /^-/) {
		#
		#   awk doesn't have getopt(), so we have to do it ourselves.
		#   This is a bit clumsy, but it works.
		#
		for (j = 2; j <= length(ARGV[i]); j++) {
			o = substr(ARGV[i], j, 1);
			if	(o == "c")	opt_c = 1;
			else if	(o == "h")	opt_h = 1;
			else if	(o == "p")	opt_p = 1;
			else if	(o == "d")	opt_d = 1;
			else if	(o == "l") {
				if (length(ARGV[i]) > j) {
					opt_l = substr(ARGV[i], j + 1);
					break;
				}
				else {
					if (++i < ARGC)
						opt_l = ARGV[i];
					else
						usage();
				}
			}
			else
				usage();
		}
	}
	else if (ARGV[i] ~ /\.m$/)
		filenames[num_files++] = ARGV[i];
	else
		usage();
}

if (!num_files || !(opt_c || opt_h))
	usage();

if (opt_p)
	debug("Will produce files in original not in current directory");

if (opt_l) {
	if (opt_l !~ /^[0-9]+$/ || opt_l < 1)
		die("Invalid line width '" opt_l "'");
	line_width = opt_l;
	debug("Line width set to " line_width);
}

for (i = 0; i < num_files; i++)
	debug("Filename: " filenames[i]);

for (file_i = 0; file_i < num_files; file_i++) {
	src = filenames[file_i];
	cfilename = hfilename = src;
	sub(/\.m$/, ".c", cfilename);
	sub(/\.m$/, ".h", hfilename);
	if (!opt_p) {
		sub(/^.*\//, "", cfilename);
		sub(/^.*\//, "", hfilename);
	}

	debug("Processing from " src " to " cfilename " / " hfilename);

	ctmpfilename = cfilename ".tmp";
	htmpfilename = hfilename ".tmp";

	common_head = \
	    "/*\n" \
	    " * This file is produced automatically.\n" \
	    " * Do not modify anything in here by hand.\n" \
	    " *\n" \
	    " * Created from source file\n" \
	    " *   " src "\n" \
	    " * with\n" \
	    " *   makeobjops.awk\n" \
	    " *\n" \
	    " * See the source file for legal information\n" \
	    " */\n";

	printc(common_head "\n" \
	    "#include <sys/param.h>\n" \
	    "#include <sys/queue.h>\n" \
	    "#include <sys/kernel.h>\n" \
	    "#include <sys/kobj.h>");

	printh(common_head);

	delete methods;		# clear list of methods
	intname = "";
	lineno = 0;
	error = 0;		# to signal clean up and gerror setting
	lastdoc = "";

	while (!error && (getline < src) > 0) {
		lineno++;

		#
		#   Take special notice of include directives.
		#
		if (/^#[ 	]*include[ 	]+["<][^">]+[">]/) {
			incld = $0;
			sub(/^#[ 	]*include[ 	]+/, "", incld);
			debug("Included file: " incld);
			printc("#include " incld);
		}

		sub(/#.*/, "");		# remove comments
		sub(/^[	 ]+/, "");	# remove leading ...
		sub(/[ 	]+$/, "");	# ... and trailing whitespace

		if (/^$/) {		# skip empty lines
		}
		else if (/^\/\*\*/)
			lastdoc = handle_doc();
		else if (/^INTERFACE[ 	]+[^ 	;]*[ 	]*;?[ 	]*$/) {
			printh(lastdoc);
			lastdoc = "";
			handle_interface();
		} else if (/^CODE[ 	]*{$/)
			printc(handle_code());
		else if (/^HEADER[	 ]*{$/)
			printh(handle_code());
		else if (/^METHOD/) {
			handle_method(0, lastdoc);
			lastdoc = "";
		} else if (/^STATICMETHOD/) {
			handle_method(1, lastdoc);
			lastdoc = "";
		} else {
			debug($0);
			warnsrc("Invalid line encountered");
			error = 1;
		}
	}

	#
	#   Print the final '#endif' in the header file.
	#
	printh("#endif /* _" intname "_if_h_ */");

	close (ctmpfilename);
	close (htmpfilename);

	if (error) {
		warn("Output skipped");
		system_check("rm -f " ctmpfilename " " htmpfilename);
		gerror = 1;
	}
	else {
		if (opt_c)
			system_check("mv -f " ctmpfilename " " cfilename);
		if (opt_h)
			system_check("mv -f " htmpfilename " " hfilename);
	}
}

exit gerror;

}


rnc2rng: Allow combine on start

rnc2rng: Allow combine on start

#!/bin/awk
# -*- indent-tabs-mode: nil; c-basic-offset: 2 -*-
# rnc2rng.awk - Convert RELAX NG Compact Syntax to XML Syntax
# Copyright (C) 2007 Shaun McCance <shaunm@gnome.org>
#
# 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 of the License, 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.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

# This program is free software, but that doesn't mean you should use it.
# I wanted to write and maintain the Mallard schema in RNC in code blocks
# within the specification, but I needed to distribute the schema in RNG.
# Since xmllint (libxml2) does not currently support RNC, and since I'm
# not willing to introduce more dependencies, awk was my only option.
#
# This awk script is *NOT* a complete implementation, and probably never
# will be.  Its sole purpose is to handle the Mallard schema, and it is
# sufficient for that task.
#
# You are, of course, free to use any of this.  If you do proliferate this
# hack, it is requested (though not required, that would be non-free) that
# you atone for your actions.  A good atonement would be contributing to
# free software.

function parse_pattern (line) {
  sub(/^ */, "", line)
  if (length(line) == 0) return;
  c = substr(line, 1, 1);
  if (c == "(" || c == "{") {
    stack[++stack_i] = substr(line, 1, 1);
    paren[++paren_i] = stack_i;
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == ")" || c == "}") {
    open = stack[paren[paren_i]];
    oc = substr(open, 1, 1) c;
    if (oc != "()" && oc != "{}") {
      print "Mismatched parentheses on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }

    tag = "";
    if (length(open) > 1 && substr(open, 2, 1) == "&") {
      tag = "interleave";
    }
    else if (length(open) > 1 && substr(open, 2, 1) == "|") {
      tag = "choice";
    }
    else if (oc == "()") {
      tag = "group";
    }

    tmp = "";
    if (tag != "") {
      tmp = "<" tag ">";
    }
    for (i = paren[paren_i] + 1; i <= stack_i; i++) {
      tmp = tmp stack[i] "\n";
    }
    if (tag != "") {
      tmp = tmp "</" tag ">";
    }
    stack_i = paren[paren_i];
    stack[stack_i] = tmp;
    paren_i--;

    if (oc == "{}") {
      if (match(stack[stack_i - 1], "^<element")) {
        tmp = stack[stack_i - 1] "\n";
        if (stack[stack_i] != "") {
          tmp = tmp stack[stack_i] "\n";
        } else {
          tmp = tmp "<empty/>\n";
        }
        tmp = tmp "</element>";
        stack[--stack_i] = tmp;
      }
      else if (match(stack[stack_i - 1], "^<attribute")) {
        tmp = stack[stack_i - 1] "\n";
        if (stack[stack_i] != "") {
          tmp = tmp stack[stack_i] "\n";
        } else {
          tmp = tmp "<empty/>\n";
        }
        tmp = tmp "</attribute>";
        stack[--stack_i] = tmp;
      }
      else if (stack[stack_i - 1] == "<list>") {
        tmp = stack[stack_i - 1] "\n";
        tmp = tmp stack[stack_i] "\n";
        tmp = tmp "</list>";
        stack[--stack_i] = tmp;
      }
      else if (stack[stack_i - 1] == "<mixed>") {
        tmp = stack[stack_i - 1] "\n";
        tmp = tmp stack[stack_i] "\n";
        tmp = tmp "</mixed>";
        stack[--stack_i] = tmp;
      }
    }
    if (paren_i == 0) {
      mode = "grammar";
    }
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "|" || c == "&" || c == ",") {
    if (length(stack[paren[paren_i]]) == 1) {
      stack[paren[paren_i]] = stack[paren[paren_i]] c;
    }
    else if (length(stack[paren[paren_i]]) < 2 || substr(stack[paren[paren_i]], 2) != c) {
      print "Mismatched infix operators on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "?") {
    stack[stack_i] = "<optional>" stack[stack_i] "</optional>"
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "*") {
    stack[stack_i] = "<zeroOrMore>" stack[stack_i] "</zeroOrMore>"
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "+") {
    stack[stack_i] = "<oneOrMore>" stack[stack_i] "</oneOrMore>"
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "\"") {
    txt = substr(line, 2);
    sub(/".*/, "", txt)
    stack[++stack_i] = "<value>" txt "</value>";
    if (length(line) >= length(txt) + 3)
      parse_pattern(substr(line, length(txt) + 3));
  }
  else if (match(line, "^element ")) {
    aft = substr(line, 8);
    sub(/^ */, "", aft);
    name = aft;
    stack[++stack_i] = "<element";
    mode = "name_class";
    name_class_i = stack_i;
    parse_name_class(name);
  }
  else if (match(line, "^attribute ")) {
    aft = substr(line, 10);
    sub(/^ */, "", aft);
    name = aft;
    stack[++stack_i] = "<attribute";
    mode = "name_class";
    name_class_i = stack_i;
    parse_name_class(name);
  }
  else if (match(line, "^list ")) {
    aft = substr(line, 5);
    sub(/^ */, "", aft);
    stack[++stack_i] = "<list>";
    if (aft != "") { parse_pattern(aft); }
  }
  else if (match(line, "^mixed ")) {
    aft = substr(line, 6);
    sub(/^ */, "", aft);
    stack[++stack_i] = "<mixed>";
    if (aft != "") { parse_pattern(aft); }
  }
  else if (match(line, /^text[^A-Za-z]/) || match(line, /^text$/)) {
    stack[++stack_i] = "<text/>";
    aft = substr(line, 5);
    sub(/^ */, "", aft);
    if (aft != "") { parse_pattern(aft); }
  }
  else if (match(line, "^default namespace ")) {
    print "default namespace appeared out of context on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  else if (match(line, "^namespace ")) {
    print "namespace appeared out of context on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  else if (match(line, "^start ")) {
    print "start appeared out of context on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  else if (match(line, "^include ")) {
    print "include appeared out of context on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  else if (match(line, /^xsd:[A-Za-z_]/)) {
    name = substr(line, 1);
    sub(/^xsd:/, "", name);
    sub(/[^A-Za-z_]+.*/, "", name);
    stack[++stack_i] = sprintf("<data type='%s' datatypeLibrary='http://www.w3.org/2001/XMLSchema-datatypes'/>",
                               name);
    if (length(line) >= length(name) + 5) {
      aft = substr(line, length(name) + 5);
      parse_pattern(aft);
    }
  }
  else if (match(line, /^[A-Za-z_]/)) {
    name = substr(line, 1);
    sub(/[^A-Za-z_]+.*/, "", name);
    if (name == "empty") {
      stack[++stack_i] = "<empty/>";
    }
    else if (name == "notAllowed") {
      stack[++stack_i] = "<notAllowed/>";
    }
    else {
      stack[++stack_i] = sprintf("<ref name='%s'/>", name);
    }
    if (length(line) >= length(name) + 1) {
      aft = substr(line, length(name) + 1);
      parse_pattern(aft);
    }
  }
}

function parse_name_class (line) {
  sub(/^ */, "", line)
  if (length(line) == 0) return;
  c = substr(line, 1, 1);
  if (c == "{") {
    if (stack_i != name_class_i) {
      tmp = "";
      for (i = stack_i; i >= name_class_i; i--) {
        if (stack[i] == "<except>") {
          tmp = "<except>" tmp "</except>";
        }
        else if (stack[i] == "<anyName>") {
          tmp = "<anyName>" tmp "</anyName>";
        }
        else {
          tmp = stack[i] tmp
        }
      }
      stack[name_class_i] = tmp;
      stack_i = name_class_i;
    }
    mode = "pattern";
    parse_pattern(line);
  }
  else if (c == "*") {
    if (stack[stack_i] == "<element" || stack[stack_i] == "<attribute") {
      stack[stack_i] = stack[stack_i] ">";
    }
    stack[++stack_i] = "<anyName>";
    parse_name_class(substr(line, 2));
  }
  else if (c == "-") {
    stack[++stack_i] = "<except>"
    parse_name_class(substr(line, 2));
  }
  else if (c == "|") {
    if (length(stack[paren[paren_i]]) == 1) {
      stack[paren[paren_i]] = stack[paren[paren_i]] c;
    }
    else if (substr(stack[paren[paren_i]], 2) != "|") {
      print "Mismatched infix operators on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }
    parse_name_class(substr(line, 2));
  }
  else if (c == "(") {
    stack[++stack_i] = "(";
    paren[++paren_i] = stack_i;
    parse_name_class(substr(line, 2));
  }
  else if (c == ")") {
    open = stack[paren[paren_i]];
    if (substr(open, 1, 1) != "(") {
      print "Mismatched parentheses on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }
    if (length(open) == 1 || substr(open, 2, 1) != "|") {
      print "Unknown name class pattern on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }
    tmp = ""
    for (i = paren[paren_i] + 1; i <= stack_i; i++) {
      tmp = tmp stack[i] "\n";
    }
    stack_i = paren[paren_i];
    stack[stack_i] = tmp;
    paren_i--;
    parse_name_class(substr(line, 2));
  }
  else if (match(line, /^[A-Za-z_]/)) {
    name = substr(line, 1);
    sub(/[^A-Za-z_]+.*/, "", name);
    if (length(line) >= length(name) + 1)
      aft = substr(line, length(name) + 1);
    else
      aft = "";
    if (length(aft) >= 2 && substr(aft, 1, 2) == ":*") {
      for (i = 1; i <= namespaces_i; i++) {
        if (nsnames[i] == name) {
          stack[++stack_i] = sprintf("<nsName ns='%s'/>", namespaces[i])
          break;
        }
      }
      if (length(aft) >= 3)
        aft = substr(aft, 3);
      else
        aft = "";
    }
    else {
      if (length(aft) >= 2 && substr(aft, 1, 1) == ":") {
        checkns = "";
        pos = 1;
        while (pos <= namespaces_i) {
          if (namespaces[pos] != "" && nsnames[pos] == name) {
            checkns = namespaces[pos];
            break;
          }
          pos++;
        }
        if (checkns == "") {
          print "Unknown namespace prefix " name " on line " FNR | "cat 1>&2";
          error = 1;
          exit 1
        }
        localname = substr(aft, 2);
        sub(/[^A-Za-z_]+.*/, "", localname);
        if (length(aft) >= length(localname) + 2)
          aft = substr(aft, length(localname) + 2);
        else
          aft = "";
        name = name ":" localname;
      }
      if (stack[stack_i] == "<element" || stack[stack_i] == "<attribute") {
        stack[stack_i] = stack[stack_i] sprintf(" name='%s'>", name);
      }
      else {
        stack[++stack_i] = sprintf("<name>%s</name>", name);
      }
    }
    parse_name_class(aft);
  }
}

function printstack () {
  pos = 1;
  while (pos <= stack_i) {
    printstackone();
  }
}
function printstackone () {
  if (substr(stack[pos], 1, 1) == "#") {
    print "<!--";
    while (substr(stack[pos], 1, 1) == "#") {
      cmt = substr(stack[pos], 2);
      sub(/^ */, "", cmt);
      print cmt;
      pos++;
    }
    print "-->";
  }
  if (substr(stack[pos], 1, 6) == "<start") {
    print stack[pos];
    pos++;
    printstackone();
    print "</start>"
  }
  else if (substr(stack[pos], 1, 7) == "<define") {
    print stack[pos];
    pos++;
    printstackone();
    print "</define>"
  }
  else {
    print stack[pos];
    pos++;
  }
}

BEGIN {
  mode = "grammar";
  stack_i = 0;
  paren_i = 0;
  namespaces_i = 0;
  include_i = 0;
  error = 0;
}

END {
  if (!error) {
    print "<grammar xmlns='http://relaxng.org/ns/structure/1.0'";
    pos = 1;
    while (pos <= namespaces_i) {
      if (namespaces[pos] != "") {
        printf " xmlns:%s='%s'", nsnames[pos], namespaces[pos];
      }
      pos++;
    }
    printf " ns='%s'>\n", default_namespace;
    printstack()
    print "</grammar>"
  }
}

mode == "pattern" && paren_i == 0 && /.*=/ { mode = "grammar"; }
mode == "grammar" && /.*=/ {
  if (match($0, "^default namespace ")) {
    namespace = substr($0, index($0, "=") + 1);
    nsname = substr($0, 19, index($0, "=") - 19);
    sub(/^ */, "", nsname);
    sub(/ *$/, "", nsname);
    sub(/^ *"/, "", namespace);
    sub(/" *$/, "", namespace);
    if (nsname != "") {
      nsnames[++namespaces_i] = nsname;
      namespaces[namespaces_i] = namespace;
    }
    default_namespace = namespace
  }
  else if (match($0, "^namespace ")) {
    namespace = substr($0, index($0, "=") + 1);
    nsname = substr($0, 11, index($0, "=") - 11);
    sub(/^ */, "", nsname);
    sub(/ *$/, "", nsname);
    sub(/^ *"/, "", namespace);
    sub(/" *$/, "", namespace);
    if (nsname != "") {
      nsnames[++namespaces_i] = nsname;
      namespaces[namespaces_i] = namespace;
    }
  }
  else {
    nameix = index($0, "=");
    combine = "";
    if (nameix < 1) next;
    if (substr($0, nameix - 1, 1) == "|") {
      combine = "choice";
      name = substr($0, 1, nameix - 2);
    }
    else if (substr($0, nameix - 1, 1) == "&") {
      combine = "interleave";
      name = substr($0, 1, nameix - 2);
    }
    else {
      name = substr($0, 1, nameix - 1);
    }
    sub(/^ */, "", name);
    sub(/ *$/, "", name);
    if (name == "start")
      define = "<start"
    else
      define = sprintf("<define name='%s'", name);
    if (combine != "")
      define = define " combine='" combine "'"
    define = define ">"
    stack[++stack_i] = define;
    mode = "pattern";
    if (length($0) >= nameix + 1)
      parse_pattern(substr($0, nameix + 1))
  }
  next;
}
mode == "grammar" && /^include / {
  href = substr($0, index($0, "\"") + 1);
  brace = substr(href, index(href, "\"") + 1);
  href = substr(href, 1, index(href, "\"") - 1);
  sub(/^ */, "", brace);
  sub(/ *$/, "", brace);
  if (brace == "{") {
    stack[++stack_i] = "<include href=\"" href "\">";
    include_i = stack_i;
  }
  else {
    stack[++stack_i] = "<include href=\"" href "\"/>";
  }
}
include_i != 0 && paren_i == 0 && /}/ {
  if (substr(stack[include_i], 1, 8) == "<include") {
    stack[++stack_i] = "</include>";
  }
  else {
    print "Mismatched parentheses on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  mode = "grammar";
  include_i = 0;
  next;
}
mode == "pattern" {
  parse_pattern($0);
  next;
}
mode == "name_class" {
  parse_name_class($0);
  next;
}
# Doesn't handle all comments. That would require modifying
# parse_pattern and parse_name_class and generally being a lot
# more clever about output. But it handles comments that start
# a line outside a pattern. Enough for me.
/#.*/ {
  stack[++stack_i] = $0
}

#!/bin/awk
# -*- indent-tabs-mode: nil; c-basic-offset: 2 -*-
# rnc2rng.awk - Convert RELAX NG Compact Syntax to XML Syntax
# Copyright (C) 2007 Shaun McCance <shaunm@gnome.org>
#
# 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 of the License, 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.,
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

# This program is free software, but that doesn't mean you should use it.
# I wanted to write and maintain the Mallard schema in RNC in code blocks
# within the specification, but I needed to distribute the schema in RNG.
# Since xmllint (libxml2) does not currently support RNC, and since I'm
# not willing to introduce more dependencies, awk was my only option.
#
# This awk script is *NOT* a complete implementation, and probably never
# will be.  Its sole purpose is to handle the Mallard schema, and it is
# sufficient for that task.
#
# You are, of course, free to use any of this.  If you do proliferate this
# hack, it is requested (though not required, that would be non-free) that
# you atone for your actions.  A good atonement would be contributing to
# free software.

function parse_pattern (line) {
  sub(/^ */, "", line)
  if (length(line) == 0) return;
  c = substr(line, 1, 1);
  if (c == "(" || c == "{") {
    stack[++stack_i] = substr(line, 1, 1);
    paren[++paren_i] = stack_i;
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == ")" || c == "}") {
    open = stack[paren[paren_i]];
    oc = substr(open, 1, 1) c;
    if (oc != "()" && oc != "{}") {
      print "Mismatched parentheses on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }

    tag = "";
    if (length(open) > 1 && substr(open, 2, 1) == "&") {
      tag = "interleave";
    }
    else if (length(open) > 1 && substr(open, 2, 1) == "|") {
      tag = "choice";
    }
    else if (oc == "()") {
      tag = "group";
    }

    tmp = "";
    if (tag != "") {
      tmp = "<" tag ">";
    }
    for (i = paren[paren_i] + 1; i <= stack_i; i++) {
      tmp = tmp stack[i] "\n";
    }
    if (tag != "") {
      tmp = tmp "</" tag ">";
    }
    stack_i = paren[paren_i];
    stack[stack_i] = tmp;
    paren_i--;

    if (oc == "{}") {
      if (match(stack[stack_i - 1], "^<element")) {
        tmp = stack[stack_i - 1] "\n";
        if (stack[stack_i] != "") {
          tmp = tmp stack[stack_i] "\n";
        } else {
          tmp = tmp "<empty/>\n";
        }
        tmp = tmp "</element>";
        stack[--stack_i] = tmp;
      }
      else if (match(stack[stack_i - 1], "^<attribute")) {
        tmp = stack[stack_i - 1] "\n";
        if (stack[stack_i] != "") {
          tmp = tmp stack[stack_i] "\n";
        } else {
          tmp = tmp "<empty/>\n";
        }
        tmp = tmp "</attribute>";
        stack[--stack_i] = tmp;
      }
      else if (stack[stack_i - 1] == "<list>") {
        tmp = stack[stack_i - 1] "\n";
        tmp = tmp stack[stack_i] "\n";
        tmp = tmp "</list>";
        stack[--stack_i] = tmp;
      }
      else if (stack[stack_i - 1] == "<mixed>") {
        tmp = stack[stack_i - 1] "\n";
        tmp = tmp stack[stack_i] "\n";
        tmp = tmp "</mixed>";
        stack[--stack_i] = tmp;
      }
    }
    if (paren_i == 0) {
      mode = "grammar";
    }
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "|" || c == "&" || c == ",") {
    if (length(stack[paren[paren_i]]) == 1) {
      stack[paren[paren_i]] = stack[paren[paren_i]] c;
    }
    else if (length(stack[paren[paren_i]]) < 2 || substr(stack[paren[paren_i]], 2) != c) {
      print "Mismatched infix operators on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "?") {
    stack[stack_i] = "<optional>" stack[stack_i] "</optional>"
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "*") {
    stack[stack_i] = "<zeroOrMore>" stack[stack_i] "</zeroOrMore>"
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "+") {
    stack[stack_i] = "<oneOrMore>" stack[stack_i] "</oneOrMore>"
    if (length(line) >= 2)
      parse_pattern(substr(line, 2));
  }
  else if (c == "\"") {
    txt = substr(line, 2);
    sub(/".*/, "", txt)
    stack[++stack_i] = "<value>" txt "</value>";
    if (length(line) >= length(txt) + 3)
      parse_pattern(substr(line, length(txt) + 3));
  }
  else if (match(line, "^element ")) {
    aft = substr(line, 8);
    sub(/^ */, "", aft);
    name = aft;
    stack[++stack_i] = "<element";
    mode = "name_class";
    name_class_i = stack_i;
    parse_name_class(name);
  }
  else if (match(line, "^attribute ")) {
    aft = substr(line, 10);
    sub(/^ */, "", aft);
    name = aft;
    stack[++stack_i] = "<attribute";
    mode = "name_class";
    name_class_i = stack_i;
    parse_name_class(name);
  }
  else if (match(line, "^list ")) {
    aft = substr(line, 5);
    sub(/^ */, "", aft);
    stack[++stack_i] = "<list>";
    if (aft != "") { parse_pattern(aft); }
  }
  else if (match(line, "^mixed ")) {
    aft = substr(line, 6);
    sub(/^ */, "", aft);
    stack[++stack_i] = "<mixed>";
    if (aft != "") { parse_pattern(aft); }
  }
  else if (match(line, /^text[^A-Za-z]/) || match(line, /^text$/)) {
    stack[++stack_i] = "<text/>";
    aft = substr(line, 5);
    sub(/^ */, "", aft);
    if (aft != "") { parse_pattern(aft); }
  }
  else if (match(line, "^default namespace ")) {
    print "default namespace appeared out of context on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  else if (match(line, "^namespace ")) {
    print "namespace appeared out of context on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  else if (match(line, "^start ")) {
    print "start appeared out of context on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  else if (match(line, "^include ")) {
    print "include appeared out of context on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  else if (match(line, /^xsd:[A-Za-z_]/)) {
    name = substr(line, 1);
    sub(/^xsd:/, "", name);
    sub(/[^A-Za-z_]+.*/, "", name);
    stack[++stack_i] = sprintf("<data type='%s' datatypeLibrary='http://www.w3.org/2001/XMLSchema-datatypes'/>",
                               name);
    if (length(line) >= length(name) + 5) {
      aft = substr(line, length(name) + 5);
      parse_pattern(aft);
    }
  }
  else if (match(line, /^[A-Za-z_]/)) {
    name = substr(line, 1);
    sub(/[^A-Za-z_]+.*/, "", name);
    if (name == "empty") {
      stack[++stack_i] = "<empty/>";
    }
    else if (name == "notAllowed") {
      stack[++stack_i] = "<notAllowed/>";
    }
    else {
      stack[++stack_i] = sprintf("<ref name='%s'/>", name);
    }
    if (length(line) >= length(name) + 1) {
      aft = substr(line, length(name) + 1);
      parse_pattern(aft);
    }
  }
}

function parse_name_class (line) {
  sub(/^ */, "", line)
  if (length(line) == 0) return;
  c = substr(line, 1, 1);
  if (c == "{") {
    if (stack_i != name_class_i) {
      tmp = "";
      for (i = stack_i; i >= name_class_i; i--) {
        if (stack[i] == "<except>") {
          tmp = "<except>" tmp "</except>";
        }
        else if (stack[i] == "<anyName>") {
          tmp = "<anyName>" tmp "</anyName>";
        }
        else {
          tmp = stack[i] tmp
        }
      }
      stack[name_class_i] = tmp;
      stack_i = name_class_i;
    }
    mode = "pattern";
    parse_pattern(line);
  }
  else if (c == "*") {
    if (stack[stack_i] == "<element" || stack[stack_i] == "<attribute") {
      stack[stack_i] = stack[stack_i] ">";
    }
    stack[++stack_i] = "<anyName>";
    parse_name_class(substr(line, 2));
  }
  else if (c == "-") {
    stack[++stack_i] = "<except>"
    parse_name_class(substr(line, 2));
  }
  else if (c == "|") {
    if (length(stack[paren[paren_i]]) == 1) {
      stack[paren[paren_i]] = stack[paren[paren_i]] c;
    }
    else if (substr(stack[paren[paren_i]], 2) != "|") {
      print "Mismatched infix operators on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }
    parse_name_class(substr(line, 2));
  }
  else if (c == "(") {
    stack[++stack_i] = "(";
    paren[++paren_i] = stack_i;
    parse_name_class(substr(line, 2));
  }
  else if (c == ")") {
    open = stack[paren[paren_i]];
    if (substr(open, 1, 1) != "(") {
      print "Mismatched parentheses on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }
    if (length(open) == 1 || substr(open, 2, 1) != "|") {
      print "Unknown name class pattern on line " FNR | "cat 1>&2";
      error = 1;
      exit 1
    }
    tmp = ""
    for (i = paren[paren_i] + 1; i <= stack_i; i++) {
      tmp = tmp stack[i] "\n";
    }
    stack_i = paren[paren_i];
    stack[stack_i] = tmp;
    paren_i--;
    parse_name_class(substr(line, 2));
  }
  else if (match(line, /^[A-Za-z_]/)) {
    name = substr(line, 1);
    sub(/[^A-Za-z_]+.*/, "", name);
    if (length(line) >= length(name) + 1)
      aft = substr(line, length(name) + 1);
    else
      aft = "";
    if (length(aft) >= 2 && substr(aft, 1, 2) == ":*") {
      for (i = 1; i <= namespaces_i; i++) {
        if (nsnames[i] == name) {
          stack[++stack_i] = sprintf("<nsName ns='%s'/>", namespaces[i])
          break;
        }
      }
      if (length(aft) >= 3)
        aft = substr(aft, 3);
      else
        aft = "";
    }
    else {
      if (length(aft) >= 2 && substr(aft, 1, 1) == ":") {
        checkns = "";
        pos = 1;
        while (pos <= namespaces_i) {
          if (namespaces[pos] != "" && nsnames[pos] == name) {
            checkns = namespaces[pos];
            break;
          }
          pos++;
        }
        if (checkns == "") {
          print "Unknown namespace prefix " name " on line " FNR | "cat 1>&2";
          error = 1;
          exit 1
        }
        localname = substr(aft, 2);
        sub(/[^A-Za-z_]+.*/, "", localname);
        if (length(aft) >= length(localname) + 2)
          aft = substr(aft, length(localname) + 2);
        else
          aft = "";
        name = name ":" localname;
      }
      if (stack[stack_i] == "<element" || stack[stack_i] == "<attribute") {
        stack[stack_i] = stack[stack_i] sprintf(" name='%s'>", name);
      }
      else {
        stack[++stack_i] = sprintf("<name>%s</name>", name);
      }
    }
    parse_name_class(aft);
  }
}

function printstack () {
  pos = 1;
  while (pos <= stack_i) {
    printstackone();
  }
}
function printstackone () {
  if (substr(stack[pos], 1, 1) == "#") {
    print "<!--";
    while (substr(stack[pos], 1, 1) == "#") {
      cmt = substr(stack[pos], 2);
      sub(/^ */, "", cmt);
      print cmt;
      pos++;
    }
    print "-->";
  }
  if (substr(stack[pos], 1, 6) == "<start") {
    print stack[pos];
    pos++;
    printstackone();
    print "</start>"
  }
  else if (substr(stack[pos], 1, 7) == "<define") {
    print stack[pos];
    pos++;
    printstackone();
    print "</define>"
  }
  else {
    print stack[pos];
    pos++;
  }
}

BEGIN {
  mode = "grammar";
  stack_i = 0;
  paren_i = 0;
  namespaces_i = 0;
  include_i = 0;
  error = 0;
}

END {
  if (!error) {
    print "<grammar xmlns='http://relaxng.org/ns/structure/1.0'";
    pos = 1;
    while (pos <= namespaces_i) {
      if (namespaces[pos] != "") {
        printf " xmlns:%s='%s'", nsnames[pos], namespaces[pos];
      }
      pos++;
    }
    printf " ns='%s'>\n", default_namespace;
    printstack()
    print "</grammar>"
  }
}

mode == "pattern" && paren_i == 0 && /.*=/ { mode = "grammar"; }
mode == "grammar" && /.*=/ {
  if (match($0, "^default namespace ")) {
    namespace = substr($0, index($0, "=") + 1);
    nsname = substr($0, 19, index($0, "=") - 19);
    sub(/^ */, "", nsname);
    sub(/ *$/, "", nsname);
    sub(/^ *"/, "", namespace);
    sub(/" *$/, "", namespace);
    if (nsname != "") {
      nsnames[++namespaces_i] = nsname;
      namespaces[namespaces_i] = namespace;
    }
    default_namespace = namespace
  }
  else if (match($0, "^namespace ")) {
    namespace = substr($0, index($0, "=") + 1);
    nsname = substr($0, 11, index($0, "=") - 11);
    sub(/^ */, "", nsname);
    sub(/ *$/, "", nsname);
    sub(/^ *"/, "", namespace);
    sub(/" *$/, "", namespace);
    if (nsname != "") {
      nsnames[++namespaces_i] = nsname;
      namespaces[namespaces_i] = namespace;
    }
  }
  else {
    nameix = index($0, "=");
    combine = "";
    if (nameix < 1) next;
    if (substr($0, nameix - 1, 1) == "|") {
      combine = "choice";
      name = substr($0, 1, nameix - 2);
    }
    else if (substr($0, nameix - 1, 1) == "&") {
      combine = "interleave";
      name = substr($0, 1, nameix - 2);
    }
    else {
      name = substr($0, 1, nameix - 1);
    }
    sub(/^ */, "", name);
    sub(/ *$/, "", name);
    if (name == "start")
      stack[++stack_i] = "<start>"
    else {
      define = sprintf("<define name='%s'", name);
      if (combine != "")
        define = define " combine='" combine "'"
      define = define ">"
      stack[++stack_i] = define;
    }
    mode = "pattern";
    if (length($0) >= nameix + 1)
      parse_pattern(substr($0, nameix + 1))
  }
  next;
}
mode == "grammar" && /^include / {
  href = substr($0, index($0, "\"") + 1);
  brace = substr(href, index(href, "\"") + 1);
  href = substr(href, 1, index(href, "\"") - 1);
  sub(/^ */, "", brace);
  sub(/ *$/, "", brace);
  if (brace == "{") {
    stack[++stack_i] = "<include href=\"" href "\">";
    include_i = stack_i;
  }
  else {
    stack[++stack_i] = "<include href=\"" href "\"/>";
  }
}
include_i != 0 && paren_i == 0 && /}/ {
  if (substr(stack[include_i], 1, 8) == "<include") {
    stack[++stack_i] = "</include>";
  }
  else {
    print "Mismatched parentheses on line " FNR | "cat 1>&2";
    error = 1;
    exit 1
  }
  mode = "grammar";
  include_i = 0;
  next;
}
mode == "pattern" {
  parse_pattern($0);
  next;
}
mode == "name_class" {
  parse_name_class($0);
  next;
}
# Doesn't handle all comments. That would require modifying
# parse_pattern and parse_name_class and generally being a lot
# more clever about output. But it handles comments that start
# a line outside a pattern. Enough for me.
/#.*/ {
  stack[++stack_i] = $0
}


(#4109) change .awk script so that VMWARE_LOCAL_SETTINGS_FILE config is commented out by default. ===VersionHistory:Pending===

##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
##
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
##
##    http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************

##
## convert_config_to_win32.awk
##
## Todd Tannenbaum <tannenba@cs.wisc.edu>, 10/06
## John Knoeller <johnkn@cs.wisc.edu>, 12/10
##

# This is an awk script to modify condor_config.generic into a form that
# works with Windows.
# Pipe condor_config.generic through this awk script and save it as
# condor_config.win, which is what the Installer expects to modify after unbundling.

BEGIN {
	FS = "="
}

# Make it so we can fill in the VM_GAHP_SERVER option if we choose to in the
# installer. This is done before the .exe append bellow, because that match
# seems to block any other matches for that line.
/^#VM_GAHP_SERVER/ {
	print "#VM_GAHP_SERVER = $(BIN)\\condor_vm-gahp.exe"
	print "VM_GAHP_SERVER = "
	next
}
# We DONT want to add a .exe extension to the vmware script, it's a perl script.
/VMWARE_SCRIPT[ \t]*=/ {
	gsub(/\//, "\\", $0)
	printf "%s\n",$0
	next
}

# Remove SHADOW_STANDARD (the standard universe shadow)
#
/^SHADOW_STANDARD/ {
	next
}
/^SHADOW_LIST/ {
    printf "SHADOW_LIST = SHADOW\n"
    next
}

# Remove STARTER_STANDARD (the standard universe starter)
#
/^STARTER_STANDARD/ {
    next
}
/^STARTER_LIST/ {
    printf "STARTER_LIST = STARTER\n"
    next
}

/^FILETRANSFER_PLUGINS[ \t]*=/ {
	gsub(/\//, "\\", $0)
	gsub(/_plugin,/, "_plugin.exe,", $0)
	gsub(/_plugin$/, "_plugin.exe", $0)
	printf "%s\n",$0
	next
}

# Email Settings
# Use condor_mail.exe for MAIL, and put in a stub for SMTP_SERVER
/^MAIL/ {
	printf "MAIL = $(BIN)\\condor_mail.exe\n\n"
	printf "## For Condor on Win32 we need to specify an SMTP server so\n"
	printf "## that Condor is able to send email.\n"
	printf "SMTP_SERVER =\n\n"
	printf "## For Condor on Win32 we may need to specify a \"from\"\n"
	printf "## address so that a valid address is used in the from\n"
	printf "## field.\n"
	printf "MAIL_FROM =\n\n"
	next
}
/^SMTP_SERVER/ {
	next
}

# Choose a Windows-reasonable value for RELEASE_DIR and LOCAL_DIR
#
/^RELEASE_DIR[ \t]*=/ {
	printf "RELEASE_DIR = C:\\Condor\n"
	next
}
/^LOCAL_DIR[ \t]*=/ {
    printf "LOCAL_DIR = $(RELEASE_DIR)\n"
    next
}

# Don't require a local config file.
#
/^\#REQUIRE_LOCAL_CONFIG_FILE \=/ {
   printf "REQUIRE_LOCAL_CONFIG_FILE = FALSE\n"
   next
}

# Specify $(FULL_HOSTNAME) as the sample commented-out entry for
# FILESYSTEM_DOMAIN and UID_DOMAIN, as this is what the installer expects.
/^UID_DOMAIN/ || /^FILESYSTEM_DOMAIN/ {
	printf "#%s= $(FULL_HOSTNAME)\n", $1
	next
}

# Have $(SBIN) point to $(BIN)
/^SBIN/ {
	printf "%s= $(BIN)\n", $1
	next
}

# Have $(LIBEXEC) point to $(BIN)
/^LIBEXEC/ {
	printf "%s= $(BIN)\n", $1
	next
}

# QUEUE_SUPER_USERS should be condor and SYSTEM, not root! :)
/^QUEUE_SUPER_USERS/ {
	printf "%s= condor, SYSTEM\n", $1
	next
}

# JOB_RENICE_INCREMENT must be 10 or load average will be messed up
# Be careful, it may be commented out in condor_config.generic.
/^.*JOB_RENICE_INCREMENT/ {
	printf "JOB_RENICE_INCREMENT = 10\n"
	next
}

# Clean out the initial guess of /usr/bin/java for JAVA... ;)
# wherever it is on Windows, it's not there.
/^JAVA[ \t]*=/ {
	printf "JAVA =\n"
	next
}

# Win32 has a path separator of ';', while on Unix it is ':'
/^JAVA_CLASSPATH_SEPARATOR/ {
	printf "JAVA_CLASSPATH_SEPARATOR = ;\n", $1
	next
}

# Win32 has the jar files located in the bin directory.
/^JAVA_CLASSPATH_DEFAULT/ {
	print "JAVA_CLASSPATH_DEFAULT = $(BIN) $(BIN)/scimark2lib.jar ."
	next
}

# There's no reasonable default place to put log files for
# daemons that run as a user (on Unix we use /tmp). Use NUL.
/(^C_GAHP_LOG)|(^C_GAHP_LOCK)|(^C_GAHP_WORKER_THREAD_LOG)|(^C_GAHP_WORKER_THREAD_LOCK)|(^VM_GAHP_LOG)/ {
	printf "%s = NUL\n", $1
	next
}

# PROCD_ADDRESS needs to refer to a valid name for a Windows named
# pipe
/^PROCD_ADDRESS/ {
	print "PROCD_ADDRESS = \\\\.\\pipe\\condor_procd_pipe"
	next
}

# Make it so we can fill in the VM GAHP options if we choose
# to in the installer.
/^#VM_TYPE/ {
	print "VM_TYPE ="
	next
}
/^#VM_MAX_NUMBER/ {
	print "VM_MAX_NUMBER = $(NUM_CPUS)"
	next
}
/^#VM_MEMORY/ {
	print "VM_MEMORY = 128"
	next
}
/^#VMWARE_LOCAL_SETTINGS_FILE/ {
	print "#VMWARE_LOCAL_SETTINGS_FILE = $(RELEASE_DIR)/condor_vmware_local_settings"
	next
}

# Set it up so we can change the VMWARE_SCRIPT option if we choose to
# do so in the installer
#/^VMWARE_SCRIPT/ {
#	printf "VMWARE_SCRIPT = $(BIN)/condor_vm_vmware\n"
#	next
#}

# Change the configuration such that we can modify the VMware
# networking types
/^#VM_NETWORKING_TYPE/ {
	print "VM_NETWORKING_TYPE = nat"
	next
}
/^#VM_NETWORKING_DEFAULT_TYPE/ {
	print "VM_NETWORKING_DEFAULT_TYPE = nat"
	next
}

# We use the equals sign so that it will not match the names above
# and trash the resulting configuration file
/^#VM_NETWORKING =/ {
	print "VM_NETWORKING = FALSE"
	next
}
/^#VMWARE_NAT_NETWORKING_TYPE/ {
	printf "VMWARE_NAT_NETWORKING_TYPE = nat\n"
	next
}
/^#VMWARE_BRIDGE_NETWORKING_TYPE/ {
	printf "VMWARE_BRIDGE_NETWORKING_TYPE = bridged\n"
	next
}

# Add a .exe to the end of all condor daemon names in $(BIN) and $(SBIN)
/BIN)\/condor_/ {
	gsub(/\//, "\\", $0)
	printf "%s.exe\n",$0
	next
}

# Add a .exe to the end of all condor daemon names in $(LIBEXEC)
/LIBEXEC)\/condor_/ {
	gsub(/\//, "\\", $0)
	printf "%s.exe\n",$0
	next
}

# convert paths relative to LOCAL_DIR, RELEASE_DIR and LOG to windows path separators
/[ \t]*=[ \t]*\$\(LOCAL_DIR\)\// {
	gsub(/\//, "\\", $0)
	printf "%s\n",$0
	next
}
/[ \t]*=[ \t]*\$\(RELEASE_DIR\)\// {
	gsub(/\//, "\\", $0)
	printf "%s\n",$0
	next
}
/[ \t]*=[ \t]*\$\(LOG\)\// {
	gsub(/\//, "\\", $0)
	printf "%s\n",$0
	next
}

# If we made it here, print out the line unchanged
{print $0}

##**************************************************************
##
## Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
## University of Wisconsin-Madison, WI.
##
## Licensed under the Apache License, Version 2.0 (the "License"); you
## may not use this file except in compliance with the License.  You may
## obtain a copy of the License at
##
##    http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS,
## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.
##
##**************************************************************

##
## convert_config_to_win32.awk
##
## Todd Tannenbaum <tannenba@cs.wisc.edu>, 10/06
## John Knoeller <johnkn@cs.wisc.edu>, 12/10
##

# This is an awk script to modify condor_config.generic into a form that
# works with Windows.
# Pipe condor_config.generic through this awk script and save it as
# condor_config.win, which is what the Installer expects to modify after unbundling.

BEGIN {
	FS = "="
}

# Make it so we can fill in the VM_GAHP_SERVER option if we choose to in the
# installer. This is done before the .exe append bellow, because that match
# seems to block any other matches for that line.
/^#VM_GAHP_SERVER/ {
	print "#VM_GAHP_SERVER = $(BIN)\\condor_vm-gahp.exe"
	print "VM_GAHP_SERVER = "
	next
}
# We DONT want to add a .exe extension to the vmware script, it's a perl script.
/VMWARE_SCRIPT[ \t]*=/ {
	gsub(/\//, "\\", $0)
	printf "%s\n",$0
	next
}

# Remove SHADOW_STANDARD (the standard universe shadow)
#
/^SHADOW_STANDARD/ {
	next
}
/^SHADOW_LIST/ {
    printf "SHADOW_LIST = SHADOW\n"
    next
}

# Remove STARTER_STANDARD (the standard universe starter)
#
/^STARTER_STANDARD/ {
    next
}
/^STARTER_LIST/ {
    printf "STARTER_LIST = STARTER\n"
    next
}

/^FILETRANSFER_PLUGINS[ \t]*=/ {
	gsub(/\//, "\\", $0)
	gsub(/_plugin,/, "_plugin.exe,", $0)
	gsub(/_plugin$/, "_plugin.exe", $0)
	printf "%s\n",$0
	next
}

# Email Settings
# Use condor_mail.exe for MAIL, and put in a stub for SMTP_SERVER
/^MAIL/ {
	printf "MAIL = $(BIN)\\condor_mail.exe\n\n"
	printf "## For Condor on Win32 we need to specify an SMTP server so\n"
	printf "## that Condor is able to send email.\n"
	printf "SMTP_SERVER =\n\n"
	printf "## For Condor on Win32 we may need to specify a \"from\"\n"
	printf "## address so that a valid address is used in the from\n"
	printf "## field.\n"
	printf "MAIL_FROM =\n\n"
	next
}
/^SMTP_SERVER/ {
	next
}

# Choose a Windows-reasonable value for RELEASE_DIR and LOCAL_DIR
#
/^RELEASE_DIR[ \t]*=/ {
	printf "RELEASE_DIR = C:\\Condor\n"
	next
}
/^LOCAL_DIR[ \t]*=/ {
    printf "LOCAL_DIR = $(RELEASE_DIR)\n"
    next
}

# Don't require a local config file.
#
/^\#REQUIRE_LOCAL_CONFIG_FILE \=/ {
   printf "REQUIRE_LOCAL_CONFIG_FILE = FALSE\n"
   next
}

# Specify $(FULL_HOSTNAME) as the sample commented-out entry for
# FILESYSTEM_DOMAIN and UID_DOMAIN, as this is what the installer expects.
/^UID_DOMAIN/ || /^FILESYSTEM_DOMAIN/ {
	printf "#%s= $(FULL_HOSTNAME)\n", $1
	next
}

# Have $(SBIN) point to $(BIN)
/^SBIN/ {
	printf "%s= $(BIN)\n", $1
	next
}

# Have $(LIBEXEC) point to $(BIN)
/^LIBEXEC/ {
	printf "%s= $(BIN)\n", $1
	next
}

# QUEUE_SUPER_USERS should be condor and SYSTEM, not root! :)
/^QUEUE_SUPER_USERS/ {
	printf "%s= condor, SYSTEM\n", $1
	next
}

# JOB_RENICE_INCREMENT must be 10 or load average will be messed up
# Be careful, it may be commented out in condor_config.generic.
/^.*JOB_RENICE_INCREMENT/ {
	printf "JOB_RENICE_INCREMENT = 10\n"
	next
}

# Clean out the initial guess of /usr/bin/java for JAVA... ;)
# wherever it is on Windows, it's not there.
/^JAVA[ \t]*=/ {
	printf "JAVA =\n"
	next
}

# Win32 has a path separator of ';', while on Unix it is ':'
/^JAVA_CLASSPATH_SEPARATOR/ {
	printf "JAVA_CLASSPATH_SEPARATOR = ;\n", $1
	next
}

# Win32 has the jar files located in the bin directory.
/^JAVA_CLASSPATH_DEFAULT/ {
	print "JAVA_CLASSPATH_DEFAULT = $(BIN) $(BIN)/scimark2lib.jar ."
	next
}

# There's no reasonable default place to put log files for
# daemons that run as a user (on Unix we use /tmp). Use NUL.
/(^C_GAHP_LOG)|(^C_GAHP_LOCK)|(^C_GAHP_WORKER_THREAD_LOG)|(^C_GAHP_WORKER_THREAD_LOCK)|(^VM_GAHP_LOG)/ {
	printf "%s = NUL\n", $1
	next
}

# PROCD_ADDRESS needs to refer to a valid name for a Windows named
# pipe
/^PROCD_ADDRESS/ {
	print "PROCD_ADDRESS = \\\\.\\pipe\\condor_procd_pipe"
	next
}

# Make it so we can fill in the VM GAHP options if we choose
# to in the installer.
/^#VM_TYPE/ {
	print "VM_TYPE ="
	next
}
/^#VM_MAX_NUMBER/ {
	print "VM_MAX_NUMBER = $(NUM_CPUS)"
	next
}
/^#VM_MEMORY/ {
	print "VM_MEMORY = 128"
	next
}
/^#VMWARE_LOCAL_SETTINGS_FILE/ {
	print "VMWARE_LOCAL_SETTINGS_FILE = $(RELEASE_DIR)/condor_vmware_local_settings"
	next
}

# Set it up so we can change the VMWARE_SCRIPT option if we choose to
# do so in the installer
#/^VMWARE_SCRIPT/ {
#	printf "VMWARE_SCRIPT = $(BIN)/condor_vm_vmware\n"
#	next
#}

# Change the configuration such that we can modify the VMware
# networking types
/^#VM_NETWORKING_TYPE/ {
	print "VM_NETWORKING_TYPE = nat"
	next
}
/^#VM_NETWORKING_DEFAULT_TYPE/ {
	print "VM_NETWORKING_DEFAULT_TYPE = nat"
	next
}

# We use the equals sign so that it will not match the names above
# and trash the resulting configuration file
/^#VM_NETWORKING =/ {
	print "VM_NETWORKING = FALSE"
	next
}
/^#VMWARE_NAT_NETWORKING_TYPE/ {
	printf "VMWARE_NAT_NETWORKING_TYPE = nat\n"
	next
}
/^#VMWARE_BRIDGE_NETWORKING_TYPE/ {
	printf "VMWARE_BRIDGE_NETWORKING_TYPE = bridged\n"
	next
}

# Add a .exe to the end of all condor daemon names in $(BIN) and $(SBIN)
/BIN)\/condor_/ {
	gsub(/\//, "\\", $0)
	printf "%s.exe\n",$0
	next
}

# Add a .exe to the end of all condor daemon names in $(LIBEXEC)
/LIBEXEC)\/condor_/ {
	gsub(/\//, "\\", $0)
	printf "%s.exe\n",$0
	next
}

# convert paths relative to LOCAL_DIR, RELEASE_DIR and LOG to windows path separators
/[ \t]*=[ \t]*\$\(LOCAL_DIR\)\// {
	gsub(/\//, "\\", $0)
	printf "%s\n",$0
	next
}
/[ \t]*=[ \t]*\$\(RELEASE_DIR\)\// {
	gsub(/\//, "\\", $0)
	printf "%s\n",$0
	next
}
/[ \t]*=[ \t]*\$\(LOG\)\// {
	gsub(/\//, "\\", $0)
	printf "%s\n",$0
	next
}

# If we made it here, print out the line unchanged
{print $0}


update

update

#!/usr/bin/gawk -f
# https://github.com/FoobarBazbot/sedbot
# https://github.com/FoobarBazbot/sedbot/blob/master/LICENSE
# by FoobarBazbot
# modified by crutchy
# https://github.com/crutchy-/test/blob/master/sedbot.awk
# 21-july-2014
function lineout(old,new,nouser) {
  if(old!=new) print (nouser?"":"<" tauntuser(user) "> ") new >outfile; close(outfile);
  if(taunt[tolower(user)]>0) taunt[tolower(user)]--;
}
function tauntuser(u) {
  if(taunt[tolower(u)]>0) for(i=1;i<10;i++) u=gensub("("vowel_re")+(.)",vowel_letter[int(rand()*vowel_n+1)]"\\2",i,u);
  return u;
}
BEGIN {
  #outfile=( ENVIRON["HOME"] "/sedbotirc/irc.sylnt.us/#soylent/in");
  line_re="^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2} <([^>]*)> (.*)$";
  blag_re="world wide web|internet|interweb|intersphere|intertubes|interblag|blogosphere|blagonet|blagosphere|blagoblag|webnet|webweb";
  blag_n=split(blag_re,blag_word,/\|/);
  vowel_re="a|e|i|o|u|y";
  vowel_n=split(vowel_re,vowel_letter,/\|/);
  slash_n=split("\1ACTION offers # a /\1|\1ACTION tosses a / to #\1|#, did you know there's THREE slashes in a proper s/// command?|\1ACTION hurls a / at #!\1|#, you bloody moron, get the syntax straight or get off this channel!!\n\1ACTION peppers # with /s\1",slash_msg,"|");
  srand();
}
$0 ~ line_re {
  user=repluser=gensub(line_re,"\\1",1);
  line=gensub(/\001ACTION (.*)\001/,"\\1",1,gensub(line_re,"\\2",1));
  update_line=1;
}
line ~ /^s\/(([^\/\\]|\\.)+)\/(([^\/\\]|\\.)*)[[:space:]]*$/ {
  update_line=0;
  taunt[tolower(user)]+=1.5;
  lineout("",gensub("#",tauntuser(user),"g",slash_msg[int(rand()*rand()*slash_n+1)]),1);
}
line ~ /^([\x41-\x7D][-0-9\x41-\x7D]*)[:,] s(.*)/ {
  repluser=gensub(/^([\x41-\x7D][-0-9\x41-\x7D]*)[:,] s(.*)/,"\\1",1,line);
  line=gensub(/^([\x41-\x7D][-0-9\x41-\x7D]*)[:,] (s.*)/,"\\2",1,line);
  print repluser ": " line "\n" >"/dev/stderr";
}
line ~ /^s/ {
  sep=substr(line,2,1);
  if(sep ~ /[\.\^\$\[\]\|\+\*\(\)\{\}]/) sep="\\"sep;
  desep="\\\\("sep")";
  s_re = "^s" sep "(([^" sep "\\\\]|\\\\.)+)" sep "(([^" sep "\\\\]|\\\\.)*)" sep "(([0-9]*[1-9][0-9]*|g)|([iI]))*[[:space:]]*$";
  if(line ~ s_re) {
    update_line=0;
    search=gensub(desep,"\\1","g",gensub(s_re,"\\1", 1, line));
    repl  =gensub(desep,"\\1","g",gensub(s_re,"\\3", 1, line));
    count =gensub(desep,"\\1","g",gensub(s_re,"\\6", 1, line));
    casein=gensub(desep,"\\1","g",gensub(s_re,"\\7", 1, line));
    print repluser ": " line "\n" s_re "\n" search "\n" repl "\n" count "\n" casein >"/dev/stderr";
    if(!count) count=1;
    if(casein) IGNORECASE=1; else IGNORECASE=0;
    newline=gensub(search,repl,count,last_line[tolower(repluser)]);
    lineout((repluser!=user?"<"repluser"> ":"")last_line[tolower(repluser)],(repluser!=user?"<"repluser"> ":"")gensub(blag_re,blag_word[int(rand()*blag_n+1)],"g",newline));
  }
}
line ~ /^[sS][eE][dD][bB][oO][tT]/ {lineout("","\001ACTION is a 53-line awk script, https://github.com/FoobarBazbot/sedbot\001",1);}
update_line {last_line[tolower(user)]=line;}

#!/usr/bin/gawk -f

# https://github.com/FoobarBazbot/sedbot
# https://github.com/FoobarBazbot/sedbot/blob/master/LICENSE
# by FoobarBazbot
# modified by crutchy
# https://github.com/crutchy-/test/blob/master/sedbot.awk
# 21-july-2014

function lineout(old,new,nouser) {
  if(old!=new) print (nouser?"":"<" tauntuser(user) "> ") new >outfile; close(outfile);
  if(taunt[tolower(user)]>0) taunt[tolower(user)]--;
}
function tauntuser(u) {
  if(taunt[tolower(u)]>0) for(i=1;i<10;i++) u=gensub("("vowel_re")+(.)",vowel_letter[int(rand()*vowel_n+1)]"\\2",i,u);
  return u;
}
BEGIN {
  line_re="^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2} <([^>]*)> (.*)$";
  blag_re="world wide web|internet|interweb|intersphere|intertubes|interblag|blogosphere|blagonet|blagosphere|blagoblag|webnet|webweb";
  blag_n=split(blag_re,blag_word,/\|/);
  vowel_re="a|e|i|o|u|y";
  vowel_n=split(vowel_re,vowel_letter,/\|/);
  slash_n=split("\1ACTION offers # a /\1|\1ACTION tosses a / to #\1|#, did you know there's THREE slashes in a proper s/// command?|\1ACTION hurls a / at #!\1|#, you bloody moron, get the syntax straight or get off this channel!!\n\1ACTION peppers # with /s\1",slash_msg,"|");
  srand();
}
$0 ~ line_re {
  user=repluser=gensub(line_re,"\\1",1);
  line=gensub(/\001ACTION (.*)\001/,"\\1",1,gensub(line_re,"\\2",1));
  update_line=1;
}
line ~ /^s\/(([^\/\\]|\\.)+)\/(([^\/\\]|\\.)*)[[:space:]]*$/ {
  update_line=0;
  taunt[tolower(user)]+=1.5;
  lineout("",gensub("#",tauntuser(user),"g",slash_msg[int(rand()*rand()*slash_n+1)]),1);
}
line ~ /^([\x41-\x7D][-0-9\x41-\x7D]*)[:,] s(.*)/ {
  repluser=gensub(/^([\x41-\x7D][-0-9\x41-\x7D]*)[:,] s(.*)/,"\\1",1,line);
  line=gensub(/^([\x41-\x7D][-0-9\x41-\x7D]*)[:,] (s.*)/,"\\2",1,line);
  print repluser ": " line "\n" >"/dev/stderr";
}
line ~ /^s/ {
  sep=substr(line,2,1);
  if(sep ~ /[\.\^\$\[\]\|\+\*\(\)\{\}]/) sep="\\"sep;
  desep="\\\\("sep")";
  s_re = "^s" sep "(([^" sep "\\\\]|\\\\.)+)" sep "(([^" sep "\\\\]|\\\\.)*)" sep "(([0-9]*[1-9][0-9]*|g)|([iI]))*[[:space:]]*$";
  if(line ~ s_re) {
    update_line=0;
    search=gensub(desep,"\\1","g",gensub(s_re,"\\1", 1, line));
    repl  =gensub(desep,"\\1","g",gensub(s_re,"\\3", 1, line));
    count =gensub(desep,"\\1","g",gensub(s_re,"\\6", 1, line));
    casein=gensub(desep,"\\1","g",gensub(s_re,"\\7", 1, line));
    print repluser ": " line "\n" s_re "\n" search "\n" repl "\n" count "\n" casein >"/dev/stderr";
    if(!count) count=1;
    if(casein) IGNORECASE=1; else IGNORECASE=0;
    newline=gensub(search,repl,count,last_line[tolower(repluser)]);
    lineout((repluser!=user?"<"repluser"> ":"")last_line[tolower(repluser)],(repluser!=user?"<"repluser"> ":"")gensub(blag_re,blag_word[int(rand()*blag_n+1)],"g",newline));
  }
}
line ~ /^[sS][eE][dD][bB][oO][tT]/ {lineout("","\001ACTION is a 53-line awk script, https://github.com/FoobarBazbot/sedbot\001",1);}
update_line {last_line[tolower(user)]=line;}


Fix order of opening and closing tags

Fix order of opening and closing tags

- When generating HTML from a manual page ensure that opening
  and closing tags always come in the right order
- Allow combining bold and underline statements

#!/usr/bin/awk -f
#
# Takes a terminal formatted manual page and generates an identical
# looking HTML
 block.
#
# This script only supports UTF-8 encoding.
#

BEGIN {
	# The backspace character is used to combine characters
	BS = "\x08"

	# special HTML character substitutions
	SUB["&"] = "&"
	SUB["<"] = "<"
	SUB[">"] = ">"

	# formatting flags
	FMT_REGULAR    = 0
	FMT_BOLD       = 1
	FMT_UNDERLINE  = 2

	# formatting selectors
	SELECT["_"] = FMT_UNDERLINE

	# opening tags
	OPEN[FMT_BOLD]                 = ""
	OPEN[FMT_UNDERLINE]            = ""
	OPEN[FMT_BOLD + FMT_UNDERLINE] = ""

	# closing tags
	CLOSE[FMT_BOLD]                 = ""
	CLOSE[FMT_UNDERLINE]            = ""
	CLOSE[FMT_BOLD + FMT_UNDERLINE] = ""

	print "
"
}

END {
	print "
"
}

function u8error(msg)
{
	printf("utf-8 error:%d:%d:%d: %s\n\n%s\n% " p "s\n", NR, p, i, msg, $0, "^")
	exit 1
}

{
	# split characters
	delete chars

	n = split($0, chars, "")

	#
	# merge utf-8 multibyte chars
	#
	delete uchars

	p = 1
	mbyte = 0
	for (i = 1; i <= n; ++i) {
		# no leading bits, 1 byte characte
		if (mbyte)
		{
			if (chars[i] < "\x80" || chars[i] >= "\xc0") {
				u8error("unexected byte in multibyte character")
			}
			uchars[p] = uchars[p] chars[i]
			p += !--mbyte
		}
		# regular 1 byte characters
		else if (chars[i] < "\x80") {
			uchars[p++] = chars[i]
		}
		# 2 leading bits, merge 2 bytes
		else if (chars[i] >= "\xc0" && chars[i] < "\xe0") {
			uchars[p] = chars[i]
			mbyte = 1
		}
		# 3 leading bits, merge 3 bytes
		else if (chars[i] >= "\xe0" && chars[i] < "\xf0") {
			uchars[p] = chars[i]
			mbyte = 2
		}
		# 4 byte characters
		else if (chars[i] >= "\xf0" && chars[i] < "\xf8") {
			uchars[p] = chars[i]
			mbyte = 3
		}
		# error
		else
		{
			u8error("byte is not a character")
		}
	}
	n = p

	#
	# detect per character formatting
	#
	delete format
	delete ochars

	olen = 0
	for (i = 1; i <= n; ++i) {
		# skip ahead of formatting to the output character
		while (uchars[i + 1] == BS) {
			i += 2
			continue
		}
		# add character
		ochars[++olen] = uchars[i]
		# apply formatting
		for (p = i - 2; uchars[p + 1] == BS; p -= 2) {
			format[olen] = SELECT[uchars[p]]
			format[olen] += (uchars[i] == uchars[p] ? FMT_BOLD : FMT_REGULAR)
		}
	}

	#
	# replace special characters
	#
	for (i = 1; i <= olen; ++i) {
		ochars[i] in SUB && ochars[i] = SUB[ochars[i]]
	}

	#
	# output with HTML formatting
	#
	$0 = ""

	last = FMT_REGULAR
	for (i = 1; i <= olen; ++i) {
		if (format[i] != last) {
			$0 = $0 CLOSE[last] OPEN[format[i]]
		}
		$0 = $0 ochars[i]
		last = format[i]
	}
	$0 = $0 CLOSE[last]

	print
}

#!/usr/bin/awk -f
#
# Takes a terminal formatted manual page and generates an identical
# looking HTML
 block.
#
# This script only supports UTF-8 encoding.
#

BEGIN {
	# The backspace character is used to combine characters
	BS = "\x08"

	# Special character substitutions
	SUB["&"] = "&"
	SUB["<"] = "<"
	SUB[">"] = ">"

	print "
"
}

END {
	print "
"
}

function u8error(msg)
{
	printf("utf-8 error:%d:%d:%d: %s\n\n%s\n% " p "s\n", NR, p, i, msg, $0, "^")
	exit 1
}

{
	# split characters
	delete chars

	n = split($0, chars, "")

	#
	# merge utf-8 multibyte chars
	#
	delete uchars

	p = 1
	mbyte = 0
	for (i = 1; i <= n; ++i) {
		# no leading bits, 1 byte characte
		if (mbyte)
		{
			if (chars[i] < "\x80" || chars[i] >= "\xc0") {
				u8error("unexected byte in multibyte character")
			}
			uchars[p] = uchars[p] chars[i]
			p += !--mbyte
		}
		# regular 1 byte characters
		else if (chars[i] < "\x80") {
			uchars[p++] = chars[i]
		}
		# 2 leading bits, merge 2 bytes
		else if (chars[i] >= "\xc0" && chars[i] < "\xe0") {
			uchars[p] = chars[i]
			mbyte = 1
		}
		# 3 leading bits, merge 3 bytes
		else if (chars[i] >= "\xe0" && chars[i] < "\xf0") {
			uchars[p] = chars[i]
			mbyte = 2
		}
		# 4 byte characters
		else if (chars[i] >= "\xf0" && chars[i] < "\xf8") {
			uchars[p] = chars[i]
			mbyte = 3
		}
		# error
		else
		{
			u8error("byte is not a character")
		}
	}
	n = p

	#
	# replace special characters
	#
	for (i = 1; i <= n; ++i) {
		uchars[i] in SUB && uchars[i] = SUB[uchars[i]]
	}

	#
	# detect per character formatting
	#
	delete hide
	delete formatted
	delete bold
	delete underline
	delete strike

	for (i = 1; i <= n; ++i) {
		if (uchars[i] != BS) {
			continue
		}
		# hide composed characters
		hide[i - 1] = hide[i] = 1
		# detect formatting
		bold[i + 1] = (uchars[i - 1] == uchars[i + 1]) || bold[i - 1];
		underline[i + 1] = !bold[i + 1] && (uchars[i - 1] == "_") || underline[i - 1];
		strike[i + 1] = !bold[i + 1] && (uchars[i - 1] == "-") || strike[i - 1];
	}

	#
	# output with HTML formatting
	#
	$0 = ""

	bmode = 0
	umode = 0
	smode = 0
	for (i = 1; i <= n; ++i) {
		if (hide[i]) {
			continue
		}
		if (!bmode && bold[i]) {
			$0 = $0 ""
			bmode = 1
		}
		if (!umode && underline[i]) {
			$0 = $0 ""
			umode = 1
		}
		if (!smode && strike[i]) {
			$0 = $0 ""
			smode = 1
		}
		if (smode && !strike[i]) {
			$0 = $0 ""
			smode = 0
		}
		if (umode && !underline[i]) {
			$0 = $0 ""
			umode = 0
		}
		if (bmode && !bold[i]) {
			$0 = $0 ""
			bmode = 0
		}
		$0 = $0 uchars[i]
	}
	if (smode && !strike[i]) {
		$0 = $0 ""
	}
	if (umode && !underline[i]) {
		$0 = $0 ""
	}
	if (bmode && !bold[i]) {
		$0 = $0 ""
	}

	print
}


gbuild: Replace SHOWINCLUDES_PREFIX without regexp.

With MSVC Japanese, SHOWINCLUDES_PREFIX includes regexp special
charactor \x5b (left square bracket). In this case replacing
SHOWINCLUDES_PREFIX with regexp fails. To fix it, this commit
changes the script not to use regexp.

Example value of $SHOWINCLUDES_PREFIX from MSVC Japanese:
$ echo $SHOWINCLUDES_PREFIX | hexdump -C
83 81 83 82 3a 20 83 43 83 93 83 4e 83 8b 81 5b |....:.C...N...[|
83 68 20 83 74 83 40 83 43 83 8b 3a 20 20 43 3a |.h.t.@.C..:  C:|
5c 54 65 6d 70 5c 73 74 64 69 6f 2e 68 0d 0a    |\Temp\stdio.h..|

Change-Id: Ic7d85fc3a93807de11155488e9d0368427375c78
Reviewed-on: https://gerrit.libreoffice.org/3579
Reviewed-by: Kohei Yoshida <6e47bc5169e040ede988a669348d2aebab98c987@suse.de>
Tested-by: Kohei Yoshida <6e47bc5169e040ede988a669348d2aebab98c987@suse.de>

#!/usr/bin/gawk -f
# -*- tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

# Create dependency information from the output of cl.exe's showInclude.  It
# needs additional information - the output name to which to write, objfile
# that depends on the includes, and the original file name.
# For best results all arguments should be absolute paths.
#
# It also consolidates the file names to a canonical form, and filters out
# duplicates.
#
# based on filter-showInclude.pl by Jan Holesovsky <kendy@suse.cz>

BEGIN {
    if (!depfile || !objectfile || !sourcefile) {
        print "usage: filter-showIncludes.awk -vdepfile=depfile.d " \
          "-vobjectfile=objfile.o -vsourcefile=source.cxx" > "/dev/stderr"
        exit 1
    }
    tempfile = depfile ".tmp"
    print objectfile " : \\\n " sourcefile " \\" > tempfile

    showincludes_prefix = ENVIRON["SHOWINCLUDES_PREFIX"];
    if (!showincludes_prefix) {
        showincludes_prefix = "Note: including file:"
    }

    # to match especially drive letters in whitelist case insensitive
    IGNORECASE = 1
    whitelist = \
        "^(" ENVIRON["SRCDIR"] "|" ENVIRON["OUTDIR"] "|" ENVIRON["WORKDIR"] ")"
    firstline = 1
}

{
    sub(/^ */, "")
    if (index($0, showincludes_prefix) == 1) {
        $0 = substr($0, 1, length(showincludes_prefix))
        sub(/^ */, "")
        gsub(/\\/, "/")
        gsub(/ /, "\\ ")
        if ($0 ~ whitelist) { # filter out system headers
            if (!($0 in incfiles)) {
                incfiles[$0]
                print " " $0 " \\" > tempfile
            }
        }
    } else {
        # because MSVC stupidly prints the include files on stderr, it's
        # necessary to forward everything that isn't matched by the pattern
        # so users get to see compiler errros
        if (firstline) { # ignore the line that just prints name of sourcefile
            firstline = 0
        } else {
            print $0 > "/dev/stderr"
        }
    }
}

END {
    if (!tempfile) {
        exit 1
    }
    print "" > tempfile

    # fdo#40099 if header.h does not exist, it will simply be considered out of
    # date and any targets that use it as a prerequisite will be updated,
    # which avoid misery when the header is deliberately deleted and removed
    # as an include
    # see http://www.makelinux.net/make3/make3-CHP-8-SECT-3
    for (file in incfiles) {
        print file " :\n" > tempfile
    }

    close(tempfile)
    movecmd = "mv " tempfile " " depfile
    ret = system(movecmd)
    if (ret) {
        print "ERROR: " movecmd " FAILED with status " ret > "/dev/stderr"
        exit ret
    }
}

# vim: set noet sw=4 ts=4:

#!/usr/bin/gawk -f
# -*- tab-width: 4; indent-tabs-mode: t -*-
#
# This file is part of the LibreOffice project.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
#

# Create dependency information from the output of cl.exe's showInclude.  It
# needs additional information - the output name to which to write, objfile
# that depends on the includes, and the original file name.
# For best results all arguments should be absolute paths.
#
# It also consolidates the file names to a canonical form, and filters out
# duplicates.
#
# based on filter-showInclude.pl by Jan Holesovsky <kendy@suse.cz>

BEGIN {
    if (!depfile || !objectfile || !sourcefile) {
        print "usage: filter-showIncludes.awk -vdepfile=depfile.d " \
          "-vobjectfile=objfile.o -vsourcefile=source.cxx" > "/dev/stderr"
        exit 1
    }
    tempfile = depfile ".tmp"
    print objectfile " : \\\n " sourcefile " \\" > tempfile

    showincludes_prefix = ENVIRON["SHOWINCLUDES_PREFIX"];
    if (!showincludes_prefix) {
        showincludes_prefix = "Note: including file:"
    }
    regex = "^ *" showincludes_prefix " *"
    pattern = "/" regex "/"

    # to match especially drive letters in whitelist case insensitive
    IGNORECASE = 1
    whitelist = \
        "^(" ENVIRON["SRCDIR"] "|" ENVIRON["OUTDIR"] "|" ENVIRON["WORKDIR"] ")"
    firstline = 1
}

{
    if ($0 ~ regex) {
        sub(regex, "")
        gsub(/\\/, "/")
        gsub(/ /, "\\ ")
        if ($0 ~ whitelist) { # filter out system headers
            if (!($0 in incfiles)) {
                incfiles[$0]
                print " " $0 " \\" > tempfile
            }
        }
    } else {
        # because MSVC stupidly prints the include files on stderr, it's
        # necessary to forward everything that isn't matched by the pattern
        # so users get to see compiler errros
        if (firstline) { # ignore the line that just prints name of sourcefile
            firstline = 0
        } else {
            print $0 > "/dev/stderr"
        }
    }
}

END {
    if (!tempfile) {
        exit 1
    }
    print "" > tempfile

    # fdo#40099 if header.h does not exist, it will simply be considered out of
    # date and any targets that use it as a prerequisite will be updated,
    # which avoid misery when the header is deliberately deleted and removed
    # as an include
    # see http://www.makelinux.net/make3/make3-CHP-8-SECT-3
    for (file in incfiles) {
        print file " :\n" > tempfile
    }

    close(tempfile)
    movecmd = "mv " tempfile " " depfile
    ret = system(movecmd)
    if (ret) {
        print "ERROR: " movecmd " FAILED with status " ret > "/dev/stderr"
        exit ret
    }
}

# vim: set noet sw=4 ts=4:


#i10000# workaround limitations of solaris awk

#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# Copyright 2000, 2010 Oracle and/or its affiliates.
#
# OpenOffice.org - a multi-platform office productivity suite
#
# This file is part of OpenOffice.org.
#
# OpenOffice.org is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# only, as published by the Free Software Foundation.
#
# OpenOffice.org 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 Lesser General Public License version 3 for more details
# (a copy is included in the LICENSE file that accompanied this code).
#
# You should have received a copy of the GNU Lesser General Public License
# version 3 along with OpenOffice.org.  If not, see
# <http://www.openoffice.org/license.html>
# for a copy of the LGPLv3 License.
#
#*************************************************************************

BEGIN {
    RS=" "
    FS=":"
}

length($1) > 0 && length($2) > 0 {
    print "COPY " $1 " " $2;
}

#*************************************************************************
#
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
#
# Copyright 2000, 2010 Oracle and/or its affiliates.
#
# OpenOffice.org - a multi-platform office productivity suite
#
# This file is part of OpenOffice.org.
#
# OpenOffice.org is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License version 3
# only, as published by the Free Software Foundation.
#
# OpenOffice.org 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 Lesser General Public License version 3 for more details
# (a copy is included in the LICENSE file that accompanied this code).
#
# You should have received a copy of the GNU Lesser General Public License
# version 3 along with OpenOffice.org.  If not, see
# <http://www.openoffice.org/license.html>
# for a copy of the LGPLv3 License.
#
#*************************************************************************

BEGIN {
    RS=" "
    FS=":"
}

NF == 2 {
    print "COPY " $1 " " $2;
}