[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-bindings
Subject:    Re: [Kde-bindings] A sample of our subset of QtC
From:       Germain Garand <germain () ebooksfrance ! com>
Date:       2003-01-12 5:10:28
[Download RAW message or body]

Le Samedi 11 Janvier 2003 19:48, Ashley Winters a écrit :
> --- Richard Dale <Richard_Dale@tipitina.demon.co.uk> wrote:
> > On Friday 10 January 2003 8:20 pm, Adam Treat wrote:
> > I don't convert any of the methods
> > with HANDLE
> > and 'Display *' types because they're X11 specific, and I'm only
> > interested
> > in a cross platform api (in java anyway).
>
> Makes sense. I wonder if you could... arrange for the ISXXX OS macros
> to all be undefined when you drive the headers through -fdump-t-u, so
> no platform-specific functions are included.

a trivial solution could be to make a filtered copy of the headers in a temp 
dir, and feed that into gcc...

Attached is a diff of my preprocessor code for kalyptus ; its complete, 
recursive, etc. - except for function-like macros... you can define whatever 
symbols you need at startup and choose those that you want read-only...

I can turn that into a script that would do the above, unless there is a 
simple gcc command line solution



["kalyptus.diff" (text/x-diff)]

Index: kalyptus
===================================================================
RCS file: /home/kde/kdebindings/kalyptus/kalyptus,v
retrieving revision 1.48
diff -u -p -r1.48 kalyptus
--- kalyptus	6 Jan 2003 03:50:33 -0000	1.48
+++ kalyptus	12 Jan 2003 05:07:47 -0000
@@ -21,12 +21,12 @@ use kdocAstUtil;
 use kdocParseDoc;
 
 use vars qw/ %rootNodes $declNodeType %options @formats_wanted
-        @includeclasses $includeclasses $skipInternal %defines $defines \
$match_qt_defines +        @includeclasses $includeclasses $skipInternal %defines \
%readonly_def $defines @readonly  $libdir $libname $outputdir @libs $striphpath \
$doPrivate $readstdin  $Version $quiet $debug $debuggen $parseonly $currentfile \
$cSourceNode $exe  %formats %flagnames $rootNode @classStack $cNode
 	$lastLine $docNode @includes $cpp $defcppcmd $cppcmd $docincluded
-	$inExtern %stats %definitions @inputqueue @codeqobject /;
+	$inExtern %stats @inputqueue @codeqobject /;
      
 ## globals
 
@@ -88,40 +88,12 @@ CODE
 %flagnames = ( v => 'virtual', 's' => 'static', p => 'pure',
 	c => 'const', l => 'slot', i => 'inline', n => 'signal' );
 
-%definitions = {
-    _STYLE_CDE => '',
-    _STYLE_MOTIF => '',
-    _STYLE_MOTIF_PLUS => '',
-    PLUS => '',
-    _STYLE_PLATINUM => '',
-    _STYLE_SGI => '',
-    _STYLE_WINDOWS => '',
-    QT_STATIC_CONST => 'static const',
-    Q_EXPORT => '',
-    Q_REFCOUNT => '',
-    QM_EXPORT_CANVAS => '',
-    QM_EXPORT_DNS => '',
-    QM_EXPORT_ICONVIEW => '',
-    QM_EXPORT_NETWORK => '',
-    QM_EXPORT_SQL => '',
-    QM_EXPORT_WORKSPACE => '',
-    QT_NO_REMOTE => 'QT_NO_REMOTE',
-    QT_ACCESSIBILITY_SUPPORT => 'QT_ACCESSIBILITY_SUPPORT',
-    Q_WS_X11 => 'Q_WS_X11',
-    Q_DISABLE_COPY => 'Q_DISABLE_COPY',
-    Q_WS_QWS => 'undef',
-    Q_WS_MAC => 'undef',
-    Q_OBJECT => <<'CODE',
-public:
-    virtual QMetaObject *metaObject() const;
-    virtual const char *className() const;
-    virtual bool qt_invoke( int, QUObject* );
-    virtual bool qt_emit( int, QUObject* );
-    static QString tr( const char *, const char * = 0 );
-    static QString trUtf8( const char *, const char * = 0 );
-private:
-CODE
-};
+# this hash holds name of symbols that must not be modified
+# during preprocessing
+
+%readonly_def = ( "signals" => 1,
+                  "slots"   => 1,
+                );
 
 =head1 KDOC -- Source documentation tool 
 
@@ -161,8 +133,8 @@ GetOptions( \%options,
 	"cppcmd|C=s",	\$cppcmd,
 	"includedir|I=s", \@includes,
 	"define=s", \%defines, # define a single preprocessing symbol
-	"defines=s", \$defines, # file containing preprocessing symbols, one per line
-
+	"defines=s",	\$defines, # file containing initial preprocessing directives (#define \
...) +        "readonly-symbols|R=s",	\@readonly, # symbols whose value shouldn't be \
modified at runtime  "quiet|q",	\$quiet,
 	"debug|D",	\$debug, # debug the parsing
 	"debuggen",	\$debuggen, # debug the file generation
@@ -204,42 +176,16 @@ if( $defines )
 {
     open( DEFS, $defines ) or die "Couldn't open $defines: $!\n";
     my @defs = <DEFS>;
-    chomp @defs;
     close DEFS;
-    foreach (@defs)
-    {
-        $defines{ $_ } = 1 unless exists $defines{ $_ };
-    }
+    @inputqueue = @defs;
+    readCxxLine();
 }
 
-# Check the %defines hash for QT_* symbols and compile the corresponding RE
-# Otherwise, compile the default ones. Used for filtering in readCxxLine.
-if ( my @qt_defines = map { ($_=~m/^QT_(.*)/)[0] } keys %defines)
-{
-    my $regexp = "m/^#\\s*ifn?def\\s+QT_(?:" . join('|', map { "\$qt_defines[$_]" } \
                0..$#qt_defines).")/o";
-    $match_qt_defines = eval "sub { my \$s=shift;
-                                   \$s=~/^#\\s*if(n)?def/ || return 0;
-                                   if(!\$1) { return \$s=~$regexp ? 0:1 }
-                                   else { return \$s=~$regexp ? 1:0 }
-                                  }";
-    die if $@;
-}
-else
-{
-    $match_qt_defines = eval q£
-    sub
-    {
-        my $s = shift;
-        $s =~ m/^\#\s*ifndef\s+QT_NO_(?:REMOTE| # not in the default compile options
-                                        NIS|    #  ...
-                                        XINERAMA|
-                                        IMAGEIO_(?:MNG|JPEG)|
-                                        STYLE_(?:MAC|INTERLACE|COMPACT)
-                                     )/x;
-    }
-    £;
-    die if $@;
-}
+# set readonly flags on given symbols
+@readonly = split /,/, join(',', @readonly);
+map { $readonly_def{ $_ } = 1 } @readonly;
+
+
 # Check if there any files to process.
 # We do it here to prevent the libraries being loaded up first.
 
@@ -419,13 +365,21 @@ sub readSourceLine
 	Reads a C++ source line, skipping comments, blank lines,
 	preprocessor tokens and the Q_OBJECT macro
 
+        Added a simple preprocessor - G.Garand<germain@ebooksfrance.com>
+
 =cut
 
+BEGIN {
+
+my @ifstack;
+
 sub readCxxLine
 {
 	my( $p );
 	my( $l );
+        my $idlock = ""; # prevent expansion of self-referential macros
 	
+INPUTLOOP:
 	while( 1 ) {
 		$p = shift @inputqueue || <INPUT>;
 		return undef if !defined ($p);
@@ -449,15 +403,29 @@ LOOP:
 			push @inputqueue, @codeqobject;
 			next;
 		}
-		# Hack, waiting for real handling of preprocessor defines
-		$p =~ s/QT_STATIC_CONST/static const/;
-		$p =~ s/KSVG_GET/KJS::Value get();/;
-		$p =~ s/KSVG_BASECLASS_GET/KJS::Value get();/;
-		$p =~ s/KSVG_BRIDGE/KJS::ObjectImp *bridge();/;
-		$p =~ s/KSVG_FORWARDGET/KJS::Value getforward();/;
-		$p =~ s/KSVG_PUT/bool put();/;
-		$p =~ s/KSVG_FORWARDPUT/bool putforward();/;
-		$p =~ s/KSVG_BASECLASS/virtual KJS::Value cache();/;
+		# Expand preprocessor defines
+                if ($p !~ /^\s*#/ and $p !~ m#.*\\\s*$# )
+                {
+                    while( $p=~/[a-zA-Z_]+[a-zA-Z0-9_]*/g )
+                    {
+                        if(exists $defines{$&} and $idlock ne $&)
+                        {
+                            $idlock ||= $&;
+                            my $subst = "${defines{$&}}";
+                            my $pos= pos $p;
+                            my $len=length($&);
+                            my $prev = $`;
+                            next if $prev=~s/(?<!\\)"/"/g % 2; # do not interpolate \
inside double quotes +                            substr($p,($pos-$len),$len) = \
$subst; +                            push @inputqueue, split(/\n/, $p);
+                            print "Input queue:\n". join ("\n", @inputqueue) \
."\n----\n" if $debug; +                            next INPUTLOOP;
+                        }
+                    }
+                }
+                $idlock = "";
+
+                # function-like macros aren't handled yet
 		if ( $p =~ m/KSVG_DEFINE_PROTOTYPE\((\w+)\)/ ) {
 			push @inputqueue, split('\n',"namespace KSVG {\nclass $1 {\n};\n};");
 		}
@@ -491,34 +459,115 @@ LOOP:
 				print "Cont: $_" if $debug;
 			}
 			else {
-				# Skip platform-specific stuff, or #if 0 stuff
-				# or #else of something we parsed (e.g. for QKeySequence)
-				if ( $p =~ m/^#\s*ifdef\s*Q_WS_/ or
-				     $p =~ m/^#\s*if\s+defined\(Q_WS_/ or
-				     $p =~ m/^#\s*if\s+defined\(Q_OS_/ or
-				     $p =~ m/^#\s*if\s+defined\(QT_THREAD_SUPPORT/ or
-				     $p =~ m/^#\s*else/ or
-				     $p =~ m/^#\s*if\s+defined\(Q_FULL_TEMPLATE_INSTANTIATION/ or
-				     $p =~ m/^#\s*ifdef\s+CONTAINER_CUSTOM_WIDGETS/ or
-				     &$match_qt_defines( $p ) or
-				     $p =~ m/^#\s*if\s+0\s+/ ) {
+                                # print "ifstack: ". join(" | ", @ifstack) . "\n" if \
$debug and @ifstack; +                                my $skip;
+                                if ($p =~ /^\s*#\s*(el)?if/ )
+                                {
+                                   push @ifstack, 1 unless $1;
+                                   if($ifstack[$#ifstack])
+                                   {
+                                     my $e = $p;
+                                     $e =~ s/^\s*#\s*//;
+                                     $e =~ s/^(el)?if\s//;
+                                     $e =~ s/(?<!")[a-zA-Z_]+[a-zA-Z0-9_]*(?!")/
+                                                   ($& eq "defined" or
+                                                    $& eq "ifdef" or
+                                                    $& eq "ifndef") ? $& : \
"\$defines\{\"$&\"\}"/ge; +                                     $e =~ \
s/^if(n)?def\s+(\S+)/($1?"!":"")." exists($2)"/e; +                                   \
$e =~ s/defined\s*\((.*?)\)/exists($1)/g; +                                     print \
"eval: $e\n" if $debug; +                                     $skip = eval "($e) ? 0 \
: 1"; +                                     if($@)
+                                     {
+                                       warn "Unhandled #if expression : $p - eval'ed \
as $e - $@\nSkipping.\n"; +                                       $skip = 1;
+                                     }
+                                   }
+                                   else
+                                   { $skip = 1 }
+                                }
+                                elsif ($p =~ /\s*#\s*else/)
+                                {
+                                  !$ifstack[$#ifstack] and $skip = 1;
+                                }
+                                elsif ($p =~ /^\s*#\s*endif/)
+                                {
+                                  pop @ifstack;
+                                  next INPUTLOOP;
+                                }
+                                elsif ($p =~ /\s*\#\s*define\s+
+                                               ([a-zA-Z_]+[a-zA-Z0-9_]*) # 1) \
identifier +                                               (\(.*?\))?                \
# 2) function-like macro args +                                               \
\s+([^\\]*)               # 3) value +                                               \
(\\)?                     # 4) multiline +                                            \
\s*$/x) +                                {
+                                    if(defined $2)
+                                    {
+                                        # skip for now
+                                        if(defined $4)
+                                        {
+                                            while ( defined $p && $p =~ m#\\\s*$# )
+                                            { $p = <INPUT>; }
+                                        }
+                                        next INPUTLOOP;
+                                    }
+                                    elsif(defined $4)
+                                    {
+                                        my $def = "";
+                                        my $symbol = $1;
+                                        my $match  = $3;
+                                        # multiline macros
+                                        do {
+                                           $def .= $match . "\n";
+                                           $p = <INPUT>;
+
+                                        }while ( defined $p and $p =~ m#(.*)\\\s*$# \
and $match = $1 ); +                                        $def .= $p if defined $p;
+                                        do {
+                                          $defines{ $symbol } = $def;
+                                          print "Defining multiline $symbol => \
$def\n" if $debug; +                                        } unless $readonly_def{ \
$symbol }; +                                    }
+                                    else
+                                    {
+                                        my $val = defined $3 ? $3 : undef;
+                                        chomp $val;
+                                        do {
+                                            $defines{ $1 } = $val;
+                                            print "Defining $1 => $val\n" if $debug;
+                                        } unless $readonly_def{ $1 };
+                                        next INPUTLOOP;
+                                    }
+                                }
+                                elsif ($p =~ \
/\s*#\s*undef\s+([a-zA-Z_]+[a-zA-Z0-9_]*)\s*$/) +                                {
+                                    delete $defines{ $1 } unless $readonly_def{ $1 \
}; +                                    next INPUTLOOP;
+                                }
+
+				if (defined $skip && $skip) {
 				     my $if_depth = 1;
 				     while ( defined $p && $if_depth > 0 ) {
 					 $p = <INPUT>;
 					 last if !defined $p;
-					 $if_depth++ if $p =~ m/^#\s*if/;
-					 $if_depth-- if $p =~ m/^#\s*endif/;
+					 $if_depth++ if $p =~ m/^\s*#\s*if/;
+					 $if_depth-- if $p =~ m/^\s*#\s*endif/;
 					 # Exit at #else in the #ifdef QT_NO_ACCEL/#else/#endif case
-					 last if $if_depth == 1 && $p =~ m/^#\s*else\s/;
-					 #ignore elif for now
+					 if ($if_depth == 1 && $p =~ /^\s*#\s*el(if\s|se)/)
+                                         {
+                                             push @inputqueue, $p;
+                                             next INPUTLOOP;
+                                         }
 					 print "Skipping ifdef'ed line: $p" if $debug;
 				     }
+                                     pop @ifstack
 				}
-
-				# multiline macros
-				while ( defined $p && $p =~ m#\\\s*$# ) {
-					$p = <INPUT>;
+                                elsif(defined $skip)
+                                {
+                                  $ifstack[$#ifstack] --
 				}
+
 			}
 			next;
 		}
@@ -526,6 +575,8 @@ LOOP:
 		$lastLine = $p;
 		return $p;
 	}
+}
+
 }
 
 =head2 readCxxCodeBlock


_______________________________________________
Kde-bindings mailing list
Kde-bindings@mail.kde.org
http://mail.kde.org/mailman/listinfo/kde-bindings

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic