Skip to content

Commit

Permalink
ImportC preprocess Win32 C programs with sppn.exe
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright committed May 10, 2022
1 parent 1adc9e7 commit 861b30a
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 34 deletions.
2 changes: 2 additions & 0 deletions .azure-pipelines/lib.sh
Expand Up @@ -52,6 +52,8 @@ install_host_dmc() {
if [ ! -f dm/README.TXT ]; then
download "http://downloads.dlang.org/other/dm857c.zip" dmc.zip
7z x dmc.zip > /dev/null
download "http://ftp.digitalmars.com/sppn.zip" sppn.zip
7z x -odm/bin sppn.zip > /dev/null
fi
dm/bin/dmc | head -n 1 || true
}
Expand Down
1 change: 1 addition & 0 deletions .azure-pipelines/windows.sh
Expand Up @@ -32,6 +32,7 @@ DM_MAKE="$PWD/dm/bin/make.exe"
if [ "$MODEL" == "32omf" ] ; then
CC="$PWD/dm/bin/dmc.exe"
AR="$PWD/dm/bin/lib.exe"
export CPPCMD="$PWD/dm/bin/sppn.exe"
else
CC="$(where cl.exe)"
AR="$(where lib.exe)" # must be done before installing dmd
Expand Down
49 changes: 25 additions & 24 deletions src/dmd/cpreprocess.d
Expand Up @@ -50,42 +50,39 @@ FileName preprocess(FileName csrcfile, out bool ifile)
const ext = FileName.ext(name);
assert(ext);
const ifilename = FileName.addExt(name[0 .. name.length - (ext.length + 1)], i_ext);
auto status = runPreprocessor(cppCommand(), csrcfile.toString(), ifilename);
const command = cppCommand();
auto status = runPreprocessor(command, csrcfile.toString(), ifilename);
if (status)
{
error(Loc.initial, "C preprocess failed for file %s, exit status %d\n", csrcfile.toChars(), status);
error(Loc.initial, "C preprocess command %.*s failed for file %s, exit status %d\n",
cast(int)command.length, command.ptr, csrcfile.toChars(), status);
fatal();
}
ifile = true;
return FileName(ifilename);
}
else version (Windows)
{
/* This actually works, but fails the test suite because:
1. For Microsoft's preprocessor, it insists on printing the filename it's preprocessing,
which causes all the fail_compilation tests to fail. Yes, even with /nologo.
cl.exe does not appear to have a "quiet" mode.
2. For Win32 with Digital Mars, the tests all fail because sppn.exe, the DMC preprocessor,
is not on the path. Even if it was, it would still fail because the DMC headers are not
there. To get the headers and sppn.exe, dmc will need to be installed on the test machines:
http://ftp.digitalmars.com/Digital_Mars_C++/Patch/dm857c.zip
/*
To get sppn.exe: http://ftp.digitalmars.com/sppn.zip
To get the dmc C headers, dmc will need to be installed:
http://ftp.digitalmars.com/Digital_Mars_C++/Patch/dm857c.zip
*/
if (target.objectFormat() == Target.ObjectFormat.coff)
const name = FileName.name(csrcfile.toString());
const ext = FileName.ext(name);
assert(ext);
const ifilename = FileName.addExt(name[0 .. name.length - (ext.length + 1)], i_ext);
const command = cppCommand();
auto status = runPreprocessor(command, csrcfile.toString(), ifilename);
if (status)
{
const name = FileName.name(csrcfile.toString());
const ext = FileName.ext(name);
assert(ext);
const ifilename = FileName.addExt(name[0 .. name.length - (ext.length + 1)], i_ext);
auto status = runPreprocessor(cppCommand(), csrcfile.toString(), ifilename);
if (status)
{
error(Loc.initial, "C preprocess failed for file %s, exit status %d\n", csrcfile.toChars(), status);
fatal();
}
//printf("C preprocess succeeded %s\n", ifilename.ptr);
return FileName(ifilename);
error(Loc.initial, "C preprocess command %.*s failed for file %s, exit status %d\n",
cast(int)command.length, command.ptr, csrcfile.toChars(), status);
fatal();
}
return csrcfile;
//printf("C preprocess succeeded %s\n", ifilename.ptr);
ifile = true;
return FileName(ifilename);
}
else
return csrcfile; // no-op
Expand All @@ -108,6 +105,10 @@ private const(char)[] cppCommand()
cmdbuf.writestring(r" /P");
return cmdbuf.extractSlice();
}
if (target.objectFormat() == Target.ObjectFormat.omf)
{
return "sppn.exe";
}
}
return "cpp";
}
55 changes: 49 additions & 6 deletions src/dmd/link.d
Expand Up @@ -1063,7 +1063,8 @@ public int runPreprocessor(const(char)[] cpp, const(char)[] filename, const(char
/* Run command, intercept stdout, remove first line that CL insists on emitting
*/
OutBuffer buf;
buf.printf("cl /P /nologo %.*s /Fi%.*s",
buf.writestring(cpp);
buf.printf(" /P /nologo %.*s /Fi%.*s",
cast(int)filename.length, filename.ptr, cast(int)output.length, output.ptr);

ubyte[2048] buffer = void;
Expand Down Expand Up @@ -1116,11 +1117,53 @@ public int runPreprocessor(const(char)[] cpp, const(char)[] filename, const(char
}
else if (target.objectFormat() == Target.ObjectFormat.omf)
{
argv.push("sppn".xarraydup.ptr); // Digital Mars C preprocessor
argv.push(filename.xarraydup.ptr); // and the input file
argv.push(null); // argv[] always ends with a null
// spawnlp returns intptr_t in some systems, not int
return spawnvp(_P_WAIT, "sppn".ptr, argv.tdata());
/* Digital Mars Win32 target
* sppn filename -oooutput
* https://www.digitalmars.com/ctg/sc.html
*/

static if (1)
{
/* Run command
*/
OutBuffer buf;
buf.writestring(cpp);
buf.printf(" %.*s -o%.*s",
cast(int)filename.length, filename.ptr, cast(int)output.length, output.ptr);

ubyte[2048] buffer = void;

bool firstLine = true;
void sinkomf(ubyte[] data)
{
printf("%.*s", cast(int)data.length, data.ptr);
}

// Convert command to wchar
wchar[1024] scratch = void;
auto smbuf = SmallBuffer!wchar(scratch.length, scratch[]);
auto szCommand = toWStringz(buf.peekChars()[0 .. buf.length], smbuf);

printf("szCommand: %ls\n", szCommand.ptr);
int exitCode = runProcessCollectStdout(szCommand.ptr, buffer[], &sinkomf);
printf("\n");
return exitCode;
}
else
{
auto cmd = cpp.xarraydup.ptr;
argv.push(cmd); // Digita; Mars C preprocessor
argv.push(filename.xarraydup.ptr); // and the input file

OutBuffer buf;
buf.writestring("-o"); // https://www.digitalmars.com/ctg/sc.html#dashofilename
buf.writeString(output);
argv.push(buf.extractData()); // output file

argv.push(null); // argv[] always ends with a null
// spawnlp returns intptr_t in some systems, not int
return spawnvp(_P_WAIT, cmd, argv.tdata());
}
}
else
{
Expand Down
5 changes: 1 addition & 4 deletions src/dmd/mars.d
Expand Up @@ -730,10 +730,7 @@ bool parseCommandlineAndConfig(size_t argc, const(char)** argv, ref Param params
error(Loc.initial, "the architecture must not be changed in the %s section of %.*s",
envsection.ptr, cast(int)global.inifilename.length, global.inifilename.ptr);

version (Posix)
global.preprocess = &preprocess;
version (Win64)
global.preprocess = &preprocess;
global.preprocess = &preprocess;
return false;
}
/// Emit the makefile dependencies for the -makedeps switch
Expand Down

0 comments on commit 861b30a

Please sign in to comment.