Newsgroup: it.comp.lang.c
Titolo: __LINE__ __FILE__ e MACRO

Ho una funzione di logging con prototype
bool printerror( char severity, const char* message );
e semplicemente per comodità di scrittura vorrei poter scrivere
if ( wrappererror( uuuh, "aiutoooo!" ) ) { ....
e se uuuh>threshold a printerror vorrei passare
"aiutoooo!" __LINE__ __FILE__
giusto per non dovermi a) ricordare di farlo b) scriverlo
uuuh sara probabilmente sempre una serie di
#define SELF_DESTRUCTION 0
#define PANIC 1
Ora le stringhe non è necessario concatenarle in runtime quindi
ovviamente vorrei che la cosa venisse fatta a compile time.
2 problemi:
1) se piazzo __LINE__ nella macro... sarà la __LINE__ di dove lo ho
scritto ovvero la linea della def della macro e non della chiamata
(scopribile appena scopro se vale la pena scoprirlo)
ma si dai...
//compile with gcc t.c -o t -std=gnu99
#include <stdio.h>
#define PIPPO __LINE__
int main( int argc, char *argv[] ) {
  // printf("uuh: %s", PIPPO );
  printf("\nuuh: %d\n\n", PIPPO );
  return 0;
}
OK, va!
2) non mi viene in mente nessuna maniera per implementare una macro di
tal fatta elegantemente... o anche brutalmente.
Ovvio che se le macro sono la strada sbagliata, non ho intenzione di
ostinarmi a voler risolvere questa cosa in questa maniera ;)
Conoscete qualche reference online per le macro in C? Sui libri di C++
che ho in casa l'argomento macro e taboo e di libri C non ne ho[sic].
thx

 tal fatta elegantemente... o anche brutalmente.
Puoi usare __VA_ARGS__, contemplato dall'ISO C:
#define log(...) printf(__FILE__ ": " __VA_ARGS__ )
Il problema e` che non riesci ad inserire il numero di riga in maniera
banale. Dovresti fare una cosa di questo tipo:
#define log(fmt, ...) printf(__FILE__ "(%d): " fmt, __LINE__ , __VA_ARGS__ )
Pero` a questo punto non sono ammesse chiamate del tipo:
log("bla");
ma solo:
log("bla %f", 3.14);
ovvero il secondo argomento non puo` essere nullo. Workaround standard:
void log_(char const *file, int line, char const *fmt, ...) {
        va_list args;
        va_start(args, fmt);
        printf("%s(%d): ");
        vprintf(fmt, args);
        va_end(args);
}
#define log(...) log_(__FILE__ , __LINE__ , __VA_ARGS__ )
Visto che usi gcc puoi anche usare un'estensione non standard per
ottenere lo stesso risultato:
#define log(fmt, args...) printf( __FILE__ "(%d): " fmt, __LINE__ , ## args)
Il controllo sul livello di verbosity puoi farlo (vale per tutte le
soluzioni) cosi`:
#define log(level, fmt, args...)                                        \
do {                                                                    \
        if (level > THRESHOLD)                                          \
                printf(__FILE__ "(%d): " fmt, __LINE__ , ## args)       \
} while(0)
Luca
-- 
Home: 
http://kronoz.cjb.net
Non capisco tutta questa eccitazione per il Multitasking: 
io sono anni che leggo in bagno.

 #define log(...) printf(__FILE__ ": " __VA_ARGS__ )
Non =E8 esattamente quello che voglio fare.
Comunque mi =E8 stato utile perch=E8 piazzando __VA_ARGS__ in google =E8
saltato fuori questo:
http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/cpp/index.h=
tml
Vorrei usare condizionali in una macro.
Passo un esempio che ooops non funziona ma magari fa intuire che cosa
voglio fare.
#include <stdio.h>
#define PIPPO( x, y ) \
#if x > 3
printf( "%s", y __LINE__ __FILE__)
#else
printf( "%s, y )
#endif
int main( ) {
  PIPPO( 0, "va quasi tutto bene" );
  PIPPO( 5, "continua cos=EC e ti verr=E0 un infarto" );
  return 0;
}
Questo dovrebbe far si che la concatenazione tra stringhe venga fatta
a compile time e non a run time.

 a compile time e non a run time.
Rileggi ;)
Luca
-- 
Home: 
http://kronoz.cjb.net
Se non sei parte della soluzione, allora sei parte del problema.