bug-cvs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Library "libcvs" Build Issue: lib/getdate.y -> lib/getdate.c Step


From: Conrad T. Pino
Subject: Library "libcvs" Build Issue: lib/getdate.y -> lib/getdate.c Step
Date: Sun, 18 Apr 2004 13:50:39 -0700

Hi All,
==============================================================
Executive summary:

The "lib/getdate.y" to "lib/getdate.c" build doesn't tightly
control the ordering of "#include" statements in .c output.

Variations in this build step result in "stdlib.h" frequently
being included *before* "config.h" even though there was *no*
change in .y input.
------------------------------
Current impact:

Windows build warns "rpl_realloc" function prototype missing
due to it's implementation with macro in "config.h" file.

No other "config.h" file in CVS archive uses "rpl_realloc" in
same manner as Windows build.

I can say nothing regarding builds that create "config.h" at
build time which is why I'm presenting this issue.
------------------------------
Future impact:

Unknown to me which is why I'm presenting this issue.
------------------------------
Promising resolution options:

1. Perl script to detect "config.h" ordering errors follows.

Beyond this I'm asking all interested parties for comment,
elaboration and/or guidance.
------------------------------
Chronology of detection, research and detailed conclusions
follows.  Research evidence with test scripts is included to
allow replication and verification.
==============================================================
While working on Visual C++ 6.0 (VC6) build files used in I
noticed compiling file "lib/getdate.c" warns function was used
without function prototype:

Line 1074: warning C4013: 'rpl_realloc' undefined;
           assuming extern returning int

Function "rpl_realloc" is replacement for C library function
"realloc" which differs from GNU implementation.  Discussion
on "rpl_realloc" use in CVS can be found at:

http://mail.gnu.org/archive/html/bug-cvs/2004-04/msg00101.html
http://mail.gnu.org/archive/html/bug-cvs/2004-04/msg00053.html
http://mail.gnu.org/archive/html/bug-cvs/2004-04/msg00054.html

which lead me to conclude use of "rpl_realloc" throughout CVS
should continue.
==============================================================
Function "rpl_realloc" is implemented by "lib/realloc.c" and
Windows build includes it in "libcvs" build but there is no
formal function prototype provided.  The Windows build uses a
macro in file "windows-NT/config.h.in" which defines:

        Line 61      /* Define to rpl_realloc ... */
        Line 62      #define realloc rpl_realloc

which is the input to build "windows-NT/config.h." file.

I assume importance of "config.h" is well known to "Bug-CVS"
audience.  Being new to CVS project I don't know the rules
for using "config.h" but I have noted "config.h" is included
*before* in almost all cases.  In the Windows build the only
exception is "lib/getdate.c" file discussed above.

When "config.h" precedes "stdlib.h" and/or "malloc.h" then
no prototype for "rpl_realloc" function is needed because
the "realloc" macro rewrites "realloc" function prototype
to use "rpl_realloc" instead.  Very neat trick and compiler
implementation insensitive however it can break down.

If file "stdlib.h" contains:

        #ifndef __STDLIB_H__
        #define __STDLIB_H__

        external void *realloc( void *, size_t );
        #endif

then the "realloc" function prototype rewrite doesn't occur
when "config.h" *follows* "stdlib.h" which is consistent with
what we have now with the "lib/getdate.c" compile.
==============================================================
File "lib/getdate.c" is a bison/yacc generated parser built
from "lib/getdate.y" file.  I've analyzed "lib/getdate.y" and
see no problem there:

        lib/getdate.y 17: #include <config.h>
        lib/getdate.y 19: #include "config.h"
        lib/getdate.y 34: #include <ctype.h>
        lib/getdate.y 42: # include <types.h>
        lib/getdate.y 44: # include <sys/types.h>
        lib/getdate.y 46: # include "xtime.h"
        lib/getdate.y 49: #include <string.h>
        lib/getdate.y 60: #include <stdlib.h>

but "lib/getdate.c" is another story:

        lib/getdate.c 4: #include <stdlib.h>
        lib/getdate.c 30: #include <config.h>
        lib/getdate.c 32: #include "config.h"
        lib/getdate.c 47: #include <ctype.h>
        lib/getdate.c 55: # include <types.h>
        lib/getdate.c 57: # include <sys/types.h>
        lib/getdate.c 59: # include "xtime.h"
        lib/getdate.c 62: #include <string.h>
        lib/getdate.c 73: #include <stdlib.h>
        error in lib/getdate.c: stdlib.h precedes config.h

The Perl script with the above test follows in this message.
==============================================================
I researched the use of "stdlib.h" in "lib/getdate.y":

C:\>cvs -z3 diff -r 1.1  -r 1.2  lib/getdate.y | grep stdlib 
> #include <stdlib.h>

and there were *no* "stdlib.h" changes after 1.2 revision.
------------------------------
I researched the use of "stdlib.h" in "lib/getdate.y":

C:\>cvs -z3 diff -r 1.1  -r 1.2  lib/getdate.c | grep stdlib 
< #include <stdlib.h>

C:\>cvs -z3 diff -r 1.2  -r 1.3  lib/getdate.c | grep stdlib 
> #include <stdlib.h>

C:\>cvs -z3 diff -r 1.5  -r 1.6  lib/getdate.c | grep stdlib 
> #include <stdlib.h>

C:\>cvs -z3 diff -r 1.7  -r 1.8  lib/getdate.c | grep stdlib 
< #include <stdlib.h>

C:\>cvs -z3 diff -r 1.17 -r 1.18 lib/getdate.c | grep stdlib 
> #include <stdlib.h>

C:\>cvs -z3 diff -r 1.19 -r 1.20 lib/getdate.c | grep stdlib 
< #include <stdlib.h>

C:\>cvs -z3 diff -r 1.22 -r 1.23 lib/getdate.c | grep stdlib 
> #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */

C:\>cvs -z3 diff -r 1.23 -r 1.24 lib/getdate.c | grep stdlib 
> #include <stdlib.h>
< #   include <stdlib.h> /* INFRINGES ON USER NAME SPACE */

and there were *no* "stdlib.h" changes after 1.24 revision
and the HEAD is now 1.26 revision.
------------------------------
The script with the above tests follows in this message.
==============================================================
Key Question:

If .y file changes once then why does .c file change so often?

IMO the answer is variation in the .y to .c build step.

The Windows build doesn't contain this .y to .c step.
I've not looked for this step's location and implementation.
I'd appreciate input from anyone on this build step.

Researching .c output shows substantial variation:

        bison vs. yacc
        yacc BSD vs. yacc S5R3
        bison/yacc versions rising and falling

which is a pleasant surprise that so much variation made so
little impact to CVS so far.  I'm drawing attention to this
issue to avoid future problems.
==============================================================
Best regards,

Conrad Pino

<perl-script name="check-getdate.pl">
use strict;

sub print_line {
        my ( $file_name, $line_num, $finp_line ) = @_;

        print $file_name, " ", $line_num, ": ", $finp_line;
}

sub print_error {
        my ( $line_inc, $line_con, $file_name, $incl_name ) = @_;

        if ( $line_inc > 0 && $line_inc < $line_con ) {
                print "error in ", $file_name, ": ", $incl_name, " precedes 
config.h\n";
        }

}

sub check_config_h {
        my ( $file_name ) = @_;
        my ( $line_num, $line_any, $line_con, $line_mal, $line_std ) = ( 0, 0, 
0, 0, 0 );

        open FINP, "< " . $file_name || die "open error: ", $file_name;
        while ( <FINP> ) {
                $line_num += 1;

                if ( /^\s*#\s*include\s*[<\"]config\.h[\">]/ ) {
                        print_line $file_name, $line_num, $_;

                        if ( $line_con <= 0 ) {
                                $line_con = $line_num;
                        }
                }
                elsif ( /^\s*#\s*include\s*[<\"]malloc\.h[\">]/ ) {
                        print_line $file_name, $line_num, $_;

                        if ( $line_mal <= 0 ) {
                                $line_mal = $line_num;
                        }
                }
                elsif ( /^\s*#\s*include\s*[<\"]stdlib\.h[\">]/ ) {
                        print_line $file_name, $line_num, $_;

                        if ( $line_std <= 0 ) {
                                $line_std = $line_num;
                        }
                }
                elsif ( /^\s*#\s*include\s*[<\"].+[\">]/ ) {
                        print_line $file_name, $line_num, $_;

                        if ( $line_any <= 0 ) {
                                $line_any = $line_num;
                        }
                }
        }
        close FINP;

        print_error $line_any, $line_con, $file_name, "#include at line " . 
$line_any;
        print_error $line_mal, $line_con, $file_name, "malloc.h";
        print_error $line_std, $line_con, $file_name, "stdlib.h";
        print "\n";
}

check_config_h "lib/getdate.y";
check_config_h "lib/getdate.c";
</perl-script>

<script>
cvs -z3 diff -r 1.1  -r 1.2  lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.2  -r 1.3  lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.3  -r 1.4  lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.4  -r 1.5  lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.5  -r 1.6  lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.6  -r 1.7  lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.7  -r 1.8  lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.8  -r 1.9  lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.9  -r 1.10 lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.10 -r 1.11 lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.11 -r 1.12 lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.12 -r 1.13 lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.13 -r 1.14 lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.14 -r 1.15 lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.15 -r 1.16 lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.16 -r 1.17 lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.17 -r 1.18 lib/getdate.y | grep stdlib
cvs -z3 diff -r 1.18 -r 1.19 lib/getdate.y | grep stdlib

cvs -z3 diff -r 1.1  -r 1.2  lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.2  -r 1.3  lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.3  -r 1.4  lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.4  -r 1.5  lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.5  -r 1.6  lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.6  -r 1.7  lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.7  -r 1.8  lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.8  -r 1.9  lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.9  -r 1.10 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.10 -r 1.11 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.11 -r 1.12 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.12 -r 1.13 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.13 -r 1.14 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.14 -r 1.15 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.15 -r 1.16 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.16 -r 1.17 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.17 -r 1.18 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.18 -r 1.19 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.19 -r 1.20 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.20 -r 1.21 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.21 -r 1.22 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.22 -r 1.23 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.23 -r 1.24 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.24 -r 1.25 lib/getdate.c | grep stdlib
cvs -z3 diff -r 1.25 -r 1.26 lib/getdate.c | grep stdlib
</script>




reply via email to

[Prev in Thread] Current Thread [Next in Thread]