I've been frantically trying to get this following code to work. The preprocessor definitions WIDR and LIDR aren't working and it's giving me the compile error:
projects/elcain.c: In function ‘main’:
projects/elcain.c:17:6: error: ‘WIDR’ undeclared (first use in this function)
if ( WIDR ) {
^
projects/elcain.c:17:6: note: each undeclared identifier is reported only once for each function it appears in
projects/elcain.c:19:13: error: ‘LIDR’ undeclared (first use in this function)
} else if ( LIDR ) {
I don't really have experience with preprocessor macros, or the preprocessor in general, so go easy on me.
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef _WIN32
#define WIDR 1
#elif defined _linux_
#define LIDR 1
#endif
int main () {
char* directory = (char*) malloc (1);
if ( WIDR ) {
strcpy(directory, "C:\\TEMP\\");
} else if ( LIDR ) {
strcpy(directory, "~/.temp/");
} else {
*directory = 0x00;
}
printf("%s\n", directory);
return 0;
}
You probably simply want this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main () {
#ifdef _WIN32
char directory[] = "C:\\TEMP\\";
#elif defined _linux_
char directory[] = "~/.temp/";
#else
#error Neither _WIN32 nor _linux_ are defined
#endif
printf("%s\n", directory);
return 0;
}
What you are looking for is something like this:
#include <stdlib.h>
#if defined unix || \
defined __unix || \
defined __unix__ || \
defined __linux__ || \
defined __FreeBSD__ || \
defined __CYGWIN__ || \
(defined __APPLE__ && defined __MACH__)
static const char TMP_DIR[] = "~/.temp/";
#elif defined WIN32 || \
defined _WIN32 || \
defined __WIN32
static const char TMP_DIR[] = "C:\\TEMP\\";
#else
#error "Platform not supported"
#endif
int
main(void)
{
printf("%s\n", TMP_DIR);
return EXIT_SUCCESS;
}
In fact both WIDR and LIDR are conditional compilation directives. In other words they exist at compilation time only.
Change your code like this:
#ifdef WIDR
strcpy(directory, "C:\\TEMP\\");
#elif defined LDIR
strcpy(directory, "~/.temp/");
#else
*directory = 0x00;
#endif
then compilation errors will gone
Related
tmp2.c
/*
gcc -Wall -Werror -g assert.c tmp2.c && ./a.out
*/
#include "tmp2.h"
#include <assert.h>
int main(void)
{
// assert(1 == 2);
Assert(1 == 2);
return 0;
}
tmp2.h
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include <math.h>
#include<stdint.h>
#include<stdalign.h>
#include<stdbool.h>
/*
* BoolIsValid
* True iff bool is valid.
*/
#define BoolIsValid(boolean) ((boolean) == false || (boolean) == true)
/*
* PointerIsValid
* True iff pointer is valid.
*/
#define PointerIsValid(pointer) ((const void*)(pointer) != NULL)
extern void
ExceptionalCondition(const char *conditionName,
const char *fileName,
int lineNumber);
/*
* USE_ASSERT_CHECKING, if defined, turns on all the assertions.
* - plai 9/5/90
*
* It should _NOT_ be defined in releases or in benchmark copies
*/
/*
* Assert() can be used in both frontend and backend code. In frontend code it
* just calls the standard assert, if it's available. If use of assertions is
* not configured, it does nothing.
*/
#define USE_ASSERT_CHECKING 0
#ifndef USE_ASSERT_CHECKING
#define Assert(condition) ((void)true)
#define AssertMarcod(condition) ((void)true)
#elif defined(FRONTEND)
#include<assert.h>
#define Assert(p) assert(p)
#define AssertMarco(p) ((void) assert(p))
#else
/*
* Assert
* Generates a fatal exception if the given condition is false.
*/
#define Assert(condition) \
do { \
if (!(condition)) \
ExceptionalCondition(#condition,__FILE__,__LINE__); \
} while (0)
/*
* AssertMacro is the same as Assert but it's suitable for use in
* expression-like macros, for example:
*
* #define foo(x) (AssertMacro(x != 0), bar(x))
*/
#define AssertMacro(condition) \
((void) ((condition) || \
(ExceptionalCondition(#condition,__FILE__,__LINE__),0)))
#endif
assert.c
#include "tmp2.h"
#include <unistd.h>
#ifdef HAVE_EXECINFO_H
#include <execinfo.h>
#endif
/*
* ExceptionalCondition - Handles the failure of an Assert()
*
* We intentionally do not go through elog() here, on the grounds of
* wanting to minimize the amount of infrastructure that has to be
* working to report an assertion failure.
*/
void
ExceptionalCondition(const char *conditionName,
const char *fileName,
int lineNumber)
{
/* Report the failure on stderr (or local equivalent) */
if (!PointerIsValid(conditionName)
|| !PointerIsValid(fileName))
fprintf(stderr,"TRAP: ExceptionalCondition: bad arguments in PID %d\n",
(int) getpid());
else
fprintf(stderr,"TRAP: failed Assert(\"%s\"), File: \"%s\", Line: %d, PID: %d\n",
conditionName, fileName, lineNumber, (int) getpid());
/* Usually this shouldn't be needed, but make sure the msg went out */
fflush(stderr);
// /* If we have support for it, dump a simple backtrace */
// #ifdef HAVE_BACKTRACE_SYMBOLS
// {
// void *buf[100];
// int nframes;
// nframes = backtrace(buf, lengthof(buf));
// backtrace_symbols_fd(buf, nframes, fileno(stderr));
// }
// #endif
/*
* If configured to do so, sleep indefinitely to allow user to attach a
* debugger. It would be nice to use pg_usleep() here, but that can sleep
* at most 2G usec or ~33 minutes, which seems too short.
*/
#ifdef SLEEP_ON_ASSERT
sleep(1000000);
#endif
abort();
}
In this context, I'm trying a way to use the AssertMacro; that is, find a way to invoke assert.c ExceptionalCondition function. Assume FRONTEND is not defined. USE_ASSERT_CHECKING can be 1 or 0.
update: to use ExceptionalCondition function I need to declare it on tmp2.h via
extern void
ExceptionalCondition(const char *conditionName,
const char *fileName,
int lineNumber);
I also need to define USE_ASSERT_CHECKING in tmp2.h or before tmp2.h.
If I don't define USE_ASSERT_CHECKING seems all the assert will be true always?
I have a list of enums:
typedef enum {
ENUM1,
ENUM2,
#if FLAG
ENUM3,
#endif
} enum_var_t;
And a corresponding list of strings to align:
typedef struct { char[50] name; int val; } name_val_map_t
name_val_map_t name_val_map_table[] = {
{.name="string1", .val=ENUM1},
{.name="string2", .val=ENUM2},
#if FLAG
{.name="string3", .val=ENUM3},
#endif
};
FLAG is a build flag, and is either 0, or 1.
I am trying to use X-Macros to align these according to an answer here:
#define IF(cond, foo) IF_IMPL(cond, foo)
#define IF_IMPL(cond, foo) IF_ ## cond (foo)
#define IF_0(foo)
#define IF_1(foo) foo
#define var_list \
X(ENUM1, "string1"), \
X(ENUM2, "string2"), \
IF(FLAG, X(ENUM3, "string3")), \
#define X(ENUMVAL, ...) ENUMVAL
typedef enum {
var_list
}
#undef X
#define X(ENUMVAL, NAME) {.name = NAME, .val = ENUMVAL}
name_val_map_t name_val_map_table = {
var_list
}
This leads to an error which says I'm passing more arguments to the IF macro than declared. I presume it is treating the comma inside the X(ENUM3, "string3") as an argument separator for IF.
I tried encapsulating the X() call with braces and removing the braces from IF_IMPL, but that didn't work either. If I try expand the argument list in IF() using ..., and VA_ARGS, I get expected expression errors. I'm trying to avoid using a def file as this makes my file unreadable. Some solution like I was trying would be perfect to avoid code replication, and for readability. Any pointers would be welcome, thanks!
Using variadic macros.
#define IF(cond, foo) IF_IMPL(cond, foo)
#define IF_IMPL(cond, ...) IF_ ## cond(__VA_ARGS__)
#define IF_0(foo, ...)
#define IF_1(foo, ...) foo, __VA_ARGS__
Test:
//usr/local/bin/tcc -run "$0"; exit $?
#include <stdio.h>
#define FLAG3 1
#define FLAG4 0
#define FLAG5 1
typedef struct { char *name; int val; } name_val_map_t;
#define IF(cond, foo) IF_IMPL(cond, foo)
#define IF_IMPL(cond, ...) IF_ ## cond(__VA_ARGS__)
#define IF_0(foo, ...)
#define IF_1(foo, ...) foo, __VA_ARGS__
#define var_list \
X(ENUM1, "string1") \
X(ENUM2, "string2") \
IF(FLAG3, X(ENUM3, "string3")) \
IF(FLAG4, X(ENUM4, "string4")) \
IF(FLAG5, X(ENUM5, "string5")) \
typedef enum {
#define X(ENUMVAL, str) ENUMVAL,
var_list
#undef X
} enum_var_t;
name_val_map_t name_val_map_table[] = {
#define X(ENUMVAL, NAME) { NAME, ENUMVAL },
var_list
#undef X
{ "sentinel value", 99 }
};
int main(void){
int x =0;
while(name_val_map_table[x].val != 99){
printf("%i, %s\n", name_val_map_table[x].val, name_val_map_table[x].name);
x++;}
return 0;
}
/* output:
0, string1
1, string2
2, string3
3, string5
*/
Another option is to manually create IF_FLAGx( X(bla, bla) ) macros for every case...
See also: macro specialization based on argument in case of MSVC bug.
This seems needlessly complicated. I would simply do this instead:
#if FLAG
#define var_list \
X(ENUM1, "string1") \
X(ENUM2, "string2") \
X(ENUM3, "string3")
#else
#define var_list \
X(ENUM1, "string1") \
X(ENUM2, "string2")
#endif
Full example:
#include <stdio.h>
#define FLAG 1
#if FLAG
#define var_list \
X(ENUM1, "string1") \
X(ENUM2, "string2") \
X(ENUM3, "string3")
#else
#define var_list \
X(ENUM1, "string1") \
X(ENUM2, "string2")
#endif
typedef enum
{
#define X(enum_var, str) enum_var,
var_list
#undef X
ENUM_N
} enum_var_t;
typedef struct
{
char name[50];
int val;
} name_val_map_t;
const name_val_map_t name_val_map_table[] =
{
#define X(enum_var, str) { .name = str, .val = enum_var },
var_list
#undef X
};
int main (void)
{
for(size_t i=0; i<ENUM_N; i++)
{
printf("%d %s\n", name_val_map_table[i].val, name_val_map_table[i].name);
}
}
Here is a snippet:
#if defined(a) || \
defined(b)
void test();
#else
void test();
#endif
Source Insight can't recognize multi-line macro.
It treats
#if defined(a) || \
defined(b)
as
#if defined(a)
#if defined(a) || defined(b)
How do I fix this?
About compile suricata.
In Makefile,when CFLAGS wrap "-Werror-implicit-function-declaration"
I got the error:
detect-engine-siggroup.c: In function ‘SigGroupHeadFree’:
detect-engine-siggroup.c:187:9: error: implicit declaration of function ‘_mm_free’ [-Werror=implicit-function-declaration]
SCFreeAligned(sgh->mask_array);
^
detect-engine-siggroup.c: In function ‘SigGroupHeadBuildHeadArray’:
detect-engine-siggroup.c:1715:5: error: implicit declaration of function ‘_mm_malloc’ [-Werror=implicit-function-declaration]
sgh->mask_array = (SignatureMask *)SCMallocAligned((cnt * sizeof(SignatureMask)), 16);
When I delete "-Werror-implicit-function-declaration" in Makefile,I will got the error:
detect-engine-siggroup.o: In function `SigGroupHeadFree':
/root/suricata/suricata-2.0.9/src/detect-engine-siggroup.c:187: undefined reference to `_mm_free'
detect-engine-siggroup.o: In function `SigGroupHeadBuildHeadArray':
/root/suricata/suricata-2.0.9/src/detect-engine-siggroup.c:1715: undefined reference to `_mm_malloc'
Note:_mm_free and _mm_malloc is define in util-mem.h
Yet,I add some code in the other source file,but not in detect-engine-siggroup.c and util-mem.h.
What's wrong?
in detect-engine-siggroup.c(note I have deleted some redundant code here):
void SigGroupHeadFree(SigGroupHead *sgh)
{
if (sgh == NULL)
return;
SCLogDebug("sgh %p", sgh);
PatternMatchDestroyGroup(sgh);
#if defined(__SSE3__) || defined(__tile__)
if (sgh->mask_array != NULL) {
/* mask is aligned */
SCFreeAligned(sgh->mask_array);
sgh->mask_array = NULL;
}
#endif
if (sgh->head_array != NULL) {
SCFree(sgh->head_array);
sgh->head_array = NULL;
}
if (sgh->match_array != NULL) {
detect_siggroup_matcharray_free_cnt++;
detect_siggroup_matcharray_memory -= (sgh->sig_cnt * sizeof(Signature *));
SCFree(sgh->match_array);
sgh->match_array = NULL;
}
sgh->sig_cnt = 0;
if (sgh->init != NULL) {
SigGroupHeadInitDataFree(sgh->init);
sgh->init = NULL;
}
SCFree(sgh);
detect_siggroup_head_free_cnt++;
detect_siggroup_head_memory -= sizeof(SigGroupHead);
return;
}
in util-mem.h(note I have deleted some redundant code here):
#ifndef __UTIL_MEM_H__
#define __UTIL_MEM_H__
#include "util-atomic.h"
#if CPPCHECK==1
#define SCMalloc malloc
#define SCCalloc calloc
#define SCRealloc realloc
#define SCFree free
#define SCStrdup strdup
#define SCMallocAligned _mm_malloc
#define SCFreeAligned _mm_free
#else /* CPPCHECK */
#if defined(_WIN32) || defined(__WIN32)
#include "mm_malloc.h"
#endif
#if defined(__tile__)
/* Need to define __mm_ function alternatives, since these are SSE only.
*/
#include <malloc.h>
#define _mm_malloc(a,b) memalign((b),(a))
#define _mm_free(a) free((a))
#endif /* defined(__tile__) */
SC_ATOMIC_EXTERN(unsigned int, engine_stage);
/* Use this only if you want to debug memory allocation and free()
* It will log a lot of lines more, so think that is a performance killer */
/* Uncomment this if you want to print memory allocations and free's() */
//#define DBG_MEM_ALLOC
#ifdef DBG_MEM_ALLOC
#define SCFree(a) ({ \
extern uint8_t print_mem_flag; \
if (print_mem_flag == 1) { \
SCLogInfo("SCFree at %p", (a)); \
} \
free((a)); \
})
#else /* !DBG_MEM_ALLOC */
#define SCFree(a) ({ \
free(a); \
})
#if defined(__WIN32) || defined(_WIN32)
#define SCFreeAligned(a) ({ \
_mm_free(a); \
})
#else /* !win */
#define SCFreeAligned(a) ({ \
_mm_free((a)); \
})
#endif /* __WIN32 */
#endif /* DBG_MEM_ALLOC */
#endif /* CPPCHECK */
#endif /* __UTIL_MEM_H__ */
#endif /* DBG_MEM_ALLOC */
#endif /* CPPCHECK */
#endif /* __UTIL_MEM_H__ */
/*********************************************************************/
Now solved the problem,reason is forgetting to #include <pmmintrin.h> /* for SSE3 */
/*********************************************************************/
It looks like you have not included util-mem.h properly. SCFreeAligned seem to expand to _mm_free, but _mm_free doesn't seem to expand. Looking at the header file the definition of _mm_free seem to be dependent on __title__ being defined.
Then the compiler just sees a call to _mm_free which is given an implicit prototype as _mm_free doesn't exist. Then of course _mm_free will not be found during linking.
Does someone know of any C99 preprocessor magic that allows for creating a string consisting of another string repeated N times?
E.g.
STRREP( "%s ", 3 )
becomes
"%s %s %s "
after preprocessing.
The only thing I could think of myself was something like this
#define STRREP( str, N ) STRREP_##N( str )
#define STRREP_0(str) ""
#define STRREP_1(str) str
#define STRREP_2(str) str str
#define STRREP_3(str) str str str
...
which works well, but is ugly as I have to define a macro for each repetition length manually. I want to use it together with variadic macros and the macro returning the number of macro arguments shown here.
Since it's a macro and N is a numeric constant anyway, how about this?
#include <stdio.h>
#define REP0(X)
#define REP1(X) X
#define REP2(X) REP1(X) X
#define REP3(X) REP2(X) X
#define REP4(X) REP3(X) X
#define REP5(X) REP4(X) X
#define REP6(X) REP5(X) X
#define REP7(X) REP6(X) X
#define REP8(X) REP7(X) X
#define REP9(X) REP8(X) X
#define REP10(X) REP9(X) X
#define REP(HUNDREDS,TENS,ONES,X) \
REP##HUNDREDS(REP10(REP10(X))) \
REP##TENS(REP10(X)) \
REP##ONES(X)
int main(void)
{
printf(REP(9,0,7, "*")); // "*" repeated 907 times
printf(REP(0,9,2, "#")); // "#" repeated 92 times
printf(REP(0,0,1, "#")); // "#" repeated 1 times
return 0;
}
My suggestion is to use the boost.
E.g.
#include <stdio.h>
#include <boost/preprocessor/repetition/repeat.hpp>
#define Fold(z, n, text) text
#define STRREP(str, n) BOOST_PP_REPEAT(n, Fold, str)
int main(){
printf("%s\n", STRREP("%s ", 3));//STRREP("%s ", 3) -> "%s %s %s "
return 0;
}
I recently discovered a recursion scheme with the CPP c-preprocessor file inclusion mechanism over the __INCLUDE_LEVEL__ preprocessor literal which is treated automatically - so maybe this algorithm only works for gcc ?!?
The algorithm is conceptually unlimited, it can be extended with additional file indirection.
The herin presented code handles an ITERATION_COUNT from 0-39202
With the comment/uncomment of the ITERATION_SEPARATOR you can
generate N elements, or 1 element with N concatenations, suitable for string repetitions.
The ITERATION_ELEMENT macro is used as the "repetition element"
You can compile the code regulary, without any additional defines. The macro invocation inside the code is idempotent.
An exemplary output:
> gcc iterate.c -o iterate -Wall -s -O3 && ./iterate.exe
0-1591 Counter
1592 Elements
iterate.c:
#include <stdio.h>
#include <inttypes.h>
int main(void) {
const char * preproc_array[] = {
#define ITERATION_COUNT 1592 //0-(199*197-1)39202 (maximum counter)
#define ITERATION_SEPARATOR , //this macro, if active, determines wheather there exits N separate elements otherwise, if outcommented, just 1 element with N concatenations
#define ITERATION_ELEMENT 0-__COUNTER__ Counter\n //the expanded macro as an arbitrary element
#include "iterate.h"
};
return !printf("%s%"PRIu32" Elements",preproc_array[
#ifndef NO_ITERATION_SEPARATOR
__COUNTER__-1
#else
0
#endif
], sizeof(preproc_array)/sizeof(const char *));
}
iterate.h:
#define ITERATION_START 1 //start index of first inclusion
#define ITERATION_LIMIT 199 //conforming to CPP preprocessor manual pg. 54 chapter 11.5, a limit of 200 is set arbitrary
#define ITERATION(...) _ITERATION(__VA_ARGS__)
#define _ITERATION(...) #__VA_ARGS__ ITERATION_SEPARATOR
#ifndef ITERATION_SEPARATOR
#define ITERATION_SEPARATOR
#define NO_ITERATION_SEPARATOR
#endif
//here begins the recursive algorithm via preprocessor file inclusion, enable the warnings if you want to see how it loops through
#if __INCLUDE_LEVEL__ <= ITERATION_COUNT/ITERATION_LIMIT
//~ #warning DIV
#define ITERATION_END ITERATION_COUNT/ITERATION_LIMIT+3 // + offset
#include "loop.h"
#define ITERATION_END ITERATION_LIMIT
#include "loop.h"
#include "iterate.h"
#endif
#if __INCLUDE_LEVEL__ == ITERATION_START
//~ #warning MOD
#define ITERATION_END ITERATION_COUNT%ITERATION_LIMIT+ITERATION_START
#include "loop.h"
#if ITERATION_COUNT % ITERATION_LIMIT
#define ITERATION_END 3 // + offset
#include "loop.h"
#endif
#endif
//end of alogrithm
loop.h:
#if __INCLUDE_LEVEL__ < ITERATION_END
#include "loop.h"
ITERATION(ITERATION_ELEMENT)
#undef ITERATION_END
#endif
Not sure whether it can be done with the macro but you can do it with the function like:
char *strrep(const char *str, int nrep)
{
if (nrep <= 0 || !str) return NULL;
char *buf = malloc(strlen(str) * nrep + 1);
if (!buf) return NULL;
for (int i = 0; i < nrep; ++i) {
strcat(buf, str);
}
return buf;
}
Now you can use it:
char *r = strrep("%s", 3);
if (r) {
...
free(r);
}
UPD: If you want to avoid malloc/free this is a variant of the first code:
/* .h */
#define STRREP_MAX_CHARS 1024
#define STRREP_INIT static char __strrep_buffer[STRREP_MAX_CHARS]
#define STRREP(str, nrep) strrep(str, nrep) ? __strrep_buffer : ""
char *strrep(const char *str, int nrep);
/* .c */
STRREP_INIT;
char *strrep(const char *str, int nrep)
{
if (nrep <= 0 || !str) return 0;
if (strlen(str) * nrep >= STRREP_MAX_CHARS) return 0;
memset(__strrep_buffer, 0, STRREP_MAX_CHARS);
for (int i = 0; i < nrep; ++i) {
strcat(__strrep_buffer, str);
}
return __strrep_buffer;
}
Now:
printf("%s\n", STRREP("%s", 3));
OTOH, this looks even uglier than the first one.
How about something like this?
#define DUP2(str) str str
#define DUP4(str) DUP2(str) DUP2(str)
#define DUP8(str) DUP4(str) DUP4(str)
#define DUP16(str) DUP8(str) DUP8(str)
#define DUP32(str) DUP16(str) DUP16(str)
#define DUP64(str) DUP32(str) DUP32(str)
#define DUP128(str) DUP64(str) DUP64(str)
#define DUP256(str) DUP128(str) DUP128(str)
#define DUP512(str) DUP256(str) DUP256(str)
#define DUP1024(str) DUP512(str) DUP512(str)