From: Peter Breitenlohner <p...@mppmu.mpg.de> * t/objc-megademo.sh: New test, trying out a package using all of C, C++, Objective C and Objective C++ at the same time. * t/list-of-tests.mk: Add it.
Signed-off-by: Stefano Lattarini <stefano.lattar...@gmail.com> --- t/list-of-tests.mk | 1 + t/objc-megademo.sh | 364 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 365 insertions(+) create mode 100755 t/objc-megademo.sh diff --git a/t/list-of-tests.mk b/t/list-of-tests.mk index 8e33f38..4bfbb89 100644 --- a/t/list-of-tests.mk +++ b/t/list-of-tests.mk @@ -708,6 +708,7 @@ t/objc-deps.sh \ t/objcxx-basic.sh \ t/objcxx-minidemo.sh \ t/objcxx-deps.sh \ +t/objc-megademo.sh \ t/objext-pr10128.sh \ t/obsolete.sh \ t/oldvars.sh \ diff --git a/t/objc-megademo.sh b/t/objc-megademo.sh new file mode 100755 index 0000000..e01b91d --- /dev/null +++ b/t/objc-megademo.sh @@ -0,0 +1,364 @@ +#! /bin/sh +# Copyright (C) 2012 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +# Stress test on Objective C/C++. + +required=libtoolize +. ./defs || Exit 1 + +## Autotools Input Files. + +cat > configure.ac << 'END' +AC_INIT([play], [1.3], [bug-autom...@gnu.org]) + +dnl Support for Object C++ was introduced only in Autoconf 2.65. +AC_PREREQ([2.65]) +AC_CONFIG_SRCDIR([play.c]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_MACRO_DIR([m4]) + +AM_INIT_AUTOMAKE + +AM_PROG_AR +LT_INIT + +AC_PROG_CC +AC_PROG_CXX +AC_PROG_OBJC +AC_PROG_OBJCXX + +AC_LANG_PUSH([Objective C++]) + +AC_CACHE_CHECK([a good Objective C++ program], + [my_cv_good_prog], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <stdarg.h>]], + [[extern void foo(int i,...);]])], + [my_cv_good_prog=PASS], + [my_cv_good_prog=FAIL])]) + +AC_CACHE_CHECK([a bad Objective C++ program], + [my_cv_bad_prog], + [AC_LINK_IFELSE([AC_LANG_PROGRAM([], [[choke me]])], + [my_cv_bad_prog=XPASS], + [my_cv_bad_prog=XFAIL])]) + +AC_CACHE_CHECK([preprocess a good Objective C++ program], + [my_cv_good_preproc], + [AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#import <objc/Object.h>]], + [[[Object class]]])], + [my_cv_good_preproc=PASS], + [my_cv_good_preproc=FAIL])]) + +AC_CACHE_CHECK([preprocess a bad Objective C++ program], + [my_cv_bad_preproc], + [AC_PREPROC_IFELSE([AC_LANG_PROGRAM([[#import <junk/Object.h>]], + [[choke me]])], + [my_cv_bad_preproc=XPASS], + [my_cv_bad_preproc=XFAIL])]) + +AC_LANG_POP([Objective C++]) + +AC_SUBST([my_cv_good_prog]) +AC_SUBST([my_cv_bad_prog]) +AC_SUBST([my_cv_good_preproc]) +AC_SUBST([my_cv_bad_preproc]) + +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_FILES([Makefile]) + +AC_OUTPUT +END + +cat > Makefile.am << 'END' +bin_PROGRAMS = play +play_SOURCES = play.h play.c playxx.cxx playo.m playoxx.mm +play_LDADD = libfoo.la +play_LDFLAGS = -lobjc +lib_LTLIBRARIES = libfoo.la +libfoo_la_SOURCES = foo.h foo.c fooxx.cxx fooo.m foooxx.mm + +check-local: test-cv +.PHONY: test-cv +test-cv: + test @my_cv_good_prog@ = PASS + test @my_cv_bad_prog@ = XFAIL + test @my_cv_good_preproc@ = PASS + test @my_cv_bad_preproc@ = XFAIL +END + +## Run Autotools. + +libtoolize +if $ACLOCAL; then + : We have a modern enough autoconf, go ahead. +elif test $? -eq 63; then + skip_ "Object C++ support requires Autoconf 2.65 or later" +else + Exit 1 # Some other aclocal failure. +fi +$AUTOHEADER +$AUTOCONF +$AUTOMAKE --add-missing + +## Program Sources. + +cat > play.h << 'END' +#ifndef PLAY_H +#define PLAY_H + +#include "foo.h" + +#ifdef __cplusplus +extern "C" { +#endif + +void hello_cxx (void); +void hello_objc (void); +void hello_objcxx (void); + +#ifdef __OBJC__ +@interface Hello_ObjC +{ } ++ (void)display; +@end +#endif /* __OBJC__ */ + +#ifdef __cplusplus +} + +class Hello_CXX +{ + public: + Hello_CXX() { } + virtual ~Hello_CXX () { } + void hello_cxx (); +}; + +#ifdef __OBJC__ +@interface Hello_ObjCXX +{ } ++ (void)display; +@end + +class Hello_OBJCXX +{ + public: + Hello_OBJCXX () { } + virtual ~Hello_OBJCXX () { } + void hello_objcxx(); +}; +#endif /* __OBJC__ */ + +#endif /* __cplusplus */ + +#endif /* PLAY_H */ +END + +cat > play.c << 'END' +#include "play.h" +int main (void) +{ + printf ("[Hello C,"); + world_c (); + hello_cxx (); + hello_objc (); + hello_objcxx (); + return 0; +} +END + +cat > playxx.cxx << 'END' +#include "play.h" + +void hello_cxx(void) +{ + Hello_CXX *hello = new Hello_CXX; + hello->hello_cxx(); +} + +void Hello_CXX::hello_cxx() +{ + std::cout << "[Hello C++,"; + World_CXX *world = new World_CXX; + world->world_cxx(); +} +END + +cat > playo.m << 'END' +#import "play.h" + +void hello_objc (void) +{ + [Hello_ObjC display]; +} + +@implementation Hello_ObjC ++ (void)display +{ + printf ("[Hello ObjC,"); + [World_ObjC display]; +} +@end +END + +cat > playoxx.mm << 'END' +#import "play.h" + +// Calling: C -> C++ -> ObjC + +void hello_objcxx (void) +{ + Hello_OBJCXX *hello = new Hello_OBJCXX; + hello->hello_objcxx (); +} + +void Hello_OBJCXX::hello_objcxx () +{ + [Hello_ObjCXX display]; +} + +@implementation Hello_ObjCXX ++ (void)display +{ + std::cout << "[Hello ObjC++,"; + [World_ObjCXX display]; +} +@end +END + +## Library Sources. + +cat > foo.h << 'END' +#ifndef FOO_H +#define FOO_H + +#ifdef __cplusplus +#include <iostream> +extern "C" { +#else +#include <stdio.h> +#endif + +void world_c (void); +void world_objcxx (void); + +#ifdef __OBJC__ +@interface World_ObjC +{ } ++ (void)display; +@end +#endif /* __OBJC__ */ + +#ifdef __cplusplus +} + +class World_CXX +{ + public: + World_CXX() { } + virtual ~World_CXX () { } + void world_cxx (); +}; + +#ifdef __OBJC__ +class World_OBJCXX +{ + public: + World_OBJCXX () { } + virtual ~World_OBJCXX () { } + void world_objcxx (); +}; + +@interface World_ObjCXX +{ } ++ (void)display; +@end +#endif /* __OBJC__ */ + +#endif /* __cplusplus */ + +#endif /* FOO_H */ +END + +cat > foo.c << 'END' +#include "foo.h" + +void world_c (void) +{ + printf (" world C]\n"); +} +END + +cat > fooxx.cxx << 'END' +#include "foo.h" + +void World_CXX::world_cxx () +{ + std::cout << " world C++]" << "\n"; +} +END + +cat > fooo.m << 'END' +#import "foo.h" + +@implementation World_ObjC ++ (void)display +{ + printf (" world ObjC]\n"); +} +@end +END + +cat > foooxx.mm << 'END' +#import "foo.h" + +// Calling: ObjC -> C++ + +@implementation World_ObjCXX ++ (void)display +{ + World_OBJCXX *world = new World_OBJCXX; + world->world_objcxx (); +} +@end + +void World_OBJCXX::world_objcxx () +{ + std::cout << " world ObjC++]" << "\n"; +} +END + +## Configure and build. + +./configure +$MAKE + +if cross_compiling; then :; else + unindent > exp << 'END' + [Hello C, world C] + [Hello C++, world C++] + [Hello ObjC, world ObjC] + [Hello ObjC++, world ObjC++] +END + ./play > got || { cat got; Exit 1; } + cat exp + cat got + diff exp got +fi + +$MAKE distcheck + +: -- 1.7.9.5