+Sun Apr 29 00:37:34 2001 Tim Janik <timj@gtk.org>
+
+ * ghook.[hc]: made hook ids a gulong.
+
2001-04-20 Dan Winship <danw@ximian.com>
* configure.in: Add a check for the Darwin dynamic linker. Use
+Sun Apr 29 00:37:34 2001 Tim Janik <timj@gtk.org>
+
+ * ghook.[hc]: made hook ids a gulong.
+
2001-04-20 Dan Winship <danw@ximian.com>
* configure.in: Add a check for the Darwin dynamic linker. Use
+Sun Apr 29 00:37:34 2001 Tim Janik <timj@gtk.org>
+
+ * ghook.[hc]: made hook ids a gulong.
+
2001-04-20 Dan Winship <danw@ximian.com>
* configure.in: Add a check for the Darwin dynamic linker. Use
+Sun Apr 29 00:37:34 2001 Tim Janik <timj@gtk.org>
+
+ * ghook.[hc]: made hook ids a gulong.
+
2001-04-20 Dan Winship <danw@ximian.com>
* configure.in: Add a check for the Darwin dynamic linker. Use
+Sun Apr 29 00:37:34 2001 Tim Janik <timj@gtk.org>
+
+ * ghook.[hc]: made hook ids a gulong.
+
2001-04-20 Dan Winship <danw@ximian.com>
* configure.in: Add a check for the Darwin dynamic linker. Use
+Sun Apr 29 00:37:34 2001 Tim Janik <timj@gtk.org>
+
+ * ghook.[hc]: made hook ids a gulong.
+
2001-04-20 Dan Winship <danw@ximian.com>
* configure.in: Add a check for the Darwin dynamic linker. Use
+Sun Apr 29 00:37:34 2001 Tim Janik <timj@gtk.org>
+
+ * ghook.[hc]: made hook ids a gulong.
+
2001-04-20 Dan Winship <danw@ximian.com>
* configure.in: Add a check for the Darwin dynamic linker. Use
+Sun Apr 29 00:37:34 2001 Tim Janik <timj@gtk.org>
+
+ * ghook.[hc]: made hook ids a gulong.
+
2001-04-20 Dan Winship <danw@ximian.com>
* configure.in: Add a check for the Darwin dynamic linker. Use
Portable way to copy <type>va_list</type> variables.
</para>
+<!-- # Unused Parameters # -->
@ap1: the <type>va_list</type> variable to place a copy of @ap2 in.
@ap2: a <type>va_list</type>.
gboolean
g_hook_destroy (GHookList *hook_list,
- guint hook_id)
+ gulong hook_id)
{
GHook *hook;
GHook*
g_hook_get (GHookList *hook_list,
- guint hook_id)
+ gulong hook_id)
{
GHook *hook;
/* --- structures --- */
struct _GHookList
{
- guint seq_id;
+ gulong seq_id;
guint hook_size : 16;
guint is_setup : 1;
GHook *hooks;
GHook *next;
GHook *prev;
guint ref_count;
- guint hook_id;
+ gulong hook_id;
guint flags;
gpointer func;
GDestroyNotify destroy;
void g_hook_unref (GHookList *hook_list,
GHook *hook);
gboolean g_hook_destroy (GHookList *hook_list,
- guint hook_id);
+ gulong hook_id);
void g_hook_destroy_link (GHookList *hook_list,
GHook *hook);
void g_hook_prepend (GHookList *hook_list,
GHook *hook,
GHookCompareFunc func);
GHook* g_hook_get (GHookList *hook_list,
- guint hook_id);
+ gulong hook_id);
GHook* g_hook_find (GHookList *hook_list,
gboolean need_valids,
GHookFindFunc func,
gboolean
g_hook_destroy (GHookList *hook_list,
- guint hook_id)
+ gulong hook_id)
{
GHook *hook;
GHook*
g_hook_get (GHookList *hook_list,
- guint hook_id)
+ gulong hook_id)
{
GHook *hook;
/* --- structures --- */
struct _GHookList
{
- guint seq_id;
+ gulong seq_id;
guint hook_size : 16;
guint is_setup : 1;
GHook *hooks;
GHook *next;
GHook *prev;
guint ref_count;
- guint hook_id;
+ gulong hook_id;
guint flags;
gpointer func;
GDestroyNotify destroy;
void g_hook_unref (GHookList *hook_list,
GHook *hook);
gboolean g_hook_destroy (GHookList *hook_list,
- guint hook_id);
+ gulong hook_id);
void g_hook_destroy_link (GHookList *hook_list,
GHook *hook);
void g_hook_prepend (GHookList *hook_list,
GHook *hook,
GHookCompareFunc func);
GHook* g_hook_get (GHookList *hook_list,
- guint hook_id);
+ gulong hook_id);
GHook* g_hook_find (GHookList *hook_list,
gboolean need_valids,
GHookFindFunc func,
+Sat Apr 28 23:39:42 2001 Tim Janik <timj@gtk.org>
+
+ * gsignal.[hc]: made signal handler and emission hook ids gulongs.
+ (signal_handlers_foreach_matched_R): only invoke callback for handlers
+ that are not disconnected (id>0).
+ (signal_emit_R): prevent invocation of signal handlers during the
+ emission they were connected within.
+
+ * glib-mkenums: publically installed perl-script to parse C code
+ enums and generate descriptions thereof.
+ * glib-mkenums.1: assorted man page.
+
2001-04-19 Havoc Pennington <hp@redhat.com>
* gobject.c (g_object_get_valist): We were returning junk memory
#
# programs to compile and install
#
-bin_PROGRAMS = gobject-query glib-genmarshal testgruntime
+bin_PROGRAMS = gobject-query glib-genmarshal glib-mkenums
+noinst_PROGRAMS = testgruntime
# source files
gobject_query_SOURCES = gobject-query.c
glib_genmarshal_SOURCES = glib-genmarshal.c
+glib_mkenums_SOURCES = glib-mkenums
testgruntime_SOURCES = testgruntime.c
# link programs against libgobject
progs_LDADD = libgobject-1.3.la $(libglib)
#
# manual pages to install
#
-man_MANS = glib-genmarshal.1
+man_MANS = glib-genmarshal.1 glib-mkenums.1
#
# auxillary files
makefile.msc.in \
gobject.def \
gobject.rc.in \
- glib-genmarshal.1
+ glib-genmarshal.1 \
+ glib-mkenums.1
BUILT_EXTRA_DIST = \
makefile.mingw \
.SH SEE ALSO
\fB
-glib-config(1)
+glib-mkenums(1)
\fP
.SH BUGS
--- /dev/null
+#!/usr/bin/perl -w
+
+# glib-mkenums.pl
+# Information about the current enumeration
+my $flags; # Is enumeration a bitmask?
+my $seenbitshift; # Have we seen bitshift operators?
+my $enum_prefix; # Prefix for this enumeration
+my $enumname; # Name for this enumeration
+my $enumshort; # $enumname without prefix
+my $enumindex = 0; # Global enum counter
+my $firstenum = 1; # Is this the first enumeration per file?
+my @entries; # [ $name, $val ] for each entry
+
+sub parse_trigraph {
+ my $opts = shift;
+ my @opts;
+
+ for $opt (split /\s*,\s*/, $opts) {
+ $opt =~ s/^\s*//;
+ $opt =~ s/\s*$//;
+ my ($key,$val) = $opt =~ /(\w+)(?:=(.+))?/;
+ defined $val or $val = 1;
+ push @opts, $key, $val;
+ }
+ @opts;
+}
+sub parse_entries {
+ my $file = shift;
+ my $file_name = shift;
+
+ while (<$file>) {
+
+ # read lines until comment end is matched
+ while (m@/\*([^*]|\*[^/*])*\**$@x) {
+ my $new;
+ defined ($new = <>) || die "Unmatched comment in $ARGV";
+ $_ .= $new;
+ }
+ # strip comments w/o options
+ s@/\*[^<]([^*]|\*[^/*])*\**\*/@@gx;
+
+ # strip newlines
+ s/\n//;
+
+ # skip empty lines
+ next if m@^\s*$@;
+
+# print STDERR "xxx $_\n";
+
+ # Handle include files
+ if (/^\#include\s*<([^>]*)>/ ) {
+ my $file= "../$1";
+ open NEWFILE, $file or die "Cannot open include file $file: $!\n";
+
+ # read lines until comment end is matched
+ while (m@/\*([^*]|\*[^/*])*\**$@x) {
+ my $new;
+ defined ($new = <>) || die "Unmatched comment in $file_name";
+ $_ .= $new;
+ }
+ # strip comments w/o options
+ s@/\*[^<]([^*]|\*[^/*])*\**\*/@@gx;
+
+ if (parse_entries (\*NEWFILE, $NEWFILE)) {
+ return 1;
+ } else {
+ next;
+ }
+ }
+
+ if (/^\s*\}\s*(\w+)/) {
+ $enumname = $1;
+ $enumindex++;
+ return 1;
+ }
+
+ if (m@^\s*
+ (\w+)\s* # name
+ (?:=( # value
+ (?:[^,/]|/(?!\*))*
+ ))?,?\s*
+ (?:/\*< # options
+ (([^*]|\*(?!/))*)
+ >\s*\*/)?,?
+ \s*$
+ @x) {
+ my ($name, $value, $options) = ($1,$2,$3);
+
+# print STDERR "xxx \"$name\" \"$value\" \"$otions\"\n";
+
+ if (!defined $flags && defined $value && $value =~ /<</) {
+ $seenbitshift = 1;
+ }
+
+ if (defined $options) {
+ my %options = parse_trigraph($options);
+ if (!defined $options{skip}) {
+ push @entries, [ $name, $options{nick} ];
+ }
+ } else {
+ push @entries, [ $name ];
+ }
+ } elsif (m@^\s*\#@) {
+ # ignore preprocessor directives
+ } else {
+ print STDERR "$0: $file_name:$.: Failed to parse `$_'\n";
+ }
+ }
+
+ return 0;
+}
+
+sub version {
+ print STDERR "glib-mkenums version glib-2.0\n"; # FIXME: autogen version?
+ print STDERR "glib-mkenums comes with ABSOLUTELY NO WARRANTY.\n";
+ print STDERR "You may redistribute copies of glib-mkenums under the terms of\n";
+ print STDERR "the GNU General Public License which can be found in the\n";
+ print STDERR "GLib source package. Sources, examples and contact\n";
+ print STDERR "information are available at http://www.gtk.org\n";
+ exit 0;
+}
+sub usage {
+ print STDERR "Usage: glib-mkenums [options] [files...]\n";
+ print STDERR " --fhead <text> output file header\n";
+ print STDERR " --fprod <text> per input file production\n";
+ print STDERR " --ftail <text> output file trailer\n";
+ print STDERR " --eprod <text> per enum text (produced prior to value itarations)\n";
+ print STDERR " --vhead <text> value header, produced before iterating over enum values\n";
+ print STDERR " --vprod <text> value text, produced for each enum value\n";
+ print STDERR " --vtail <text> value tail, produced after iterating over enum values\n";
+ print STDERR " --comments <text> comment structure\n";
+ print STDERR " -h, --help show this help message\n";
+ print STDERR " -v, --version print version informations\n";
+ print STDERR "Production text substitutions:\n";
+ print STDERR " \@EnumName\@ PrefixTheXEnum\n";
+ print STDERR " \@enum_name\@ prefix_the_xenum\n";
+ print STDERR " \@ENUMNAME\@ PREFIX_THE_XENUM\n";
+ print STDERR " \@ENUMSHORT\@ THE_XENUM\n";
+ print STDERR " \@VALUENAME\@ PREFIX_THE_XVALUE\n";
+ print STDERR " \@valuenick\@ the-xvalue\n";
+ print STDERR " \@type\@ either enum or flags\n";
+ print STDERR " \@Type\@ either Enum or Flags\n";
+ print STDERR " \@TYPE\@ either ENUM or FLAGS\n";
+ print STDERR " \@filename\@ name of current input file\n";
+ exit 0;
+}
+
+# production variables:
+my $fhead = ""; # output file header
+my $fprod = ""; # per input file production
+my $ftail = ""; # output file trailer
+my $eprod = ""; # per enum text (produced prior to value itarations)
+my $vhead = ""; # value header, produced before iterating over enum values
+my $vprod = ""; # value text, produced for each enum value
+my $vtail = ""; # value tail, produced after iterating over enum values
+# other options
+my $comment_tmpl = "/* \@comment\@ */";
+
+if (!defined $ARGV[0]) {
+ usage;
+}
+while ($_ = $ARGV[0], /^-/) {
+ shift;
+ last if /^--$/;
+ if (/^--fhead$/) { $fhead = $fhead . shift }
+ elsif (/^--fprod$/) { $fprod = $fprod . shift }
+ elsif (/^--ftail$/) { $ftail = $ftail . shift }
+ elsif (/^--eprod$/) { $eprod = $eprod . shift }
+ elsif (/^--vhead$/) { $vhead = $vhead . shift }
+ elsif (/^--vprod$/) { $vprod = $vprod . shift }
+ elsif (/^--vtail$/) { $vtail = $vtail . shift }
+ elsif (/^--comments$/) { $comment_tmpl = shift }
+ elsif (/^--help$/ || /^-h$/) { usage; }
+ elsif (/^--version$/ || /^-v$/) { version; }
+ else { usage; }
+}
+
+# put auto-generation comment
+{
+ my $comment = $comment_tmpl;
+ $comment =~ s/\@comment\@/Generated data (by glib-mkenums)/;
+ print "\n" . $comment . "\n\n";
+}
+
+if (length($fhead)) {
+ my $prod = $fhead;
+
+ $prod =~ s/\@filename\@/$ARGV/g;
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+}
+
+while (<>) {
+ if (eof) {
+ close (ARGV); # reset line numbering
+ $firstenum = 1; # Flag to print filename at next enum
+ }
+
+ # read lines until comment end is matched
+ while (m@/\*([^*]|\*[^/*])*\**$@x) {
+ my $new;
+ defined ($new = <>) || die "Unmatched comment in $ARGV";
+ $_ .= $new;
+ }
+ # strip comments w/o options
+ s@/\*[^<]([^*]|\*[^/*])*\**\*/@@gx;
+
+# print STDERR "xxx $_\n";
+
+ if (m@^\s*typedef\s+enum\s*
+ ({)?\s*
+ (?:/\*<
+ (([^*]|\*(?!/))*)
+ >\s*\*/)?
+ @x) {
+ if (defined $2) {
+ my %options = parse_trigraph ($2);
+ next if defined $options{skip};
+ $enum_prefix = $options{prefix};
+ $flags = $options{flags};
+ } else {
+ $enum_prefix = undef;
+ $flags = undef;
+ }
+ # Didn't have trailing '{' look on next lines
+ if (!defined $1) {
+ while (<>) {
+ if (s/^\s*\{//) {
+ last;
+ }
+ }
+ }
+
+ $seenbitshift = 0;
+ @entries = ();
+
+ # Now parse the entries
+ parse_entries (\*ARGV, $ARGV);
+
+ # figure out if this was a flags or enums enumeration
+ if (!defined $flags) {
+ $flags = $seenbitshift;
+ }
+
+ # Autogenerate a prefix
+ if (!defined $enum_prefix) {
+ for (@entries) {
+ my $nick = $_->[1];
+ if (!defined $nick) {
+ my $name = $_->[0];
+ if (defined $enum_prefix) {
+ my $tmp = ~ ($name ^ $enum_prefix);
+ ($tmp) = $tmp =~ /(^\xff*)/;
+ $enum_prefix = $enum_prefix & $tmp;
+ } else {
+ $enum_prefix = $name;
+ }
+ }
+ }
+ if (!defined $enum_prefix) {
+ $enum_prefix = "";
+ } else {
+ # Trim so that it ends in an underscore
+ $enum_prefix =~ s/_[^_]*$/_/;
+ }
+ } else {
+ # canonicalize user defined prefixes
+ $enum_prefix = uc($enum_prefix);
+ $enum_prefix =~ s/-/_/g;
+ $enum_prefix =~ s/(.*)([^_])$/$1$2_/;
+ }
+
+ for $entry (@entries) {
+ my ($name,$nick) = @{$entry};
+ if (!defined $nick) {
+ ($nick = $name) =~ s/^$enum_prefix//;
+ $nick =~ tr/_/-/;
+ $nick = lc($nick);
+ @{$entry} = ($name, $nick);
+ }
+ }
+
+
+ # Spit out the output
+
+ # enumname is e.g. GMatchType
+ $enspace = $enumname;
+ $enspace =~ s/^([A-Z][a-z]*).*$/$1/;
+
+ $enumshort = $enumname;
+ $enumshort =~ s/^[A-Z][a-z]*//;
+ $enumshort =~ s/([^A-Z])([A-Z])/$1_$2/g;
+ $enumshort =~ s/([A-Z][A-Z])([A-Z][0-9a-z])/$1_$2/g;
+ $enumshort = uc($enumshort);
+
+ $enumlong = uc($enspace) . "_" . $enumshort;
+ $enumsym = lc($enspace) . "_" . lc($enumshort);
+
+ if ($firstenum) {
+ $firstenum = 0;
+
+ if (length($fprod)) {
+ my $prod = $fprod;
+
+ $prod =~ s/\@filename\@/$ARGV/g;
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+ }
+ }
+
+ if (length($eprod)) {
+ my $prod = $eprod;
+
+ $prod =~ s/\@enum_name\@/$enumsym/g;
+ $prod =~ s/\@EnumName\@/$enumname/g;
+ $prod =~ s/\@ENUMSHORT\@/$enumshort/g;
+ $prod =~ s/\@ENUMNAME\@/$enumlong/g;
+ if ($flags) { $prod =~ s/\@type\@/flags/g; } else { $prod =~ s/\@type\@/enum/g; }
+ if ($flags) { $prod =~ s/\@Type\@/Flags/g; } else { $prod =~ s/\@Type\@/Enum/g; }
+ if ($flags) { $prod =~ s/\@TYPE\@/FLAGS/g; } else { $prod =~ s/\@TYPE\@/ENUM/g; }
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+ }
+
+ if (length($vhead)) {
+ my $prod = $vhead;
+
+ $prod =~ s/\@enum_name\@/$enumsym/g;
+ $prod =~ s/\@EnumName\@/$enumname/g;
+ $prod =~ s/\@ENUMSHORT\@/$enumshort/g;
+ $prod =~ s/\@ENUMNAME\@/$enumlong/g;
+ if ($flags) { $prod =~ s/\@type\@/flags/g; } else { $prod =~ s/\@type\@/enum/g; }
+ if ($flags) { $prod =~ s/\@Type\@/Flags/g; } else { $prod =~ s/\@Type\@/Enum/g; }
+ if ($flags) { $prod =~ s/\@TYPE\@/FLAGS/g; } else { $prod =~ s/\@TYPE\@/ENUM/g; }
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+ }
+
+ if (length($vprod)) {
+ my $prod = $vprod;
+
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+ for (@entries) {
+ my ($name,$nick) = @{$_};
+ my $tmp_prod = $vprod;
+
+ $tmp_prod =~ s/\@VALUENAME\@/$name/g;
+ $tmp_prod =~ s/\@valuenick\@/$nick/g;
+ if ($flags) { $tmp_prod =~ s/\@type\@/flags/g; } else { $tmp_prod =~ s/\@type\@/enum/g; }
+ if ($flags) { $tmp_prod =~ s/\@Type\@/Flags/g; } else { $tmp_prod =~ s/\@Type\@/Enum/g; }
+ if ($flags) { $tmp_prod =~ s/\@TYPE\@/FLAGS/g; } else { $tmp_prod =~ s/\@TYPE\@/ENUM/g; }
+
+ print "$tmp_prod\n";
+ }
+ }
+
+ if (length($vtail)) {
+ my $prod = $vtail;
+
+ $prod =~ s/\@enum_name\@/$enumsym/g;
+ $prod =~ s/\@EnumName\@/$enumname/g;
+ $prod =~ s/\@ENUMSHORT\@/$enumshort/g;
+ $prod =~ s/\@ENUMNAME\@/$enumlong/g;
+ if ($flags) { $prod =~ s/\@type\@/flags/g; } else { $prod =~ s/\@type\@/enum/g; }
+ if ($flags) { $prod =~ s/\@Type\@/Flags/g; } else { $prod =~ s/\@Type\@/Enum/g; }
+ if ($flags) { $prod =~ s/\@TYPE\@/FLAGS/g; } else { $prod =~ s/\@TYPE\@/ENUM/g; }
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+ }
+ }
+}
+
+if (length($ftail)) {
+ my $prod = $ftail;
+
+ $prod =~ s/\@filename\@/$ARGV/g;
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+}
+
+# put auto-generation comment
+{
+ my $comment = $comment_tmpl;
+ $comment =~ s/\@comment\@/Generated data ends here/;
+ print "\n" . $comment . "\n\n";
+}
--- /dev/null
+.TH GLIB-MKENUMS 1 "20 Apr 2001"
+.SH NAME
+glib-mkenums \- C language enum description generation utility
+.SH SYNOPSIS
+
+\fBglib-mkenums\fP [\fIoptions\fP] [\fIfiles...\fP]
+
+.SH DESCRIPTION
+\fBglib-mkenums\fP is a small perl-script utility that parses C code to extract enum
+definitions and produces enum descriptions based on text templates specified
+by the user. Most frequently this script is used to produce C code that contains
+enum values as strings so programs can provide value name strings for introspection.
+
+.SH INVOCATION
+
+\fBglib-mkenums\fP takes a list of valid C code files as input. The options
+specified controll the text that is output, certain substitutions are performed
+on the text templates for keywords enclosed in @ characters.
+
+
+.SS Options
+.TP
+\fI--fhead <text>
+Put out <text> prior to processing input files.
+.TP
+\fI--fprod <text>
+Put out <text> everytime a new input file is being processed.
+.TP
+\fI--ftail <text>
+Put out <text> after all input files have been processed.
+.TP
+\fI--eprod <text>
+Put out <text> everytime an enum is encountered in the input files.
+.TP
+\fI--vhead <text>
+Put out <text> before iterating over the set of values of an enum.
+.TP
+\fI--vprod <text>
+Put out <text> for every value of an enum.
+.TP
+\fI--vtail <text>
+Put out <text> after iterating over all values of an enum.
+.TP
+\fI--comments <text>
+Template for auto-generated comments, the default (for C code generations) is
+"/* @comment@ */".
+.TP
+\fI-h, --help\fP
+Print brief help and exit.
+.TP
+\fI-v, --version\fP
+Print version and exit.
+.PP
+
+
+.SS Production text substitutions
+Certain keywords enclosed in @ characters will be substituted in the outputted
+text. For the substitution examples of the keywords below, the following example
+enum definition is assumed:
+.PP
+.RS
+.nf
+typedef enum
+{
+ PREFIX_THE_XVALUE = 1 << 3,
+ PREFIX_ANOTHER_VALUE = 1 << 4
+} PrefixTheXEnum;
+.fi
+.RE
+
+.TP 12
+\fI@EnumName@
+The name of the enum currently being processed, enum names are assumed to be
+properly namespaced and to use mixed capitalization to seperate
+words (e.g. PrefixTheXEnum).
+.TP 12
+\fI@enum_name@
+The enum name with words lowercase and word-seperated by underscores (e.g. prefix_the_xenum).
+.TP 12
+\fI@ENUMNAME@
+The enum name with words uppercase and word-seperated by underscores (e.g. PREFIX_THE_XENUM).
+.TP 12
+\fI@ENUMSHORT@
+The enum name with words uppercase and word-seperated by underscores, prefix stripped (e.g. THE_XENUM).
+.TP 12
+\fI@VALUENAME@
+The enum value name currently being processed with words uppercase and word-seperated by underscores,
+this is the assumed literal notation of enum values in the C sources (e.g. PREFIX_THE_XVALUE).
+.TP 12
+\fI@valuenick@
+A nick name for the enum value currently being processed, this is usually generated by stripping
+common prefix words of all the enum values of the current enum, the words are lowercase and
+underscores are subsituted by a minus (e.g. the-xvalue).
+.TP 12
+\fI@type@
+This is substituted either by "enum" or "flags", depending on whether the enum value definitions
+contained bit-shift operators or not (e.g. flags).
+.TP 12
+\fI@Type@
+The same as \fI@type@\fP with the first letter capitalized (e.g. Flags).
+.TP 12
+\fI@TYPE@
+The same as \fI@type@\fP with all letters uppercased (e.g. FLAGS).
+.TP 12
+\fI@filename@
+The name of the input file currently being processed (e.g. foo.h).
+
+.SS Trigraph extensions
+Some C comments are treated specially in the parsed enum definitions, such comments
+start out with the trigraph sequence "/*<" and end with the trigraph sequence ">*/".
+Per enum definition, the options "skip" and "flags" can be specified, to indicate
+this enum definition to be skipped, or for it to be treated as a flags definition, or
+to specify the common prefix to be stripped from all values to generate value nicknames,
+respectively.
+Per value definition, the options "skip" and "nick" are supported. The former causes the
+value to be skipped, and the latter can be used to specify the otherwise auto-generated
+nickname.
+Examples:
+.PP
+.RS
+.nf
+typedef enum /*< skip >*/
+{
+ PREFIX_FOO
+} PrefixThisEnumWillBeSkipped;
+typedef enum /*< flags,prefix=PREFIX >*/
+{
+ PREFIX_THE_ZEROTH_VALUE, /*< skip >*/
+ PREFIX_THE_FIRST_VALUE,
+ PREFIX_THE_SECOND_VALUE,
+ PREFIX_THE_THIRD_VALUE, /*< nick=the-last-value >*/
+} PrefixTheFlagsEnum;
+.fi
+.RE
+
+.SH SEE ALSO
+\fB
+glib-genmarshal(1)
+\fP
+
+.SH BUGS
+None known yet.
+
+.SH AUTHOR
+.B glib-mkenums
+was written by Tim Janik <timj@gtk.org> and Owen Taylor <otaylor@redhat.com>.
+.PP
+This manual page was provided by Tim Janik <timj@gtk.org>.
--- /dev/null
+#!/usr/bin/perl -w
+
+# glib-mkenums.pl
+# Information about the current enumeration
+my $flags; # Is enumeration a bitmask?
+my $seenbitshift; # Have we seen bitshift operators?
+my $enum_prefix; # Prefix for this enumeration
+my $enumname; # Name for this enumeration
+my $enumshort; # $enumname without prefix
+my $enumindex = 0; # Global enum counter
+my $firstenum = 1; # Is this the first enumeration per file?
+my @entries; # [ $name, $val ] for each entry
+
+sub parse_trigraph {
+ my $opts = shift;
+ my @opts;
+
+ for $opt (split /\s*,\s*/, $opts) {
+ $opt =~ s/^\s*//;
+ $opt =~ s/\s*$//;
+ my ($key,$val) = $opt =~ /(\w+)(?:=(.+))?/;
+ defined $val or $val = 1;
+ push @opts, $key, $val;
+ }
+ @opts;
+}
+sub parse_entries {
+ my $file = shift;
+ my $file_name = shift;
+
+ while (<$file>) {
+
+ # read lines until comment end is matched
+ while (m@/\*([^*]|\*[^/*])*\**$@x) {
+ my $new;
+ defined ($new = <>) || die "Unmatched comment in $ARGV";
+ $_ .= $new;
+ }
+ # strip comments w/o options
+ s@/\*[^<]([^*]|\*[^/*])*\**\*/@@gx;
+
+ # strip newlines
+ s/\n//;
+
+ # skip empty lines
+ next if m@^\s*$@;
+
+# print STDERR "xxx $_\n";
+
+ # Handle include files
+ if (/^\#include\s*<([^>]*)>/ ) {
+ my $file= "../$1";
+ open NEWFILE, $file or die "Cannot open include file $file: $!\n";
+
+ # read lines until comment end is matched
+ while (m@/\*([^*]|\*[^/*])*\**$@x) {
+ my $new;
+ defined ($new = <>) || die "Unmatched comment in $file_name";
+ $_ .= $new;
+ }
+ # strip comments w/o options
+ s@/\*[^<]([^*]|\*[^/*])*\**\*/@@gx;
+
+ if (parse_entries (\*NEWFILE, $NEWFILE)) {
+ return 1;
+ } else {
+ next;
+ }
+ }
+
+ if (/^\s*\}\s*(\w+)/) {
+ $enumname = $1;
+ $enumindex++;
+ return 1;
+ }
+
+ if (m@^\s*
+ (\w+)\s* # name
+ (?:=( # value
+ (?:[^,/]|/(?!\*))*
+ ))?,?\s*
+ (?:/\*< # options
+ (([^*]|\*(?!/))*)
+ >\s*\*/)?,?
+ \s*$
+ @x) {
+ my ($name, $value, $options) = ($1,$2,$3);
+
+# print STDERR "xxx \"$name\" \"$value\" \"$otions\"\n";
+
+ if (!defined $flags && defined $value && $value =~ /<</) {
+ $seenbitshift = 1;
+ }
+
+ if (defined $options) {
+ my %options = parse_trigraph($options);
+ if (!defined $options{skip}) {
+ push @entries, [ $name, $options{nick} ];
+ }
+ } else {
+ push @entries, [ $name ];
+ }
+ } elsif (m@^\s*\#@) {
+ # ignore preprocessor directives
+ } else {
+ print STDERR "$0: $file_name:$.: Failed to parse `$_'\n";
+ }
+ }
+
+ return 0;
+}
+
+sub version {
+ print STDERR "glib-mkenums version glib-2.0\n"; # FIXME: autogen version?
+ print STDERR "glib-mkenums comes with ABSOLUTELY NO WARRANTY.\n";
+ print STDERR "You may redistribute copies of glib-mkenums under the terms of\n";
+ print STDERR "the GNU General Public License which can be found in the\n";
+ print STDERR "GLib source package. Sources, examples and contact\n";
+ print STDERR "information are available at http://www.gtk.org\n";
+ exit 0;
+}
+sub usage {
+ print STDERR "Usage: glib-mkenums [options] [files...]\n";
+ print STDERR " --fhead <text> output file header\n";
+ print STDERR " --fprod <text> per input file production\n";
+ print STDERR " --ftail <text> output file trailer\n";
+ print STDERR " --eprod <text> per enum text (produced prior to value itarations)\n";
+ print STDERR " --vhead <text> value header, produced before iterating over enum values\n";
+ print STDERR " --vprod <text> value text, produced for each enum value\n";
+ print STDERR " --vtail <text> value tail, produced after iterating over enum values\n";
+ print STDERR " --comments <text> comment structure\n";
+ print STDERR " -h, --help show this help message\n";
+ print STDERR " -v, --version print version informations\n";
+ print STDERR "Production text substitutions:\n";
+ print STDERR " \@EnumName\@ PrefixTheXEnum\n";
+ print STDERR " \@enum_name\@ prefix_the_xenum\n";
+ print STDERR " \@ENUMNAME\@ PREFIX_THE_XENUM\n";
+ print STDERR " \@ENUMSHORT\@ THE_XENUM\n";
+ print STDERR " \@VALUENAME\@ PREFIX_THE_XVALUE\n";
+ print STDERR " \@valuenick\@ the-xvalue\n";
+ print STDERR " \@type\@ either enum or flags\n";
+ print STDERR " \@Type\@ either Enum or Flags\n";
+ print STDERR " \@TYPE\@ either ENUM or FLAGS\n";
+ print STDERR " \@filename\@ name of current input file\n";
+ exit 0;
+}
+
+# production variables:
+my $fhead = ""; # output file header
+my $fprod = ""; # per input file production
+my $ftail = ""; # output file trailer
+my $eprod = ""; # per enum text (produced prior to value itarations)
+my $vhead = ""; # value header, produced before iterating over enum values
+my $vprod = ""; # value text, produced for each enum value
+my $vtail = ""; # value tail, produced after iterating over enum values
+# other options
+my $comment_tmpl = "/* \@comment\@ */";
+
+if (!defined $ARGV[0]) {
+ usage;
+}
+while ($_ = $ARGV[0], /^-/) {
+ shift;
+ last if /^--$/;
+ if (/^--fhead$/) { $fhead = $fhead . shift }
+ elsif (/^--fprod$/) { $fprod = $fprod . shift }
+ elsif (/^--ftail$/) { $ftail = $ftail . shift }
+ elsif (/^--eprod$/) { $eprod = $eprod . shift }
+ elsif (/^--vhead$/) { $vhead = $vhead . shift }
+ elsif (/^--vprod$/) { $vprod = $vprod . shift }
+ elsif (/^--vtail$/) { $vtail = $vtail . shift }
+ elsif (/^--comments$/) { $comment_tmpl = shift }
+ elsif (/^--help$/ || /^-h$/) { usage; }
+ elsif (/^--version$/ || /^-v$/) { version; }
+ else { usage; }
+}
+
+# put auto-generation comment
+{
+ my $comment = $comment_tmpl;
+ $comment =~ s/\@comment\@/Generated data (by glib-mkenums)/;
+ print "\n" . $comment . "\n\n";
+}
+
+if (length($fhead)) {
+ my $prod = $fhead;
+
+ $prod =~ s/\@filename\@/$ARGV/g;
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+}
+
+while (<>) {
+ if (eof) {
+ close (ARGV); # reset line numbering
+ $firstenum = 1; # Flag to print filename at next enum
+ }
+
+ # read lines until comment end is matched
+ while (m@/\*([^*]|\*[^/*])*\**$@x) {
+ my $new;
+ defined ($new = <>) || die "Unmatched comment in $ARGV";
+ $_ .= $new;
+ }
+ # strip comments w/o options
+ s@/\*[^<]([^*]|\*[^/*])*\**\*/@@gx;
+
+# print STDERR "xxx $_\n";
+
+ if (m@^\s*typedef\s+enum\s*
+ ({)?\s*
+ (?:/\*<
+ (([^*]|\*(?!/))*)
+ >\s*\*/)?
+ @x) {
+ if (defined $2) {
+ my %options = parse_trigraph ($2);
+ next if defined $options{skip};
+ $enum_prefix = $options{prefix};
+ $flags = $options{flags};
+ } else {
+ $enum_prefix = undef;
+ $flags = undef;
+ }
+ # Didn't have trailing '{' look on next lines
+ if (!defined $1) {
+ while (<>) {
+ if (s/^\s*\{//) {
+ last;
+ }
+ }
+ }
+
+ $seenbitshift = 0;
+ @entries = ();
+
+ # Now parse the entries
+ parse_entries (\*ARGV, $ARGV);
+
+ # figure out if this was a flags or enums enumeration
+ if (!defined $flags) {
+ $flags = $seenbitshift;
+ }
+
+ # Autogenerate a prefix
+ if (!defined $enum_prefix) {
+ for (@entries) {
+ my $nick = $_->[1];
+ if (!defined $nick) {
+ my $name = $_->[0];
+ if (defined $enum_prefix) {
+ my $tmp = ~ ($name ^ $enum_prefix);
+ ($tmp) = $tmp =~ /(^\xff*)/;
+ $enum_prefix = $enum_prefix & $tmp;
+ } else {
+ $enum_prefix = $name;
+ }
+ }
+ }
+ if (!defined $enum_prefix) {
+ $enum_prefix = "";
+ } else {
+ # Trim so that it ends in an underscore
+ $enum_prefix =~ s/_[^_]*$/_/;
+ }
+ } else {
+ # canonicalize user defined prefixes
+ $enum_prefix = uc($enum_prefix);
+ $enum_prefix =~ s/-/_/g;
+ $enum_prefix =~ s/(.*)([^_])$/$1$2_/;
+ }
+
+ for $entry (@entries) {
+ my ($name,$nick) = @{$entry};
+ if (!defined $nick) {
+ ($nick = $name) =~ s/^$enum_prefix//;
+ $nick =~ tr/_/-/;
+ $nick = lc($nick);
+ @{$entry} = ($name, $nick);
+ }
+ }
+
+
+ # Spit out the output
+
+ # enumname is e.g. GMatchType
+ $enspace = $enumname;
+ $enspace =~ s/^([A-Z][a-z]*).*$/$1/;
+
+ $enumshort = $enumname;
+ $enumshort =~ s/^[A-Z][a-z]*//;
+ $enumshort =~ s/([^A-Z])([A-Z])/$1_$2/g;
+ $enumshort =~ s/([A-Z][A-Z])([A-Z][0-9a-z])/$1_$2/g;
+ $enumshort = uc($enumshort);
+
+ $enumlong = uc($enspace) . "_" . $enumshort;
+ $enumsym = lc($enspace) . "_" . lc($enumshort);
+
+ if ($firstenum) {
+ $firstenum = 0;
+
+ if (length($fprod)) {
+ my $prod = $fprod;
+
+ $prod =~ s/\@filename\@/$ARGV/g;
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+ }
+ }
+
+ if (length($eprod)) {
+ my $prod = $eprod;
+
+ $prod =~ s/\@enum_name\@/$enumsym/g;
+ $prod =~ s/\@EnumName\@/$enumname/g;
+ $prod =~ s/\@ENUMSHORT\@/$enumshort/g;
+ $prod =~ s/\@ENUMNAME\@/$enumlong/g;
+ if ($flags) { $prod =~ s/\@type\@/flags/g; } else { $prod =~ s/\@type\@/enum/g; }
+ if ($flags) { $prod =~ s/\@Type\@/Flags/g; } else { $prod =~ s/\@Type\@/Enum/g; }
+ if ($flags) { $prod =~ s/\@TYPE\@/FLAGS/g; } else { $prod =~ s/\@TYPE\@/ENUM/g; }
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+ }
+
+ if (length($vhead)) {
+ my $prod = $vhead;
+
+ $prod =~ s/\@enum_name\@/$enumsym/g;
+ $prod =~ s/\@EnumName\@/$enumname/g;
+ $prod =~ s/\@ENUMSHORT\@/$enumshort/g;
+ $prod =~ s/\@ENUMNAME\@/$enumlong/g;
+ if ($flags) { $prod =~ s/\@type\@/flags/g; } else { $prod =~ s/\@type\@/enum/g; }
+ if ($flags) { $prod =~ s/\@Type\@/Flags/g; } else { $prod =~ s/\@Type\@/Enum/g; }
+ if ($flags) { $prod =~ s/\@TYPE\@/FLAGS/g; } else { $prod =~ s/\@TYPE\@/ENUM/g; }
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+ }
+
+ if (length($vprod)) {
+ my $prod = $vprod;
+
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+ for (@entries) {
+ my ($name,$nick) = @{$_};
+ my $tmp_prod = $vprod;
+
+ $tmp_prod =~ s/\@VALUENAME\@/$name/g;
+ $tmp_prod =~ s/\@valuenick\@/$nick/g;
+ if ($flags) { $tmp_prod =~ s/\@type\@/flags/g; } else { $tmp_prod =~ s/\@type\@/enum/g; }
+ if ($flags) { $tmp_prod =~ s/\@Type\@/Flags/g; } else { $tmp_prod =~ s/\@Type\@/Enum/g; }
+ if ($flags) { $tmp_prod =~ s/\@TYPE\@/FLAGS/g; } else { $tmp_prod =~ s/\@TYPE\@/ENUM/g; }
+
+ print "$tmp_prod\n";
+ }
+ }
+
+ if (length($vtail)) {
+ my $prod = $vtail;
+
+ $prod =~ s/\@enum_name\@/$enumsym/g;
+ $prod =~ s/\@EnumName\@/$enumname/g;
+ $prod =~ s/\@ENUMSHORT\@/$enumshort/g;
+ $prod =~ s/\@ENUMNAME\@/$enumlong/g;
+ if ($flags) { $prod =~ s/\@type\@/flags/g; } else { $prod =~ s/\@type\@/enum/g; }
+ if ($flags) { $prod =~ s/\@Type\@/Flags/g; } else { $prod =~ s/\@Type\@/Enum/g; }
+ if ($flags) { $prod =~ s/\@TYPE\@/FLAGS/g; } else { $prod =~ s/\@TYPE\@/ENUM/g; }
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+ }
+ }
+}
+
+if (length($ftail)) {
+ my $prod = $ftail;
+
+ $prod =~ s/\@filename\@/$ARGV/g;
+ $prod =~ s/\\a/\a/g; $prod =~ s/\\b/\b/g; $prod =~ s/\\t/\t/g; $prod =~ s/\\n/\n/g;
+ $prod =~ s/\\v/\v/g; $prod =~ s/\\f/\f/g; $prod =~ s/\\r/\r/g;
+
+ print "$prod\n";
+}
+
+# put auto-generation comment
+{
+ my $comment = $comment_tmpl;
+ $comment =~ s/\@comment\@/Generated data ends here/;
+ print "\n" . $comment . "\n\n";
+}
gpointer instance,
Handler *handler);
static Handler* handler_lookup (gpointer instance,
- guint handler_id,
+ gulong handler_id,
guint *signal_id_p);
static inline HandlerMatch* handler_match_prepend (HandlerMatch *list,
Handler *handler,
};
struct _Handler
{
- guint id;
+ gulong sequential_number;
Handler *next;
Handler *prev;
GQuark detail;
static Emission *g_restart_emissions = NULL;
static GTrashStack *g_handler_ts = NULL;
static GTrashStack *g_emission_ts = NULL;
+static gulong g_handler_sequential_number = 1;
G_LOCK_DEFINE_STATIC (g_signal_mutex);
static Handler*
handler_lookup (gpointer instance,
- guint handler_id,
+ gulong handler_id,
guint *signal_id_p)
{
GBSearchArray *hlbsa = g_hash_table_lookup (g_handler_list_bsa_ht, instance);
Handler *handler;
for (handler = hlist->handlers; handler; handler = handler->next)
- if (handler->id == handler_id)
+ if (handler->sequential_number == handler_id)
{
if (signal_id_p)
*signal_id_p = hlist->signal_id;
mask = ~mask;
for (handler = hlist ? hlist->handlers : NULL; handler; handler = handler->next)
- if (handler->id &&
+ if (handler->sequential_number &&
((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
}
for (handler = hlist->handlers; handler; handler = handler->next)
- if (handler->id &&
+ if (handler->sequential_number &&
((mask & G_SIGNAL_MATCH_DETAIL) || handler->detail == detail) &&
((mask & G_SIGNAL_MATCH_CLOSURE) || handler->closure == closure) &&
((mask & G_SIGNAL_MATCH_DATA) || handler->closure->data == data) &&
static inline Handler*
handler_new (gboolean after)
{
- static guint handler_id = 1;
Handler *handler = g_generic_node_alloc (&g_handler_ts,
sizeof (Handler),
HANDLER_PRE_ALLOC);
#ifndef G_DISABLE_CHECKS
- if (handler_id == 0)
+ if (g_handler_sequential_number < 1)
g_error (G_STRLOC ": handler id overflow, %s", REPORT_BUG);
#endif
- handler->id = handler_id++;
+ handler->sequential_number = g_handler_sequential_number++;
handler->prev = NULL;
handler->next = NULL;
handler->detail = 0;
}
}
-guint
+gulong
g_signal_add_emission_hook (guint signal_id,
GQuark detail,
GSignalEmissionHook hook_func,
gpointer hook_data,
GDestroyNotify data_destroy)
{
- static guint seq_hook_id = 1;
+ static gulong seq_hook_id = 1;
SignalNode *node;
GHook *hook;
SignalHook *signal_hook;
}
void
-g_signal_remove_emission_hook (guint signal_id,
- guint hook_id)
+g_signal_remove_emission_hook (guint signal_id,
+ gulong hook_id)
{
SignalNode *node;
if (!node || node->destroyed)
g_warning ("%s: invalid signal id `%u'", G_STRLOC, signal_id);
else if (!node->emission_hooks || !g_hook_destroy (node->emission_hooks, hook_id))
- g_warning ("%s: signal \"%s\" had no hook (%u) to remove", G_STRLOC, node->name, hook_id);
+ g_warning ("%s: signal \"%s\" had no hook (%lu) to remove", G_STRLOC, node->name, hook_id);
G_UNLOCK (g_signal_mutex);
}
G_LOCK (g_signal_mutex);
}
-guint
+gulong
g_signal_connect_closure_by_id (gpointer instance,
guint signal_id,
GQuark detail,
gboolean after)
{
SignalNode *node;
- guint handler_id = 0;
+ gulong handler_seq_no = 0;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
g_return_val_if_fail (signal_id > 0, 0);
{
Handler *handler = handler_new (after);
- handler_id = handler->id;
+ handler_seq_no = handler->sequential_number;
handler->detail = detail;
handler->closure = g_closure_ref (closure);
g_closure_sink (closure);
g_warning ("%s: signal id `%u' is invalid for instance `%p'", G_STRLOC, signal_id, instance);
G_UNLOCK (g_signal_mutex);
- return handler_id;
+ return handler_seq_no;
}
-guint
+gulong
g_signal_connect_closure (gpointer instance,
const gchar *detailed_signal,
GClosure *closure,
gboolean after)
{
- guint signal_id, handler_id = 0;
+ guint signal_id;
+ gulong handler_seq_no = 0;
GQuark detail = 0;
GType itype;
{
Handler *handler = handler_new (after);
- handler_id = handler->id;
+ handler_seq_no = handler->sequential_number;
handler->detail = detail;
handler->closure = g_closure_ref (closure);
g_closure_sink (closure);
g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
G_UNLOCK (g_signal_mutex);
- return handler_id;
+ return handler_seq_no;
}
-guint
+gulong
g_signal_connect_data (gpointer instance,
const gchar *detailed_signal,
GCallback c_handler,
gboolean swapped,
gboolean after)
{
- guint signal_id, handler_id = 0;
+ guint signal_id;
+ gulong handler_seq_no = 0;
GQuark detail = 0;
GType itype;
{
Handler *handler = handler_new (after);
- handler_id = handler->id;
+ handler_seq_no = handler->sequential_number;
handler->detail = detail;
handler->closure = g_closure_ref ((swapped ? g_cclosure_new_swap : g_cclosure_new) (c_handler, data, destroy_data));
g_closure_sink (handler->closure);
g_warning ("%s: signal `%s' is invalid for instance `%p'", G_STRLOC, detailed_signal, instance);
G_UNLOCK (g_signal_mutex);
- return handler_id;
+ return handler_seq_no;
}
void
g_signal_handler_block (gpointer instance,
- guint handler_id)
+ gulong handler_id)
{
Handler *handler;
if (handler->block_count >= HANDLER_MAX_BLOCK_COUNT - 1)
g_error (G_STRLOC ": handler block_count overflow, %s", REPORT_BUG);
#endif
-
handler->block_count += 1;
}
else
- g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
+ g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id);
G_UNLOCK (g_signal_mutex);
}
void
g_signal_handler_unblock (gpointer instance,
- guint handler_id)
+ gulong handler_id)
{
Handler *handler;
if (handler->block_count)
handler->block_count -= 1;
else
- g_warning (G_STRLOC ": handler `%u' of instance `%p' is not blocked", handler_id, instance);
+ g_warning (G_STRLOC ": handler `%lu' of instance `%p' is not blocked", handler_id, instance);
}
else
- g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
+ g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id);
G_UNLOCK (g_signal_mutex);
}
void
g_signal_handler_disconnect (gpointer instance,
- guint handler_id)
+ gulong handler_id)
{
Handler *handler;
guint signal_id;
handler = handler_lookup (instance, handler_id, &signal_id);
if (handler)
{
- handler->id = 0;
+ handler->sequential_number = 0;
handler->block_count = 1;
handler_unref_R (signal_id, instance, handler);
}
else
- g_warning ("%s: instance `%p' has no handler with id `%u'", G_STRLOC, instance, handler_id);
+ g_warning ("%s: instance `%p' has no handler with id `%lu'", G_STRLOC, instance, handler_id);
G_UNLOCK (g_signal_mutex);
}
/* cruel unlink, this works because _all_ handlers vanish */
tmp->next = NULL;
tmp->prev = tmp;
- if (tmp->id)
+ if (tmp->sequential_number)
{
- tmp->id = 0;
+ tmp->sequential_number = 0;
handler_unref_R (0, NULL, tmp);
}
}
G_UNLOCK (g_signal_mutex);
}
-guint
+gulong
g_signal_handler_find (gpointer instance,
GSignalMatchType mask,
guint signal_id,
gpointer func,
gpointer data)
{
- guint handler_id = 0;
+ gulong handler_seq_no = 0;
g_return_val_if_fail (G_TYPE_CHECK_INSTANCE (instance), 0);
g_return_val_if_fail ((mask & ~G_SIGNAL_MATCH_MASK) == 0, 0);
mlist = handlers_find (instance, mask, signal_id, detail, closure, func, data, TRUE);
if (mlist)
{
- handler_id = mlist->handler->id;
+ handler_seq_no = mlist->handler->sequential_number;
handler_match_free1_R (mlist, instance);
}
G_UNLOCK (g_signal_mutex);
}
- return handler_id;
+ return handler_seq_no;
}
static guint
gpointer func,
gpointer data,
void (*callback) (gpointer instance,
- guint handler_id))
+ gulong handler_seq_no))
{
HandlerMatch *mlist;
guint n_handlers = 0;
while (mlist)
{
n_handlers++;
- G_UNLOCK (g_signal_mutex);
- callback (instance, mlist->handler->id);
- G_LOCK (g_signal_mutex);
+ if (mlist->handler->sequential_number)
+ {
+ G_UNLOCK (g_signal_mutex);
+ callback (instance, mlist->handler->sequential_number);
+ G_LOCK (g_signal_mutex);
+ }
mlist = handler_match_free1_R (mlist, instance);
}
Handler *handler_list = NULL;
GValue *return_accu, accu = { 0, };
guint signal_id = node->signal_id;
+ gulong max_sequential_handler_number;
gboolean return_value_altered = FALSE;
#ifdef G_ENABLE_DEBUG
if (handler_list)
handler_unref_R (signal_id, instance, handler_list);
+ max_sequential_handler_number = g_handler_sequential_number;
hlist = handler_list_lookup (signal_id, instance);
handler_list = hlist ? hlist->handlers : NULL;
if (handler_list)
handler_list = handler;
break;
}
- else if (!handler->block_count && (!handler->detail || handler->detail == detail))
+ else if (!handler->block_count && (!handler->detail || handler->detail == detail) &&
+ handler->sequential_number < max_sequential_handler_number)
{
G_UNLOCK (g_signal_mutex);
g_closure_invoke (handler->closure,
{
Handler *tmp;
- if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail))
+ if (handler->after && !handler->block_count && (!handler->detail || handler->detail == detail) &&
+ handler->sequential_number < max_sequential_handler_number)
{
G_UNLOCK (g_signal_mutex);
g_closure_invoke (handler->closure,
void g_signal_stop_emission (gpointer instance,
guint signal_id,
GQuark detail);
-guint g_signal_add_emission_hook (guint signal_id,
+gulong g_signal_add_emission_hook (guint signal_id,
GQuark quark,
GSignalEmissionHook hook_func,
gpointer hook_data,
GDestroyNotify data_destroy);
void g_signal_remove_emission_hook (guint signal_id,
- guint hook_id);
+ gulong hook_id);
/* --- signal handlers --- */
guint signal_id,
GQuark detail,
gboolean may_be_blocked);
-guint g_signal_connect_closure_by_id (gpointer instance,
+gulong g_signal_connect_closure_by_id (gpointer instance,
guint signal_id,
GQuark detail,
GClosure *closure,
gboolean after);
-guint g_signal_connect_closure (gpointer instance,
+gulong g_signal_connect_closure (gpointer instance,
const gchar *detailed_signal,
GClosure *closure,
gboolean after);
-guint g_signal_connect_data (gpointer instance,
+gulong g_signal_connect_data (gpointer instance,
const gchar *detailed_signal,
GCallback c_handler,
gpointer data,
gboolean swapped,
gboolean after);
void g_signal_handler_block (gpointer instance,
- guint handler_id);
+ gulong handler_id);
void g_signal_handler_unblock (gpointer instance,
- guint handler_id);
+ gulong handler_id);
void g_signal_handler_disconnect (gpointer instance,
- guint handler_id);
-guint g_signal_handler_find (gpointer instance,
+ gulong handler_id);
+gulong g_signal_handler_find (gpointer instance,
GSignalMatchType mask,
guint signal_id,
GQuark detail,