• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/timemachine/gettext-0.17/gnulib-local/build-aux/
1#!/bin/sh
2# Minimal Object-Oriented style PreProcessor.
3
4# Copyright (C) 2006-2007 Free Software Foundation, Inc.
5# Written by Bruno Haible <bruno@clisp.org>, 2006.
6#
7# This program is free software: you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 3 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
20# As a special exception to the GNU General Public License, if you
21# distribute this file as part of a program that contains a
22# configuration script generated by Autoconf, you may include it under
23# the same distribution terms that you use for the rest of that program.
24
25# Usage: moopp source.oo.c source.oo.h superclass.oo.h ...
26# Arguments:
27#   - the source file of the class,
28#   - the header file declaring the class,
29#   - the header file declaring its superclass,
30#   - etc. up to the root class.
31# Creates four files in the current directory:
32#   - source.c, the preprocessing result of source.oo.c,
33#   - source.h, the preprocessing result of source.oo.h,
34#   - class.priv.h, a file declaring the private fields of the class,
35#   - class.vt.h, a file declaring the virtual function table of the class.
36
37# This implementation of the preprocessor is a quick hack. It makes assumptions
38# about the source code:
39#   - GNU indentation style,
40#   - the struct declaration must be in a single line,
41#   - no comments on the struct declaration line,
42#   - no #ifs in relevant position,
43#   - ...
44# Someday this should be rewritten to use a proper tokenizer and parser.
45
46# func_usage
47# outputs to stdout the --help usage message.
48func_usage ()
49{
50  echo "\
51Usage: moopp [OPTION]... SOURCE.oo.c SOURCE.oo.h SUPERCLASS.oo.h ...
52
53Preprocesses SOURCE.oo.c into CLASS.c and SOURCE.oo.h into CLASS.h,
54where CLASS is the name of the class defined in these files.
55
56See moo.h for the object-oriented features and the syntax of the input files.
57
58Options:
59      --help           print this help and exit
60      --version        print version information and exit
61      --dllexport=NAME Arrange so that the specified class name can be accessed
62                       from outside the shared library it is compiled into.
63                       This option can be repeated.
64
65Report bugs to <bruno@clisp.org>."
66}
67
68# func_version
69# outputs to stdout the --version message.
70func_version ()
71{
72  echo "$progname (GNU $package) $version"
73  echo "Copyright (C) 2006-2007 Free Software Foundation, Inc.
74License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
75This is free software: you are free to change and redistribute it.
76There is NO WARRANTY, to the extent permitted by law."
77  echo "Written by" "Bruno Haible"
78}
79
80# func_fatal_error message
81# outputs to stderr a fatal error message, and terminates the program.
82func_fatal_error ()
83{
84  echo "moopp: *** $1" 1>&2
85  echo "moopp: *** Stop." 1>&2
86  exit 1
87}
88
89# Command-line option processing.
90# Removes the OPTIONS from the arguments. Sets the variables:
91# - dllexports      list of class names to export from Woe32 DLLs
92dllexports=
93while test $# -gt 0; do
94  case "$1" in
95    --dllexport | --dllexpor | --dllexpo | --dllexp | --dllex | --dlle )
96      shift
97      if test $# = 0; then
98        func_fatal_error "missing argument for --dllexport"
99      fi
100      case "$1" in
101        -*) func_fatal_error "missing argument for --dllexport" ;;
102      esac
103      dllexports="$dllexports $1"
104      shift ;;
105    --dllexport=* )
106      arg=`echo "X$1" | sed -e 's/^X--dllexport=//'`
107      dllexports="$dllexports $arg"
108      shift ;;
109    --help | --hel | --he | --h )
110      func_usage
111      exit 0 ;;
112   --version | --versio | --versi | --vers | --ver | --ve | --v )
113      func_version
114      exit 0 ;;
115    -- )      # Stop option prcessing
116      shift; break ;;
117    -* )
118      func_fatal_error "unrecognized option: $option"
119      ;;
120    * )
121      break ;;
122  esac
123done
124
125if test $# -lt 2; then
126  func_fatal_error "Usage: $0 [OPTION]... source.oo.c source.oo.h superclass.oo.h ..."
127fi
128
129# Check that all files exist.
130for file
131do
132  test -r "$file" || {
133    func_fatal_error "file $file does not exist"
134  }
135done
136
137source_impl_file="$1"
138source_header_file="$2"
139shift
140shift
141
142case "$source_impl_file" in
143  *.oo.c) ;;
144  *) func_fatal_error "invalid class source file name: $source_impl_file" ;;
145esac
146case "$source_header_file" in
147  *.oo.h) ;;
148  *) func_fatal_error "invalid class header file name: $source_header_file" ;;
149esac
150
151# A sed expression that removes empty lines.
152sed_remove_empty_lines='/^$/d'
153
154# A sed expression that removes ANSI C and ISO C99 comments.
155sed_remove_comments="
156/[/][/*]/{
157  ta
158  :a
159  s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)//.*,\\1,
160  te
161  s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)/[*]\\([^*]\\|[*][^/*]\\)*[*][*]*/,\\1 ,
162  ta
163  /^\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*[/][*]/{
164    s,^\\(\\([^\"'/]\\|\"\\([^\\\"]\\|[\\].\\)*\"\\|'\\([^\\']\\|[\\].\\)*'\\|[/][^\"'/*]\\|[/]\"\\([^\\\"]\\|[\\].\\)*\"\\|[/]'\\([^\\']\\|[\\].\\)*'\\)*\\)/[*].*,\\1 ,
165    tu
166    :u
167    n
168    s,^\\([^*]\\|[*][^/*]\\)*[*][*]*/,,
169    tv
170    s,^.*\$,,
171    bu
172    :v
173  }
174  :e
175}"
176# The same thing as an extended regular expression, for use with
177# sed --regexp-extended.
178sed_remove_comments_ERE="
179/[/][/*]/{
180  ta
181  :a
182  s,^(([^\"'/]|\"([^\\\"]|[\\].)*\"|'([^\\']|[\\].)*'|[/][^\"'/*]|[/]\"([^\\\"]|[\\].)*\"|[/]'([^\\']|[\\].)*')*)//.*,\\1,
183  te
184  s,^(([^\"'/]|\"([^\\\"]|[\\].)*\"|'([^\\']|[\\].)*'|[/][^\"'/*]|[/]\"([^\\\"]|[\\].)*\"|[/]'([^\\']|[\\].)*')*)/[*]([^*]|[*][^/*])*[*][*]*/,\\1 ,
185  ta
186  /^([^\"'/]|\"([^\\\"]|[\\].)*\"|'([^\\']|[\\].)*'|[/][^\"'/*]|[/]\"([^\\\"]|[\\].)*\"|[/]'([^\\']|[\\].)*')*[/][*]/{
187    s,^(([^\"'/]|\"([^\\\"]|[\\].)*\"|'([^\\']|[\\].)*'|[/][^\"'/*]|[/]\"([^\\\"]|[\\].)*\"|[/]'([^\\']|[\\].)*')*)/[*].*,\\1 ,
188    tu
189    :u
190    n
191    s,^([^*]|[*][^/*])*[*][*]*/,,
192    tv
193    s,^.*\$,,
194    bu
195    :v
196  }
197  :e
198}"
199
200# Check that 'sed' supports the kind of regular expressions used in
201# sed_remove_comments. The use of \| meaning alternation of basic regular
202# expressions is a GNU extension.
203sed_test='s,^\(\(a\|X\)*\)//.*,\1,'
204sed_result=`echo 'aaa//bcd' | sed -e "$sed_test"`
205test "$sed_result" = 'aaa' \
206  || func_fatal_error "The 'sed' program is not GNU sed. Try installing GNU sed."
207
208# func_check_impl_syntax file
209# Check the syntax of the source implementation file.
210# Output:
211#   - classname         name of the class being defined (without 'struct')
212#   - superclassname    name of the superclass, or empty for a root class
213#   - impl_decl_lineno  line number of the class name declaration ('struct')
214#   - impl_beg_lineno   line number of the start of the class declaration ('{')
215#   - impl_end_lineno   line number of the end of the class declaration ('}')
216#   - fields            field declarations, including preprocessor directives
217func_check_impl_syntax ()
218{
219  file="$1"
220  sed -e "$sed_remove_comments" < "$file" | grep '^fields:' > /dev/null || {
221    func_fatal_error "$file does not contain 'fields:'"
222  }
223  test `sed -e "$sed_remove_comments" < "$file" | grep -c '^fields:'` = 1 || {
224    func_fatal_error "$file contains more than one 'fields:'"
225  }
226  fields_lineno=`sed -e "$sed_remove_comments" < "$file" | grep -n '^fields:' | sed -e 's,:.*,,'`
227  sed_before_fields="$fields_lineno"',$d'
228  impl_decl_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_before_fields" | grep -n '^struct[ 	]' | tail -n 1 | sed -e 's,:.*,,'`
229  test -n "$impl_decl_lineno" || {
230    func_fatal_error "$file: class declaration not found"
231  }
232  class_line=`sed -e "$sed_remove_comments" < "$file" | sed -n -e "$impl_decl_lineno"'p'`
233  sed_extract_classname='s,^struct[ 	][ 	]*\([A-Za-z_0-9]*\).*,\1,p'
234  classname=`echo "$class_line" | sed -n -e "$sed_extract_classname"`
235  test -n "$classname" || {
236    func_fatal_error "$0: $file: class name not recognized at line $impl_decl_lineno"
237  }
238  superclassname=
239  if echo "$class_line" | grep ':' > /dev/null; then
240    sed_extract_superclassname='s,^.*:[ 	]*struct[ 	][ 	]*\([A-Za-z_0-9]*\).*,\1,p'
241    superclassname=`echo "$class_line" | sed -n -e "$sed_extract_superclassname"`
242    test -n "$superclassname" || {
243      func_fatal_error "$file: superclass name not recognized at line $impl_decl_lineno"
244    }
245  fi
246  impl_beg_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_before_fields" | grep -n '^{' | tail -n 1 | sed -e 's,:.*,,'`
247  { test -n "$impl_beg_lineno" && test "$impl_decl_lineno" -lt "$impl_beg_lineno"; } || {
248    func_fatal_error "$file: opening brace of class declaration not found after line $impl_decl_lineno"
249  }
250  sed_after_fields='1,'"$fields_lineno"'d'
251  impl_end_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_after_fields" | grep -n '^}' | sed -e '1q' | sed -e 's,:.*,,'`
252  test -n "$impl_end_lineno" || {
253    func_fatal_error "$file: closing brace of class declaration not found after line $fields_lineno"
254  }
255  impl_end_lineno=`expr $fields_lineno + $impl_end_lineno`
256  sed_extract_fields="$impl_end_lineno"',$d;1,'"$fields_lineno"'d'
257  fields=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_extract_fields"`
258}
259
260# func_check_header_syntax file
261# Check the syntax of a header file.
262# Output:
263#   - classname         name of the class being defined (without 'struct')
264#   - superclassname    name of the superclass, or empty for a root class
265#   - class_decl_lineno line number of the class name declaration ('struct')
266#   - class_beg_lineno  line number of the start of the class declaration ('{')
267#   - class_end_lineno  line number of the end of the class declaration ('}')
268#   - methods           newline-separated list of method declarations
269func_check_header_syntax ()
270{
271  file="$1"
272  sed -e "$sed_remove_comments" < "$file" | grep '^methods:' > /dev/null || {
273    func_fatal_error "$file does not contain 'methods:'"
274  }
275  test `sed -e "$sed_remove_comments" < "$file" | grep -c '^methods:'` = 1 || {
276    func_fatal_error "$file contains more than one 'methods:'"
277  }
278  methods_lineno=`sed -e "$sed_remove_comments" < "$file" | grep -n '^methods:' | sed -e 's,:.*,,'`
279  sed_before_methods="$methods_lineno"',$d'
280  class_decl_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_before_methods" | grep -n '^struct[ 	]' | tail -n 1 | sed -e 's,:.*,,'`
281  test -n "$class_decl_lineno" || {
282    func_fatal_error "$file: class declaration not found"
283  }
284  class_line=`sed -e "$sed_remove_comments" < "$file" | sed -n -e "$class_decl_lineno"'p'`
285  sed_extract_classname='s,^struct[ 	][ 	]*\([A-Za-z_0-9]*\).*,\1,p'
286  classname=`echo "$class_line" | sed -n -e "$sed_extract_classname"`
287  test -n "$classname" || {
288    func_fatal_error "$0: $file: class name not recognized at line $class_decl_lineno"
289  }
290  superclassname=
291  if echo "$class_line" | grep ':' > /dev/null; then
292    sed_extract_superclassname='s,^.*:[ 	]*struct[ 	][ 	]*\([A-Za-z_0-9]*\).*,\1,p'
293    superclassname=`echo "$class_line" | sed -n -e "$sed_extract_superclassname"`
294    test -n "$superclassname" || {
295      func_fatal_error "$file: superclass name not recognized at line $class_decl_lineno"
296    }
297  fi
298  class_beg_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_before_methods" | grep -n '^{' | tail -n 1 | sed -e 's,:.*,,'`
299  { test -n "$class_beg_lineno" && test "$class_decl_lineno" -lt "$class_beg_lineno"; } || {
300    func_fatal_error "$file: opening brace of class declaration not found after line $class_decl_lineno"
301  }
302  sed_after_methods='1,'"$methods_lineno"'d'
303  class_end_lineno=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_after_methods" | grep -n '^}' | sed -e '1q' | sed -e 's,:.*,,'`
304  test -n "$class_end_lineno" || {
305    func_fatal_error "$file: closing brace of class declaration not found after line $methods_lineno"
306  }
307  class_end_lineno=`expr $methods_lineno + $class_end_lineno`
308  sed_extract_methods="$class_end_lineno"',$d;1,'"$methods_lineno"'d'
309  methods=`sed -e "$sed_remove_comments" < "$file" | sed -e "$sed_extract_methods" | tr '\n' ' ' | tr ';' '\n' | sed -e 's,[ 	]*$,,'`
310  sed_remove_valid_arg1_lines='/([ 	]*'"$classname"'_t[ 	]*[A-Za-z_0-9]*[ 	]*[,)]/d'
311  sed_extract_method_name='s,^.*[^A-Za-z_0-9]\([A-Za-z_0-9][A-Za-z_0-9]*\)[ 	]*(.*$,\1,'
312  methods_with_bad_arg1=`echo "$methods" | sed -e "$sed_remove_empty_lines" -e "$sed_remove_valid_arg1_lines" -e "$sed_extract_method_name"`
313  if test -n "$methods_with_bad_arg1"; then
314    methods_with_bad_arg1=`{ echo "$methods_with_bad_arg1" | sed -e 's/$/, /' | tr -d '\n'; echo; } | sed -e 's/\(, \)*$//'`
315    func_fatal_error "$file: some methods don't have a first argument of type ${classname}_t: $methods_with_bad_arg1"
316  fi
317}
318
319func_check_impl_syntax "$source_impl_file"
320impl_classname="$classname"
321impl_superclassname="$superclassname"
322
323func_check_header_syntax "$source_header_file"
324main_classname="$classname"
325main_superclassname="$superclassname"
326main_class_decl_lineno="$class_decl_lineno"
327main_class_beg_lineno="$class_beg_lineno"
328main_class_end_lineno="$class_end_lineno"
329main_methods="$methods"
330all_superclasses=
331all_methods="$methods"
332inherited_methods=
333last_header_file="$source_header_file"
334expected_superclassname="$superclassname"
335
336for file
337do
338  if test -z "$expected_superclassname"; then
339    func_fatal_error "file $last_header_file does not specify a superclass; superfluous command line argument $file"
340  fi
341  func_check_header_syntax "$file"
342  all_superclasses="$classname $all_superclasses"
343  all_methods="$methods
344$all_methods"
345  inherited_methods="$methods
346$inherited_methods"
347  if test "$classname" != "$expected_superclassname"; then
348    func_fatal_error "file $last_header_file specifies superclass '$expected_superclassname', but file $file defines class '$classname'"
349  fi
350  last_header_file="$file"
351  expected_superclassname="$superclassname"
352done
353
354if test -n "$expected_superclassname"; then
355  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"
356fi
357
358if test "$impl_classname" != "$main_classname"; then
359  func_fatal_error "file $source_header_file specifies class '$main_classname', but file $source_impl_file specifies class '$impl_classname'"
360fi
361if test "$impl_superclassname" != "$main_superclassname"; then
362  if test -z "$main_superclassname"; then
363    func_fatal_error "file $source_header_file specifies no superclass, but file $source_impl_file specifies a superclass '$impl_superclassname'"
364  fi
365  if test -z "$impl_superclassname"; then
366    func_fatal_error "file $source_header_file specifies a superclass '$main_superclassname', but file $source_impl_file specifies no superclass"
367  fi
368  func_fatal_error "file $source_header_file specifies a superclass '$main_superclassname', but file $source_impl_file specifies a superclass '$impl_superclassname'"
369fi
370
371# func_start_creation file
372# starts the creation of the named file.
373func_start_creation ()
374{
375  file="$1"
376  if test -f "$file"; then
377    echo "Updating $file (backup in ${file}~)"
378    mv -f "$file" "${file}~" || func_fatal_error "failed"
379  else
380    echo "Creating $file"
381  fi
382}
383
384# func_emit_priv_h newfile
385# outputs to $newfile the contents of class.priv.h.
386func_emit_priv_h ()
387{
388  newfile="$1"
389  {
390    echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'
391    echo
392    if test -n "${main_superclassname}"; then
393      echo "/* Field layout of superclass.  */"
394      echo "#include \"${main_superclassname}.priv.h\""
395      echo
396    fi
397    echo "/* Field layout of ${main_classname} class.  */"
398    echo "struct ${main_classname}_representation"
399    echo "{"
400    if test -n "${main_superclassname}"; then
401      echo "  struct ${main_superclassname}_representation base;"
402    else
403      echo "  const void *vtable;"
404    fi
405    echo "$fields" | sed -e "$sed_remove_empty_lines"
406    echo "};"
407  } > "$newfile"
408}
409
410# func_emit_vt_h newfile
411# outputs to $newfile the contents of class.vt.h.
412func_emit_vt_h ()
413{
414  newfile="$1"
415  {
416    echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'
417    echo
418    if test -n "${main_superclassname}"; then
419      echo "/* Virtual function table layout of superclass.  */"
420      echo "#include \"${main_superclassname}.vt.h\""
421      echo
422    fi
423    echo "/* Virtual function table layout of ${main_classname} class.  */"
424    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,$,;,'
425  } > "$newfile"
426}
427
428# In C++ mode, we have a precise type checking. But in C mode, we have only
429# loose type checking: So that rootclass_t and subclass_t are assignment
430# compatible, we have to define subclass_t as identical to rootclass_t.
431# Therefore we need an alias name for the representation of any type in the
432# hierarchy.
433if test -z "$main_superclassname"; then
434  main_repclassalias="any_${main_classname}_representation"
435else
436  main_repclassalias="${main_classname}_representation"
437fi
438
439sed_extract_method_rettype='s,^\(.*[^A-Za-z_0-9]\)[A-Za-z_0-9][A-Za-z_0-9]*[ 	]*(.*$,\1,
440s,^[ 	]*,,
441s,[ 	]*$,,'
442sed_extract_method_name='s,^.*[^A-Za-z_0-9]\([A-Za-z_0-9][A-Za-z_0-9]*\)[ 	]*(.*$,\1,'
443sed_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,'
444sed_extract_method_args='s,^.*[^A-Za-z_0-9]\([A-Za-z_0-9][A-Za-z_0-9]*\)$,\1,'
445
446# func_emit_source_h newfile newfile_base
447# outputs to $newfile the contents of source.h.
448source_header_file_base=`echo "$source_header_file" | sed -e 's,^.*/,,'`
449func_emit_source_h ()
450{
451  newfile="$1"
452  newfile_base="$2"
453  # Use DLL_VARIABLE if and only if the main classname is among the names
454  # specified with --dllexport options.
455  dllexport_for_variables=
456  for name in $dllexports; do
457    if test "${main_classname}" = "${name}"; then
458      dllexport_for_variables=" DLL_VARIABLE"
459      break
460    fi
461  done
462  {
463    echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'
464    echo
465    echo "#line 1 \"${source_header_file_base}\""
466    cat "$source_header_file" | sed -e "${main_class_decl_lineno}"',$d'
467    echo "#line "`expr 3 + ${main_class_decl_lineno} + 1`" \"$newfile_base\""
468    echo "struct ${main_repclassalias};"
469    echo "/* ${main_classname}_t is defined as a pointer to struct ${main_repclassalias}."
470    echo "   In C++ mode, we use a smart pointer class."
471    echo "   In C mode, we have no other choice than a typedef to the root class type.  */"
472    echo "#if IS_CPLUSPLUS"
473    echo "struct ${main_classname}_t"
474    echo "{"
475    echo "private:"
476    echo "  struct ${main_repclassalias} *_pointer;"
477    echo "public:"
478    echo "  ${main_classname}_t () : _pointer (NULL) {}"
479    echo "  ${main_classname}_t (struct ${main_repclassalias} *pointer) : _pointer (pointer) {}"
480    echo "  struct ${main_repclassalias} * operator -> () { return _pointer; }"
481    echo "  operator struct ${main_repclassalias} * () { return _pointer; }"
482    atroot=yes
483    for classname in $all_superclasses; do
484      if test -n "$atroot"; then
485        repclassalias="any_${classname}_representation"
486      else
487        repclassalias="${classname}_representation"
488      fi
489      echo "  operator struct ${repclassalias} * () { return (struct ${repclassalias} *) _pointer; }"
490      atroot=
491    done
492    # The 'operator void *' is needed to avoid ambiguous conversion chains.
493    echo "  operator void * () { return _pointer; }"
494    # The 'operator ==' and 'operator !=' are needed to avoid ambiguous comparisons with NULL.
495    echo "  bool operator == (const void *p) { return _pointer == p; }"
496    echo "  bool operator != (const void *p) { return _pointer != p; }"
497    atroot=yes
498    for classname in $all_superclasses; do
499      if test -n "$atroot"; then
500        repclassalias="any_${classname}_representation"
501      else
502        repclassalias="${classname}_representation"
503      fi
504      echo "  operator ${classname}_t () { return (${classname}_t) (struct ${repclassalias} *) _pointer; }"
505      # The 'explicit' constructors allow to downcast.
506      echo "  explicit ${main_classname}_t (${classname}_t x) : _pointer ((struct ${main_repclassalias} *) (void *) x) {}"
507      atroot=
508    done
509    echo "};"
510    echo "#else"
511    if test -n "${main_superclassname}"; then
512      echo "typedef ${main_superclassname}_t ${main_classname}_t;"
513    else
514      echo "typedef struct ${main_repclassalias} * ${main_classname}_t;"
515    fi
516    echo "#endif"
517    echo
518    echo "/* Functions that invoke the methods.  */"
519    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,$,;,'
520    echo
521    # Now come the implementation details.
522    echo "/* Type representing an implementation of ${main_classname}_t.  */"
523    echo "struct ${main_classname}_implementation"
524    echo "{"
525    echo "  const typeinfo_t * const *superclasses;"
526    echo "  size_t superclasses_length;"
527    echo "  size_t instance_size;"
528    echo "#define THIS_ARG ${main_classname}_t first_arg"
529    echo "#include \"${main_classname}.vt.h\""
530    echo "#undef THIS_ARG"
531    echo "};"
532    echo
533    echo "/* Public portion of the object pointed to by a ${main_classname}_t.  */"
534    echo "struct ${main_classname}_representation_header"
535    echo "{"
536    echo "  const struct ${main_classname}_implementation *vtable;"
537    echo "};"
538    echo
539    echo "#if HAVE_INLINE"
540    echo
541    echo "/* Define the functions that invoke the methods as inline accesses to"
542    echo "   the ${main_classname}_implementation."
543    echo "   Use #define to avoid a warning because of extern vs. static.  */"
544    echo
545    echo "$all_methods" | sed -e "$sed_remove_empty_lines" |
546      while read method; do
547        rettype=`echo "$method" | sed -e "$sed_extract_method_rettype"`
548        name=`echo "$method" | sed -e "$sed_extract_method_name"`
549        arglist=`echo "$method" | sed -e "$sed_extract_method_arglist"`
550        if test "$arglist" = "void"; then
551          args=
552        else
553          args=`{ echo "$arglist" | tr ',' '\n' | sed -e "$sed_extract_method_args" | tr '\n' ','; echo; } | sed -e 's/,$//'`
554        fi
555        if test "$rettype" = "void"; then
556          return=
557        else
558          return="return "
559        fi
560        echo "# define ${main_classname}_${name} ${main_classname}_${name}_inline"
561        echo "static inline $rettype"
562        echo "${main_classname}_${name} ($arglist)"
563        echo "{"
564        echo "  const struct ${main_classname}_implementation *vtable ="
565        echo "    ((struct ${main_classname}_representation_header *) (struct ${main_repclassalias} *) first_arg)->vtable;"
566        echo "  ${return}vtable->${name} ($args);"
567        echo "}"
568        echo
569      done
570    echo "#endif"
571    echo
572    echo "extern${dllexport_for_variables} const typeinfo_t ${main_classname}_typeinfo;"
573    if test -n "${main_superclassname}"; then
574      superclasses_array_initializer="${main_superclassname}_SUPERCLASSES"
575    else
576      superclasses_array_initializer="NULL"
577    fi
578    echo "#define ${main_classname}_SUPERCLASSES &${main_classname}_typeinfo, ${superclasses_array_initializer}"
579    if test -n "${main_superclassname}"; then
580      echo "#define ${main_classname}_SUPERCLASSES_LENGTH (1 + ${main_superclassname}_SUPERCLASSES_LENGTH)"
581    else
582      echo "#define ${main_classname}_SUPERCLASSES_LENGTH (1 + 1)"
583    fi
584    echo
585    echo "extern${dllexport_for_variables} const struct ${main_classname}_implementation ${main_classname}_vtable;"
586    echo
587    echo "#line "`expr $main_class_end_lineno + 1`" \"${source_header_file_base}\""
588    cat "$source_header_file" | sed -e "1,${main_class_end_lineno}d"
589  } > "$newfile"
590}
591
592# func_emit_source_c newfile newfile_base
593# outputs to $newfile the contents of source.c.
594source_impl_file_base=`echo "$source_impl_file" | sed -e 's,^.*/,,'`
595func_emit_source_c ()
596{
597  newfile="$1"
598  newfile_base="$2"
599  {
600    echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'
601    echo
602    echo "#line 1 \"${source_impl_file_base}\""
603    cat "$source_impl_file" | sed -e "${impl_decl_lineno}"',$d'
604    echo "#line "`expr 3 + ${impl_decl_lineno} + 1`" \"$newfile_base\""
605    # In C mode, where subclass_t is identical to rootclass_t, we define the
606    # any_rootclass_representation type to the right one for subclass.
607    if test -n "$all_superclasses"; then
608      for classname in $all_superclasses; do
609        rootclassname="$classname"
610        break
611      done
612    else
613      rootclassname="$main_classname"
614    fi
615    echo "#if !IS_CPLUSPLUS"
616    echo "#define ${main_classname}_representation any_${rootclassname}_representation"
617    echo "#endif"
618    echo "#include \"${main_classname}.priv.h\""
619    echo
620    echo "const typeinfo_t ${main_classname}_typeinfo = { \"${main_classname}\" };"
621    echo
622    echo "static const typeinfo_t * const ${main_classname}_superclasses[] ="
623    echo "  { ${main_classname}_SUPERCLASSES };"
624    echo
625    if test -n "${main_superclassname}"; then
626      echo "#define super ${main_superclassname}_vtable"
627      echo
628    fi
629    echo "#line "`expr $impl_end_lineno + 1`" \"${source_impl_file_base}\""
630    cat "$source_impl_file" | sed -e "1,${impl_end_lineno}d" | sed -e "s,${main_classname}::,${main_classname}__,g"
631    echo
632    lineno=`wc -l < "$newfile"`
633    echo "#line "`expr $lineno + 2`" \"$newfile_base\""
634    # Define trivial stubs for methods that are not defined or overridden.
635    inherited_method_names=`echo "$inherited_methods" | sed -e "$sed_remove_empty_lines" | sed -e "$sed_extract_method_name"`
636    echo "$all_methods" | sed -e "$sed_remove_empty_lines" |
637      while read method; do
638        rettype=`echo "$method" | sed -e "$sed_extract_method_rettype"`
639        name=`echo "$method" | sed -e "$sed_extract_method_name"`
640        arglist=`echo "$method" | sed -e "$sed_extract_method_arglist"`
641        if test "$arglist" = "void"; then
642          args=
643        else
644          args=`{ echo "$arglist" | tr ',' '\n' | sed -e "$sed_extract_method_args" | tr '\n' ','; echo; } | sed -e 's/,$//'`
645        fi
646        if test "$rettype" = "void"; then
647          return=
648        else
649          return="return "
650        fi
651        if cat "$source_impl_file" | sed -e "1,${impl_end_lineno}d" | sed -e "$sed_remove_comments" | grep "${main_classname}::${name} *(" > /dev/null; then
652          # The class defines or overrides the method.
653          :
654        else
655          # Add a stub for the method.
656          inherited=
657          for i in $inherited_method_names; do
658            if test "$i" = "$name"; then
659              inherited=yes
660            fi
661          done
662          echo "$rettype"
663          echo "${main_classname}__${name} ($arglist)"
664          echo "{"
665          if test -n "$inherited"; then
666            echo "  ${return}super.${name} ($args);"
667          else
668            echo "  /* Abstract (unimplemented) method called.  */"
669            echo "  abort ();"
670            # Avoid C++ compiler warning about missing return value.
671            echo "  #ifndef __GNUC__"
672            echo "  ${return}${main_classname}__${name} ($args);"
673            echo "  #endif"
674          fi
675          echo "}"
676          echo
677        fi
678      done
679    echo
680    echo "const struct ${main_classname}_implementation ${main_classname}_vtable ="
681    echo "{"
682    echo "  ${main_classname}_superclasses,"
683    echo "  sizeof (${main_classname}_superclasses) / sizeof (${main_classname}_superclasses[0]),"
684    echo "  sizeof (struct ${main_classname}_representation),"
685    echo "$all_methods" | sed -e "$sed_remove_empty_lines" |
686      while read method; do
687        name=`echo "$method" | sed -e "$sed_extract_method_name"`
688        echo "  ${main_classname}__${name},"
689      done
690    echo "};"
691    echo
692    echo "#if !HAVE_INLINE"
693    echo
694    echo "/* Define the functions that invoke the methods.  */"
695    echo
696    echo "$all_methods" | sed -e "$sed_remove_empty_lines" |
697      while read method; do
698        rettype=`echo "$method" | sed -e "$sed_extract_method_rettype"`
699        name=`echo "$method" | sed -e "$sed_extract_method_name"`
700        arglist=`echo "$method" | sed -e "$sed_extract_method_arglist"`
701        if test "$arglist" = "void"; then
702          args=
703        else
704          args=`{ echo "$arglist" | tr ',' '\n' | sed -e "$sed_extract_method_args" | tr '\n' ','; echo; } | sed -e 's/,$//'`
705        fi
706        if test "$rettype" = "void"; then
707          return=
708        else
709          return="return "
710        fi
711        echo "$rettype"
712        echo "${main_classname}_${name} ($arglist)"
713        echo "{"
714        echo "  const struct ${main_classname}_implementation *vtable ="
715        echo "    ((struct ${main_classname}_representation_header *) (struct ${main_repclassalias} *) first_arg)->vtable;"
716        echo "  ${return}vtable->${name} ($args);"
717        echo "}"
718        echo
719      done
720    echo "#endif"
721  } > "$newfile"
722}
723
724# Generate the files in the source directory, not in the current directory.
725# This is needed because they need to be distributed, since not all platforms
726# have GNU 'sed' preinstalled.
727
728sed_butbase='s,[^/]*$,,'
729destdir=`echo "$source_impl_file" | sed -e "$sed_butbase"`
730
731# Generate the source.h file first. The Makefile.am snippets rely on the
732# fact that the other generated files have the same or a newer timestamp.
733#
734# Also, generate the source.c file last. The Makefile.am snippets don't know
735# about the other generated files; they assume that when the source.c file
736# is finished, this command is complete.
737
738new_source_header_file_base=`echo "$source_header_file_base" | sed -e 's,\.oo\.h$,.h,'`
739new_source_header_file="${destdir}$new_source_header_file_base"
740func_start_creation "$new_source_header_file"
741func_emit_source_h "$new_source_header_file" "$new_source_header_file_base" \
742  || func_fatal_error "failed"
743
744new_priv_header_file="${destdir}${main_classname}.priv.h"
745func_start_creation "$new_priv_header_file"
746func_emit_priv_h "$new_priv_header_file" \
747  || func_fatal_error "failed"
748
749new_vt_header_file="${destdir}${main_classname}.vt.h"
750func_start_creation "$new_vt_header_file"
751func_emit_vt_h "$new_vt_header_file" \
752  || func_fatal_error "failed"
753
754new_source_impl_file_base=`echo "$source_impl_file_base" | sed -e 's,\.oo\.c$,.c,'`
755new_source_impl_file="${destdir}$new_source_impl_file_base"
756func_start_creation "$new_source_impl_file"
757func_emit_source_c "$new_source_impl_file" "$new_source_impl_file_base" \
758  || func_fatal_error "failed"
759