18
5
The goal is to create a preprocessor for the C language, as small as possible in terms of source code size in bytes, in your preferred language. Its input will be a C source file, and its output will be the pre-processed source code.
The items that it will need to be able to process shall be: Comment removal (line/block), #include directives (by opening files at relative paths and replacing text at the point needed), #define, #undef, #if, #elif, #else, #endif, #ifdef, #ifndef, and defined(). Other C preprocessor directives like #pragmas or #errors may be ignored.
There is no need to calculate arithmetic expressions or comparison operators in #if directives, we assume the expression will evaluate to true as long as it contains an integer other than zero (its main use will be for the defined() directive). Examples of possible input and output follow (possible extra whitespaces in output files were trimmed for better appearance, there is no need for your code to do so). A program able to process the following examples properly will be considered sufficient.
----Input file: foo.c (main file being preprocessed)
#include "bar.h" // Line may or may not exist
#ifdef NEEDS_BAZZER
#include "baz.h"
#endif // NEEDS_BAZZER
#ifdef _BAZ_H_
int main(int argc, char ** argv)
{
/* Main function.
In case that bar.h defined NEEDS_BAZ as true,
we call baz.h's macro BAZZER with the length of the
program's argument list. */
return BAZZER(argc);
}
#elif defined(_BAR_H_)
// In case that bar.h was included but didn't define NEEDS_BAZ.
#undef _BAR_H_
#define NEEDS_BARRER
#include "bar.h"
int main(int argc, char ** argv)
{
return BARRER(argc);
}
#else
// In case that bar.h wasn't included at all.
int main()
{return 0;}
#endif // _BAZ_H_
----Input file bar.h (Included header)
#ifndef _BAR_H_
#define _BAR_H_
#ifdef NEEDS_BARRER
int bar(int * i)
{
*i += 4 + *i;
return *i;
}
#define BARRER(i) (bar(&i), i*=2, bar(&i))
#else
#define NEEDS_BAZZER // Line may or may not exist
#endif // NEEDS_BARRER
#endif // _BAR_H_
----Input file baz.h (Included header)
#ifndef _BAZ_H_
#define _BAZ_H_
int baz(int * i)
{
*i = 4 * (*i + 2);
return *i;
}
#define BAZZER(i) (baz(&i), i+=2, baz(&i))
#endif // _BAZ_H_
----Output file foopp.c (no edits)
int baz(int * i)
{
*i = 4 * (*i + 2);
return *i;
}
int main(int argc, char ** argv)
{
return (baz(&argc), argc+=2, baz(&argc));
}
----Output file foopp2.c (with foo.c's first line removed)
int main()
{return 0;}
----Output file foopp3.c (with bar.h's line "#define NEEDS_BAZZER" removed)
int bar(int * i)
{
*i += 4 + *i;
return *i;
}
int main(int argc, char ** argv)
{
return (bar(&argc), argc*=2, bar(&argc));
}
Can you provide input/output samples? – Florent – 2014-02-12T19:40:30.713
Provide us a test code. It's nearly impossible without examples. – Ismael Miguel – 2014-02-12T22:01:10.407
Uh sure, I will. Just be a bit patient as I can't be very fast due to time and workload constraints. – Thanasis Papoutsidakis – 2014-02-13T10:19:08.820
1How much of
#if
needs to be supported? i.e. does the preprocessor need to support expressions with arithmetic, bitwise operations, etc? – Hasturkun – 2014-02-13T11:08:04.593ok, example input/output and further explanations added – Thanasis Papoutsidakis – 2014-02-13T12:10:56.120
Sorry for taking so long, but its hard to make such a code. – Ismael Miguel – 2014-02-16T03:28:04.813
No problem :) I pretty much figured that out :) – Thanasis Papoutsidakis – 2014-02-16T10:27:11.000
@IsmaelMiguel because C is an obscure language that you could never find examples of online, let alone a Great C Compiler of some sort to verify against... :P – Nick T – 2014-02-27T00:24:26.247