summaryrefslogtreecommitdiff
path: root/gnulib-local/build-aux/moopp
diff options
context:
space:
mode:
Diffstat (limited to 'gnulib-local/build-aux/moopp')
-rwxr-xr-xgnulib-local/build-aux/moopp760
1 files changed, 760 insertions, 0 deletions
diff --git a/gnulib-local/build-aux/moopp b/gnulib-local/build-aux/moopp
new file mode 100755
index 0000000..6be82fc
--- /dev/null
+++ b/gnulib-local/build-aux/moopp
@@ -0,0 +1,760 @@
+#!/bin/sh
+# Minimal Object-Oriented style PreProcessor.
+
+# Copyright (C) 2006-2008 Free Software Foundation, Inc.
+# Written by Bruno Haible <bruno@clisp.org>, 2006.
+#
+# 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 3 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, see <http://www.gnu.org/licenses/>.
+
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that program.
+
+# Usage: moopp source.oo.c source.oo.h superclass.oo.h ...
+# Arguments:
+# - the source file of the class,
+# - the header file declaring the class,
+# - the header file declaring its superclass,
+# - etc. up to the root class.
+# Creates four files in the current directory:
+# - source.c, the preprocessing result of source.oo.c,
+# - source.h, the preprocessing result of source.oo.h,
+# - class.priv.h, a file declaring the private fields of the class,
+# - class.vt.h, a file declaring the virtual function table of the class.
+
+# This implementation of the preprocessor is a quick hack. It makes assumptions
+# about the source code:
+# - GNU indentation style,
+# - the struct declaration must be in a single line,
+# - no comments on the struct declaration line,
+# - no #ifs in relevant position,
+# - ...
+# Someday this should be rewritten to use a proper tokenizer and parser.
+
+# func_usage
+# outputs to stdout the --help usage message.
+func_usage ()
+{
+ echo "\
+Usage: moopp [OPTION]... SOURCE.oo.c SOURCE.oo.h SUPERCLASS.oo.h ...
+
+Preprocesses SOURCE.oo.c into CLASS.c and SOURCE.oo.h into CLASS.h,
+where CLASS is the name of the class defined in these files.
+
+See moo.h for the object-oriented features and the syntax of the input files.
+
+Options:
+ --help print this help and exit
+ --version print version information and exit
+ --dllexport=NAME Arrange so that the specified class name can be accessed
+ from outside the shared library it is compiled into.
+ This option can be repeated.
+
+Report bugs to <bruno@clisp.org>."
+}
+
+# func_version
+# outputs to stdout the --version message.
+func_version ()
+{
+ echo "$progname (GNU $package) $version"
+ echo "Copyright (C) 2006-2007 Free Software Foundation, Inc.
+License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
+This is free software: you are free to change and redistribute it.
+There is NO WARRANTY, to the extent permitted by law."
+ echo "Written by" "Bruno Haible"
+}
+
+# func_fatal_error message
+# outputs to stderr a fatal error message, and terminates the program.
+func_fatal_error ()
+{
+ echo "moopp: *** $1" 1>&2
+ echo "moopp: *** Stop." 1>&2
+ exit 1
+}
+
+# Command-line option processing.
+# Removes the OPTIONS from the arguments. Sets the variables:
+# - dllexports list of class names to export from Woe32 DLLs
+dllexports=
+while test $# -gt 0; do
+ case "$1" in
+ --dllexport | --dllexpor | --dllexpo | --dllexp | --dllex | --dlle )
+ shift
+ if test $# = 0; then
+ func_fatal_error "missing argument for --dllexport"
+ fi
+ case "$1" in
+ -*) func_fatal_error "missing argument for --dllexport" ;;
+ esac
+ dllexports="$dllexports $1"
+ shift ;;
+ --dllexport=* )
+ arg=`echo "X$1" | sed -e 's/^X--dllexport=//'`
+ dllexports="$dllexports $arg"
+ shift ;;
+ --help | --hel | --he | --h )
+ func_usage
+ exit 0 ;;
+ --version | --versio | --versi | --vers | --ver | --ve | --v )
+ func_version
+ exit 0 ;;
+ -- ) # Stop option prcessing
+ shift; break ;;
+ -* )
+ func_fatal_error "unrecognized option: $option"
+ ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# -lt 2; then
+ func_fatal_error "Usage: $0 [OPTION]... source.oo.c source.oo.h superclass.oo.h ..."
+fi
+
+# Check that all files exist.
+for file
+do
+ test -r "$file" || {
+ func_fatal_error "file $file does not exist"
+ }
+done
+
+source_impl_file="$1"
+source_header_file="$2"
+shift
+shift
+
+case "$source_impl_file" in
+ *.oo.c) ;;
+ *) func_fatal_error "invalid class source file name: $source_impl_file" ;;
+esac
+case "$source_header_file" in
+ *.oo.h) ;;
+ *) func_fatal_error "invalid class header file name: $source_header_file" ;;
+esac
+
+# A sed expression that removes empty lines.
+sed_remove_empty_lines='/^$/d'
+
+# A sed expression that removes ANSI C and ISO C99 comments.
+sed_remove_comments="
+/[/][/*]/{
+ ta
+ :a
+ s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)//.*,\\1,
+ te
+ s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)/[*]\\([^*]\\|[*][^/*]\\)*[*][*]*/,\\1 ,
+ ta
+ /^\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*[/][*]/{
+ s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)/[*].*,\\1 ,
+ tu
+ :u
+ n
+ s,^\\([^*]\\|[*][^/*]\\)*[*][*]*/,,
+ tv
+ s,^.*\$,,
+ bu
+ :v
+ }
+ :e
+}"
+# The same thing as an extended regular expression, for use with
+# sed --regexp-extended.
+sed_remove_comments_ERE="
+/[/][/*]/{
+ ta
+ :a
+ s,^(([^\"'/]|\"([^\\\"]|[\\].)*\"|'([^\\']|[\\].)*'|[/][^\"'/*]|[/]\"([^\\\"]|[\\].)*\"|[/]'([^\\']|[\\].)*')*)//.*,\\1,
+ te
+ s,^(([^\"'/]|\"([^\\\"]|[\\].)*\"|'([^\\']|[\\].)*'|[/][^\"'/*]|[/]\"([^\\\"]|[\\].)*\"|[/]'([^\\']|[\\].)*')*)/[*]([^*]|[*][^/*])*[*][*]*/,\\1 ,
+ ta
+ /^([^\"'/]|\"([^\\\"]|[\\].)*\"|'([^\\']|[\\].)*'|[/][^\"'/*]|[/]\"([^\\\"]|[\\].)*\"|[/]'([^\\']|[\\].)*')*[/][*]/{
+ s,^(([^\"'/]|\"([^\\\"]|[\\].)*\"|'([^\\']|[\\].)*'|[/][^\"'/*]|[/]\"([^\\\"]|[\\].)*\"|[/]'([^\\']|[\\].)*')*)/[*].*,\\1 ,
+ tu
+ :u
+ n
+ s,^([^*]|[*][^/*])*[*][*]*/,,
+ tv
+ s,^.*\$,,
+ bu
+ :v
+ }
+ :e
+}"
+
+# Check that 'sed' supports the kind of regular expressions used in
+# sed_remove_comments. The use of \| meaning alternation of basic regular
+# expressions is a GNU extension.
+sed_test='s,^\(\(a\|X\)*\)//.*,\1,'
+sed_result=`echo 'aaa//bcd' | sed -e "$sed_test"`
+test "$sed_result" = 'aaa' \
+ || func_fatal_error "The 'sed' program is not GNU sed. Try installing GNU sed."
+
+# func_check_impl_syntax file
+# Check the syntax of the source implementation file.
+# Output:
+# - classname name of the class being defined (without 'struct')
+# - superclassname name of the superclass, or empty for a root class
+# - impl_decl_lineno line number of the class name declaration ('struct')
+# - impl_beg_lineno line number of the start of the class declaration ('{')
+# - impl_end_lineno line number of the end of the class declaration ('}')
+# - fields field declarations, including preprocessor directives
+func_check_impl_syntax ()
+{
+ file="$1"
+ sed -e "$sed_remove_comments" < "$file" | grep '^fields:' > /dev/null || {
+ func_fatal_error "$file does not contain 'fields:'"
+ }
+ test `sed -e "$sed_remove_comments" < "$file" | grep -c '^fields:'` = 1 || {
+ func_fatal_error "$file contains more than one 'fields:'"
+ }
+ fields_lineno=`sed -e "$sed_remove_comments" < "$file" | grep -n '^fields:' | sed -e 's,:.*,,'`
+ sed_before_fields="$fields_lineno"',$d'
+ impl_decl_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_before_fields" | grep -n '^struct[ ]' | tail -n 1 | sed -e 's,:.*,,'`
+ test -n "$impl_decl_lineno" || {
+ func_fatal_error "$file: class declaration not found"
+ }
+ class_line=`sed -e "$sed_remove_comments" < "$file" | sed -n -e "$impl_decl_lineno"'p'`
+ sed_extract_classname='s,^struct[ ][ ]*\([A-Za-z_0-9]*\).*,\1,p'
+ classname=`echo "$class_line" | sed -n -e "$sed_extract_classname"`
+ test -n "$classname" || {
+ func_fatal_error "$0: $file: class name not recognized at line $impl_decl_lineno"
+ }
+ superclassname=
+ if echo "$class_line" | grep ':' > /dev/null; then
+ sed_extract_superclassname='s,^.*:[ ]*struct[ ][ ]*\([A-Za-z_0-9]*\).*,\1,p'
+ superclassname=`echo "$class_line" | sed -n -e "$sed_extract_superclassname"`
+ test -n "$superclassname" || {
+ func_fatal_error "$file: superclass name not recognized at line $impl_decl_lineno"
+ }
+ fi
+ impl_beg_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_before_fields" | grep -n '^{' | tail -n 1 | sed -e 's,:.*,,'`
+ { test -n "$impl_beg_lineno" && test "$impl_decl_lineno" -lt "$impl_beg_lineno"; } || {
+ func_fatal_error "$file: opening brace of class declaration not found after line $impl_decl_lineno"
+ }
+ sed_after_fields='1,'"$fields_lineno"'d'
+ impl_end_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_after_fields" | grep -n '^}' | sed -e '1q' | sed -e 's,:.*,,'`
+ test -n "$impl_end_lineno" || {
+ func_fatal_error "$file: closing brace of class declaration not found after line $fields_lineno"
+ }
+ impl_end_lineno=`expr $fields_lineno + $impl_end_lineno`
+ sed_extract_fields="$impl_end_lineno"',$d;1,'"$fields_lineno"'d'
+ fields=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_extract_fields"`
+}
+
+# func_check_header_syntax file
+# Check the syntax of a header file.
+# Output:
+# - classname name of the class being defined (without 'struct')
+# - superclassname name of the superclass, or empty for a root class
+# - class_decl_lineno line number of the class name declaration ('struct')
+# - class_beg_lineno line number of the start of the class declaration ('{')
+# - class_end_lineno line number of the end of the class declaration ('}')
+# - methods newline-separated list of method declarations
+func_check_header_syntax ()
+{
+ file="$1"
+ sed -e "$sed_remove_comments" < "$file" | grep '^methods:' > /dev/null || {
+ func_fatal_error "$file does not contain 'methods:'"
+ }
+ test `sed -e "$sed_remove_comments" < "$file" | grep -c '^methods:'` = 1 || {
+ func_fatal_error "$file contains more than one 'methods:'"
+ }
+ methods_lineno=`sed -e "$sed_remove_comments" < "$file" | grep -n '^methods:' | sed -e 's,:.*,,'`
+ sed_before_methods="$methods_lineno"',$d'
+ class_decl_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_before_methods" | grep -n '^struct[ ]' | tail -n 1 | sed -e 's,:.*,,'`
+ test -n "$class_decl_lineno" || {
+ func_fatal_error "$file: class declaration not found"
+ }
+ class_line=`sed -e "$sed_remove_comments" < "$file" | sed -n -e "$class_decl_lineno"'p'`
+ sed_extract_classname='s,^struct[ ][ ]*\([A-Za-z_0-9]*\).*,\1,p'
+ classname=`echo "$class_line" | sed -n -e "$sed_extract_classname"`
+ test -n "$classname" || {
+ func_fatal_error "$0: $file: class name not recognized at line $class_decl_lineno"
+ }
+ superclassname=
+ if echo "$class_line" | grep ':' > /dev/null; then
+ sed_extract_superclassname='s,^.*:[ ]*struct[ ][ ]*\([A-Za-z_0-9]*\).*,\1,p'
+ superclassname=`echo "$class_line" | sed -n -e "$sed_extract_superclassname"`
+ test -n "$superclassname" || {
+ func_fatal_error "$file: superclass name not recognized at line $class_decl_lineno"
+ }
+ fi
+ class_beg_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_before_methods" | grep -n '^{' | tail -n 1 | sed -e 's,:.*,,'`
+ { test -n "$class_beg_lineno" && test "$class_decl_lineno" -lt "$class_beg_lineno"; } || {
+ func_fatal_error "$file: opening brace of class declaration not found after line $class_decl_lineno"
+ }
+ sed_after_methods='1,'"$methods_lineno"'d'
+ class_end_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_after_methods" | grep -n '^}' | sed -e '1q' | sed -e 's,:.*,,'`
+ test -n "$class_end_lineno" || {
+ func_fatal_error "$file: closing brace of class declaration not found after line $methods_lineno"
+ }
+ class_end_lineno=`expr $methods_lineno + $class_end_lineno`
+ sed_extract_methods="$class_end_lineno"',$d;1,'"$methods_lineno"'d'
+ methods=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_extract_methods" | tr '\n' ' ' | tr ';' '\n' | sed -e 's,[ ]*$,,'`
+ sed_remove_valid_arg1_lines='/([ ]*'"$classname"'_t[ ]*[A-Za-z_0-9]*[ ]*[,)]/d'
+ sed_extract_method_name='s,^.*[^A-Za-z_0-9]\([A-Za-z_0-9][A-Za-z_0-9]*\)[ ]*(.*$,\1,'
+ methods_with_bad_arg1=`echo "$methods" | sed -e "$sed_remove_empty_lines" -e "$sed_remove_valid_arg1_lines" -e "$sed_extract_method_name"`
+ if test -n "$methods_with_bad_arg1"; then
+ methods_with_bad_arg1=`{ echo "$methods_with_bad_arg1" | sed -e 's/$/, /' | tr -d '\n'; echo; } | sed -e 's/\(, \)*$//'`
+ func_fatal_error "$file: some methods don't have a first argument of type ${classname}_t: $methods_with_bad_arg1"
+ fi
+}
+
+func_check_impl_syntax "$source_impl_file"
+impl_classname="$classname"
+impl_superclassname="$superclassname"
+
+func_check_header_syntax "$source_header_file"
+main_classname="$classname"
+main_superclassname="$superclassname"
+main_class_decl_lineno="$class_decl_lineno"
+main_class_beg_lineno="$class_beg_lineno"
+main_class_end_lineno="$class_end_lineno"
+main_methods="$methods"
+all_superclasses=
+all_methods="$methods"
+inherited_methods=
+last_header_file="$source_header_file"
+expected_superclassname="$superclassname"
+
+for file
+do
+ if test -z "$expected_superclassname"; then
+ func_fatal_error "file $last_header_file does not specify a superclass; superfluous command line argument $file"
+ fi
+ func_check_header_syntax "$file"
+ all_superclasses="$classname $all_superclasses"
+ all_methods="$methods
+$all_methods"
+ inherited_methods="$methods
+$inherited_methods"
+ if test "$classname" != "$expected_superclassname"; then
+ func_fatal_error "file $last_header_file specifies superclass '$expected_superclassname', but file $file defines class '$classname'"
+ fi
+ last_header_file="$file"
+ expected_superclassname="$superclassname"
+done
+
+if test -n "$expected_superclassname"; then
+ func_fatal_error "$0: file $last_header_file specifies superclass '$expected_superclassname', please specify the header file that defines it as additional command line argument"
+fi
+
+if test "$impl_classname" != "$main_classname"; then
+ func_fatal_error "file $source_header_file specifies class '$main_classname', but file $source_impl_file specifies class '$impl_classname'"
+fi
+if test "$impl_superclassname" != "$main_superclassname"; then
+ if test -z "$main_superclassname"; then
+ func_fatal_error "file $source_header_file specifies no superclass, but file $source_impl_file specifies a superclass '$impl_superclassname'"
+ fi
+ if test -z "$impl_superclassname"; then
+ func_fatal_error "file $source_header_file specifies a superclass '$main_superclassname', but file $source_impl_file specifies no superclass"
+ fi
+ func_fatal_error "file $source_header_file specifies a superclass '$main_superclassname', but file $source_impl_file specifies a superclass '$impl_superclassname'"
+fi
+
+# func_start_creation file
+# starts the creation of the named file.
+func_start_creation ()
+{
+ file="$1"
+ if test -f "$file"; then
+ echo "Updating $file (backup in ${file}~)"
+ mv -f "$file" "${file}~" || func_fatal_error "failed"
+ else
+ echo "Creating $file"
+ fi
+}
+
+# func_emit_priv_h newfile
+# outputs to $newfile the contents of class.priv.h.
+func_emit_priv_h ()
+{
+ newfile="$1"
+ {
+ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'
+ echo
+ if test -n "${main_superclassname}"; then
+ echo "/* Field layout of superclass. */"
+ echo "#include \"${main_superclassname}.priv.h\""
+ echo
+ fi
+ echo "/* Field layout of ${main_classname} class. */"
+ echo "struct ${main_classname}_representation"
+ echo "{"
+ if test -n "${main_superclassname}"; then
+ echo " struct ${main_superclassname}_representation base;"
+ else
+ echo " const void *vtable;"
+ fi
+ echo "$fields" | sed -e "$sed_remove_empty_lines"
+ echo "};"
+ } > "$newfile"
+}
+
+# func_emit_vt_h newfile
+# outputs to $newfile the contents of class.vt.h.
+func_emit_vt_h ()
+{
+ newfile="$1"
+ {
+ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'
+ echo
+ if test -n "${main_superclassname}"; then
+ echo "/* Virtual function table layout of superclass. */"
+ echo "#include \"${main_superclassname}.vt.h\""
+ echo
+ fi
+ echo "/* Virtual function table layout of ${main_classname} class. */"
+ echo "$main_methods" | sed -e "$sed_remove_empty_lines" -e 's/\([^A-Za-z_0-9]\)\([A-Za-z_0-9][A-Za-z_0-9]*\)[ ]*([^,)]*/\1(*\2) (THIS_ARG/' -e 's,$,;,'
+ } > "$newfile"
+}
+
+# In C++ mode, we have a precise type checking. But in C mode, we have only
+# loose type checking: So that rootclass_t and subclass_t are assignment
+# compatible, we have to define subclass_t as identical to rootclass_t.
+# Therefore we need an alias name for the representation of any type in the
+# hierarchy.
+if test -z "$main_superclassname"; then
+ main_repclassalias="any_${main_classname}_representation"
+else
+ main_repclassalias="${main_classname}_representation"
+fi
+
+sed_extract_method_rettype='s,^\(.*[^A-Za-z_0-9]\)[A-Za-z_0-9][A-Za-z_0-9]*[ ]*(.*$,\1,
+s,^[ ]*,,
+s,[ ]*$,,'
+sed_extract_method_name='s,^.*[^A-Za-z_0-9]\([A-Za-z_0-9][A-Za-z_0-9]*\)[ ]*(.*$,\1,'
+sed_extract_method_arglist='s,^.*[^A-Za-z_0-9][A-Za-z_0-9][A-Za-z_0-9]*[ ]*([^,)]*\(.*\)).*$,'"${main_classname}_t"' first_arg\1,'
+sed_extract_method_args='s,^.*[^A-Za-z_0-9]\([A-Za-z_0-9][A-Za-z_0-9]*\)$,\1,'
+
+# func_emit_source_h newfile newfile_base
+# outputs to $newfile the contents of source.h.
+source_header_file_base=`echo "$source_header_file" | sed -e 's,^.*/,,'`
+func_emit_source_h ()
+{
+ newfile="$1"
+ newfile_base="$2"
+ # Use DLL_VARIABLE if and only if the main classname is among the names
+ # specified with --dllexport options.
+ dllexport_for_variables=
+ for name in $dllexports; do
+ if test "${main_classname}" = "${name}"; then
+ dllexport_for_variables=" DLL_VARIABLE"
+ break
+ fi
+ done
+ {
+ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'
+ echo
+ echo "#line 1 \"${source_header_file_base}\""
+ cat "$source_header_file" | sed -e "${main_class_decl_lineno}"',$d'
+ echo "#line "`expr 3 + ${main_class_decl_lineno} + 1`" \"$newfile_base\""
+ echo "struct ${main_repclassalias};"
+ echo "/* ${main_classname}_t is defined as a pointer to struct ${main_repclassalias}."
+ echo " In C++ mode, we use a smart pointer class."
+ echo " In C mode, we have no other choice than a typedef to the root class type. */"
+ echo "#if IS_CPLUSPLUS"
+ echo "struct ${main_classname}_t"
+ echo "{"
+ echo "private:"
+ echo " struct ${main_repclassalias} *_pointer;"
+ echo "public:"
+ echo " ${main_classname}_t () : _pointer (NULL) {}"
+ echo " ${main_classname}_t (struct ${main_repclassalias} *pointer) : _pointer (pointer) {}"
+ echo " struct ${main_repclassalias} * operator -> () { return _pointer; }"
+ echo " operator struct ${main_repclassalias} * () { return _pointer; }"
+ atroot=yes
+ for classname in $all_superclasses; do
+ if test -n "$atroot"; then
+ repclassalias="any_${classname}_representation"
+ else
+ repclassalias="${classname}_representation"
+ fi
+ echo " operator struct ${repclassalias} * () { return (struct ${repclassalias} *) _pointer; }"
+ atroot=
+ done
+ # The 'operator void *' is needed to avoid ambiguous conversion chains.
+ echo " operator void * () { return _pointer; }"
+ # The 'operator ==' and 'operator !=' are needed to avoid ambiguous comparisons with NULL.
+ echo " bool operator == (const void *p) { return _pointer == p; }"
+ echo " bool operator != (const void *p) { return _pointer != p; }"
+ atroot=yes
+ for classname in $all_superclasses; do
+ if test -n "$atroot"; then
+ repclassalias="any_${classname}_representation"
+ else
+ repclassalias="${classname}_representation"
+ fi
+ echo " operator ${classname}_t () { return (${classname}_t) (struct ${repclassalias} *) _pointer; }"
+ # The 'explicit' constructors allow to downcast.
+ echo " explicit ${main_classname}_t (${classname}_t x) : _pointer ((struct ${main_repclassalias} *) (void *) x) {}"
+ atroot=
+ done
+ echo "};"
+ echo "#else"
+ if test -n "${main_superclassname}"; then
+ echo "typedef ${main_superclassname}_t ${main_classname}_t;"
+ else
+ echo "typedef struct ${main_repclassalias} * ${main_classname}_t;"
+ fi
+ echo "#endif"
+ echo
+ echo "/* Functions that invoke the methods. */"
+ echo "$all_methods" | sed -e "$sed_remove_empty_lines" -e 's/\([^A-Za-z_0-9]\)\([A-Za-z_0-9][A-Za-z_0-9]*\)[ ]*([^,)]*/\1'"${main_classname}_"'\2 ('"${main_classname}_t first_arg"'/' -e 's,^,extern ,' -e 's,$,;,'
+ echo
+ # Now come the implementation details.
+ echo "/* Type representing an implementation of ${main_classname}_t. */"
+ echo "struct ${main_classname}_implementation"
+ echo "{"
+ echo " const typeinfo_t * const *superclasses;"
+ echo " size_t superclasses_length;"
+ echo " size_t instance_size;"
+ echo "#define THIS_ARG ${main_classname}_t first_arg"
+ echo "#include \"${main_classname}.vt.h\""
+ echo "#undef THIS_ARG"
+ echo "};"
+ echo
+ echo "/* Public portion of the object pointed to by a ${main_classname}_t. */"
+ echo "struct ${main_classname}_representation_header"
+ echo "{"
+ echo " const struct ${main_classname}_implementation *vtable;"
+ echo "};"
+ echo
+ echo "#if HAVE_INLINE"
+ echo
+ echo "/* Define the functions that invoke the methods as inline accesses to"
+ echo " the ${main_classname}_implementation."
+ echo " Use #define to avoid a warning because of extern vs. static. */"
+ echo
+ echo "$all_methods" | sed -e "$sed_remove_empty_lines" |
+ while read method; do
+ rettype=`echo "$method" | sed -e "$sed_extract_method_rettype"`
+ name=`echo "$method" | sed -e "$sed_extract_method_name"`
+ arglist=`echo "$method" | sed -e "$sed_extract_method_arglist"`
+ if test "$arglist" = "void"; then
+ args=
+ else
+ args=`{ echo "$arglist" | tr ',' '\n' | sed -e "$sed_extract_method_args" | tr '\n' ','; echo; } | sed -e 's/,$//'`
+ fi
+ if test "$rettype" = "void"; then
+ return=
+ else
+ return="return "
+ fi
+ echo "# define ${main_classname}_${name} ${main_classname}_${name}_inline"
+ echo "static inline $rettype"
+ echo "${main_classname}_${name} ($arglist)"
+ echo "{"
+ echo " const struct ${main_classname}_implementation *vtable ="
+ echo " ((struct ${main_classname}_representation_header *) (struct ${main_repclassalias} *) first_arg)->vtable;"
+ echo " ${return}vtable->${name} ($args);"
+ echo "}"
+ echo
+ done
+ echo "#endif"
+ echo
+ echo "extern${dllexport_for_variables} const typeinfo_t ${main_classname}_typeinfo;"
+ if test -n "${main_superclassname}"; then
+ superclasses_array_initializer="${main_superclassname}_SUPERCLASSES"
+ else
+ superclasses_array_initializer="NULL"
+ fi
+ echo "#define ${main_classname}_SUPERCLASSES &${main_classname}_typeinfo, ${superclasses_array_initializer}"
+ if test -n "${main_superclassname}"; then
+ echo "#define ${main_classname}_SUPERCLASSES_LENGTH (1 + ${main_superclassname}_SUPERCLASSES_LENGTH)"
+ else
+ echo "#define ${main_classname}_SUPERCLASSES_LENGTH (1 + 1)"
+ fi
+ echo
+ echo "extern${dllexport_for_variables} const struct ${main_classname}_implementation ${main_classname}_vtable;"
+ echo
+ echo "#line "`expr $main_class_end_lineno + 1`" \"${source_header_file_base}\""
+ cat "$source_header_file" | sed -e "1,${main_class_end_lineno}d"
+ } > "$newfile"
+}
+
+# func_emit_source_c newfile newfile_base
+# outputs to $newfile the contents of source.c.
+source_impl_file_base=`echo "$source_impl_file" | sed -e 's,^.*/,,'`
+func_emit_source_c ()
+{
+ newfile="$1"
+ newfile_base="$2"
+ {
+ echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'
+ echo
+ echo "#line 1 \"${source_impl_file_base}\""
+ cat "$source_impl_file" | sed -e "${impl_decl_lineno}"',$d'
+ echo "#line "`expr 3 + ${impl_decl_lineno} + 1`" \"$newfile_base\""
+ # In C mode, where subclass_t is identical to rootclass_t, we define the
+ # any_rootclass_representation type to the right one for subclass.
+ if test -n "$all_superclasses"; then
+ for classname in $all_superclasses; do
+ rootclassname="$classname"
+ break
+ done
+ else
+ rootclassname="$main_classname"
+ fi
+ echo "#if !IS_CPLUSPLUS"
+ echo "#define ${main_classname}_representation any_${rootclassname}_representation"
+ echo "#endif"
+ echo "#include \"${main_classname}.priv.h\""
+ echo
+ echo "const typeinfo_t ${main_classname}_typeinfo = { \"${main_classname}\" };"
+ echo
+ echo "static const typeinfo_t * const ${main_classname}_superclasses[] ="
+ echo " { ${main_classname}_SUPERCLASSES };"
+ echo
+ if test -n "${main_superclassname}"; then
+ echo "#define super ${main_superclassname}_vtable"
+ echo
+ fi
+ echo "#line "`expr $impl_end_lineno + 1`" \"${source_impl_file_base}\""
+ cat "$source_impl_file" | sed -e "1,${impl_end_lineno}d" | sed -e "s,${main_classname}::,${main_classname}__,g"
+ echo
+ lineno=`wc -l < "$newfile"`
+ echo "#line "`expr $lineno + 2`" \"$newfile_base\""
+ # Define trivial stubs for methods that are not defined or overridden.
+ inherited_method_names=`echo "$inherited_methods" | sed -e "$sed_remove_empty_lines" | sed -e "$sed_extract_method_name"`
+ echo "$all_methods" | sed -e "$sed_remove_empty_lines" |
+ while read method; do
+ rettype=`echo "$method" | sed -e "$sed_extract_method_rettype"`
+ name=`echo "$method" | sed -e "$sed_extract_method_name"`
+ arglist=`echo "$method" | sed -e "$sed_extract_method_arglist"`
+ if test "$arglist" = "void"; then
+ args=
+ else
+ args=`{ echo "$arglist" | tr ',' '\n' | sed -e "$sed_extract_method_args" | tr '\n' ','; echo; } | sed -e 's/,$//'`
+ fi
+ if test "$rettype" = "void"; then
+ return=
+ else
+ return="return "
+ fi
+ if cat "$source_impl_file" | sed -e "1,${impl_end_lineno}d" | sed -e "$sed_remove_comments" | grep "${main_classname}::${name} *(" > /dev/null; then
+ # The class defines or overrides the method.
+ :
+ else
+ # Add a stub for the method.
+ inherited=
+ for i in $inherited_method_names; do
+ if test "$i" = "$name"; then
+ inherited=yes
+ fi
+ done
+ # First a prototype, to avoid gcc -Wmissing-prototypes warnings.
+ echo "$rettype ${main_classname}__${name} ($arglist);"
+ echo "$rettype"
+ echo "${main_classname}__${name} ($arglist)"
+ echo "{"
+ if test -n "$inherited"; then
+ echo " ${return}super.${name} ($args);"
+ else
+ echo " /* Abstract (unimplemented) method called. */"
+ echo " abort ();"
+ # Avoid C++ compiler warning about missing return value.
+ echo " #ifndef __GNUC__"
+ echo " ${return}${main_classname}__${name} ($args);"
+ echo " #endif"
+ fi
+ echo "}"
+ echo
+ fi
+ done
+ echo
+ echo "const struct ${main_classname}_implementation ${main_classname}_vtable ="
+ echo "{"
+ echo " ${main_classname}_superclasses,"
+ echo " sizeof (${main_classname}_superclasses) / sizeof (${main_classname}_superclasses[0]),"
+ echo " sizeof (struct ${main_classname}_representation),"
+ echo "$all_methods" | sed -e "$sed_remove_empty_lines" |
+ while read method; do
+ name=`echo "$method" | sed -e "$sed_extract_method_name"`
+ echo " ${main_classname}__${name},"
+ done
+ echo "};"
+ echo
+ echo "#if !HAVE_INLINE"
+ echo
+ echo "/* Define the functions that invoke the methods. */"
+ echo
+ echo "$all_methods" | sed -e "$sed_remove_empty_lines" |
+ while read method; do
+ rettype=`echo "$method" | sed -e "$sed_extract_method_rettype"`
+ name=`echo "$method" | sed -e "$sed_extract_method_name"`
+ arglist=`echo "$method" | sed -e "$sed_extract_method_arglist"`
+ if test "$arglist" = "void"; then
+ args=
+ else
+ args=`{ echo "$arglist" | tr ',' '\n' | sed -e "$sed_extract_method_args" | tr '\n' ','; echo; } | sed -e 's/,$//'`
+ fi
+ if test "$rettype" = "void"; then
+ return=
+ else
+ return="return "
+ fi
+ echo "$rettype"
+ echo "${main_classname}_${name} ($arglist)"
+ echo "{"
+ echo " const struct ${main_classname}_implementation *vtable ="
+ echo " ((struct ${main_classname}_representation_header *) (struct ${main_repclassalias} *) first_arg)->vtable;"
+ echo " ${return}vtable->${name} ($args);"
+ echo "}"
+ echo
+ done
+ echo "#endif"
+ } > "$newfile"
+}
+
+# Generate the files in the source directory, not in the current directory.
+# This is needed because they need to be distributed, since not all platforms
+# have GNU 'sed' preinstalled.
+
+sed_butbase='s,[^/]*$,,'
+destdir=`echo "$source_impl_file" | sed -e "$sed_butbase"`
+
+# Generate the source.h file first. The Makefile.am snippets rely on the
+# fact that the other generated files have the same or a newer timestamp.
+#
+# Also, generate the source.c file last. The Makefile.am snippets don't know
+# about the other generated files; they assume that when the source.c file
+# is finished, this command is complete.
+
+new_source_header_file_base=`echo "$source_header_file_base" | sed -e 's,\.oo\.h$,.h,'`
+new_source_header_file="${destdir}$new_source_header_file_base"
+func_start_creation "$new_source_header_file"
+func_emit_source_h "$new_source_header_file" "$new_source_header_file_base" \
+ || func_fatal_error "failed"
+
+new_priv_header_file="${destdir}${main_classname}.priv.h"
+func_start_creation "$new_priv_header_file"
+func_emit_priv_h "$new_priv_header_file" \
+ || func_fatal_error "failed"
+
+new_vt_header_file="${destdir}${main_classname}.vt.h"
+func_start_creation "$new_vt_header_file"
+func_emit_vt_h "$new_vt_header_file" \
+ || func_fatal_error "failed"
+
+new_source_impl_file_base=`echo "$source_impl_file_base" | sed -e 's,\.oo\.c$,.c,'`
+new_source_impl_file="${destdir}$new_source_impl_file_base"
+func_start_creation "$new_source_impl_file"
+func_emit_source_c "$new_source_impl_file" "$new_source_impl_file_base" \
+ || func_fatal_error "failed"