I have a project with many files and they all include one header called logging.h, I dont know what happened but for some reason when i try to compile this happens. I can not revert the changes and I dont know what to do.
These lines repeat themselves multiple times
/usr/bin/ld: fs/operations.o: in function `send_request':
/root/so/mbroker/utils/logging.h:59: multiple definition of `send_request'; mbroker/mbroker.o:/root/so/mbroker/utils/logging.h:59: first defined here
/usr/bin/ld: fs/operations.o: in function `serialize':
/root/so/mbroker/utils/logging.h:68: multiple definition of `serialize'; mbroker/mbroker.o:/root/so/mbroker/utils/logging.h:68: first defined here
/usr/bin/ld: fs/state.o: in function `clear_session':
/root/so/mbroker/utils/logging.h:53: multiple definition of `clear_session'; mbroker/mbroker.o:/root/so/mbroker/utils/logging.h:53: first defined here
As you can see it's all happening in logging.h
Here's my logging.h
#ifndef __UTILS_LOGGING_H__
#define __UTILS_LOGGING_H__
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h> //open
#include <fcntl.h> //flags for open
#include <unistd.h>
#define PIPENAME 256
#define BOXNAME 32
#define MSIZE 256
#define COMMAND 8
static const __uint8_t REGISTER_PUBLISHER = 1;
static const __uint8_t REGISTER_SUBSCRIBER = 2;
static const __uint8_t CREATE_BOX = 3;
static const __uint8_t REMOVE_BOX = 5;
static const __uint8_t LIST_BOX = 7;
static const char INVALID_SESSIONS[] = "Invalid number of sessions";
static const char PIPENAME_TOO_BIG[] = "The pipe's name has too many characters";
static const char INVALID_BOXNAME[] = "The box's name is invalid";
static const char INVALID_NUMBER_OF_ARGUMENTS[] = "Insufficient or too many arguments";
static const char INVALID_ARGUMENTS[] = "One of the arguments is invalid";
static const char UNEXISTENT_PIPE[] = "Pipe doesn't exist";
static const char EXISTENT_PIPE[] = "Pipe already exists";
static const char ERROR_WRITING_PIPE[] = "Error writing to pipe";
static const char SIGNAL_FAIL[] ="Failed to initialize signals";
typedef struct box{
char boxname[BOXNAME];
int hasWriter;
int n_readers;
struct box *next;
} box;
typedef struct req{
int _code;
char _client_pipe[PIPENAME];
char _box_name[BOXNAME];
} request;
typedef enum {
LOG_QUIET = 0,
LOG_NORMAL = 1,
LOG_VERBOSE = 2,
} log_level_t;
//deletes fifo
void clear_session(int fd, char* fn){
close(fd);
unlink(fn);
}
/*writes to pipe tx a pointer with information*/
void send_request(int tx, request *r1) {
ssize_t ret = write(tx, &r1, sizeof(r1));
if (ret < 0) {
fprintf(stdout, "ERROR: %s\n", ERROR_WRITING_PIPE);
exit(EXIT_FAILURE);
}
}
/*Returns a pointer to a struct containing the request*/
request *serialize(int code, char* client_pipe, char* box_name){
request *r1 = (request*) malloc(sizeof(request));
r1->_code = code;
strcpy(r1->_client_pipe, client_pipe);
strcpy(r1->_box_name, box_name);
return r1;
}
void sig_handler(int sig);
void set_log_level(log_level_t level);
extern log_level_t g_level;
#define INFO(...) \
do { \
char buf[2048]; \
snprintf(buf, 2048, __VA_ARGS__); \
fprintf(stderr, "[INFO]: %s:%d :: %s :: %s\n", __FILE__, __LINE__, \
__func__, buf); \
} while (0);
#define PANIC(...) \
do { \
char buf[2048]; \
snprintf(buf, 2048, __VA_ARGS__); \
fprintf(stderr, "[PANIC]: %s:%d :: %s :: %s\n", __FILE__, __LINE__, \
__func__, buf); \
exit(EXIT_FAILURE); \
} while (0);
#define WARN(...) \
do { \
if (g_level == LOG_NORMAL || g_level == LOG_VERBOSE) { \
char buf[2048]; \
snprintf(buf, 2048, __VA_ARGS__); \
fprintf(stderr, "[WARN]: %s:%d :: %s :: %s\n", __FILE__, \
__LINE__, __func__, buf); \
} \
} while (0);
#define LOG(...) \
do { \
if (g_level == LOG_NORMAL || g_level == LOG_VERBOSE) { \
char buf[2048]; \
snprintf(buf, 2048, __VA_ARGS__); \
fprintf(stderr, "[LOG]: %s:%d :: %s :: %s\n", __FILE__, \
__LINE__, __func__, buf); \
} \
} while (0);
#define DEBUG(...) \
do { \
if (g_level == LOG_VERBOSE) { \
char buf[2048]; \
snprintf(buf, 2048, __VA_ARGS__); \
fprintf(stderr, "[DEBUG]: %s:%d :: %s :: %s\n", __FILE__, \
__LINE__, __func__, buf); \
} \
} while (0);
#endif // __UTILS_LOGGING_H__
I tried deleting files, going back as far as i could but this error wont stop haunting me.
I also tried make clean multiple times, but did nothing either.
I went back to an old backup of the project which was ok and now it's showing me this same error message again. I tried compiling both through vsc and through wsl.
Now that i think it through, the error might have started when i included .c in another file. I have long deleted that include line but am still getting the errors.
The solution involved only writing prototypes on the header and implementing the functions in a logging.c. It's weird the compiler only warned me after like many and many trials, but it's solved and that's all i could ask for.
Related
I am trying to write a small log system.
void write_log_msg(char * type, char * file_name, int line_number, char * fmt, ...);
To call this function in a nice way, I used macro
#define log_msg(fmt, ...) (write_log_msg(LOG, __FILE__, __LINE__, fmt, ##__VA_ARGS__))
I want to format the date of now and I use the function strftime to do that. But when I do, it seems it overwrites the data stored in __FILE__ and __LINE__ and I can't tell why.
time_t now = time(NULL);
char date_str[DATE_SIZE];
char time_str[TIME_SIZE];
struct tm * local_now = localtime(&now);
printf("file %s\n", file_name);
printf("line %d\n", line_number);
status = strftime(date_str, DATE_SIZE, "%b %d %Y", local_now);
if(status == 0){
printf("Error 1");
exit(EXIT_FAILURE);
}
status = strftime(time_str, TIME_SIZE, "%X", local_now);
if(status == 0){
printf("Error 2");
exit(EXIT_FAILURE);
}
When I check for the content of the value of __FILE__ and __LINE__ before strftime, it works just fine then the __FILE__ takes the value of date_str and line_str I can't even tell. Any idea why it would do that ? Thanks !
Any idea why it would do that ?
I am trying to create a ContikiOS firmware that acts as a gateway using Rime and REST. The gateway must communicate to other motes with the Rime mesh, and can communicate to the outside via a REST API.
The following code is a combination from two default Contiki examples (rest-example/rest-server-example.c and rime/example-mesh.c). Therefore I include "rest.h", "net/rime.h", "net/rime/mesh.h".
The problem is when I try to compile this firmware using following makefile, the rime files don't get included into obj_sky and any Rime functions I use in the firmware get an 'undefined reference' error. However when I remove the lines in the makefile and any code referring to REST in the firmware code, it does compile (and adds the rime files to obj_sky).
Would anyone have an idea why rime does not get added after adding the rest-http app and what I can do to have it compile?
Thank you
Code
Compiler info
> make gateway.sky TARGET=sky
CC gateway.c
CC ../../platform/sky/./contiki-sky-main.c
LD gateway.sky
/usr/lib/gcc/msp430/4.6.3/../../../../msp430/bin/ld: gateway.sky section `.data' will not fit in region `rom'
/usr/lib/gcc/msp430/4.6.3/../../../../msp430/bin/ld: section .vectors loaded at [000000000000ffe0,000000000000ffff] overlaps section .data loaded at [000000000000ff0c,0000000000010037]
/usr/lib/gcc/msp430/4.6.3/../../../../msp430/bin/ld: region `rom' overflowed by 88 bytes
gateway.co: In function `process_thread_init_mesh':
gateway.c:(.text.process_thread_init_mesh+0x10): undefined reference to `mesh_close'
gateway.c:(.text.process_thread_init_mesh+0x26): undefined reference to `mesh_open'
gateway.co: In function `recv':
gateway.c:(.text.recv+0x48): undefined reference to `mesh_send'
gateway.co: In function `enable_handler':
gateway.c:(.text.enable_handler+0x80): undefined reference to `mesh_send'
collect2: ld returned 1 exit status
../../Makefile.include:254: recipe for target 'gateway.sky' failed
Process returned error code 2
make: *** [gateway.sky] Error 1
rm obj_sky/contiki-sky-main.o gateway.co
Makefile
all: gateway mote
ifndef TARGET
TARGET=sky
endif
CONTIKI=../..
WITH_UIP6=1
UIP_CONF_IPV6=1
WITH_COAP = 0
APPS += rest-http
include $(CONTIKI)/Makefile.include
Lines to compile for REST
WITH_UIP6=1
UIP_CONF_IPV6=1
WITH_COAP = 0
APPS += rest-http
gateway.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "contiki.h"
#include "contiki-net.h"
#include "rest.h"
#include "net/rime.h"
#include "net/rime/mesh.h"
#if defined (PLATFORM_HAS_LIGHT)
#include "dev/light-sensor.h"
#endif
#if defined (PLATFORM_HAS_BATT)
#include "dev/battery-sensor.h"
#endif
#if defined (PLATFORM_HAS_SHT11)
#include "dev/sht11-sensor.h"
#endif
#if defined (PLATFORM_HAS_LEDS)
#include "dev/leds.h"
#endif
#define DEBUG 1
#if DEBUG
#include <stdio.h>
#define PRINTF(...) printf(__VA_ARGS__)
#define PRINT6ADDR(addr) PRINTF(" %02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x ", ((uint8_t *)addr)[0], ((uint8_t *)addr)[1], ((uint8_t *)addr)[2], ((uint8_t *)addr)[3], ((uint8_t *)addr)[4], ((uint8_t *)addr)[5], ((uint8_t *)addr)[6], ((uint8_t *)addr)[7], ((uint8_t *)addr)[8], ((uint8_t *)addr)[9], ((uint8_t *)addr)[10], ((uint8_t *)addr)[11], ((uint8_t *)addr)[12], ((uint8_t *)addr)[13], ((uint8_t *)addr)[14], ((uint8_t *)addr)[15])
#define PRINTLLADDR(lladdr) PRINTF(" %02x:%02x:%02x:%02x:%02x:%02x ",(lladdr)->addr[0], (lladdr)->addr[1], (lladdr)->addr[2], (lladdr)->addr[3],(lladdr)->addr[4], (lladdr)->addr[5])
#else
#define PRINTF(...)
#define PRINT6ADDR(addr)
#define PRINTLLADDR(addr)
#endif
#define MESSAGE "Hello"
/*---------------------------------------------------------------------------*/
/*---------------------------------RIME--------------------------------------*/
/*---------------------------------------------------------------------------*/
static struct mesh_conn mesh;
PROCESS(init_mesh, "RIME Mesh");
/*---------------------------------------------------------------------------*/
static void
sent(struct mesh_conn *c)
{
printf("packet sent\n");
}
static void
timedout(struct mesh_conn *c)
{
printf("packet timedout\n");
}
static void
recv(struct mesh_conn *c, const rimeaddr_t *from, uint8_t hops)
{
printf("Data received from %d.%d: %.*s (%d)\n",
from->u8[0], from->u8[1],
packetbuf_datalen(), (char *)packetbuf_dataptr(), packetbuf_datalen());
packetbuf_copyfrom(MESSAGE, strlen(MESSAGE));
mesh_send(&mesh, from);
}
static void
send(int to, char * msg)
{
printf("Sending data to %d", to);
rimeaddr_t addr;
packetbuf_copyfrom(msg, strlen(msg));
addr.u8[0] = to;
addr.u8[1] = 0;
mesh_send(&mesh, &addr);
}
const static struct mesh_callbacks callbacks = {recv, sent, timedout};
/*---------------------------------------------------------------------------*/
PROCESS_THREAD(init_mesh, ev, data)
{
PROCESS_EXITHANDLER(mesh_close(&mesh);)
PROCESS_BEGIN();
mesh_open(&mesh, 132, &callbacks);
PROCESS_END();
}
/*---------------------------------------------------------------------------*/
/*----------------------------------REST-------------------------------------*/
/*---------------------------------------------------------------------------*/
RESOURCE(enable, METHOD_GET, "enable");
void
enable_handler(REQUEST* request, RESPONSE* response)
{
int moteId = 0;
char moteIdstr[12];
sprintf(moteIdstr, "%d", moteId);
char command[20];
char responseText[255];
if (rest_get_query_variable(request, "moteId", moteIdstr, 10)) {
PRINTF("moteId %s\n", moteIdstr);
send(moteId, command);
sprintf(responseText,"Command execute for mote %s!\n", moteIdstr);
} else {
sprintf(responseText,"Mote not available!\n");
}
rest_set_header_content_type(response, TEXT_PLAIN);
rest_set_response_payload(response, (uint8_t*)responseText, strlen(responseText));
}
PROCESS(gateway_rest, "Gateway Rest");
PROCESS_THREAD(gateway_rest, ev, data)
{
PROCESS_BEGIN();
#ifdef WITH_COAP
PRINTF("COAP Server\n");
#else
PRINTF("HTTP Server\n");
#endif
rest_init();
rest_activate_resource(&resource_enable);
//rest_activate_resource(&resource_disable);
PROCESS_END();
}
/*---------------*/
AUTOSTART_PROCESSES(&init_mesh, &gateway_rest);
Info
I am using Sky motes to compile the code in Cooja.
I am currently developing a unit test library in C and I wanted to add a functionality Catch (in C++) had.
When you do, using Catch :
int x = 5;
REQUIRE(x == 4);
The output will be something like this :
Failed statement : x == 4
evaluated as 5 == 4
Is it possible to do something like that in C ?
This needs to be done at runtime.
You could do something like this. It's not very convenient, but it works:
#include <stdio.h>
#include <stdlib.h>
#define ASSERT_INT 1
#define ASSERT_EQ(x,y,type) do { if((x)!=(y)) { \
switch(type) { \
case ASSERT_INT: \
printf("Failed statement : %s == %d\n\tevaluated as %d == %d\n", \
#x, (y),(x), (y)); break; \
} exit(EXIT_FAILURE); }} while(0)
It requires some work though. If you want many operations you can do like this:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define ASSERT_INT 1
#define ASSERT_EQ 1
#define ASSERT(x,y,op,type) do { \
int success; \
char op_str[3]; \
switch(op) { \
case ASSERT_EQ: \
strcpy(op_str, "==");success = ((x) == (y)); break; \
} \
if(!success) { \
switch(type) { \
case ASSERT_INT: \
printf("Failed statement : %s %s %d\n\tevaluated as %d %s %d\n", \
#x, op_str, (y),(x), op_str, (y)); break; \
} exit(EXIT_FAILURE); }} while(0)
And the output:
$ ./a.out
Failed statement : x == 4
evaluated as 5 == 4
You will need to add a modified version of strcpy(op_str, "==");success = ((x) == (y)); break; for each different logical operation and a modified version of printf("Failed statement : %s %s %d\n\tevaluated as %d %s %d\n", #x, op_str, (y),(x), op_str, (y)); break; for each different type.
I have excerpts of code for a multi-level debug implementation, which I don't know how to make it work.
I have tried some of the suggestions posted here about using the do {...} while (0), and I also tried to declare a global variable called Debug, but none of them seem to work.
What should I do?
#include <stdio.h>
#include <stdlib.h>
//#define DEBUG(fmt, ...) fprintf (stderr, fmt, __VA_ARGS__ )
#ifdef DEBON
#define DEBUG(level, fmt, ...) \
if (Debug >= level) \
fprintf (stderr, fmt, __VA_ARGS__)
#else
#define DEBUG(level, fmt, ...)
#endif
int process ( int i1, int i2)
{
int val;
DEBUG (1, "process (%i, %i)\n", i1, i2);
val = i1 * i2;
DEBUG (3, "return %i\n", val);
return val;
}
int main ( int argc, char *argv[])
{
int arg1 = 0, arg2 = 0;
if (argc > 1)
arg1 = atoi (argv[1]);
if ( argc == 3)
arg2 = atoi (argv[2]);
DEBUG (1, "processed %i arguments\n", argc -1 );
DEBUG (3, "arg1 = %i, arg2 = %i\n" , arg1, arg2);
printf ("%d\n", process (arg1, arg2));
return 0;
}
Below is a simpler file I put together to see if I can get this working. No luck yet.
#define DEBUG(level, fmt, ...) if (Debug >= level ) fprintf (stderr, fmt, __VA_ARGS__)
#include <stdio.h>
int Debug;
int main()
{
int i1 = 1;
int i2 = 2;
DEBUG(3, "process (%i, %i)\n", i1, i2);
}
You last example works after minor tweaks. The idea in the book is to have your program parse the command line options and set the value of a global variable named Debug.
#include <stdio.h>
#include <stdlib.h>
#define DEBUG(level, fmt, ...) do if (Debug >= level) fprintf(stderr, fmt, __VA_ARGS__); while (0)
int Debug = 1; // default debug level == 1
int main(int argc, char *argv[])
{
int i1 = 1;
int i2 = 2;
size_t i;
for(i = 1; i < argc; ++i)
if ((argv[i][0] == '-') && (argv[i][1] == 'd'))
Debug = strtol(argv[i] + 2, 0, 10);
DEBUG(3, "process (%i, %i)\n", i1, i2);
return 0;
}
I'm going through Zed Shaw's tutorial on C debug macros, and am running an undeclared label problem, call the following file debug_macro.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#define clean_errno() (errno == 0 ? "None" : strerror(errno))
#define log_err(M, ...) fprintf(stderr, "[ERROR] (%s:%d: errno: %s) " M "\n", __FILE__, __LINE__, clean_errno(), ##__VA_ARGS__)
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
int test_check(char *file_name)
{
FILE *input = NULL;
char *block = NULL;
block = malloc(100);
input = fopen(file_name, "r");
check(input, "Failed to open %s.", file_name);
free(block);
fclose(input);
return 0;
error:
if(input) free(input);
if(block) free(block);
return -1;
}
int main(int argc, char *argv[])
{
// open up a bogus file and then trigger error
check(test_check("bogus.txt") == 0, "failed with bogus.txt");
return 0;
}
When I compile it with either cc or gcc, I get the following error:
gcc -Wall -g -O0 -I/opt/X11/include goto.c -o goto
goto.c:36:5: error: use of undeclared label 'error'
check(test_check("bogus.txt") == 0, "failed with bogus.txt");
^
goto.c:10:78: note: expanded from macro 'check'
#define check(A, M, ...) if(!(A)) { log_err(M, ##__VA_ARGS__); errno=0; goto error; }
^
1 error generated.
make: *** [goto] Error 1
shell returned 2
Press ENTER or type command to continue
When the macro is expanded, it inserts a goto error inside the test_check function, which has an error: label defined, so I don't know why I'm getting this compiler error.
You are trying to jump from main to another function test_check, but goto can only jump to a label inside the same function.
C11 ยง6.8.6.1 The goto statement
A goto statement causes an unconditional jump to the statement prefixed by the named
label in the enclosing function.