May 23, 2004 Proposal for handling command line "defines" | ||||
|---|---|---|---|---|
| ||||
Submitted for your approval...
I whipped up this Perl script as a proof-of-concept sort of thingy. Ideally I would like this functionality added to the compiler, but a compiler that creates a source file would be unusual.
The command:
perl dpp.pl defs.d -Danint=123 -Dadouble=12.3f -Dastring="This is text" -Dabool
Executes the script to strip out the -D items and build a file "compilation.d" that contains:
-----
struct defines
{
static int anint = 123 ;
static double adouble = 12.3f ;
static char[] astring = "This is text" ;
static bool abool = true ;
}
-----
Then executes dmd, adding compilation.d to the file list.
In the program simply add:
import compilation ;
to have access to the "defines" from the command line -- with appropriate types!
defs.d contains:
-----
import std.c.stdio ;
import compilation ;
int main ( char[][] args )
{
int[] anarray = new int[compilation.defines.anint] ;
printf ( "astring = %.*s\n" , compilation.defines.astring ) ;
printf ( "anint = %d\n" , compilation.defines.anint ) ;
printf ( "adouble = %f\n" , compilation.defines.adouble ) ;
printf ( "abool = %.*s\n" , compilation.defines.abool?"True":"False" ) ;
printf ( "arr.len = %d\n" , anarray.length ) ;
return ( 0 ) ;
}
-----
And produces output:
-----
astring = This is text
anint = 123
adouble = 12.300000
abool = True
arr.len = 123
-----
The script is pretty rough because I'm not much good with Perl, but it's good enough for my purpose at this time.
dpp.pl
-----
# DPP.PL -- D preprocessor concept proofalizer (very simplistic)
$filename = "compilation.d" ;
$struct = "defines" ;
$opened = 0 ;
$cmd = "" ;
# Traverse the command line items
while ( @ARGV > 0 )
{
$item = shift ( @ARGV ) ;
# If this item is a define
if ( substr ( $item , 0 , 2 ) eq "-D" )
{
# Open file when first define found
if ( $opened == 0 )
{
open ( TMPFILE , ">$filename" ) ;
printf ( TMPFILE "struct $struct\n{\n" ) ;
# $cmd .= " " . $filename ;
$opened = 1 ;
}
# Remove the -D
$item = substr ( $item , 2 ) ;
# Determine type
# If the item has a value
if ( $item =~ m/=/ )
{
# Separate the name and value
@parts = split ( "=" , $item ) ;
# If the value is all digits
if ( @parts[1] !~ m/\D/ )
{
printf ( TMPFILE " static int %s = %s ;\n" , @parts[0] , @parts[1] ) ;
}
else
{
# If the value is digits and dots (this needs work)
if ( @parts[1] =~ m/\d\./ )
{
printf ( TMPFILE " static double %s = %s ;\n" , @parts[0] , @parts[1] ) ;
}
# Otherwise, it's just text
else
{
printf ( TMPFILE " static char[] %s = \"%s\" ;\n" , @parts[0] , @parts[1] ) ;
}
}
}
# If no value, make it a bool true (C preprocessor doesn't do falsies)
else
{
printf ( TMPFILE " static bool %s = true ;\n" , $item ) ;
}
}
# If not a define, keep it on the command line
else
{
$cmd .= " " . $item ;
}
}
# Finish the file if one was started
if ( $opened )
{
printf ( TMPFILE "}" ) ;
close ( TMPFILE ) ;
$cmd .= " " . $filename ;
}
# Now do the compile
system ( "dmd" . $cmd ) ;
-----
| ||||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply