A way to use C in (Pure) batch
Posted: 29 Jan 2017 08:26
Well, not so pure because you have to have a compiler. This batch file uses tcc.
Works fine for me:
Output:
How do you change the compiler?
Change the line to something else. Be sure to specify %~n0_C.c as the file you want to compile and %~n0.exe as the file you want to be generated.
Well, what if you WANT more batch?
Just add it in the multi-line comment. There are a few additions to trick the C code and to trick the Batch code, so it doesn't give a bunch of errors when loading this.
But how does it work???
This piece of code works in both C and Batch. It's meaningless in C, but meaningful in Batch. It's basically "@echo off".
C Compiler perspective:
Hey, look, //! That's a single-line comment. I'm gonna ignore everything here, which in this case is ">nul 2>&1 & @echo off".
Batch Parser perspective:
I don't know what is the command //. Redirect it to stdout instead of stderr and redirect it to nul beacuse of >nul 2>&1. Wait, what's this &? Another command. This one says to do @echo off. I can do that! (does @echo off)
C Compiler perspective:
So basically, we make a function "dummy0" with int return type that returns 0 and defines "i".
Batch perspective:
What is that first line? Ignoring it.
The second? Hmm... so go to the label "bat". Okay.
The other ones? Yep, just ignore them.
C Compiler perspective:
Print "Welcome to the C/Batch hybrid!" and leave.
Batch perspective:
(never loads this)
C perspective: Multi line comment! Ignoring...
Batch perspective: What is /*? Oh well, ignoring it.
C perspective: Comment...
Batch perspective: Look, the label we were looking for! Go!
C perspective: Still a comment...
Batch perspective: So @echo off, and type this program's code to %~n0_C.c.
Alright, what's next? Ah, use tcc. Then, delete %~n0_C.c and let's call %~n0.exe with all of our arguments.
Next, we'll delete it and exit.
C perspective: End of multiline comment and start of single line comment. It contains >nul 2>&1.
Batch parser perspective: I have no idea what is */ //, but i'll not give an error.
Works fine for me:
Code: Select all
// >nul 2>&1 & @echo off
int dummy0(void) { // >nul 2>&1
int i; // >nul 2>&1 & goto bat
return 0; // >nul 2>&1
} // >nul 2>&1
#include <stdio.h>
int main(void)
{
printf("Welcome to the C/Batch hybrid!");
return 0;
};
/* >nul 2>&1
:bat
;@echo off
type %~n0.bat >> %~n0_C.c
tcc -o %~n0.exe %~n0_C.c
del %~n0_C.c
call %~n0.exe %*
del %~n0.exe
exit /b
*/ // >nul 2>&1
Output:
How do you change the compiler?
Change the line
Code: Select all
tcc -o %~n0.exe %~n0_C.c
Well, what if you WANT more batch?
Just add it in the multi-line comment. There are a few additions to trick the C code and to trick the Batch code, so it doesn't give a bunch of errors when loading this.
But how does it work???
Code: Select all
// >nul 2>&1 & @echo off
C Compiler perspective:
Hey, look, //! That's a single-line comment. I'm gonna ignore everything here, which in this case is ">nul 2>&1 & @echo off".
Batch Parser perspective:
I don't know what is the command //. Redirect it to stdout instead of stderr and redirect it to nul beacuse of >nul 2>&1. Wait, what's this &? Another command. This one says to do @echo off. I can do that! (does @echo off)
Code: Select all
int dummy0(void) { // >nul 2>&1
int i; // >nul 2>&1 & goto bat
return 0; // >nul 2>&1
} // >nul 2>&1
C Compiler perspective:
So basically, we make a function "dummy0" with int return type that returns 0 and defines "i".
Batch perspective:
What is that first line? Ignoring it.
The second? Hmm... so go to the label "bat". Okay.
The other ones? Yep, just ignore them.
Code: Select all
#include <stdio.h>
int main(void)
{
printf("Welcome to the C/Batch hybrid!");
return 0;
};
C Compiler perspective:
Print "Welcome to the C/Batch hybrid!" and leave.
Batch perspective:
(never loads this)
Code: Select all
/* >nul 2>&1
C perspective: Multi line comment! Ignoring...
Batch perspective: What is /*? Oh well, ignoring it.
Code: Select all
:bat
C perspective: Comment...
Batch perspective: Look, the label we were looking for! Go!
Code: Select all
;@echo off
type %~n0.bat >> %~n0_C.c
tcc -o %~n0.exe %~n0_C.c
del %~n0_C.c
call %~n0.exe %*
del %~n0.exe
exit /b
C perspective: Still a comment...
Batch perspective: So @echo off, and type this program's code to %~n0_C.c.
Alright, what's next? Ah, use tcc. Then, delete %~n0_C.c and let's call %~n0.exe with all of our arguments.
Next, we'll delete it and exit.
Code: Select all
*/ // >nul 2>&1
C perspective: End of multiline comment and start of single line comment. It contains >nul 2>&1.
Batch parser perspective: I have no idea what is */ //, but i'll not give an error.