#define CHAZ_USE_SHORT_NAMES
#include "Charmonizer/Core/Compiler.h"
#include "Charmonizer/Core/ConfWriter.h"
#include "Charmonizer/Core/Util.h"
#include "Charmonizer/Probe/FuncMacro.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
static
char
iso_func_code[] =
QUOTE( #include
"_charm.h"
)
QUOTE(
int
main() { )
QUOTE( Charm_Setup; )
QUOTE(
printf
(
"%s"
, __func__); )
QUOTE(
return
0; )
QUOTE( } );
static
char
gnuc_func_code[] =
QUOTE( #include
"_charm.h"
)
QUOTE(
int
main() { )
QUOTE( Charm_Setup; )
QUOTE(
printf
(
"%s"
, __FUNCTION__); )
QUOTE(
return
0; )
QUOTE( } );
static
char
inline_code[] =
QUOTE( #include
"_charm.h"
)
QUOTE(
static
%s
int
foo() {
return
1; } )
QUOTE(
int
main() { )
QUOTE( Charm_Setup; )
QUOTE(
printf
(
"%%d"
, foo()); )
QUOTE(
return
0; )
QUOTE( } );
static
char
*
S_try_inline(
const
char
*keyword,
size_t
*output_len) {
char
code[
sizeof
(inline_code) + 30 ];
sprintf
(code, inline_code, keyword);
return
CC_capture_output(code,
strlen
(code), output_len);
}
static
const
char
* inline_options[] = {
"__inline"
,
"__inline__"
,
"inline"
};
static
int
num_inline_options =
sizeof
(inline_options) /
sizeof
(
void
*);
void
FuncMacro_run(
void
)
{
int
i;
char
*output;
size_t
output_len;
chaz_bool_t has_funcmac =
false
;
chaz_bool_t has_iso_funcmac =
false
;
chaz_bool_t has_gnuc_funcmac =
false
;
chaz_bool_t has_inline =
false
;
ConfWriter_start_module(
"FuncMacro"
);
output = CC_capture_output(iso_func_code,
strlen
(iso_func_code),
&output_len);
if
(output != NULL &&
strncmp
(output,
"main"
, 4) == 0) {
has_funcmac =
true
;
has_iso_funcmac =
true
;
}
free
(output);
output = CC_capture_output(gnuc_func_code,
strlen
(gnuc_func_code),
&output_len);
if
(output != NULL &&
strncmp
(output,
"main"
, 4) == 0) {
has_funcmac =
true
;
has_gnuc_funcmac =
true
;
}
free
(output);
if
(has_funcmac) {
const
char
*macro_text = has_iso_funcmac
?
"__func__"
:
"__FUNCTION__"
;
ConfWriter_append_conf(
"#define CHY_HAS_FUNC_MACRO\n"
"#define CHY_FUNC_MACRO %s\n"
,
macro_text
);
}
if
(has_iso_funcmac) {
ConfWriter_append_conf(
"#define CHY_HAS_ISO_FUNC_MACRO\n"
);
}
if
(has_gnuc_funcmac) {
ConfWriter_append_conf(
"#define CHY_HAS_GNUC_FUNC_MACRO\n"
);
}
for
(i = 0; i < num_inline_options; i++) {
const
char
*inline_option = inline_options[i];
output = S_try_inline(inline_option, &output_len);
if
(output != NULL) {
has_inline =
true
;
ConfWriter_append_conf(
"#define CHY_INLINE %s\n"
, inline_option);
free
(output);
break
;
}
}
if
(!has_inline) {
ConfWriter_append_conf(
"#define CHY_INLINE\n"
);
}
ConfWriter_start_short_names();
if
(has_iso_funcmac)
ConfWriter_shorten_macro(
"HAS_ISO_FUNC_MACRO"
);
if
(has_gnuc_funcmac)
ConfWriter_shorten_macro(
"HAS_GNUC_FUNC_MACRO"
);
if
(has_iso_funcmac || has_gnuc_funcmac) {
ConfWriter_shorten_macro(
"HAS_FUNC_MACRO"
);
ConfWriter_shorten_macro(
"FUNC_MACRO"
);
}
ConfWriter_shorten_macro(
"INLINE"
);
ConfWriter_end_short_names();
ConfWriter_end_module();
}