incubator-lucy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Marvin Humphrey <>
Subject Re: [KinoSearch] Compile 0.30_07 on FreeBSD 7
Date Sat, 14 Nov 2009 20:48:01 GMT
On Sat, Nov 14, 2009 at 01:30:16AM -0600, Peter Karman wrote:

CC to the Lucy developers list...

>> I threw some fprintf to stderr in the (generated?)
>> charmonizer/gen/Charmonizer/Core/Compiler.c

Yes, it's generated.  

  trunk/charmonizer/src/Charmonizer/Core/Compiler.charm   <-- orig
  trunk/charmonizer/gen/Charmonizer/Core/Compiler.c       <-- generated

The philosophy of Charmonizer is to use C to bootstrap C, but embedding C code
in C string literals is messy.  To avoid that, we surround code blocks with
"METAQUOTE" tags and run ".charm" files through a filter to produce ".c" files.

Source code in trunk/charmonizer/src/Charmonizer/Probe/LargeFiles.charm:

    /* Code for checking 64-bit lseek. */
    static char lseek_code[] = METAQUOTE
        #include "_charm.h"
        int main() {
            int fd;
            fd = open("_charm_lseek", O_WRONLY | O_CREAT, 0666);
            if (fd == -1) { exit(-1); }
            %s(stdout, 0, SEEK_SET);
            printf("%%d", 1);
            if (close(fd)) { exit(-1); }
            return 0;

Generated code in trunk/charmonizer/gen/Charmonizer/Probe/LargeFiles.c:

    /* Code for checking 64-bit lseek. */
    static char lseek_code[] = "\n"
        "    %s\n"
        "    #include \"_charm.h\"\n"
        "    int main() {\n"
        "        int fd;\n"
        "        Charm_Setup;\n"
        "        fd = open(\"_charm_lseek\", O_WRONLY | O_CREAT, 0666);\n"
        "        if (fd == -1) { exit(-1); }\n"
        "        %s(stdout, 0, SEEK_SET);\n"
        "        printf(\"%%d\", 1);\n"
        "        if (close(fd)) { exit(-1); }\n"
        "        return 0;\n"
        "    }\n"

Browsing through the generated code just now, though, I have to say that the
messy-string-literals problem isn't as bad as we anticipated it would be when
we were designing Charmonizer.  It might be worth ditching it.


  * Big gain in terms of conceptual simplicity.
  * The statement "Charmonizer uses C to bootstrap C" would be 100% true.
  * We'd rid ourselves of the trunk/charmonizer/bin/metaquote utility app, 
    which is currently implemented in Perl.
    * No more Perl dependency for Charmonizer.
    * No more need to pre-generate files when prepping non-Perl distros.
  * Slightly simpler build processes, since our build scripts will be able to
    use the source files directly and won't have to run metaquote to get
    usable C files.

To achieve those gains, we have to resign ourselves to writing code like

   "        printf(\"%%d\", 1);\n"

... instead of this...

            printf("%%d", 1);

... to put this line into our mini test-compile:

   printf("%d", 1);


> More info. The problem seems to come in the call to add_inc_dir(".") at line 58
> in Compiler.c. If I comment that out, everything compiles and tests out just fine.
> I threw some more debugging in add_inc_dir() to see what was going on. strdup()
> returns a copy of "." as expected, but the assignment to self->inc_dirs breaks
> somehow.

Seems like a fencepost error of some sort.  

FWIW, the intent of add_inc_dir(), translated into Perl, is simply:

    push @{ $self->{inc_dirs} }, $dir;

> [0] == ' ('
> passed in '.', num_dirs=1, last=' ('

That's whack.  The inc_dirs member var is an array of strings -- a
NULL-terminated list of NULL-terminated char* vars.  During chaz_CC_new, "."
is the first dir that gets added; at that point, self->inc_dirs should be a
single-element array with NULL as its only member.  This is where we start
off, just a few lines above the call to add_inc_dir():

    self->inc_dirs        = (char**)calloc(sizeof(char*), 1);

There shouldn't *be* a "last" at that point -- the first element in that array
should be a NULL and trying to dereference it by printing self->inc_dirs[0]
as a string should segfault.  Is self->inc_dirs[0] non-NULL?

Also, maybe there's something weird with the realloc?

     self->inc_dirs = realloc(self->inc_dirs, num_dirs + 1);

Yeah, that's probably a problem.  Should be a "* sizeof(char*)" multiplier in
there, methinks.

Marvin Humphrey

View raw message