diff options
Diffstat (limited to 'tools')
31 files changed, 679 insertions, 533 deletions
diff --git a/tools/defs_gen/docextract.py b/tools/defs_gen/docextract.py index 7bf49119..1b18f56c 100644 --- a/tools/defs_gen/docextract.py +++ b/tools/defs_gen/docextract.py @@ -12,12 +12,17 @@ import sys, os, re # option being specified. no_since = False +# Used to tell if extract() shall collect information from subdirectories. +# This variable is modified from docextract_to_xml based on the --no-recursion +# option being specified. +no_recursion = False + __all__ = ['extract'] class GtkDoc: def __init__(self): self.name = None - # The block type ('function', 'signal', property', 'enum') + # The block type ('function', 'signal', property', 'section', 'enum') self.block_type = '' self.params = [] self.annotations = [] @@ -65,6 +70,7 @@ function_name_pattern = re.compile(r'^([a-z]\w*)\s*:?(\s*\(.*\)\s*){0,2}\s*$') signal_name_pattern = re.compile(r'^([A-Z]\w+::[a-z0-9-]+)\s*:?(\s*\(.*\)\s*){0,2}\s*$') property_name_pattern = re.compile(r'^([A-Z]\w+:[a-z0-9-]+)\s*:?(\s*\(.*\)\s*){0,2}\s*$') enum_name_pattern = re.compile(r'^([A-Z]\w+)\s*:?(\s*\(.*\)\s*){0,2}\s*$') +section_name_pattern = re.compile(r'^(SECTION:[a-z0-9_-]+)\s*:?(\s*\(.*\)\s*){0,2}\s*$') return_pattern = re.compile(r'^@?(returns:|return\s+value:)(.*\n?)$', re.IGNORECASE) deprecated_pattern = re.compile(r'^(deprecated\s*:\s*.*\n?)$', re.IGNORECASE) rename_to_pattern = re.compile(r'^(rename\s+to)\s*:\s*(.*\n?)$', re.IGNORECASE) @@ -77,9 +83,13 @@ annotation_lead_pattern = re.compile(r'^\s*\(\s*(.*?)\s*\)\s*') # These patterns determine the identifier of the current comment block. They # are grouped in a list for easy determination of block identifiers (in -# skip_to_identifier). The function_name_pattern should be tested for last -# because it always matches signal and property identifiers. -identifier_patterns = [ signal_name_pattern, property_name_pattern, enum_name_pattern, function_name_pattern ] +# skip_to_identifier). +# The function_name_pattern shall be tested for last, because it always matches +# signal and property identifiers. +# The property_name_pattern shall be tested for after the section_name_pattern, +# because the property_name_pattern matches most section identifiers. +identifier_patterns = [ signal_name_pattern, section_name_pattern, + property_name_pattern, enum_name_pattern, function_name_pattern ] # This pattern is to match return sections that forget to have a colon (':') # after the initial 'Return' phrase. It is not included by default in the list @@ -195,6 +205,8 @@ def skip_to_identifier(fp, line, cur_doc): # Set the GtkDoc type. if pattern == signal_name_pattern: cur_doc.set_type('signal') + elif pattern == section_name_pattern: + cur_doc.set_type('section') elif pattern == property_name_pattern: cur_doc.set_type('property') elif pattern == enum_name_pattern: @@ -450,8 +462,9 @@ def parse_dir(dir, doc_dict): if file in ('.', '..'): continue path = os.path.join(dir, file) if os.path.isdir(path): - parse_dir(path, doc_dict) - if len(file) > 2 and (file[-2:] == '.c' or file[-2:] == '.h'): + if not no_recursion: + parse_dir(path, doc_dict) + elif len(file) > 2 and file[-2:] in ('.c', '.h'): sys.stderr.write("Processing " + path + '\n') parse_file(open(path, 'r'), doc_dict) @@ -504,6 +517,6 @@ def extract_tmpl(dirs, doc_dict=None): path = os.path.join(dir, file) if os.path.isdir(path): continue - if len(file) > 2 and file[-2:] == '.sgml': + if len(file) > 5 and file[-5:] == '.sgml': parse_tmpl(open(path, 'r'), doc_dict) return doc_dict diff --git a/tools/defs_gen/docextract_to_xml.py b/tools/defs_gen/docextract_to_xml.py index 4222250a..a3221350 100755 --- a/tools/defs_gen/docextract_to_xml.py +++ b/tools/defs_gen/docextract_to_xml.py @@ -14,8 +14,8 @@ import docextract def usage(): sys.stderr.write('usage: docextract_to_xml.py ' + - '[-s /src/dir | --source-dir=/src/dir] ' + - '[-a | --with-annotations] [-p | --with-properties] ' + + '[-s /src/dir | --source-dir=/src/dir] [-a | --with-annotations] ' + + '[-p | --with-properties] [-c | --with-sections] [-r | --no-recursion] ' + '[-n | --no-since] [-i | --no-signals ] [-e | --no-enums ]\n') sys.exit(1) @@ -61,10 +61,11 @@ def print_annotations(annotations): if __name__ == '__main__': try: - opts, args = getopt.getopt(sys.argv[1:], "d:s:o:apnie", + opts, args = getopt.getopt(sys.argv[1:], "d:s:o:apcrnie", ["source-dir=", "with-annotations", - "with-properties", "no-since", - "no-signals", "no-enums"]) + "with-properties", "with-sections", + "no-recursion", "no-since", + "no-signals", "no-enums"]) except getopt.error as e: sys.stderr.write('docextract_to_xml.py: %s\n' % e) usage() @@ -72,6 +73,7 @@ if __name__ == '__main__': with_annotations = False with_signals = True with_properties = False + with_sections = False with_enums = True for opt, arg in opts: if opt in ('-s', '--source-dir'): @@ -80,6 +82,10 @@ if __name__ == '__main__': with_annotations = True if opt in ('-p', '--with-properties'): with_properties = True + if opt in ('-c', '--with-sections'): + with_sections = True + if opt in ('-r', '--no-recursion'): + docextract.no_recursion = True if opt in ('-n', '--no-since'): docextract.no_since = True if opt in ('-i', '--no-signals'): @@ -99,8 +105,8 @@ if __name__ == '__main__': print("<root>") for name, value in sorted(docs.items()): - # Get the type of comment block ('function', 'signal' or - # 'property') (the value is a GtkDoc). + # Get the type of comment block ('function', 'signal', + # 'property', 'section' or 'enum') (the value is a GtkDoc). block_type = value.get_type() # Skip signals if the option was not specified. @@ -109,6 +115,18 @@ if __name__ == '__main__': # Likewise for properties. elif block_type == 'property' and not with_properties: continue + # Likewise for sections. + elif block_type == 'section': + if not with_sections: + continue + # Delete 'SECTION:' from the name. + # (It could easily be deleted by docextract.extract(), but then + # there would be a theoretical risk that a section name would + # be identical to a function name, when all kinds of elements + # are stored in the docs dictionary with their names as key.) + last_colon_pos = name.rfind(':') + if last_colon_pos >= 0: + name = name[last_colon_pos+1:] # Likewise for enums. elif block_type == 'enum' and not with_enums: continue @@ -133,9 +151,9 @@ if __name__ == '__main__': print("</parameters>") - if block_type != 'property' and block_type != 'enum': - # Show the return-type (also if not dealing with a property or - # enum): + if block_type not in ('property', 'section', 'enum'): + # Show the return-type if not dealing with a property, section + # or enum: if with_annotations: print("<return>") print("<return_description>" + escape_text(value.ret[0]) + \ diff --git a/tools/defs_gen/h2def.py b/tools/defs_gen/h2def.py index d0cd5a24..1f33771f 100755 --- a/tools/defs_gen/h2def.py +++ b/tools/defs_gen/h2def.py @@ -289,11 +289,11 @@ def clean_func(buf): pat = re.compile(r"""\\\n""", re.MULTILINE) buf = pat.sub('', buf) - # Preprocess directives + # Preprocessor directives pat = re.compile(r"""^[#].*?$""", re.MULTILINE) buf = pat.sub('', buf) - #typedefs, stucts, and enums + #typedefs, structs, and enums pat = re.compile(r"""^(typedef|struct|enum)(\s|.|\n)*?;\s*""", re.MULTILINE) buf = pat.sub('', buf) @@ -307,7 +307,7 @@ def clean_func(buf): buf = pat.sub('', buf) #strip *_DEPRECATED_IN_*_FOR (*): - pat = re.compile(r"""[A-Z]+_DEPRECATED_IN_[0-9]_([0-9]*)_FOR\s*\(\S*\)\S*""", re.MULTILINE) + pat = re.compile(r"""[A-Z]+_DEPRECATED_IN_[0-9]_([0-9]*)_FOR\s*\(.*\)\S*""", re.MULTILINE) buf = pat.sub('', buf) #strip *_DEPRECATED* diff --git a/tools/extra_defs_gen/generate_defs_gio.cc b/tools/extra_defs_gen/generate_defs_gio.cc index 213f52e8..602b59b4 100644 --- a/tools/extra_defs_gen/generate_defs_gio.cc +++ b/tools/extra_defs_gen/generate_defs_gio.cc @@ -93,6 +93,7 @@ int main(int, char**) << get_defs(G_TYPE_SETTINGS_BACKEND) << get_defs(G_TYPE_SIMPLE_ASYNC_RESULT) << get_defs(G_TYPE_SIMPLE_ACTION) + << get_defs(G_TYPE_SIMPLE_IO_STREAM) << get_defs(G_TYPE_SUBPROCESS) << get_defs(G_TYPE_SUBPROCESS_LAUNCHER) << get_defs(G_TYPE_THEMED_ICON) @@ -114,13 +115,18 @@ int main(int, char**) << get_defs(G_TYPE_SRV_TARGET) << get_defs(G_TYPE_RESOLVER) << get_defs(G_TYPE_NETWORK_ADDRESS) + << get_defs(G_TYPE_NETWORK_MONITOR) << get_defs(G_TYPE_NETWORK_SERVICE) << get_defs(G_TYPE_SETTINGS) + << get_defs(G_TYPE_SETTINGS_SCHEMA) + << get_defs(G_TYPE_SETTINGS_SCHEMA_KEY) + << get_defs(G_TYPE_SETTINGS_SCHEMA_SOURCE) << get_defs(G_TYPE_SIMPLE_PERMISSION) << get_defs(G_TYPE_SOCKET) << get_defs(G_TYPE_SOCKET_CLIENT) << get_defs(G_TYPE_SOCKET_CONNECTION) << get_defs(G_TYPE_TCP_CONNECTION) + << get_defs(G_TYPE_TCP_WRAPPER_CONNECTION) << get_defs(G_TYPE_TLS_BACKEND) << get_defs(G_TYPE_TLS_CERTIFICATE) << get_defs(G_TYPE_TLS_CLIENT_CONNECTION) diff --git a/tools/extra_defs_gen/generate_extra_defs.cc b/tools/extra_defs_gen/generate_extra_defs.cc index f209348c..bc8a78cf 100644 --- a/tools/extra_defs_gen/generate_extra_defs.cc +++ b/tools/extra_defs_gen/generate_extra_defs.cc @@ -69,7 +69,7 @@ std::string get_properties(GType gtype) std::string strObjectName = g_type_name(gtype); //Get the list of properties: - GParamSpec** ppParamSpec = 0; + GParamSpec** ppParamSpec = nullptr; guint iCount = 0; if(G_TYPE_IS_OBJECT(gtype)) { @@ -160,8 +160,8 @@ std::string get_signals(GType gtype, GTypeIsAPointerFunc is_a_pointer_func) std::string strResult; std::string strObjectName = g_type_name(gtype); - gpointer gclass_ref = 0; - gpointer ginterface_ref = 0; + gpointer gclass_ref = nullptr; + gpointer ginterface_ref = nullptr; if(G_TYPE_IS_OBJECT(gtype)) gclass_ref = g_type_class_ref(gtype); //Ensures that class_init() is called. @@ -220,16 +220,16 @@ std::string get_signals(GType gtype, GTypeIsAPointerFunc is_a_pointer_func) { strResult += " (parameters\n"; - for(unsigned i = 0; i < signalQuery.n_params; i++) + for(unsigned j = 0; j < signalQuery.n_params; j++) { - GType typeParamMangled = pParameters[i]; + GType typeParamMangled = pParameters[j]; //Parameter name: //We can't get the real parameter name from the GObject system. It's not registered with g_signal_new(). - gchar* pchNum = g_strdup_printf("%d", i); + gchar* pchNum = g_strdup_printf("%d", j); std::string strParamName = "p" + std::string(pchNum); g_free(pchNum); - pchNum = 0; + pchNum = nullptr; //Just like above, for the return type: std::string strTypeName = get_type_name_signal( typeParamMangled & ~G_SIGNAL_TYPE_STATIC_SCOPE, is_a_pointer_func ); //The type is mangled with a flag. Hacky. diff --git a/tools/gen_scripts/gio_generate_docs.sh b/tools/gen_scripts/gio_generate_docs.sh index 7c815021..81fc2e8a 100755 --- a/tools/gen_scripts/gio_generate_docs.sh +++ b/tools/gen_scripts/gio_generate_docs.sh @@ -13,6 +13,7 @@ PREFIX="$JHBUILD_SOURCES" ROOT_DIR="$(dirname "$0")/../.." OUT_DIR="$ROOT_DIR/gio/src" +PARAMS="--with-properties --no-recursion" for dir in "$PREFIX"/glib/gio; do PARAMS="$PARAMS -s $dir" done diff --git a/tools/gen_scripts/gio_generate_extra_defs.sh b/tools/gen_scripts/gio_generate_extra_defs.sh index 4e428bdb..b4330d71 100755 --- a/tools/gen_scripts/gio_generate_extra_defs.sh +++ b/tools/gen_scripts/gio_generate_extra_defs.sh @@ -3,9 +3,36 @@ # This script assumes that it resides in the tools/gen_scripts directory and # the defs file will be placed in gio/src. +# To update the gio_signals.defs file: +# 1. ./gio_generate_extra_defs.sh +# Generates gio/src/gio_signals.defs.orig and gio/src/gio_signals.defs. +# If any hunks from the patch file fail to apply, apply them manually to the +# gio_signals.defs file, if required. +# 2. Optional: Remove gio/src/gio_signals.defs.orig. + +# To update the gio_signals.defs file and the patch file: +# 1. Like step 1 when updating only the gio_signals.defs file. +# 2. Apply new patches manually to the gio_signals.defs file. +# 3. ./gio_generate_extra_defs.sh --make-patch +# 4. Like step 2 when updating only the gio_signals.defs file. + ROOT_DIR="$(dirname "$0")/../.." GEN_DIR="$ROOT_DIR/tools/extra_defs_gen" OUT_DIR="$ROOT_DIR/gio/src" +OUT_FILE=gio_signals.defs +OUT_DIR_FILE="$OUT_DIR"/$OUT_FILE -"$GEN_DIR"/generate_defs_gio > "$OUT_DIR"/gio_signals.defs -patch "$OUT_DIR"/gio_signals.defs "$OUT_DIR"/gio_signals.defs.patch +if [ $# -eq 0 ] +then + "$GEN_DIR"/generate_defs_gio > "$OUT_DIR_FILE" + # patch version 2.7.5 does not like directory names. + cd "$OUT_DIR" + PATCH_OPTIONS="--backup --version-control=simple --suffix=.orig" + patch $PATCH_OPTIONS $OUT_FILE $OUT_FILE.patch +elif [ "$1" = "--make-patch" ] +then + diff --unified=5 "$OUT_DIR_FILE".orig "$OUT_DIR_FILE" > "$OUT_DIR_FILE".patch +else + echo "Usage: $0 [--make-patch]" + exit 1 +fi diff --git a/tools/gen_scripts/glib_generate_docs.sh b/tools/gen_scripts/glib_generate_docs.sh index a77c04a7..92a942ff 100755 --- a/tools/gen_scripts/glib_generate_docs.sh +++ b/tools/gen_scripts/glib_generate_docs.sh @@ -13,7 +13,8 @@ PREFIX="$JHBUILD_SOURCES" ROOT_DIR="$(dirname "$0")/../.." OUT_DIR="$ROOT_DIR/glib/src" -for dir in "$PREFIX"/glib/{glib,gmodule,gobject,gthread}; do +PARAMS="--with-properties --no-recursion" +for dir in "$PREFIX"/glib/{glib,glib/deprecated,gmodule,gobject,gthread}; do PARAMS="$PARAMS -s $dir" done diff --git a/tools/generate_wrap_init.pl.in b/tools/generate_wrap_init.pl.in index 1381dfe3..f49fe2f2 100644 --- a/tools/generate_wrap_init.pl.in +++ b/tools/generate_wrap_init.pl.in @@ -66,7 +66,7 @@ while ($ARGV[0] =~ /^-/) { if ($ARGV[0] =~ /--namespace=(\S+)/) { - push(@namespace_whole, $1); + push(@namespace_whole, split('::', $1)); if($parent_dir eq "") { $parent_dir = lc($1) . "mm"; } diff --git a/tools/gmmproc.in b/tools/gmmproc.in index 8b576539..e9295031 100644 --- a/tools/gmmproc.in +++ b/tools/gmmproc.in @@ -123,22 +123,27 @@ if ($main::unwrapped) # Don't take non-readable construct-only properties into account. my @properties = grep { $$_{entity_type} eq 'property' and ( $$_{readable} or not $$_{construct_only} ) } @unwrapped; + # Don't print a name of any kind between the first and second colon on a line, + # if there is any chance that "error" is (part of) the name. + # MS Visual Studio will misunderstand. + # See https://mail.gnome.org/archives/gtkmm-list/2014-November/msg00044.html + local $, = "\ngmmproc: "; local $\ = "\n"; if (@methods) { - print STDERR ("gmmproc: $main::source: Unwrapped functions:", + print STDERR ("gmmproc, $main::source: Unwrapped functions:", map($$_{c_name}, @methods)); } if (@properties) { - print STDERR ("gmmproc: $main::source: Unwrapped properties:", + print STDERR ("gmmproc, $main::source: Unwrapped properties:", map($$_{class} . '::' . $$_{name}, @properties)); } if (@signals) { - print STDERR ("gmmproc: $main::source: Unwrapped signals:", + print STDERR ("gmmproc, $main::source: Unwrapped signals:", map($$_{class} . '::' . $$_{name}, @signals)); } } diff --git a/tools/m4/class_boxedtype.m4 b/tools/m4/class_boxedtype.m4 index 1a9b731f..1afa53a5 100644 --- a/tools/m4/class_boxedtype.m4 +++ b/tools/m4/class_boxedtype.m4 @@ -135,6 +135,20 @@ __CPPNAME__::__CPPNAME__`'(const __CPPNAME__& other) gobject_ ((other.gobject_) ? __BOXEDTYPE_FUNC_COPY`'(other.gobject_) : 0) {} +__CPPNAME__::__CPPNAME__`'(__CPPNAME__&& other) +: + gobject_(other.gobject_) +{ + other.gobject_ = nullptr; +} + +__CPPNAME__& __CPPNAME__::operator=(__CPPNAME__`'&& other) +{ + __CPPNAME__ temp (other); + swap(temp); + return *this; +} + ifdef(`__BOOL_CUSTOM_CTOR_CAST__',,`dnl else __CPPNAME__::__CPPNAME__`'(__CNAME__* gobject, bool make_a_copy) : @@ -208,6 +222,9 @@ ifdef(`__BOOL_CUSTOM_CTOR_CAST__',,`dnl else __CPPNAME__`'(const __CPPNAME__& other); __CPPNAME__& operator=(const __CPPNAME__& other); + __CPPNAME__`'(__CPPNAME__&& other); + __CPPNAME__& operator=(__CPPNAME__&& other); + _IMPORT(SECTION_DTOR_DOCUMENTATION) ~__CPPNAME__`'(); diff --git a/tools/m4/class_gobject.m4 b/tools/m4/class_gobject.m4 index f097f180..edd0c5b5 100644 --- a/tools/m4/class_gobject.m4 +++ b/tools/m4/class_gobject.m4 @@ -115,7 +115,10 @@ ifdef(`__BOOL_NO_WRAP_FUNCTION__',`dnl _STRUCT_PROTOTYPE() ')dnl +#ifndef DOXYGEN_SHOULD_SKIP_THIS __NAMESPACE_BEGIN__ class __CPPNAME__`'_Class; __NAMESPACE_END__ +#endif //DOXYGEN_SHOULD_SKIP_THIS + _SECTION(SECTION_HEADER3) ifdef(`__BOOL_NO_WRAP_FUNCTION__',`dnl @@ -245,10 +248,9 @@ private:')dnl endif friend class __CPPNAME__`'_Class; static CppClassType `'__BASE__`'_class_; -private: // noncopyable - __CPPNAME__`'(const __CPPNAME__&); - __CPPNAME__& operator=(const __CPPNAME__&); + __CPPNAME__`'(const __CPPNAME__&) = delete; + __CPPNAME__& operator=(const __CPPNAME__&) = delete; protected: explicit __CPPNAME__`'(const Glib::ConstructParams& construct_params); diff --git a/tools/m4/class_interface.m4 b/tools/m4/class_interface.m4 index fe4add6b..7226a32b 100644 --- a/tools/m4/class_interface.m4 +++ b/tools/m4/class_interface.m4 @@ -92,11 +92,11 @@ const Glib::Interface_Class& __CPPNAME__`'_Class::init() void __CPPNAME__`'_Class::iface_init_function(void* g_iface, void*) { - BaseClassType *const klass = static_cast<BaseClassType*>(g_iface); + const auto klass = static_cast<BaseClassType*>(g_iface); //This is just to avoid an "unused variable" warning when there are no vfuncs or signal handlers to connect. //This is a temporary fix until I find out why I can not seem to derive a GtkFileChooser interface. murrayc - g_assert(klass != 0); + g_assert(klass != nullptr); _IMPORT(SECTION_PCC_CLASS_INIT_VFUNCS) @@ -117,7 +117,10 @@ define(`_END_CLASS_INTERFACE',` _SECTION(SECTION_HEADER1) _STRUCT_PROTOTYPE() +#ifndef DOXYGEN_SHOULD_SKIP_THIS __NAMESPACE_BEGIN__ class __CPPNAME__`'_Class; __NAMESPACE_END__ +#endif // DOXYGEN_SHOULD_SKIP_THIS + _SECTION(SECTION_HEADER3) ifdef(`__BOOL_NO_WRAP_FUNCTION__',`dnl @@ -231,14 +234,14 @@ public: typedef __CNAME__ BaseObjectType; typedef __CCLASS__ BaseClassType; + // noncopyable + __CPPNAME__`'(const __CPPNAME__&) = delete; + __CPPNAME__& operator=(const __CPPNAME__&) = delete; + private: friend class __CPPNAME__`'_Class; static CppClassType `'__BASE__`'_class_; - // noncopyable - __CPPNAME__`'(const __CPPNAME__&); - __CPPNAME__& operator=(const __CPPNAME__&); - #endif /* DOXYGEN_SHOULD_SKIP_THIS */ protected: /** diff --git a/tools/m4/class_opaque_copyable.m4 b/tools/m4/class_opaque_copyable.m4 index 9e53649e..f3fe4bd6 100644 --- a/tools/m4/class_opaque_copyable.m4 +++ b/tools/m4/class_opaque_copyable.m4 @@ -113,7 +113,7 @@ __CPPNAME__::__CPPNAME__`'(__CNAME__* castitem, bool make_a_copy /* = false */) if(castitem) gobject_ = __OPAQUE_FUNC_COPY`'(castitem); else - gobject_ = 0; + gobject_ = nullptr; } } ') @@ -122,7 +122,7 @@ ifelse(__OPAQUE_FUNC_COPY,NONE,`dnl ',`dnl else __CPPNAME__& __CPPNAME__::operator=(const __CPPNAME__`'& src) { - __CNAME__ *const new_gobject = (src.gobject_) ? __OPAQUE_FUNC_COPY`'(src.gobject_) : 0; + const auto new_gobject = (src.gobject_) ? __OPAQUE_FUNC_COPY`'(src.gobject_) : 0; if(gobject_) __OPAQUE_FUNC_FREE`'(gobject_); diff --git a/tools/m4/class_opaque_refcounted.m4 b/tools/m4/class_opaque_refcounted.m4 index c9242baf..847ac3be 100644 --- a/tools/m4/class_opaque_refcounted.m4 +++ b/tools/m4/class_opaque_refcounted.m4 @@ -116,7 +116,7 @@ const __CNAME__* __CPPNAME__::gobj() const __CNAME__* __CPPNAME__::gobj_copy() const { // See the comment at the top of this file, if you want to know why the cast works. - __CNAME__ *const gobject = reinterpret_cast<__CNAME__*>(const_cast<__CPPNAME__*>(this)); + const auto gobject = reinterpret_cast<__CNAME__*>(const_cast<__CPPNAME__*>(this)); __OPAQUE_FUNC_REF`'(gobject); return gobject; } @@ -171,11 +171,11 @@ protected: __CPPNAME__`'(); void operator delete(void*, std::size_t); -private: // noncopyable - __CPPNAME__`'(const __CPPNAME__&); - __CPPNAME__& operator=(const __CPPNAME__&); + __CPPNAME__`'(const __CPPNAME__&) = delete; + __CPPNAME__& operator=(const __CPPNAME__&) = delete; +private: _IMPORT(SECTION_CLASS2) ') diff --git a/tools/m4/class_shared.m4 b/tools/m4/class_shared.m4 index 4175b575..3442ad15 100644 --- a/tools/m4/class_shared.m4 +++ b/tools/m4/class_shared.m4 @@ -190,7 +190,7 @@ ifdef(`__BOOL_DO_NOT_DERIVE_GTYPE__',`dnl void __CPPNAME__`'_Class::class_init_function(void* g_class, void* class_data) { - BaseClassType *const klass = static_cast<BaseClassType*>(g_class); + const auto klass = static_cast<BaseClassType*>(g_class); CppClassParent::class_init_function(klass, class_data); _IMPORT(SECTION_PCC_CLASS_INIT_VFUNCS) diff --git a/tools/m4/convert_gio.m4 b/tools/m4/convert_gio.m4 index 3d170668..8219d4d0 100644 --- a/tools/m4/convert_gio.m4 +++ b/tools/m4/convert_gio.m4 @@ -32,6 +32,8 @@ _CONV_ENUM(G,FileType) _CONV_ENUM(G,MountMountFlags) _CONV_ENUM(G,MountOperationResult) _CONV_ENUM(G,MountUnmountFlags) +_CONV_ENUM(G,NetworkConnectivity) +_CONV_ENUM(G,NotificationPriority) _CONV_ENUM(G,OutputStreamSpliceFlags) _CONV_ENUM(G,PasswordSave) _CONV_ENUM(G,ResolverRecordType) @@ -240,6 +242,10 @@ _CONVERSION(`PasswordSave',`GPasswordSave',`($2)$3') #MountOperation #_CONVERSION(`GAskPasswordFlags',`AskPasswordFlags',`($2)$3') +# NetworkMonitor +_CONVERSION(`GNetworkMonitor*',`Glib::RefPtr<NetworkMonitor>',`Glib::wrap($3)') + + # Notification _CONVERSION(`GNotification*',`Glib::RefPtr<Notification>',`Glib::wrap($3)') _CONVERSION(`const Glib::RefPtr<Notification>&',`GNotification*',__CONVERT_CONST_REFPTR_TO_P) @@ -262,6 +268,14 @@ _CONVERSION(`GSettings*',`Glib::RefPtr<Settings>',`Glib::wrap($3)') _CONVERSION(`const Glib::StringArrayHandle&',`const gchar*-const*',`($3).data()') _CONVERSION(`const Glib::RefPtr<SettingsBackend>&',`GSettingsBackend*',__CONVERT_REFPTR_TO_P) +_CONVERSION(`GSettingsSchemaKey*',`Glib::RefPtr<SettingsSchemaKey>',`Glib::wrap($3)') +_CONVERSION(`GSettingsSchemaKey*',`Glib::RefPtr<const SettingsSchemaKey>',`Glib::wrap($3)') + +_CONVERSION(`GSettingsSchema*',`Glib::RefPtr<SettingsSchema>',`Glib::wrap($3)') +_CONVERSION(`GSettingsSchema*',`Glib::RefPtr<const SettingsSchema>',`Glib::wrap($3)') + +_CONVERSION(`GSettingsSchemaSource*',`Glib::RefPtr<SettingsSchemaSource>',`Glib::wrap($3)') + #Socket _CONVERSION(`const Glib::RefPtr<Socket>&',`GSocket*',__CONVERT_CONST_REFPTR_TO_P) diff --git a/tools/m4/enum.m4 b/tools/m4/enum.m4 index 3ac338b2..dc988925 100644 --- a/tools/m4/enum.m4 +++ b/tools/m4/enum.m4 @@ -1,5 +1,6 @@ dnl dnl _ENUM(cpp_type, c_type, value_suffix, `element_list', `flags', `optional_refdoc_comment', 'get_type_function_name') +dnl $1 $2 $3 $4 $5 $6 $7 dnl m4_define(`_ENUM',`dnl _PUSH() @@ -20,6 +21,7 @@ m4_define(`__DOCGROUP_'__MODULE_CANONICAL__`_ENUMS__')dnl dnl dnl /** $6 + * * @ingroup __MODULE_CANONICAL__`'Enums m4_ifelse($3,Flags,`dnl * @par Bitwise operators: diff --git a/tools/m4/filelist.am b/tools/m4/filelist.am index 04d0b01b..55fedb2b 100644 --- a/tools/m4/filelist.am +++ b/tools/m4/filelist.am @@ -25,7 +25,6 @@ files_codegen_m4 = \ initialize_gio.m4 \ initialize_glib.m4 \ initialize_glibmm.m4 \ - list.m4 \ member.m4 \ method.m4 \ property.m4 \ diff --git a/tools/m4/gerror.m4 b/tools/m4/gerror.m4 index a8b8437e..e48aef6e 100644 --- a/tools/m4/gerror.m4 +++ b/tools/m4/gerror.m4 @@ -15,7 +15,7 @@ _POP() class __CPPNAME__ : public Glib::Error { public: - $6 + /** $6 */ enum Code { diff --git a/tools/m4/list.m4 b/tools/m4/list.m4 deleted file mode 100644 index 954beb19..00000000 --- a/tools/m4/list.m4 +++ /dev/null @@ -1,232 +0,0 @@ -_PUSH() - -dnl -dnl These variables affect the generation of the list -dnl -define(GP_LIST_HELPER_NAMESPACE,`define(`__LIST_NAMESPACE__',$1)') -define(GP_LIST_ELEM,`define(`__LISTELEM__',`$*')') -define(GP_LIST_ITER,`define(`__LISTITER__',`$*')') -define(GP_LIST_NOINSERT,`define(`__LISTEO__')') - -dnl -dnl GP_LIST(ListName, ParentCppType, ParentCType, ChildCppType, FieldNameC) -dnl -dnl In the .ccg file, you'll need to implement: -dnl iterator insert(iterator position, element_type& e); -dnl -dnl Fieldname assumed to be children if not specified -define(GP_LIST,` -_PUSH() - -define(`__LISTNAME__',$1) -define(`__LISTPARENT__',$2) -define(`__LISTPARENT_G__',$3) -define(`__LISTTYPE__',$4) -define(`__LISTELEM__',const Element) -define(`__LISTITER__',Glib::List_Iterator< __LISTTYPE__ >) -define(`__LIST_NAMESPACE__',$2_Helpers) -#define(`__LISTFIELD__',ifelse($5,,children,$5)) -define(`__LISTFIELD__',$5) - -_SECTION(SECTION_USR) -') - -dnl -dnl GP_LIST_END() -dnl -dnl Closes a list -define(GP_LIST_END,`dnl -_POP() - -class __LISTNAME__ : public Glib::HelperList< __LISTTYPE__, __LISTELEM__, __LISTITER__ > -{ -public: - __LISTNAME__`'(); - explicit __LISTNAME__`'(__LISTPARENT_G__* gparent); - __LISTNAME__`'(const __LISTNAME__& src); - virtual ~__LISTNAME__`'() {} - - __LISTNAME__& operator=(const __LISTNAME__& src); - - typedef Glib::HelperList< __LISTTYPE__, __LISTELEM__, __LISTITER__ > type_base; - - __LISTPARENT_G__* gparent(); - const __LISTPARENT_G__* gparent() const; - - virtual GList*& glist() const; // front of list - - virtual void erase(iterator start, iterator stop); - virtual iterator erase(iterator); //Implented as custom or by LIST_CONTAINER_REMOVE - virtual void remove(const_reference); //Implented as custom or by LIST_CONTAINER_REMOVE - - /// This is order n. (use at own risk) - reference operator[](size_type l) const; - -ifdef(`__LISTEO__',`dnl -protected: - //Hide these because it's read-only: - iterator insert(iterator position, element_type& e); - - inline void pop_front(); - inline void pop_back(); -,`dnl -public: - iterator insert(iterator position, element_type& e); //custom-implemented. - - template <class InputIterator> - inline void insert(iterator position, InputIterator first, InputIterator last) - { - for(;first != last; ++first) - position = insert(position, *first); - } - - inline void push_front(element_type& e) - { insert(begin(), e); } - inline void push_back(element_type& e) - { insert(end(), e); } -')dnl - -_IMPORT(SECTION_USR) -}; - -_PUSH(SECTION_CC) - -namespace __LIST_NAMESPACE__ -{ - -__LISTNAME__::__LISTNAME__`'() -{} - -__LISTNAME__::__LISTNAME__`'(__LISTPARENT_G__* gparent) -: type_base((GObject*)gparent) -{} - -__LISTNAME__::__LISTNAME__`'(const __LISTNAME__& src) -: - type_base(src) -{} - -__LISTNAME__& __LISTNAME__::operator=(const __LISTNAME__& src) -{ - type_base::operator=(src); - return *this; -} - -ifelse(__LISTFIELD__,CUSTOM,`dnl -',`dnl else -GList*& __LISTNAME__::glist() const -{ - return ((__LISTPARENT_G__*)gparent_)->__LISTFIELD__; -} -')dnl endif - -void __LISTNAME__::erase(iterator start, iterator stop) -{ - type_base::erase(start, stop); -} - -__LISTPARENT_G__* __LISTNAME__::gparent() -{ - return (__LISTPARENT_G__*)type_base::gparent(); -} - -const __LISTPARENT_G__* __LISTNAME__::gparent() const -{ - return (__LISTPARENT_G__*)type_base::gparent(); -} - -__LISTNAME__::reference __LISTNAME__::operator[](size_type l) const -{ - return type_base::operator[](l); -} - -} /* namespace __LIST_NAMESPACE__ */ - -undefine(`__LISTNAME__')dnl -undefine(`__LISTTYPE__')dnl -undefine(`__LISTPARENT__')dnl -undefine(`__LISTELEM__')dnl -undefine(`__LISTFIELD__')dnl -_POP() -') - -dnl -dnl GP_LIST_FIND(access_method) -dnl -dnl Defines find(containertype) and find(Widget&) -dnl access_method is the name of method returning a Widget* -define(GP_LIST_FIND,` - iterator find(const_reference c); - iterator find(Widget&); -_PUSH(SECTION_CC) - -namespace __LIST_NAMESPACE__ -{ - -__LISTNAME__::iterator __LISTNAME__::find(const_reference w) -{ - iterator i = begin(); - while (i != end() && (i->ifelse($1,,,$1()->)gobj() != w.ifelse($1,,,$1()->)gobj())) - ++i; - return i; -} - -__LISTNAME__::iterator __LISTNAME__::find(Widget& w) -{ - iterator i = begin(); - while (i != end() && ((GtkWidget*)i->ifelse($1,,,$1()->)gobj() != w.gobj())) - ++i; - return i; -} - -} /* namespace __LIST_NAMESPACE__ */ - -_POP() -') - -dnl -dnl GP_LIST_CONTAINER_REMOVE(access_method) -dnl -dnl Implements remove(const_reference), erase(iterator) -dnl and defines remove(Widget&) -dnl (assumes that the widget uses gtk+ container methods). -dnl access_method is the name of the method returning a Widget* -define(GP_LIST_CONTAINER_REMOVE,` -virtual void remove(Widget& w); //Implented as custom or by LIST_CONTAINER_REMOVE -_PUSH(SECTION_CC) - -namespace __LIST_NAMESPACE__ -{ - -void __LISTNAME__::remove(const_reference child) -{ - gtk_container_remove(GTK_CONTAINER(gparent_), - (GtkWidget*)(child.ifelse($1,,,$1()->)gobj())); -} - -void __LISTNAME__::remove(Widget& widget) -{ - gtk_container_remove(GTK_CONTAINER(gparent_), (GtkWidget*)(widget.gobj())); -} - -__LISTNAME__::iterator __LISTNAME__::erase(iterator position) -{ - //Check that it is a valid iterator, to a real item: - if ( !position.node_|| (position == end()) ) - return end(); - - //Get an iterator the the next item, to return: - iterator next = position; - next++; - - //Use GTK+ C function to remove it, by providing the GtkWidget*: - gtk_container_remove( GTK_CONTAINER(gparent_), (GtkWidget*)(position->ifelse($1,,,$1()->)gobj()) ); - return next; -} - -} /* namespace __LIST_NAMESPACE__ */ - -_POP() -') - -_POP()dnl diff --git a/tools/m4/method.m4 b/tools/m4/method.m4 index 3c48b3e1..3ca4de6e 100644 --- a/tools/m4/method.m4 +++ b/tools/m4/method.m4 @@ -1,22 +1,24 @@ -dnl $Id$ - dnl dnl dnl Code generation sections for making a method. dnl dnl - dnl dnl method -dnl $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18 $19 $20 $21 -dnl _METHOD(cppname,cname,cpprettype,crettype,arglist,cdeclarations,cargs,cinitializations,const,refreturn,errthrow,deprecated,constversion,ifdef,arglist_without_types,out_param,out_param_cpptype,slot_type,slot_name,no_slot_copy,wrap_line) +dnl $1 $2 $3 $4 $5 $6 $7 $8 +dnl _METHOD(cppname,cname,cpprettype,crettype,arglist,cdeclarations,cargs,cinitializations, +dnl $9 $10 $11 $12 $13 $14 $15 +dnl const,refreturn,errthrow,deprecated,constversion,arglist_without_types,ifdef, +dnl $16 $17 $18 $19 $20 $21 +dnl out_param,out_param_cpptype,slot_type,slot_name,no_slot_copy,wrap_line) define(`_METHOD',`dnl _PUSH(SECTION_CC) -ifelse(`$12',,,`_DEPRECATE_IFDEF_START -')dnl ifelse(`$15',,,`#ifdef $15' )dnl +ifelse(`$12',,,`_DEPRECATE_IFDEF_START`'dnl The expansion of _DEPRECATE_IFDEF_START ends with a newline +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +')dnl $3 __CPPNAME__::$1`'($5)ifelse(`$9',1,` const') { ifelse(`$13',,dnl @@ -26,10 +28,10 @@ dnl If a slot type has been specified insert a slot copy declaration. dnl See if the slot should or should not be copied `ifelse(`$20',,dnl ` // Create a copy of the slot. - $18* slot_copy = new $18($19); ',dnl + auto slot_copy = new $18($19); ',dnl dnl ` // Use the original slot (not a copy). - $18* slot_copy = const_cast<$18*>(&$19);') + auto slot_copy = const_cast<$18*>(&$19);') ')`'dnl dnl Insert the declarations for C output parameters @@ -59,17 +61,17 @@ ifelse(`$8',,,`$8 ')dnl ')',dnl End if a C++ output parameter is specified. dnl If is errthrow or refreturn -`ifelse(`$11',,,` GError* gerror = 0; +`ifelse(`$11',,,` GError* gerror = nullptr; ')dnl dnl If a slot type has been specified insert a slot copy declaration. ifelse(`$18',,,dnl dnl See if the slot should or should not be copied `ifelse(`$20',,dnl ` // Create a copy of the slot. - $18* slot_copy = new $18($19); ',dnl + auto slot_copy = new $18($19); ',dnl dnl ` // Use the original slot (not a copy). - $18* slot_copy = const_cast<$18*>(&$19);') + auto slot_copy = const_cast<$18*>(&$19);') ')`'dnl dnl Insert the declarations for C output parameters @@ -99,24 +101,27 @@ ifelse(`$3',void,,` return retvalue; ',` return const_cast<__CPPNAME__*>(this)->$1($14); ')dnl } - -ifelse(`$15',,,` -#endif // $15 -')dnl -ifelse(`$12',,,`_DEPRECATE_IFDEF_END -')dnl +ifelse(`$12',,,`G_GNUC_END_IGNORE_DEPRECATIONS +_DEPRECATE_IFDEF_END')`'dnl The expansion of _DEPRECATE_IFDEF_END ends with a newline +ifelse(`$15',,,`#endif // $15 +') _POP()') dnl dnl static method -dnl $1 $2 $3 $4 $5 $6 $7 $8 $9 $10 $11 $12 $13 $14 $15 $16 $17 $18 -dnl _STATIC_METHOD(cppname,cname,cpprettype,crettype,arglist,cdeclarations,cargs,cinitializations,refreturn,errthrow,deprecated,ifdef,out_param,out_param_type,slot_type,slot_name,no_slot_copy,wrap_line) +dnl $1 $2 $3 $4 $5 $6 $7 +dnl _STATIC_METHOD(cppname,cname,cpprettype,crettype,arglist,cdeclarations,cargs, +dnl $8 $9 $10 $11 $12 $13 +dnl cinitializations,refreturn,errthrow,deprecated,ifdef,out_param, +dnl $14 $15 $16 $17 $18 +dnl out_param_type,slot_type,slot_name,no_slot_copy,wrap_line) define(`_STATIC_METHOD',`dnl _PUSH(SECTION_CC) -ifelse(`$11',,,`_DEPRECATE_IFDEF_START -')dnl ifelse(`$12',,,`#ifdef $12' )dnl +ifelse(`$11',,,`_DEPRECATE_IFDEF_START`'dnl The expansion of _DEPRECATE_IFDEF_START ends with a newline +G_GNUC_BEGIN_IGNORE_DEPRECATIONS +')dnl $3 __CPPNAME__::$1($5) { ifelse(`$9'`$10',,dnl @@ -125,10 +130,10 @@ ifelse(`$15',,,dnl dnl See if the slot should or should not be copied `ifelse(`$17',,dnl ` // Create a copy of the slot. - $15* slot_copy = new $15($16); ',dnl + auto slot_copy = new $15($16); ',dnl dnl ` // Use the original slot (not a copy). - $15* slot_copy = const_cast<$15*>(&$16);') + auto slot_copy = const_cast<$15*>(&$16);') ')`'dnl dnl Insert declarations for C the output parameters @@ -150,16 +155,16 @@ dnl Return the value if it was stored and if the method returns something ifelse(`$3',void,,`ifelse(`$6',,,` return retval; ')')dnl ',dnl End if a C++ output parameter is specified. -`ifelse(`$10',,,` GError* gerror = 0;') +`ifelse(`$10',,,` GError* gerror = nullptr;') dnl If a slot type has been specified insert a slot copy declaration. ifelse(`$15',,,dnl dnl See if the slot should or should not be copied `ifelse(`$17',,dnl ` // Create a copy of the slot. - $15* slot_copy = new $15($16); ',dnl + auto slot_copy = new $15($16); ',dnl dnl ` // Use the original slot (not a copy). - $15* slot_copy = const_cast<$15*>(&$16);') + auto slot_copy = const_cast<$15*>(&$16);') ')`'dnl dnl Insert the declarations for the C output parameters @@ -185,10 +190,8 @@ ifelse(`$3',void,,` return retvalue; ')dnl ')dnl } - -ifelse(`$12',,,` -#endif // $12 -')dnl -ifelse(`$11',,,`_DEPRECATE_IFDEF_END +ifelse(`$11',,,`G_GNUC_END_IGNORE_DEPRECATIONS +_DEPRECATE_IFDEF_END')`'dnl The expansion of _DEPRECATE_IFDEF_END ends with a newline +ifelse(`$12',,,`#endif // $12 ') _POP()') diff --git a/tools/m4/property.m4 b/tools/m4/property.m4 index 119f21cb..1709affa 100644 --- a/tools/m4/property.m4 +++ b/tools/m4/property.m4 @@ -1,5 +1,3 @@ -dnl $Id$ - dnl dnl dnl Code generation sections for properties @@ -17,25 +15,20 @@ dnl Put spaces around the template parameter if necessary. pushdef(`__PROXY_TYPE__',`dnl Glib::PropertyProxy$4< _QUOTE($3) >'dnl )dnl -#ifdef GLIBMM_PROPERTIES_ENABLED /** $6 * - * You rarely need to use properties because there are get_ and set_ methods for almost all of them. * @return A PropertyProxy$4 that allows you to dnl ifelse($4,_ReadOnly,get,`ifelse($4,_WriteOnly,set,get or set)') the value of the property, * or receive notification when the value of the property changes. */ __PROXY_TYPE__ property_$2`'() ifelse($4,_ReadOnly, const,); -#endif //#GLIBMM_PROPERTIES_ENABLED _PUSH(SECTION_CC_PROPERTYPROXIES) ifelse(`$5',,,`_DEPRECATE_IFDEF_START ')dnl -#ifdef GLIBMM_PROPERTIES_ENABLED __PROXY_TYPE__ __CPPNAME__::property_$2`'() ifelse($4,_ReadOnly, const,) { return __PROXY_TYPE__`'(this, "$1"); } -#endif //GLIBMM_PROPERTIES_ENABLED ifelse(`$5',,,`_DEPRECATE_IFDEF_END ')dnl diff --git a/tools/m4/signal.m4 b/tools/m4/signal.m4 index d84838d9..d85f93c7 100644 --- a/tools/m4/signal.m4 +++ b/tools/m4/signal.m4 @@ -1,4 +1,3 @@ - # # --------------------------- Signal Decl---------------------------- # @@ -14,15 +13,29 @@ dnl $8 = `custom_c_callback (boolean)', dnl $9 = `deprecated' (boolean), dnl $10 = `refdoc_comment', dnl $11 = ifdef, -dnl $12 = exceptionHandler) +dnl $12 = exceptionHandler, +dnl $13 = detail_name, +dnl $14 = two_signal_methods (boolean)) define(`_SIGNAL_PROXY',` ifelse(`$11',,,`#ifdef $11' )dnl ifelse(`$9',,,`_DEPRECATE_IFDEF_START ')dnl +ifelse($13,,`dnl no detail_name +$10 + Glib::SignalProxy`'_NUM($6)< $5`'_COMMA_PREFIX($6) > signal_$4`'(); +',dnl detail_name +$14,0,`dnl +$10 + Glib::SignalProxyDetailed`'_NUM($6)< $5`'_COMMA_PREFIX($6) > signal_$4`'(const Glib::ustring& $13 = Glib::ustring()); +',`dnl detail_name and two_signal_methods $10 Glib::SignalProxy`'_NUM($6)< $5`'_COMMA_PREFIX($6) > signal_$4`'(); + +$10 + Glib::SignalProxyDetailed`'_NUM($6)< $5`'_COMMA_PREFIX($6) > signal_$4`'(const Glib::ustring& $13); +')dnl end detail_name ifelse(`$9',,,`_DEPRECATE_IFDEF_END ')dnl ifelse(`$11',,,`#endif // $11 @@ -54,25 +67,22 @@ static $2 __CPPNAME__`'_signal_$4_callback`'(__CNAME__`'* self, _COMMA_SUFFIX($3 using namespace __NAMESPACE__; typedef sigc::slot< $5`'_COMMA_PREFIX($6) > SlotType; - __CPPNAME__* obj = dynamic_cast<__CPPNAME__*>(Glib::ObjectBase::_get_current_wrapper((GObject*) self)); + auto obj = dynamic_cast<__CPPNAME__*>(Glib::ObjectBase::_get_current_wrapper((GObject*) self)); // Do not try to call a signal on a disassociated wrapper. if(obj) { - #ifdef GLIBMM_EXCEPTIONS_ENABLED try { - #endif //GLIBMM_EXCEPTIONS_ENABLED - if(sigc::slot_base *const slot = Glib::SignalProxyNormal::data_to_slot`'(data)) + if(const auto slot = Glib::SignalProxyNormal::data_to_slot`'(data)) ifelse(`$2',void,`dnl (*static_cast<SlotType*>(slot))($7); ',`dnl else return _CONVERT($5,$2,`(*static_cast<SlotType*>(slot))($7)'); ')dnl endif - #ifdef GLIBMM_EXCEPTIONS_ENABLED } catch(...) { -ifelse($15, `', `dnl +ifelse($12, `', `dnl Glib::exception_handlers_invoke`'(); ', `dnl try @@ -85,7 +95,6 @@ ifelse($15, `', `dnl } ')dnl } - #endif //GLIBMM_EXCEPTIONS_ENABLED } ifelse($2,void,,`dnl else @@ -100,17 +109,14 @@ static $2 __CPPNAME__`'_signal_$4_notify_callback`'(__CNAME__`'* self, _COMMA_SU using namespace __NAMESPACE__; typedef sigc::slot< void`'_COMMA_PREFIX($6) > SlotType; - __CPPNAME__* obj = dynamic_cast<__CPPNAME__*>(Glib::ObjectBase::_get_current_wrapper((GObject*) self)); + auto obj = dynamic_cast<__CPPNAME__*>(Glib::ObjectBase::_get_current_wrapper((GObject*) self)); // Do not try to call a signal on a disassociated wrapper. if(obj) { - #ifdef GLIBMM_EXCEPTIONS_ENABLED try { - #endif //GLIBMM_EXCEPTIONS_ENABLED - if(sigc::slot_base *const slot = Glib::SignalProxyNormal::data_to_slot`'(data)) + if(const auto slot = Glib::SignalProxyNormal::data_to_slot`'(data)) (*static_cast<SlotType*>(slot))($7); - #ifdef GLIBMM_EXCEPTIONS_ENABLED } catch(...) { @@ -127,7 +133,6 @@ ifelse($12, `', `dnl } ')dnl } - #endif //GLIBMM_EXCEPTIONS_ENABLED } typedef $2 RType; @@ -155,10 +160,28 @@ ifelse(`$11',,,`#ifdef $11' )dnl ifelse(`$9',,,`_DEPRECATE_IFDEF_START ')dnl +ifelse($13,,`dnl no detail_name +Glib::SignalProxy`'_NUM($6)< $5`'_COMMA_PREFIX($6) > __CPPNAME__::signal_$4`'() +{ + return Glib::SignalProxy`'_NUM($6)< $5`'_COMMA_PREFIX($6) >(this, &__CPPNAME__`'_signal_$4_info); +} +',dnl detail_name +$14,0,`dnl +Glib::SignalProxyDetailed`'_NUM($6)< $5`'_COMMA_PREFIX($6) > __CPPNAME__::signal_$4`'(const Glib::ustring& $13) +{ + return Glib::SignalProxyDetailed`'_NUM($6)< $5`'_COMMA_PREFIX($6) >(this, &__CPPNAME__`'_signal_$4_info, $13); +} +',`dnl detail_name and two_signal_methods Glib::SignalProxy`'_NUM($6)< $5`'_COMMA_PREFIX($6) > __CPPNAME__::signal_$4`'() { return Glib::SignalProxy`'_NUM($6)< $5`'_COMMA_PREFIX($6) >(this, &__CPPNAME__`'_signal_$4_info); } + +Glib::SignalProxyDetailed`'_NUM($6)< $5`'_COMMA_PREFIX($6) > __CPPNAME__::signal_$4`'(const Glib::ustring& $13) +{ + return Glib::SignalProxyDetailed`'_NUM($6)< $5`'_COMMA_PREFIX($6) >(this, &__CPPNAME__`'_signal_$4_info, $13); +} +')dnl end detail_name ifelse(`$9',,,`_DEPRECATE_IFDEF_END ')dnl ifelse(`$11',,,`#endif // $11 @@ -212,7 +235,7 @@ $4 __CPPNAME__`'_Class::$2_callback`'($5) dnl First, do a simple cast to ObjectBase. We will have to do a dynamic_cast dnl eventually, but it is not necessary to check whether we need to call dnl the vfunc. - Glib::ObjectBase *const obj_base = static_cast<Glib::ObjectBase*>( + const auto obj_base = static_cast<Glib::ObjectBase*>( Glib::ObjectBase::_get_current_wrapper`'((GObject*)$8)); _IMPORT(SECTION_CHECK) @@ -225,13 +248,11 @@ _IMPORT(SECTION_CHECK) { dnl We need to do a dynamic cast to get the real object type, to call the dnl C++ vfunc on it. - CppObjectType *const obj = dynamic_cast<CppObjectType* const>(obj_base); + const auto obj = dynamic_cast<CppObjectType* const>(obj_base); if(obj) // This can be NULL during destruction. { - #ifdef GLIBMM_EXCEPTIONS_ENABLED try // Trap C++ exceptions which would normally be lost because this is a C callback. { - #endif //GLIBMM_EXCEPTIONS_ENABLED // Call the virtual member method, which derived classes might override. ifelse($4,void,`dnl obj->on_$1`'($7); @@ -239,16 +260,15 @@ ifelse($4,void,`dnl ',`dnl return _CONVERT($3,$4,`obj->on_$1`'($7)'); ')dnl - #ifdef GLIBMM_EXCEPTIONS_ENABLED } catch(...) { -ifelse($15, `', `dnl +ifelse($11, `', `dnl Glib::exception_handlers_invoke`'(); ', `dnl try { - return _CONVERT($3, $4, `obj->$15`'()'); + return _CONVERT($3, $4, `obj->$11`'()'); } catch(...) { @@ -256,17 +276,16 @@ ifelse($15, `', `dnl } ')dnl } - #endif //GLIBMM_EXCEPTIONS_ENABLED } } - BaseClassType *const base = static_cast<BaseClassType*>( + const auto base = static_cast<BaseClassType*>( ifdef(`__BOOL_IS_INTERFACE__',`dnl _IFACE_PARENT_FROM_OBJECT($8)dnl ',`dnl _PARENT_GCLASS_FROM_OBJECT($8)dnl ') ); -dnl g_assert(base != 0); +dnl g_assert(base != nullptr); // Call the original underlying C function: if(base && base->$2) @@ -306,13 +325,13 @@ ifelse(`$9',,,`#ifdef $9' )dnl $3 __NAMESPACE__::__CPPNAME__::on_$1`'($5) { - BaseClassType *const base = static_cast<BaseClassType*>( + const auto base = static_cast<BaseClassType*>( ifdef(`__BOOL_IS_INTERFACE__',`dnl _IFACE_PARENT_FROM_OBJECT(gobject_)dnl ',`dnl _PARENT_GCLASS_FROM_OBJECT(gobject_)dnl ') ); -dnl g_assert(base != 0); +dnl g_assert(base != nullptr); if(base && base->$2) ifelse($3,void,`dnl diff --git a/tools/m4/vfunc.m4 b/tools/m4/vfunc.m4 index beac4c86..fd2aeb82 100644 --- a/tools/m4/vfunc.m4 +++ b/tools/m4/vfunc.m4 @@ -20,28 +20,30 @@ _POP()') dnl $1 $2 $3 $4 dnl _VFUNC_PCC(cppname,gtkname,cpprettype,crettype, -dnl $5 $6 $7 $8 $9 $10 $11 -dnl `<cargs and names>',`<cnames>',`<cpparg names>',firstarg, refreturn_ctype, ifdef, errthrow, -dnl $12 $13 $14 $15 -dnl slot_type, c_data_param_name, return_value, exception_handler) +dnl $5 $6 $7 $8 +dnl `<cargs and names>',`<cnames>',`<cpparg names>',firstarg, +dnl $9 $10 $11 $12 +dnl refreturn_ctype, keep_return, ifdef, errthrow, +dnl $13 $14 $15 $16 +dnl slot_type, c_data_param_name, return_value, exception_handler) dnl dnl Note: _get_current_wrapper_inline() could be used throughout for performance instead of _get_current_wrapper(), dnl and is_derived_() instead of is_derived_(), dnl but it is not yet clear whether that would be a worthwhile performance optimization. define(`_VFUNC_PCC',`dnl _PUSH(SECTION_PCC_VFUNCS) -ifelse(`$10',,,`#ifdef $10' +ifelse(`$11',,,`#ifdef $11' )dnl $4 __CPPNAME__`'_Class::$2_vfunc_callback`'($5) { -ifelse(`$13',,,dnl -` const $12* slot = static_cast<$12*>($13); +ifelse(`$14',,,dnl +` const auto slot = static_cast<$13*>($14); ')dnl dnl First, do a simple cast to ObjectBase. We will have to do a dynamic_cast dnl eventually, but it is not necessary to check whether we need to call dnl the vfunc. - Glib::ObjectBase *const obj_base = static_cast<Glib::ObjectBase*>( + const auto obj_base = static_cast<Glib::ObjectBase*>( Glib::ObjectBase::_get_current_wrapper`'((GObject*)$8)); _IMPORT(SECTION_CHECK) @@ -54,37 +56,50 @@ _IMPORT(SECTION_CHECK) { dnl We need to do a dynamic cast to get the real object type, to call the dnl C++ vfunc on it. - CppObjectType *const obj = dynamic_cast<CppObjectType* const>(obj_base); + const auto obj = dynamic_cast<CppObjectType* const>(obj_base); if(obj) // This can be NULL during destruction. { - #ifdef GLIBMM_EXCEPTIONS_ENABLED try // Trap C++ exceptions which would normally be lost because this is a C callback. { - #endif //GLIBMM_EXCEPTIONS_ENABLED // Call the virtual member method, which derived classes might override. ifelse($4,void,`dnl obj->$1`'($7); return; -',`dnl +',`dnl not void ifelse($9,refreturn_ctype,`dnl Assume Glib::unwrap_copy() is correct if refreturn_ctype is requested. return Glib::unwrap_copy`'(`obj->$1'($7)); -',`dnl +',`dnl not refreturn_ctype +ifelse($10,keep_return,`dnl + static auto quark_return_value = g_quark_from_static_string("__NAMESPACE__::__CPPNAME__::$1"); + + auto return_value = static_cast<$3*>(g_object_get_qdata(obj_base->gobj(), quark_return_value)); + if (!return_value) + { + return_value = new $3`'(); + g_object_set_qdata_full(obj_base->gobj(), quark_return_value, return_value, + &Glib::destroy_notify_delete<$3>); + } + // Keep a copy of the return value. The caller is not expected + // to free the object that the returned pointer points to. + *return_value = obj->$1`'($7); + return _CONVERT($3,$4,`(*return_value)'); +',`dnl not keep_return return _CONVERT($3,$4,`obj->$1`'($7)'); -')dnl -')dnl - #ifdef GLIBMM_EXCEPTIONS_ENABLED +')dnl end keep_return +')dnl end refreturn_ctype +')dnl end void } catch(...) { -ifelse($15, `', `dnl +ifelse($16, `', `dnl Glib::exception_handlers_invoke`'(); ', `dnl try { ifelse($9,refreturn_ctype,`dnl - return Glib::unwrap_copy`'(obj->$15`'()); + return Glib::unwrap_copy`'(obj->$16`'()); ', `dnl - return _CONVERT($3, $4, `obj->$15`'()'); + return _CONVERT($3, $4, `obj->$16`'()'); ')dnl } catch(...) @@ -93,7 +108,6 @@ ifelse($9,refreturn_ctype,`dnl } ')dnl } - #endif //GLIBMM_EXCEPTIONS_ENABLED } } @@ -103,13 +117,13 @@ ifdef(`__BOOL_IS_INTERFACE__',`dnl ',`dnl _PARENT_GCLASS_FROM_OBJECT($8)dnl ') ); -dnl g_assert(base != 0); +dnl g_assert(base != nullptr); // Call the original underlying C function: if(base && base->$2) { ifelse($4,void,,`$4 retval = ')(*base->$2)`'($6); -ifelse($11,errthrow,`dnl +ifelse($12,errthrow,`dnl if(*error) ::Glib::Error::throw_exception(*error); ')dnl @@ -118,15 +132,15 @@ ifelse($4,void,,` return retval; } ifelse($4,void,,`dnl -ifelse(`$14', `',`dnl +ifelse(`$15', `',`dnl typedef $4 RType; return RType`'(); ',`dnl - return _CONVERT($3,$4,`$14'); + return _CONVERT($3,$4,`$15'); ')dnl ')dnl } -ifelse(`$10',,,`#endif // $10 +ifelse(`$11',,,`#endif // $11 ')dnl _POP()') @@ -144,24 +158,24 @@ ifelse(`$11',,,dnl dnl See if the slot should or should not be copied `ifelse(`$13',,dnl ` // Create a copy of the slot. - $11* slot_copy = new $11($12); ',dnl + auto slot_copy = new $11($12); ',dnl dnl ` // Use the original slot (not a copy). - $11* slot_copy = const_cast<$11*>(&$12);') + auto slot_copy = const_cast<$11*>(&$12);') ')dnl - BaseClassType *const base = static_cast<BaseClassType*>( + const auto base = static_cast<BaseClassType*>( ifdef(`__BOOL_IS_INTERFACE__',`dnl _IFACE_PARENT_FROM_OBJECT(gobject_)dnl ',`dnl _PARENT_GCLASS_FROM_OBJECT(gobject_)dnl ') ); -dnl g_assert(base != 0); +dnl g_assert(base != nullptr); if(base && base->$2) { ifelse($10,errthrow,`dnl - GError* gerror = 0; + GError* gerror = nullptr; ')dnl ifelse($3,void,`dnl (*base->$2)`'(ifelse(`$7',1,const_cast<__CNAME__*>(gobj()),gobj())`'_COMMA_PREFIX($6)); @@ -209,4 +223,3 @@ ifelse(`$5',,,`#endif // $5 ')dnl _POP()') - diff --git a/tools/pm/DocsParser.pm b/tools/pm/DocsParser.pm index c771fc3c..8dae9c14 100644 --- a/tools/pm/DocsParser.pm +++ b/tools/pm/DocsParser.pm @@ -25,7 +25,7 @@ use XML::Parser; use strict; use warnings; -# use Util; +use Util; use Function; use GtkDefs; use Object; @@ -112,18 +112,19 @@ sub parse_on_start($$%) $tag = lc($tag); - if($tag eq "function" or $tag eq "signal" or $tag eq "enum") + if($tag eq "function" or $tag eq "signal" or $tag eq "property" or $tag eq "enum") { if(defined $DocsParser::objCurrentFunction) { $objParser->xpcroak( - "\nClose a function, signal or enum tag before you open another one."); + "\nClose a function, signal, property or enum tag before you open another one."); } my $functionName = $attr{name}; - # Change signal name from Class::a-signal-name to Class::a_signal_name. - $functionName =~ s/-/_/g if($tag eq "signal"); + # Change signal name from Class::a-signal-name to Class::a_signal_name + # and property name from Class:a-property-name to Class:a_property_name + $functionName =~ s/-/_/g if ($tag eq "signal" or $tag eq "property"); #Reuse existing Function, if it exists: #(For instance, if this is the override parse) @@ -195,7 +196,7 @@ sub parse_on_end($$) $tag = lc($tag); - if($tag eq "function" or $tag eq "signal" or $tag eq "enum") + if($tag eq "function" or $tag eq "signal" or $tag eq "property" or $tag eq "enum") { # Store the Function structure in the array: my $functionName = $$DocsParser::objCurrentFunction{name}; @@ -233,14 +234,15 @@ sub parse_on_cdata($$) } } -sub lookup_enum_documentation($$$) +sub lookup_enum_documentation($$$$) { - my ($c_enum_name, $cpp_enum_name, $ref_flags) = @_; + my ($c_enum_name, $cpp_enum_name, $indent, $ref_flags) = @_; my @subst_in = []; my @subst_out = []; + my $newin = ""; - # Get the substitutions. + # Get the substitutions, and recognize some flags too. foreach(@$ref_flags) { if(/^\s*s#([^#]+)#([^#]*)#\s*$/) @@ -248,6 +250,10 @@ sub lookup_enum_documentation($$$) push(@subst_in, $1); push(@subst_out, $2); } + elsif(/^\s*newin(.*)/) #If newin is at the start. + { + $newin = string_unquote(string_trim($1)); + } } my $objFunction = $DocsParser::hasharrayFunctions{$c_enum_name}; @@ -285,19 +291,23 @@ sub lookup_enum_documentation($$$) $param =~ s/([a-zA-Z0-9]*(_[a-zA-Z0-9]+)*)_?/$1/g; if(length($desc) > 0) { - $desc =~ s/\n/ /g; - $desc =~ s/ $//; - $desc =~ s/^\s+//; # Chop off leading whitespace + # Chop off leading and trailing whitespace. + $desc =~ s/^\s+//; + $desc =~ s/\s+$//; $desc .= '.' unless($desc =~ /(?:^|\.)$/); - $docs .= "\@var $cpp_enum_name ${param}\n \u${desc}\n\n"; # \u = Convert next char to uppercase + $docs .= "\@var $cpp_enum_name ${param}\n\u${desc}\n\n"; # \u = Convert next char to uppercase } } - # Append the enum description docs. - $docs .= "\@enum $cpp_enum_name\n"; - $docs .= $$objFunction{description}; + # Replace @newin in the enum description, but don't in the element descriptions. + my $description = "\@enum $cpp_enum_name\n"; + $description .= $$objFunction{description}; + DocsParser::convert_docs_to_cpp($objFunction, \$description); + DocsParser::replace_or_add_newin(\$description, $newin); + # Append the enum description docs. DocsParser::convert_docs_to_cpp($objFunction, \$docs); + $docs .= "\n\n$description"; DocsParser::add_m4_quotes(\$docs); # Escape the space after "i.e." or "e.g." in the brief description. @@ -305,20 +315,21 @@ sub lookup_enum_documentation($$$) remove_example_code($c_enum_name, \$docs); - # Convert to Doxygen-style comment. - $docs =~ s/\n/\n \* /g; - $docs = "\/\*\* " . $docs; + # Add indentation and an asterisk on all lines except the first. + # $docs does not contain leading "/**" and trailing "*/". + $docs =~ s/\n/\n${indent}\* /g; return $docs; } -# $strCommentBlock lookup_documentation($strFunctionName, $deprecation_docs, $objCppfunc) +# $strCommentBlock lookup_documentation($strFunctionName, $deprecation_docs, $newin, $objCppfunc) # The final objCppfunc parameter is optional. If passed, it is used to # decide if the final C parameter should be omitted if the C++ method -# has a slot parameter. -sub lookup_documentation($$;$) +# has a slot parameter. It is also used for converting C parameter names to +# C++ parameter names in the documentation, if they differ. +sub lookup_documentation($$$;$) { - my ($functionName, $deprecation_docs, $objCppfunc) = @_; + my ($functionName, $deprecation_docs, $newin, $objCppfunc) = @_; my $objFunction = $DocsParser::hasharrayFunctions{$functionName}; if(!$objFunction) @@ -335,18 +346,30 @@ sub lookup_documentation($$;$) } DocsParser::convert_docs_to_cpp($objFunction, \$text); + DocsParser::replace_or_add_newin(\$text, $newin); # A blank line, marking the end of a paragraph, is needed after @newin. # Most @newins are at the end of a function description. $text .= "\n"; - #Add note about deprecation if we have specified that in our _WRAP_METHOD() call: + # Add note about deprecation if we have specified that in our _WRAP_METHOD(), + # _WRAP_SIGNAL(), _WRAP_PROPERTY() or _WRAP_CHILD_PROPERTY() call: if($deprecation_docs ne "") { $text .= "\n\@deprecated $deprecation_docs\n"; } - DocsParser::append_parameter_docs($objFunction, \$text, $objCppfunc); + my %param_name_mappings = DocsParser::append_parameter_docs($objFunction, \$text, $objCppfunc); DocsParser::append_return_docs($objFunction, \$text); + + # Convert C parameter names to C++ parameter names where they differ. + foreach my $key (keys %param_name_mappings) + { + $text =~ s/\@(param|a) $key\b/\@$1 $param_name_mappings{$key}/g; + } + + # Remove leading and trailing white space. + $text = string_trim($text); + DocsParser::add_m4_quotes(\$text); # Escape the space after "i.e." or "e.g." in the brief description. @@ -375,7 +398,8 @@ sub remove_example_code($$) ($$text =~ s"<programlisting>.*?</programlisting>"\n[C example ellipted]"sg); $example_removals += ($$text =~ s"\|\[.*?]\|"\n[C example ellipted]"sg); - print STDERR "gmmproc: $main::source: $obj_name: Example code discarded.\n" + # See "MS Visual Studio" comment in gmmproc.in. + print STDERR "gmmproc, $main::source, $obj_name: Example code discarded.\n" if ($example_removals); } @@ -396,51 +420,143 @@ sub add_m4_quotes($) # The final objCppfunc is optional. If passed, it is used to determine # if the final C parameter should be omitted if the C++ method has a -# slot parameter. +# slot parameter. It is also used for converting C parameter names to +# C++ parameter names in the documentation, if they differ. sub append_parameter_docs($$;$) { my ($obj_function, $text, $objCppfunc) = @_; - my @param_names = @{$$obj_function{param_names}}; + my @docs_param_names = @{$$obj_function{param_names}}; my $param_descriptions = \$$obj_function{param_descriptions}; - - # Strip first parameter if this is a method. my $defs_method = GtkDefs::lookup_method_dont_mark($$obj_function{name}); - # the second alternative is for use with method-mappings meaning: - # this function is mapped into this Gtk::class - shift(@param_names) if(($defs_method && $$defs_method{class} ne "") || - ($$obj_function{mapped_class} ne "")); + my @c_param_names = $defs_method ? @{$$defs_method{param_names}} : @docs_param_names; + + # The information in + # $obj_function comes from the docs.xml file, + # $objCppfunc comes from _WRAP_METHOD() or _WRAP_SIGNAL() in the .hg file, + # $defs_method comes from the methods.defs file. + + # Ideally @docs_param_names and @c_param_names are identical. + # In the real world the parameters in the C documentation are sometimes not + # listed in the same order as the arguments in the C function declaration. + # We try to handle that case to some extent. If no argument name is misspelt + # in either the docs or the C function declaration, it usually succeeds for + # methods, but not for signals. For signals there is no C function declaration + # to compare with. If the docs of some method or signal get badly distorted + # due to imperfections in the C docs, and it's difficult to get the C docs + # corrected, correct docs can be added to the docs_override.xml file. + + # Skip first param if this is a signal. + if ($$obj_function{name} =~ /\w+::/) + { + shift(@docs_param_names); + shift(@c_param_names); + } + # Skip first parameter if this is a non-static method. + elsif (defined($objCppfunc)) + { + if (!$$objCppfunc{static}) + { + shift(@docs_param_names); + shift(@c_param_names); + } + } + # The second alternative is for use with method-mappings meaning: + # this function is mapped into this Gtk::class. + elsif (($defs_method && $$defs_method{class} ne "") || + $$obj_function{mapped_class} ne "") + { + shift(@docs_param_names); + shift(@c_param_names); + } - # Also skip first param if this is a signal. - shift(@param_names) if ($$obj_function{name} =~ /\w+::/); # Skip the last param if there is a slot because it would be a # gpointer user_data parameter. - pop(@param_names) if (defined($objCppfunc) && $$objCppfunc{slot_name}); + if (defined($objCppfunc) && $$objCppfunc{slot_name}) + { + pop(@docs_param_names); + pop(@c_param_names); + } - foreach my $param (@param_names) + # Skip the last param if it's an error output param. + if (scalar @docs_param_names && $docs_param_names[-1] eq "error") + { + pop(@docs_param_names); + pop(@c_param_names); + } + + my $cpp_param_names; + my $param_mappings; + my $out_param_index = 1000; # No method has that many arguments, hopefully. + if (defined($objCppfunc)) { - if ($param ne "error" ) #We wrap GErrors as exceptions, so ignore these. + $cpp_param_names = $$objCppfunc{param_names}; + $param_mappings = $$objCppfunc{param_mappings}; # C name -> C++ index + if (exists $$param_mappings{OUT}) { - my $desc = $$param_descriptions->{$param}; + $out_param_index = $$param_mappings{OUT}; + } + } + my %param_name_mappings; # C name -> C++ name - # Deal with callback parameters converting the docs to a slot - # compatible format. - if ($param eq "callback") + for (my $i = 0; $i < @docs_param_names; ++$i) + { + my $param = $docs_param_names[$i]; + my $desc = $$param_descriptions->{$param}; + + if (defined($objCppfunc)) + { + # If the C++ name is not equal to the C name, mark that the name + # shall be changed in the documentation. + my $cpp_name = $param; + if (exists $$param_mappings{$param}) { - $param = "slot"; - $$text =~ s/\@a callback/\@a slot/g; + # Rename and/or reorder declaration ({c_name} or {.}) in _WRAP_*(). + $cpp_name = $$cpp_param_names[$$param_mappings{$param}]; } - - $param =~ s/([a-zA-Z0-9]*(_[a-zA-Z0-9]+)*)_?/$1/g; - DocsParser::convert_docs_to_cpp($obj_function, \$desc); - if(length($desc) > 0) + elsif ($c_param_names[$i] eq $param) + { + # Location in docs coincides with location in C declaration. + my $cpp_index = $i; + $cpp_index++ if ($i >= $out_param_index); + $cpp_name = $$cpp_param_names[$cpp_index]; + } + else + { + # Search for the param in the C declaration. + for (my $j = 0; $j < @c_param_names; ++$j) + { + if ($c_param_names[$j] eq $param) + { + my $cpp_index = $j; + $cpp_index++ if ($j >= $out_param_index); + $cpp_name = $$cpp_param_names[$cpp_index]; + last; + } + } + } + if ($cpp_name ne $param) { - $desc .= '.' unless($desc =~ /(?:^|\.)$/); - $$text .= "\n\@param ${param} \u${desc}"; + $param_name_mappings{$param} = $cpp_name; } } + elsif ($param eq "callback") + { + # Deal with callback parameters converting the docs to a slot + # compatible format. + $param_name_mappings{$param} = "slot"; + } + + $param =~ s/([a-zA-Z0-9]*(_[a-zA-Z0-9]+)*)_?/$1/g; + DocsParser::convert_docs_to_cpp($obj_function, \$desc); + if(length($desc) > 0) + { + $desc .= '.' unless($desc =~ /(?:^|\.)$/); + $$text .= "\n\@param ${param} \u${desc}"; + } } + return %param_name_mappings; } @@ -513,14 +629,20 @@ sub convert_tags_to_doxygen($) s"<variablelist>\n?(.*?)</variablelist>\n?"&DocsParser::convert_variablelist($1)"esg; # Use our Doxygen @newin alias. - # If Since is not followed by a colon, substitute @newin only if it's - # in a sentence of its own at the end of the string. - s/\bSince:\s*(\d+)\.(\d+)\.(\d+)\b\.?/\@newin{$1,$2,$3}/g; - s/\bSince:\s*(\d+)\.(\d+)\b\.?/\@newin{$1,$2}/g; - s/(\.\s+)Since\s+(\d+)\.(\d+)\.(\d+)\.?$/$1\@newin{$2,$3,$4}/; - s/(\.\s+)Since\s+(\d+)\.(\d+)\.?$/$1\@newin{$2,$3}/; - - s"\b->\b"->"g; + # Accept "Since" with or without a following colon. + # Require the Since clause to be + # - at the end of the string, + # - at the end of a line and followed by a blank line, or + # - followed by "Deprecated". + # If none of these requirements is met, "Since" may be embedded inside + # a function description, referring to only a part of the description. + # See e.g. g_date_time_format() and gdk_cursor_new_from_pixbuf(). + # Doxygen assumes that @newin is followed by a paragraph that describes + # what is new, but we don't use it that way. + my $first_part = '\bSince[:\h]\h*(\d+)\.(\d+)'; # \h == [\t ] (horizontal whitespace) + my $last_part = '\.?(\s*$|\h*\n\h*\n|\s+Deprecated)'; + s/$first_part\.(\d+)$last_part/\@newin{$1,$2,$3}$4/g; + s/$first_part$last_part/\@newin{$1,$2}$3/g; # Doxygen is too dumb to handle — s"—" \@htmlonly—\@endhtmlonly "g; @@ -540,6 +662,21 @@ sub convert_tags_to_doxygen($) } } +# void replace_or_add_newin(\$text, $newin) +# If $newin is not empty, replace the version numbers in an existing @newin +# Doxygen alias, or add one if there is none. +sub replace_or_add_newin($$) +{ + my ($text, $newin) = @_; + + return if ($newin eq ""); + + if (!($$text =~ s/\@newin\{[\d,]+\}/\@newin{$newin}/)) + { + $$text .= "\n\n\@newin{$newin}"; + } +} + # Convert <simplelist> tags to a list of newline-separated elements. sub convert_simplelist($) { @@ -691,7 +828,7 @@ sub lookup_object_of_method($$) } else { - print "DocsParser.pm:lookup_object_of_method(): Warning: GtkDefs::lookup_object() failed for object name=" . $object . ", function name=" . $name . "\n"; + print "DocsParser.pm: lookup_object_of_method(): Warning: GtkDefs::lookup_object() failed for object name=" . $object . ", function name=" . $name . "\n"; print " This may be a missing define-object in a *.defs file.\n" } } diff --git a/tools/pm/Enum.pm b/tools/pm/Enum.pm index 8d0ce774..61840771 100644 --- a/tools/pm/Enum.pm +++ b/tools/pm/Enum.pm @@ -300,7 +300,7 @@ sub build_element_list($$$$) push(@subst_in, $1); push(@subst_out, $2); } - elsif($_ !~ /^\s*$/) + elsif($_ !~ /^\s*(?:newin.*)?$/) # newin or only white space { return undef; } diff --git a/tools/pm/Output.pm b/tools/pm/Output.pm index 05e0fa16..587d06ba 100644 --- a/tools/pm/Output.pm +++ b/tools/pm/Output.pm @@ -72,15 +72,16 @@ sub output_wrap_failed($$$) { my ($self, $cname, $error) = @_; + # See "MS Visual Studio" comment in gmmproc.in. my $str = sprintf("//gtkmmproc error: %s : %s", $cname, $error); - print STDERR "Output.pm: $main::source: $cname : $error\n"; + print STDERR "Output.pm, $main::source, $cname : $error\n"; $self->append($str); } sub error { my $format=shift @_; - printf STDERR "Output.pm: $main::source: $format",@_; + printf STDERR "Output.pm, $main::source: $format",@_; } sub ifdef($$) @@ -204,6 +205,9 @@ sub output_wrap_vfunc_cc($$$$$$$$) my $refreturn_ctype = ""; $refreturn_ctype = "refreturn_ctype" if($$objCFunc{rettype_needs_ref}); + my $keep_return = ""; + $keep_return = "keep_return" if($$objCppfunc{keep_return}); + # Get the conversions. my $conversions = convert_args_c_to_cpp($objCFunc, $objCppfunc, $line_num); @@ -211,7 +215,7 @@ sub output_wrap_vfunc_cc($$$$$$$$) my $returnValue = $$objCppfunc{return_value}; my $exceptionHandler = $$objCppfunc{exception_handler}; - my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s,%s)dnl\n", + my $str = sprintf("_VFUNC_PCC(%s,%s,%s,%s,\`%s\',\`%s\',\`%s\',%s,%s,%s,%s,%s,%s,%s,%s,%s)dnl\n", $$objCppfunc{name}, $cname, $$objCppfunc{rettype}, @@ -221,6 +225,7 @@ sub output_wrap_vfunc_cc($$$$$$$$) $conversions, ${$objCFunc->get_param_names()}[0], $refreturn_ctype, + $keep_return, $ifdef, $errthrow, $$objCppfunc{slot_type}, @@ -578,11 +583,14 @@ sub output_wrap_create($$$) } } -# void output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) -# custom_signalproxy_name is "" when no type conversion is required - a normal templates SignalProxy will be used instead. -sub output_wrap_sig_decl($$$$$$$$$$$) +# void output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppfunc, $signal_name, +# $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs, +# $newin, $exceptionHandler, $detail_name, $bTwoSignalMethods) +sub output_wrap_sig_decl($$$$$$$$$$$$$$) { - my ($self, $filename, $line_num, $objCSignal, $objCppfunc, $signal_name, $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) = @_; + my ($self, $filename, $line_num, $objCSignal, $objCppfunc, $signal_name, + $bCustomCCallback, $ifdef, $commentblock, $deprecated, $deprecation_docs, + $newin, $exceptionHandler, $detail_name, $bTwoSignalMethods) = @_; # _SIGNAL_PROXY(c_signal_name, c_return_type, `<c_arg_types_and_names>', # cpp_signal_name, cpp_return_type, `<cpp_arg_types>',`<c_args_to_cpp>', @@ -594,8 +602,8 @@ sub output_wrap_sig_decl($$$$$$$$$$$) $underscored_signal_name =~ s/-/_/g; # Get the existing signal documentation from the parsed docs. - my $documentation = - DocsParser::lookup_documentation("$$objCSignal{class}::$underscored_signal_name", $deprecation_docs); + my $documentation = DocsParser::lookup_documentation( + "$$objCSignal{class}::$underscored_signal_name", $deprecation_docs, $newin, $objCppfunc); # Create a merged Doxygen comment block for the signal from the looked up # docs (the block will also contain a prototype of the slot as an example). @@ -609,6 +617,9 @@ sub output_wrap_sig_decl($$$$$$$$$$$) { # Strip leading whitespace $doxycomment =~ s/^\s+//; + # Add a level of m4 quotes. Necessary if $commentblock contains __FT__ or __BT__. + # DocsParser::lookup_documentation() adds it in $documentation. + $commentblock = "`" . $commentblock . "'"; # We don't have something to add, so just use $commentblock with # opening and closing tokens added. @@ -629,7 +640,7 @@ sub output_wrap_sig_decl($$$$$$$$$$$) my $conversions = convert_args_c_to_cpp($objCSignal, $objCppfunc, $line_num); - my $str = sprintf("_SIGNAL_PROXY(%s,%s,\`%s\',%s,%s,\`%s\',\`%s\',\`%s\',%s,\`%s\',%s,%s)dnl\n", + my $str = sprintf("_SIGNAL_PROXY(%s,%s,\`%s\',%s,%s,\`%s\',\`%s\',\`%s\',%s,\`%s\',%s,%s,%s,%s)dnl\n", $signal_name, $$objCSignal{rettype}, $objCSignal->args_types_and_names_without_object(), @@ -641,7 +652,9 @@ sub output_wrap_sig_decl($$$$$$$$$$$) $deprecated, $doxycomment, $ifdef, - $exceptionHandler + $exceptionHandler, + $detail_name, # If a detailed name is supported (signal_name::detail_name) + $bTwoSignalMethods # If separate signal_xxx() methods for detailed and general name. ); $self->append($str); @@ -675,17 +688,10 @@ sub output_wrap_enum($$$$$$$) # Get the enum documentation from the parsed docs. my $enum_docs = - DocsParser::lookup_enum_documentation("$c_type", "$cpp_type", \@flags); - - # Remove initial Doxygen comment block start ('/**') from the enum docs - # to merge the passed in Doxygen comment block. - $enum_docs =~ s/\/\*\*\s+//g; - - # Make sure indentation of passed in comment is correct. - $comment =~ s/\n\s*\*/\n */g; + DocsParser::lookup_enum_documentation("$c_type", "$cpp_type", " ", \@flags); # Merge the passed in comment to the existing enum documentation. - $comment = $comment . "\n * " . $enum_docs; + $comment .= "\n * " . $enum_docs if $enum_docs ne ""; my $str = sprintf("_ENUM(%s,%s,%s,\`%s\',\`%s\',\`%s\')dnl\n", $cpp_type, @@ -706,7 +712,7 @@ sub output_wrap_enum_docs_only($$$$$$$) # Get the existing enum description from the parsed docs. my $enum_docs = - DocsParser::lookup_enum_documentation("$c_type", "$cpp_type", \@flags); + DocsParser::lookup_enum_documentation("$c_type", "$cpp_type", " ", \@flags); if($enum_docs eq "") { @@ -715,17 +721,10 @@ sub output_wrap_enum_docs_only($$$$$$$) } # Include the enum docs in the module's enum docs group. - $enum_docs .= "\n * \@ingroup ${module_canonical}Enums\n"; + $enum_docs .= "\n *\n * \@ingroup ${module_canonical}Enums"; - # Remove initial Doxygen comment block start ('/**') from the enum docs - # to merge the passed in Doxygen comment block. - $enum_docs =~ s/\/\*\*\s+//g; - # Merge the passed in comment to the existing enum documentation. - $comment = "\/\*\* " . $comment . "\n * " . $enum_docs . "\n */\n"; - - # Make sure indentation of passed in comment is correct. - $comment =~ s/\n\s*\*/\n */g; + $comment = "/** " . $comment . "\n * " . $enum_docs . "\n */\n"; $self->append($comment); } @@ -761,10 +760,7 @@ sub output_wrap_gerror($$$$$$$) # Get the enum documentation from the parsed docs. my $enum_docs = - DocsParser::lookup_enum_documentation("$c_enum", "Code", \@flags); - - # Make sure indentation of enum documentation is correct. - $enum_docs =~ s/\n\s*\*/\n \*/g; + DocsParser::lookup_enum_documentation("$c_enum", "Code", " ", \@flags); # Prevent Doxygen from auto-linking to a class called Error. $enum_docs =~ s/([^%])(Error code)/$1%$2/g; @@ -785,7 +781,8 @@ sub output_wrap_gerror($$$$$$$) # void output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, $proxy_macro) sub output_wrap_any_property($$$$$$$$$$) { - my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, $proxy_macro) = @_; + my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, + $deprecation_docs, $newin, $objProperty, $proxy_macro) = @_; my $objDefsParser = $$self{objDefsParser}; @@ -817,9 +814,44 @@ sub output_wrap_any_property($$$$$$$$$$) my $name_underscored = $name; $name_underscored =~ tr/-/_/; - # Get the property documentation, if any, and add m4 quotes. - my $documentation = $objProperty->get_docs($deprecation_docs); - add_m4_quotes(\$documentation) if ($documentation ne ""); + # Get the existing property documentation, if any, from the parsed docs. + my $documentation = DocsParser::lookup_documentation( + "$$objProperty{class}:$name_underscored", $deprecation_docs, $newin); + + if ($documentation ne "") + { + # Remove leading "/**" and trailing "*/". They will be added by the m4 macro. + $documentation =~ s/^\s*\/\*\*\s*//; + $documentation =~ s/\s*\*\/\s*$//; + } + + if ($documentation =~ /^`?[*\s]* + (?: + \@newin\{[\d,]+\} + |[Ss]ince[:\h]+\d+\.\d+ + |\@deprecated\s + |[Dd]eprecated[:\s] + )/x) + { + # The documentation begins with a "@newin", "Since", "@deprecated" or + # "Deprecated" line. Get documentation also from the Property object, + # but don't add another @newin or @deprecated. + my $objdoc = $objProperty->get_docs("", ""); + if ($objdoc ne "") + { + add_m4_quotes(\$objdoc); + $documentation = "$objdoc\n *\n * $documentation"; + } + } + elsif ($documentation eq "") + { + # Try to get the (usually short) documentation from the Property object. + $documentation = $objProperty->get_docs($deprecation_docs, $newin); + if ($documentation ne "") + { + add_m4_quotes(\$documentation); + } + } #Declaration: if($deprecated ne "") @@ -863,7 +895,8 @@ sub output_wrap_any_property($$$$$$$$$$) # void output_wrap_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs) sub output_wrap_property($$$$$$$$) { - my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_; + my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, + $deprecation_docs, $newin) = @_; my $objProperty = GtkDefs::lookup_property($c_class, $name); if($objProperty eq 0) #If the lookup failed: @@ -872,7 +905,8 @@ sub output_wrap_property($$$$$$$$) } else { - $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objProperty, "_PROPERTY_PROXY"); + $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, + $deprecated, $deprecation_docs, $newin, $objProperty, "_PROPERTY_PROXY"); } } @@ -880,7 +914,8 @@ sub output_wrap_property($$$$$$$$) # void output_wrap_child_property($filename, $line_num, $name, $cpp_type, $deprecated, $deprecation_docs) sub output_wrap_child_property($$$$$$$$) { - my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs) = @_; + my ($self, $filename, $line_num, $name, $cpp_type, $c_class, $deprecated, + $deprecation_docs, $newin) = @_; my $objChildProperty = GtkDefs::lookup_child_property($c_class, $name); if($objChildProperty eq 0) #If the lookup failed: @@ -889,7 +924,8 @@ sub output_wrap_child_property($$$$$$$$) } else { - $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, $deprecated, $deprecation_docs, $objChildProperty, "_CHILD_PROPERTY_PROXY"); + $self->output_wrap_any_property($filename, $line_num, $name, $cpp_type, $c_class, + $deprecated, $deprecation_docs, $newin, $objChildProperty, "_CHILD_PROPERTY_PROXY"); } } diff --git a/tools/pm/Property.pm b/tools/pm/Property.pm index f89140ea..8e2a131f 100644 --- a/tools/pm/Property.pm +++ b/tools/pm/Property.pm @@ -112,15 +112,21 @@ sub get_writable($) sub get_docs($$) { - my ($self, $deprecation_docs) = @_; + my ($self, $deprecation_docs, $newin) = @_; my $text = $$self{docs}; - #Add note about deprecation if we have specified that in our _WRAP_METHOD() call: + #Add note about deprecation if we have specified that in our _WRAP_PROPERTY() + #or_WRAP_CHILD_PROPERTY() call: if($deprecation_docs ne "") { $text .= "\n * \@deprecated $deprecation_docs"; } + if ($newin ne "") + { + $text .= "\n *\n * \@newin{$newin}"; + } + return $text; } diff --git a/tools/pm/WrapParser.pm b/tools/pm/WrapParser.pm index dc12eb47..b33ecb13 100644 --- a/tools/pm/WrapParser.pm +++ b/tools/pm/WrapParser.pm @@ -111,6 +111,8 @@ sub parse_and_build_output($) if ($token eq "_DEFS") { $self->on_defs(); next;} #Read the defs file. if ($token eq "_IGNORE") { $self->on_ignore(); next;} #Ignore a function. if ($token eq "_IGNORE_SIGNAL") { $self->on_ignore_signal(); next;} #Ignore a signal. + if ($token eq "_IGNORE_PROPERTY") { $self->on_ignore_property(); next;} #Ignore a property. + if ($token eq "_IGNORE_CHILD_PROPERTY") { $self->on_ignore_child_property(); next;} #Ignore a child property. if ($token eq "_WRAP_METHOD") { $self->on_wrap_method(); next;} if ($token eq "_WRAP_METHOD_DOCS_ONLY") { $self->on_wrap_method_docs_only(); next;} if ($token eq "_WRAP_CORBA_METHOD") { $self->on_wrap_corba_method(); next;} #Used in libbonobo*mm. @@ -471,25 +473,42 @@ sub on_ignore($) } } -sub on_ignore_signal($) +# void on_ignore_signal_or_property(\&lookup_function, $type) +sub on_ignore_signal_or_property($$$) { - my ($self) = @_; - my $objOutputter = $$self{objOutputter}; + my ($self, $lookup_function, $type) = @_; my $str = $self->extract_bracketed_text(); - $str = string_trim($str); - $str = string_unquote($str); my @args = split(/\s+|,/,$str); foreach (@args) { - next if ($_ eq ""); - my $objCsignal = GtkDefs::lookup_signal($$self{c_class}, $_); #Pretend that we've used it. - if(!$objCsignal) + my $name = string_unquote($_); + next if ($name eq ""); + my $objCentity = $lookup_function->($$self{c_class}, $name); #Pretend that we've used it. + if (!$objCentity) { - $objOutputter->output_wrap_failed($_, "ignored signal defs lookup failed"); + $$self{objOutputter}->output_wrap_failed($name, "ignored $type defs lookup failed"); } } } +sub on_ignore_signal($) +{ + my ($self) = @_; + $self->on_ignore_signal_or_property(\&GtkDefs::lookup_signal, "signal"); +} + +sub on_ignore_property($) +{ + my ($self) = @_; + $self->on_ignore_signal_or_property(\&GtkDefs::lookup_property, "property"); +} + +sub on_ignore_child_property($) +{ + my ($self) = @_; + $self->on_ignore_signal_or_property(\&GtkDefs::lookup_child_property, "child property"); +} + ######################################## ### we have certain macros we need to insert at end of statements # void on_class($, $strClassCommand) @@ -683,11 +702,12 @@ sub extract_bracketed_text($) ######################################## ### breaks up a string by commas (smart) -# @strings string_split_commas($string) -sub string_split_commas($) +# @strings string_split_commas($string [, $ignore_quotes]) +sub string_split_commas($;$) { - my ($in) = @_; + my ($in, $ignore_quotes) = @_; + $ignore_quotes = 2 unless defined $ignore_quotes; my @out; my $level = 0; my $in_braces = 0; @@ -701,10 +721,10 @@ sub string_split_commas($) next if ($t eq ""); - # TODO: Delete the test for scalar(@out) >= 2 when we can stop accepting + # TODO: Delete the test for scalar(@out) >= $ignore_quotes when we can stop accepting # .hg files with unpaired quotes, such as _WRAP_PROPERTY("text_column, int). # See also TODO in extract_bracketed_text(). - $in_quotes = !$in_quotes if ($t eq '"' and scalar(@out) >= 2); + $in_quotes = !$in_quotes if ($t eq '"' and scalar(@out) >= $ignore_quotes); if (!$in_quotes) { $in_braces++ if ($t eq "{"); @@ -931,6 +951,7 @@ sub on_wrap_method($) $$objCfunc{constversion} = 0; $$objCfunc{deprecated} = ""; my $deprecation_docs = ""; + my $newin = ""; my $ifdef; while($#args >= 2) # If the optional ref/err/deprecated arguments are there. { @@ -957,6 +978,10 @@ sub on_wrap_method($) $deprecation_docs = string_unquote(string_trim($1)); } } + elsif($argRef =~ /^newin(.*)/) #If newin is at the start. + { + $newin = string_unquote(string_trim($1)); + } elsif($argRef =~ /^ifdef(.*)/) #If ifdef is at the start. { $ifdef = $1; @@ -989,7 +1014,7 @@ sub on_wrap_method($) else { $commentblock = DocsParser::lookup_documentation($argCFunctionName, - $deprecation_docs, $objCppfunc); + $deprecation_docs, $newin, $objCppfunc); } $objOutputter->output_wrap_meth($filename, $line_num, $objCppfunc, $objCfunc, $argCppMethodDecl, $commentblock, $ifdef); @@ -1007,7 +1032,7 @@ sub on_wrap_method_docs_only($) my $line_num = $$self{line_num}; my $str = $self->extract_bracketed_text(); - my @args = string_split_commas($str); + my @args = string_split_commas($str, 1); my $entity_type = "method"; @@ -1038,8 +1063,8 @@ sub on_wrap_method_docs_only($) } } - # Extra ref needed? $$objCfunc{throw_any_errors} = 0; + my $newin = ""; while($#args >= 1) # If the optional ref/err arguments are there. { my $argRef = string_trim(pop @args); @@ -1047,11 +1072,14 @@ sub on_wrap_method_docs_only($) { $$objCfunc{throw_any_errors} = 1; } + elsif($argRef =~ /^newin(.*)/) #If newin is at the start. + { + $newin = string_unquote(string_trim($1)); + } } my $commentblock = ""; - $commentblock = DocsParser::lookup_documentation($argCFunctionName, ""); - + $commentblock = DocsParser::lookup_documentation($argCFunctionName, "", $newin); $objOutputter->output_wrap_meth_docs_only($filename, $line_num, $commentblock); } @@ -1205,10 +1233,13 @@ sub on_wrap_signal($$) my $bNoDefaultHandler = 0; my $bCustomCCallback = 0; my $bRefreturn = 0; - my $ifdef; + my $ifdef = ""; my $argDeprecated = ""; my $deprecation_docs = ""; + my $newin = ""; my $exceptionHandler = ""; + my $detail_name = ""; + my $bTwoSignalMethods = 0; while($#args >= 2) # If optional arguments are there. { @@ -1217,23 +1248,19 @@ sub on_wrap_signal($$) { $bCustomDefaultHandler = 1; } - - if($argRef eq "no_default_handler") + elsif($argRef eq "no_default_handler") { $bNoDefaultHandler = 1; } - - if($argRef eq "custom_c_callback") + elsif($argRef eq "custom_c_callback") { $bCustomCCallback = 1; } - - if($argRef eq "refreturn") + elsif($argRef eq "refreturn") { $bRefreturn = 1; } - - if($argRef =~ /^deprecated(.*)/) #If deprecated is at the start. + elsif($argRef =~ /^deprecated(.*)/) #If deprecated is at the start. { $argDeprecated = "deprecated"; @@ -1242,21 +1269,36 @@ sub on_wrap_signal($$) $deprecation_docs = string_unquote(string_trim($1)); } } - + elsif($argRef =~ /^newin(.*)/) #If newin is at the start. + { + $newin = string_unquote(string_trim($1)); + } elsif($argRef =~ /^ifdef(.*)/) #If ifdef is at the start. { $ifdef = $1; } - elsif($argRef =~ /^exception_handler\s+(.*)/) #If exception_handler at the start. { - $exceptionHandler = $1; + $exceptionHandler = $1; + } + elsif($argRef =~ /^detail_name\s+(.+)/) #If detail_name at the start. + { + $detail_name = $1; + } + elsif($argRef eq "two_signal_methods") + { + $bTwoSignalMethods = 1; + } + else + { + $self->error("_WRAP_SIGNAL: Invalid option '$argRef'.\n"); } } $self->output_wrap_signal($argCppDecl, $argCName, $$self{filename}, $$self{line_num}, $bCustomDefaultHandler, $bNoDefaultHandler, $bCustomCCallback, - $bRefreturn, $ifdef, $commentblock, $argDeprecated, $deprecation_docs, $exceptionHandler); + $bRefreturn, $ifdef, $commentblock, $argDeprecated, $deprecation_docs, + $newin, $exceptionHandler, $detail_name, $bTwoSignalMethods); } # void on_wrap_vfunc() @@ -1279,6 +1321,7 @@ sub on_wrap_vfunc($) $argCName = string_unquote($argCName); my $refreturn = 0; + my $keep_return = 0; my $refreturn_ctype = 0; my $returnValue = ""; my $exceptionHandler = ""; @@ -1299,6 +1342,12 @@ sub on_wrap_vfunc($) { $refreturn = 1; } + # Must a copy of the return value be kept, because the caller does not + # get its own copy? + elsif($argRef eq "keep_return") + { + $keep_return = 1; + } elsif($argRef eq "refreturn_ctype") { $refreturn_ctype = 1; @@ -1354,7 +1403,7 @@ sub on_wrap_vfunc($) } $self->output_wrap_vfunc($argCppDecl, $argCName, $$self{filename}, $$self{line_num}, - $refreturn, $refreturn_ctype, $custom_vfunc, + $refreturn, $keep_return, $refreturn_ctype, $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow, $slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler); } @@ -1452,6 +1501,7 @@ sub on_wrap_any_property($) #TODO: Reduce duplication with on_wrap_method(): my $argDeprecated = ""; my $deprecation_docs = ""; + my $newin = ""; while($#args >= 2) # If the optional arguments are there. { my $argRef = string_trim(pop @args); @@ -1465,9 +1515,14 @@ sub on_wrap_any_property($) $deprecation_docs = string_unquote(string_trim($1)); } } + elsif($argRef =~ /^newin(.*)/) #If newin is at the start. + { + $newin = string_unquote(string_trim($1)); + } } - return ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs); + return ($filename, $line_num, $argPropertyName, $argCppType, + $argDeprecated, $deprecation_docs, $newin); } sub on_wrap_property($) @@ -1477,9 +1532,11 @@ sub on_wrap_property($) return unless ($self->check_for_eof()); - my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs) = $self->on_wrap_any_property(); + my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, + $deprecation_docs, $newin) = $self->on_wrap_any_property(); - $objOutputter->output_wrap_property($filename, $line_num, $argPropertyName, $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs); + $objOutputter->output_wrap_property($filename, $line_num, $argPropertyName, + $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs, $newin); } sub on_wrap_child_property($) @@ -1489,9 +1546,11 @@ sub on_wrap_child_property($) return unless ($self->check_for_eof()); - my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, $deprecation_docs) = $self->on_wrap_any_property(); + my ($filename, $line_num, $argPropertyName, $argCppType, $argDeprecated, + $deprecation_docs, $newin) = $self->on_wrap_any_property(); - $objOutputter->output_wrap_child_property($filename, $line_num, $argPropertyName, $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs); + $objOutputter->output_wrap_child_property($filename, $line_num, $argPropertyName, + $argCppType, $$self{c_class}, $argDeprecated, $deprecation_docs, $newin); } sub output_wrap_check($$$$$$) @@ -1515,12 +1574,14 @@ sub output_wrap_check($$$$$$) # void output_wrap($CppDecl, $signal_name, $filename, $line_num, $bCustomDefaultHandler, # $bNoDefaultHandler, $bCustomCCallback, $bRefreturn, $ifdef, -# $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) -sub output_wrap_signal($$$$$$$$$$$$) +# $commentblock, $deprecated, $deprecation_docs, $newin, $exceptionHandler, +# $detail_name, $bTwoSignalMethods) +sub output_wrap_signal($$$$$$$$$$$$$$$$$) { my ($self, $CppDecl, $signal_name, $filename, $line_num, $bCustomDefaultHandler, $bNoDefaultHandler, $bCustomCCallback, $bRefreturn, $ifdef, - $commentblock, $deprecated, $deprecation_docs, $exceptionHandler) = @_; + $commentblock, $deprecated, $deprecation_docs, $newin, $exceptionHandler, + $detail_name, $bTwoSignalMethods) = @_; #Some checks: return if ($self->output_wrap_check($CppDecl, $signal_name, @@ -1554,7 +1615,8 @@ sub output_wrap_signal($$$$$$$$$$$$) $objOutputter->output_wrap_sig_decl($filename, $line_num, $objCSignal, $objCppSignal, $signal_name, $bCustomCCallback, $ifdef, $commentblock, - $deprecated, $deprecation_docs, $exceptionHandler); + $deprecated, $deprecation_docs, $newin, $exceptionHandler, + $detail_name, $bTwoSignalMethods); if($bNoDefaultHandler eq 0) { @@ -1570,12 +1632,12 @@ sub output_wrap_signal($$$$$$$$$$$$) } # void output_wrap_vfunc($CppDecl, $vfunc_name, $filename, $line_num, -# $refreturn, $refreturn_ctype, +# $refreturn, $keep_return, $refreturn_ctype, # $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow, # $slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler) -sub output_wrap_vfunc($$$$$$$$$$$$$$) +sub output_wrap_vfunc($$$$$$$$$$$$$$$$$) { - my ($self, $CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $refreturn_ctype, + my ($self, $CppDecl, $vfunc_name, $filename, $line_num, $refreturn, $keep_return, $refreturn_ctype, $custom_vfunc, $custom_vfunc_callback, $ifdef, $errthrow, $slot_name, $slot_callback, $no_slot_copy, $returnValue, $exceptionHandler) = @_; @@ -1608,6 +1670,7 @@ sub output_wrap_vfunc($$$$$$$$$$$$$$) # These macros are defined in vfunc.m4: $$objCppVfunc{rettype_needs_ref} = $refreturn; + $$objCppVfunc{keep_return} = $keep_return; $$objCppVfunc{return_value} = $returnValue; $$objCppVfunc{exception_handler} = $exceptionHandler; $$objCppVfunc{name} .= "_vfunc"; #All vfuncs should have the "_vfunc" suffix, and a separate easily-named invoker method. diff --git a/tools/test_scripts/testheaders.sh b/tools/test_scripts/testheaders.sh index b6de3976..150ada4e 100755 --- a/tools/test_scripts/testheaders.sh +++ b/tools/test_scripts/testheaders.sh @@ -75,11 +75,11 @@ do for headerfile in $i/${i}mm/*.h do echo "=== $headerfile" - g++ -c -x c++ -o /dev/null $headerfile $CFLAGS + g++ -c -x c++ -std=c++11 -o /dev/null $headerfile $CFLAGS done else echo "=== $i" - g++ -c -x c++ -o /dev/null $i $CFLAGS + g++ -c -x c++ -std=c++11 -o /dev/null $i $CFLAGS fi done |