You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucy.apache.org by ma...@apache.org on 2006/07/06 18:25:12 UTC

svn commit: r419607 - in /lucene/lucy/trunk/charmonizer: ./ README interpreters/ interpreters/perl/ interpreters/perl/Charmonizer.pm modules/ modules/end.charm modules/integers.charm modules/start.charm

Author: marvin
Date: Thu Jul  6 09:25:11 2006
New Revision: 419607

URL: http://svn.apache.org/viewvc?rev=419607&view=rev
Log:
Add Charmonizer, a mini-language for writing portable C header files.  A
prototype interpreter written in Perl is provided.

Added:
    lucene/lucy/trunk/charmonizer/
    lucene/lucy/trunk/charmonizer/README
    lucene/lucy/trunk/charmonizer/interpreters/
    lucene/lucy/trunk/charmonizer/interpreters/perl/
    lucene/lucy/trunk/charmonizer/interpreters/perl/Charmonizer.pm
    lucene/lucy/trunk/charmonizer/modules/
    lucene/lucy/trunk/charmonizer/modules/end.charm
    lucene/lucy/trunk/charmonizer/modules/integers.charm
    lucene/lucy/trunk/charmonizer/modules/start.charm

Added: lucene/lucy/trunk/charmonizer/README
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/charmonizer/README?rev=419607&view=auto
==============================================================================
--- lucene/lucy/trunk/charmonizer/README (added)
+++ lucene/lucy/trunk/charmonizer/README Thu Jul  6 09:25:11 2006
@@ -0,0 +1,178 @@
+NAME
+
+    Charmonizer - Mini-language targeted at writing portable C headers.
+
+OVERVIEW
+
+    Charmonizer is a tool for writing portable C header files.  It is
+    implemented using a small domain-specific language, also called
+    "Charmonizer", and a "native" interpreter, written in a language such as
+    Perl or Ruby.
+    
+    The Charmonizer language is neither succinct, nor flexible, nor powerful,
+    because the project's primary design specs did not require it to be any of
+    those things:
+    
+      1. It must write portable C header files.
+      2. It must require only a C compiler and the native build enviroment.
+      3. It must be easy to write a robust, reliable Charmonizer interpreter.
+    
+    Charmonizer source code consists of a linear series of function calls.
+    There are no conditionals, no loops, and no variables.  Of course it's
+    challenging to get much done without conditionals or variables, but
+    Charmonizer is able to rely upon C's preprocessor for those.  
+    
+    Charmonizer doesn't require complex functionality because basically all
+    it needs to do is attempt compilation of miniature C programs and capture
+    output from them when they build successfully.  If the C preprocessor had
+    exception handling along the lines of Perl's "eval $string" functionality
+    (ha ha), Charmonizer-the-language wouldn't be necessary.
+
+PROGRAM STRUCTURE
+
+    Each run of Charmonizer follows this outline:
+    
+        I.   Initialize a temporary target file named _charmonize.c 
+        II.  Process a series of .charm files, appending _charmonize.c as
+             they indicate.
+        III. Compile _charmonize.c, run it, and capture its output to a new
+             file: the portable C header file.
+
+    Each of these steps requires a Charmonizer interpreter.  Consult the
+    documentation of your favorite among them for details.
+
+CHARMONIZER SOURCE FILES
+
+    Charmonizer source files, as mentioned above, consist of a linear series of
+    function calls.  The first function called must always be CH_api_version.
+
+    The preferred file extension is '.charm'.
+  
+LANGUAGE SYNTAX
+
+    Functions names begin with 'CH_', and all function calls must be
+    terminated with a corresponding close directive beginning with 'CH_end_'.
+    For instance, if Charmonizer had a CH_print function, here's how it
+    might work:
+    
+        CH_print
+          string Hello, world.
+        CH_end_print
+    
+    However, Charmonizer doesn't have a CH_print function, because it
+    doesn't need one.
+    
+    Files are parsed line by line.  Leading whitespace at the front of any
+    line gets ignored (unless it is part of a quoted string), so Charmonizer
+    files can be sensibly indented.
+    
+    Each line falls into one of five categories:
+    
+      * blank 
+      * start of a function
+      * end of a function
+      * name-value parameter pair 
+      * part of a multi-line quoted string
+    
+    Quoted strings begin with 'CH_quote' and are terminated by
+    'CH_end_quote'.  The strings are completely literal -- no interpolation,
+    and no escapes.  (If for some odd reason you want to embed the text
+    "CH_quote" within a string, you're out of luck.)
+
+        CH_append_raw
+          string CH_quote
+            #define TYPEDEF_PREFIX "lucy_"
+          CH_end_quote
+        CH_end_append_raw
+
+    C-style multi-line comments delimited by '/*' and '*/' are allowed.
+    Comment delimiters within quoted strings are treated as literal text, not
+    comments.
+    
+        /* This is a valid comment. */
+        CH_append_raw
+          string CH_quote
+            /* This comment will end up in _charmonize.c */
+            /* This un-terminated comment will mess up _charmonize.c,
+             * but it's not invalid Charmonizer syntax, as it's 
+             * within a quoted string.
+          CH_end_quote
+        CH_end_append_raw /* This is another valid comment. */
+    
+    All functions accept only named parameters in the form of key-value pairs.
+    Parameter names must consist of only pure ASCII alphanumerics plus the
+    underscore, and cannot start with a digit.  
+
+        CH_do_something
+          an-illegal-parameter oops
+          4nother_illegal_parameter 4RGH!
+          a_valid_parameter Ah! Just right. /* value is "Ah! Just right." */
+        CH_end_do_something
+    
+    The value of the parameter starts with the first non-whitespace character
+    following the key and is terminated immediately following the last
+    non-whitespace character in the line (not including comments, which are
+    stripped beforehand).  In the event you need a value with leading or
+    trailing whitespace (e.g. a terminating newline, which won't ordinarily be
+    there) use the CH_quote mechanism.
+
+FUNCTIONS
+
+    CH_append_raw
+
+            CH_append_raw
+              string CH_quote
+                #define CONSTANT_PREFIX "LUCY_"
+              CH_end_quote
+            CH_end_append_raw
+
+        Append verbatim contents of the specified string to the target file.
+
+
+    CH_append_output
+
+            CH_append_output
+              source CH_quote
+                #include <stdio.h>
+                int main() 
+                {
+                    printf("#define SIZEOF_LONG %d\n", (int)sizeof(long));
+                    return 0;
+                }
+              CH_end_quote
+            CH_end_append_output
+
+        Compile the supplied source code and append its output to the target
+        file.  If the code fails to compile, do nothing.
+
+    CH_api_version
+    
+            CH_api_version
+              api_version 0.01
+            CH_end_api_version
+
+        Indicate the version of Charmonizer that a .charm file conforms to.
+
+AUTHOR
+
+    Marvin Humphrey, <marvin at rectangular dot com>
+
+COPYRIGHT AND LICENSE
+
+    /**
+     * Copyright 2006 The Apache Software Foundation
+     *
+     * Licensed under the Apache License, Version 2.0 (the "License");
+     * you may not use this file except in compliance with the License.
+     * You may obtain a copy of the License at
+     *
+     *     http://www.apache.org/licenses/LICENSE-2.0
+     *
+     * Unless required by applicable law or agreed to in writing, software
+     * distributed under the License is distributed on an "AS IS" BASIS,
+     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+     * implied.  See the License for the specific language governing
+     * permissions and limitations under the License.
+     */
+
+

Added: lucene/lucy/trunk/charmonizer/interpreters/perl/Charmonizer.pm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/charmonizer/interpreters/perl/Charmonizer.pm?rev=419607&view=auto
==============================================================================
--- lucene/lucy/trunk/charmonizer/interpreters/perl/Charmonizer.pm (added)
+++ lucene/lucy/trunk/charmonizer/interpreters/perl/Charmonizer.pm Thu Jul  6 09:25:11 2006
@@ -0,0 +1,399 @@
+package Charmonizer;
+use strict;
+use warnings;
+
+our $VERSION = 0.01;
+
+use Carp;
+use Config;
+use File::Spec::Functions qw( rel2abs );
+
+our %class_defaults = (
+    modules        => [],
+    out_path       => undef,
+    compiler       => $Config{cc},
+    charmonizer_fh => undef,
+    clean_up       => 1,
+);
+
+sub new {
+    my $class = shift;
+    $class = ref($class) || $class;
+    my $self = bless {%class_defaults}, $class;
+
+    # verify params
+    while (@_) {
+        my ( $var, $val ) = ( shift, shift );
+        confess "Unrecognized param: '$var'"
+            unless exists $class_defaults{$var};
+        $self->{$var} = $val;
+    }
+    confess "Missing required parameter 'out_path'"
+        unless defined $self->{out_path};
+    confess "No modules supplied" unless @{ $self->{modules} };
+
+    # test for a working C compiler, without which all hope is lost
+    open( my $charmonizer_fh, '>', '_charmonize.c' )
+        or confess("Can't open '_charmonize.c': $!");
+    print $charmonizer_fh "int main(){ return 0; }";
+    close $charmonizer_fh or confess("Can't close '_charmonize.c': $!");
+    system( $self->{compiler}, '-o', '_charmonize', '_charmonize.c' )
+        and confess("Test compilation failed");
+
+    # reopen _charmonize.c, clobbering previous test content
+    open( $charmonizer_fh, '>', '_charmonize.c' )
+        or confess("Can't open '_charmonize.c': $!");
+    $self->{charmonizer_fh} = $charmonizer_fh;
+
+    # parse and prepare all modules.
+    my @modules;
+    for my $module_path ( @{ $self->{modules} } ) {
+        push @modules,
+            Charmonizer::Module->new(
+            charmonizer_fh => $charmonizer_fh,
+            path           => $module_path,
+            compiler       => $self->{compiler},
+            );
+    }
+    $self->{modules} = \@modules;
+
+    return $self;
+}
+
+sub run {
+    my $self           = shift;
+    my $charmonizer_fh = $self->{charmonizer_fh};
+
+    # write _charmonize.c
+    $_->run for @{ $self->{modules} };
+    close $charmonizer_fh or confess("Can't close '_charmonize.c': $!");
+
+    # compile _charmonize.c and capture its output
+    system( $Config{cc}, '-o', '_charmonize', '_charmonize.c' )
+        and confess("_charmonize.c failed to compile");
+    my $command = rel2abs('_charmonize');
+    open( my $out_fh, '>', $self->{out_path} )
+        or confess("Can't open '$self->{out_path}': $!");
+    print $out_fh `$command`;
+
+    # clean up
+    for ( '_charmonize.c', '_charmonize' ) {
+        next unless -e $_;
+        unlink $_ or confess("Couldn't unlink '$_': $!");
+    }
+}
+
+package Charmonizer::Module;
+use strict;
+use warnings;
+
+use Carp;
+use File::Spec::Functions qw( rel2abs );
+
+my $end_of_line   = qr/(?:\015\012|\012|\015|\z)/;
+my $identifier    = qr/\b[a-zA-Z_][a-zA-Z0-9_]*\b/;
+my $start_quote   = qr/CH_quote/;
+my $end_quote     = qr/CH_end_quote/;
+my $start_comment = qr#/\*#;
+my $end_comment   = qr#\*/#;
+
+sub new {
+    my $unused = shift;
+    my $self = bless {
+        tree => [],      # more of a dowel, actually (no branches)
+        code => undef,
+        @_
+        },
+        __PACKAGE__;
+
+    # if code wasn't supplied, get it from a file
+    if ( !defined $self->{code} ) {
+        open( my $module_fh, '<', $self->{path} )
+            or confess("Can't open '$self->{path}': $!");
+        $self->{code} = do { local $/; <$module_fh> };
+        close $module_fh or confess("Can't close '$self->{path}': $!");
+    }
+
+    # parse now, rather than when run() is called.
+    $self->_parse;
+
+    return $self;
+}
+
+# Parse the source, checking for syntax errors.
+sub _parse {
+    my $self = shift;
+    my $tree = $self->{tree};
+    my $code = $self->_strip_comments( $self->{code} );
+    my %inside;
+    my $func_nick;
+    my $args = {};
+    my ( $param, $value ) = ( '', '' );
+    my $line_number = 0;
+
+    # consume copy of source line by line
+LINE: while ( length $code and $code =~ s/(.*?$end_of_line)//s ) {
+        my $line = $1;
+        $line_number++;
+
+        # append the line to a value if we're inside a quoted string.
+        if ( $inside{quote} ) {
+            if ( $line =~ s/^\s*CH_end_quote// ) {
+                $inside{quote} = 0;
+                $args->{$param} = $value;
+                ( $param, $value ) = ( '', '' );
+            }
+            else {
+                $value .= $line;
+            }
+            next LINE;
+        }
+
+        if ( $inside{function} ) {
+            # if we've reached the end of a function, add a node to the tree
+            if ( $line =~ s/^\s*CH_end_$func_nick// ) {
+                push @$tree,
+                    {
+                    function => $inside{function},
+                    args     => $args,
+                    };
+                $inside{function} = 0;
+                undef $func_nick;
+                $args = {};
+            }
+            # add a named parameter
+            elsif ( $line =~ s/^\s*($identifier)\s+(.*?)\s*$// ) {
+                ( $param, $value ) = ( $1, $2 );
+                # check for start of quoted string
+                if ( $value =~ s/^$start_quote// ) {
+                    $inside{quote} = 1;
+                    # check for quote close
+                    if ( $value =~ s/$end_quote\s*$// ) {
+                        $inside{quote} = 0;
+                        $args->{$param} = $value;
+                    }
+                    else {
+                        next LINE;
+                    }
+                }
+                # no quoted string, so add the param
+                else {
+                    $args->{$param} = $value;
+                }
+            }
+        }
+
+        # start a function
+        if ( $line =~ s/\s*(CH_(\w+))// ) {
+            # don't allow nested functions
+            if ( $inside{function} ) {
+                confess(  "Parse error: already inside $inside{function} "
+                        . "at line $line_number" );
+            }
+            $inside{function} = $1;
+            $func_nick = $2;
+        }
+
+        # if there's anything other than whitespace left, it's a syntax error
+        if ( $line =~ /\S/ ) {
+            confess("Syntax error at $self->{path} line $line_number");
+        }
+    }
+
+    # Require all modules to name their api version
+    if ( $tree->[0]{function} ne "CH_api_version" ) {
+        confess("$self->{path} doesn't begin with CH_api_version");
+    }
+}
+
+# Remove comments from source, but preserve newlines (and thus line numbers).
+sub _strip_comments {
+    my ( $self, $code ) = @_;
+    my $new_code    = '';
+    my $line_number = 1;
+
+    for ($code) {
+        while ( length($_) ) {
+            if (s/^(.*?)($start_quote|$start_comment)//s) {
+                # append everything up to the quote/comment
+                my ( $preceding_code, $delimiter ) = ( $1, $2 );
+                $new_code .= $preceding_code;
+                $line_number += $self->_count_newlines($preceding_code);
+
+                if ( $delimiter eq 'CH_quote' ) {
+                    # it's a quote, so include the quote and the delimiters
+                    $new_code .= $delimiter;
+                    s/^(.*?$end_quote)//s
+                        or confess(
+                              "Unterminated quote starting at $self->{path} "
+                            . "line $line_number" );
+                    $new_code .= $1;
+                }
+                else {
+                    # it's a comment, so strip it
+                    s/^(.*?$end_comment)//s
+                        or confess(
+                        "Unterminated comment starting at $self->{path} "
+                            . "line $line_number" );
+                    $line_number += $self->_count_newlines($1);
+                }
+            }
+            # once we've passed the last comment/quote, concat the rest
+            else {
+                $new_code .= $_;
+                $_ = '';
+            }
+        }
+    }
+
+    return $new_code;
+}
+
+sub run {
+    my $self = shift;
+
+    # process nodes linearly
+    for my $node ( @{ $self->{tree} } ) {
+        my $func = $node->{function};
+        $self->$func( $node->{args} );
+    }
+}
+
+# Helper function for determining line number.
+sub _count_newlines {
+    my $code         = shift;
+    my $num_newlines = 0;
+    while ( length $code and $code =~ s/.*?$end_of_line//g ) {
+        $num_newlines++;
+    }
+    return $num_newlines;
+}
+
+sub CH_api_version {
+    my ( $self, $args ) = @_;
+    if ( int( $args->{version} ) > int($Charmonizer::VERSION) ) {
+        confess(  "File '$self->{path}' version $args->{api_version} "
+                . "incompatible with Charmonizer version $Charmonizer::VERSION"
+        );
+    }
+}
+
+sub CH_append_raw {
+    my ( $self, $args ) = @_;
+    my $charmonizer_fh = $self->{charmonizer_fh};
+    confess(  "Missing required argument 'string' at $self->{path} "
+            . "line $args->{line_number}" )
+        unless defined $args->{string};
+    print $charmonizer_fh $args->{string};
+}
+
+sub CH_append_output {
+    my ( $self, $args ) = @_;
+    my $charmonizer_fh = $self->{charmonizer_fh};
+
+    # print the test code to a probe C file
+    open( my $probe_fh, '>', '_ch_probe.c' )
+        or confess("Can't open '_ch_probe.c': $!");
+    print $probe_fh $args->{source};
+    close $probe_fh or confess("Can't close '_ch_probe.c': $!");
+
+    # suppress error messages, since we know some of these will fail.
+    open( ERRCOPY, ">&STDERR" ) or confess $!;
+    close STDERR or confess $!;
+    my $succeeded
+        = system( $self->{compiler}, '-o', '_ch_probe', '_ch_probe.c' ) == 0;
+    open( STDERR, ">&ERRCOPY" ) or confess $!;
+    close ERRCOPY or confess $!;
+
+    # append the output of the compiled program to the
+    if ($succeeded) {
+        my $command = rel2abs('_ch_probe');
+        print $charmonizer_fh `$command`;
+    }
+
+    # clean up probe files
+    for ( '_ch_probe', '_ch_probe.c' ) {
+        next unless -e $_;
+        unlink $_ or confess "Can't unlink file '$_': $!";
+    }
+}
+
+1;
+
+__END__
+
+=head1 NAME
+
+Charmonizer - Write portable C header files.
+
+=head1 SYNOPSIS
+
+    my $charmonizer = Charmonizer->new(
+        modules => [
+            'modules/start.charm',
+            'modules/integers.charm',
+            'modules/end.charm',
+        ],
+        out_path => 'charmonized.h',
+    );
+    $charmonizer->run;
+
+=head1 DESCRIPTION
+
+The Charmonizer class supplies an interpreter for the Charmonizer language,
+which is used to write portable C header files.  There are only two methods,
+because all the functionality is in the Charmonizer language itself.
+
+=head1 METHODS
+
+=head2 new
+
+Constructor.  Takes hash-style labeled parameters.
+
+=over
+
+=item *
+
+B<modules> -- an arrayref, where each element in the array is a filepath
+pointing to a Charmonizer module file (typically ending in ".charm").
+
+=item *
+
+B<out_path> -- indicates where the final output from the Charmonizer program
+should end up.
+
+=item *
+
+B<compiler> -- The command used to invoke the C compiler on your system.  The
+default is C<$Config{cc}> -- see the docs for L<Config>.
+
+=back
+
+=head2 run
+
+Run the Charmonizer program, generating the header file.
+
+=head1 AUTHOR
+
+Marvin Humphrey, E<lt>marvin at rectangular dot comE<gt>
+
+=head1 COPYRIGHT AND LICENSE
+
+    /**
+     * Copyright 2006 The Apache Software Foundation
+     *
+     * Licensed under the Apache License, Version 2.0 (the "License");
+     * you may not use this file except in compliance with the License.
+     * You may obtain a copy of the License at
+     *
+     *     http://www.apache.org/licenses/LICENSE-2.0
+     *
+     * Unless required by applicable law or agreed to in writing, software
+     * distributed under the License is distributed on an "AS IS" BASIS,
+     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+     * implied.  See the License for the specific language governing
+     * permissions and limitations under the License.
+     */
+
+=cut
+

Added: lucene/lucy/trunk/charmonizer/modules/end.charm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/charmonizer/modules/end.charm?rev=419607&view=auto
==============================================================================
--- lucene/lucy/trunk/charmonizer/modules/end.charm (added)
+++ lucene/lucy/trunk/charmonizer/modules/end.charm Thu Jul  6 09:25:11 2006
@@ -0,0 +1,11 @@
+CH_api_version
+  version 0
+CH_end_api_version
+
+CH_append_raw
+  string CH_quote
+
+    return 0;
+}
+  CH_end_quote
+CH_end_append_raw

Added: lucene/lucy/trunk/charmonizer/modules/integers.charm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/charmonizer/modules/integers.charm?rev=419607&view=auto
==============================================================================
--- lucene/lucy/trunk/charmonizer/modules/integers.charm (added)
+++ lucene/lucy/trunk/charmonizer/modules/integers.charm Thu Jul  6 09:25:11 2006
@@ -0,0 +1,110 @@
+CH_api_version
+  version 0
+CH_end_api_version
+
+/* Check for inttypes.h. */
+CH_append_output
+  source CH_quote
+    #include <stdio.h>
+    #include <inttypes.h>
+    int main()
+    {
+        printf("#define HAS_INTTYPES_H 1\n");
+        return 0;
+    }
+  CH_end_quote
+CH_end_append_output
+
+
+/* Check for long longs. */
+CH_append_output
+  source CH_quote
+    #include <stdio.h>
+    int main() 
+    {
+        long long foo = 4;
+        printf("#define HAS_LONG_LONG 1\n");
+        printf("#define SIZEOF_LONG_LONG %d\n", (int)sizeof(long long));
+        return 0;
+    }
+  CH_end_quote
+CH_end_append_output
+
+
+/* Record sizeof() for several common integer types. */
+CH_append_output
+  source CH_quote
+    #include <stdio.h>
+    int main () {
+        printf("#define SIZEOF_CHAR %d\n", (int)sizeof(char));
+        printf("#define SIZEOF_SHORT %d\n", (int)sizeof(short));
+        printf("#define SIZEOF_INT %d\n", (int)sizeof(int));
+        printf("#define SIZEOF_LONG %d\n", (int)sizeof(long));
+        printf("#define SIZEOF_PTR %d\n", (int)sizeof(void *));
+        return 0;
+    }
+  CH_end_quote
+CH_end_append_output
+
+
+CH_append_raw
+    string CH_quote
+
+/* 8 bit integers */
+#if SIZEOF_CHAR == 1
+    printf("typedef char %s" "i8_t;\n", TYPEDEF_PREFIX);  
+    printf("typedef unsigned char %s" "u8_t;\n", TYPEDEF_PREFIX);  
+#else 
+ #error "No 8-bit integer type available"
+#endif
+
+/* 16-bit integers */
+#if SIZEOF_SHORT == 2
+    printf("typedef short %s" "i16_t;\n", TYPEDEF_PREFIX);  
+    printf("typedef unsigned short %s" "u16_t;\n", TYPEDEF_PREFIX);  
+#else
+ #error "No 16-bit integer type available"
+#endif
+
+/* 32-bit integers */
+#if SIZEOF_INT == 4
+    printf("typedef int %s" "i32_t;\n", TYPEDEF_PREFIX);  
+    printf("typedef unsigned int %s" "u32_t;\n", TYPEDEF_PREFIX);  
+#elif SIZEOF_LONG == 4
+    printf("typedef long %s" "i32_t;\n", TYPEDEF_PREFIX);  
+    printf("typedef unsigned long %s" "u32_t;\n", TYPEDEF_PREFIX);  
+#else
+ #error "No 32-bit integer type available"
+#endif
+
+ /* 64-bit integers */
+#if SIZEOF_LONG == 8
+    printf("typedef long %s" "i64_t;\n", TYPEDEF_PREFIX);  
+    printf("typedef unsigned long %s" "u64_t;\n", TYPEDEF_PREFIX); 
+#elif defined HAS_LONG_LONG
+ #if SIZEOF_LONG_LONG == 8
+    printf("typedef long long %s" "i64_t;\n", TYPEDEF_PREFIX);  
+    printf("typedef unsigned long long %s" "u64_t;\n", TYPEDEF_PREFIX); 
+ #else
+  #error "No 64-bit integer type available"
+ #endif
+#endif
+
+/* pointers */
+#if SIZEOF_PTR == SIZEOF_INT
+    printf("typedef int %s" "iptr_t;\n", TYPEDEF_PREFIX);
+    printf("typedef unsigned int %s" "uptr_t;\n", TYPEDEF_PREFIX);
+#elif SIZEOF_PTR == SIZEOF_LONG
+    printf("typedef long %s" "ptr_t;\n", TYPEDEF_PREFIX);
+    printf("typedef unsigned long %s" "uptr_t;\n", TYPEDEF_PREFIX);
+#elif defined HAS_LONG_LONG
+ #if SIZEOF_PTR == SIZEOF_LONG_LONG
+    printf("typedef long long %s" "iptr_t;\n", TYPEDEF_PREFIX);
+    printf("typedef unsigned long long %s" "uptr_t;\n", TYPEDEF_PREFIX);
+ #else
+  #error "Couldn't find integer type with same size as pointer"
+ #endif
+#endif
+
+  CH_end_quote
+CH_end_append_raw

Added: lucene/lucy/trunk/charmonizer/modules/start.charm
URL: http://svn.apache.org/viewvc/lucene/lucy/trunk/charmonizer/modules/start.charm?rev=419607&view=auto
==============================================================================
--- lucene/lucy/trunk/charmonizer/modules/start.charm (added)
+++ lucene/lucy/trunk/charmonizer/modules/start.charm Thu Jul  6 09:25:11 2006
@@ -0,0 +1,19 @@
+CH_api_version
+  version 0
+CH_end_api_version
+
+CH_append_raw
+  string CH_quote
+
+#include <stdio.h>
+
+#define TYPEDEF_PREFIX "lucy_"
+#define CONSTANT_PREFIX "LUCY_"
+#define MACRO_PREFIX "Lucy_"
+
+int main() 
+{
+    printf("/* Header file auto-generated by Charmonizer. */\n\n");
+
+  CH_end_quote
+CH_end_append_raw