[linux-l] Re: Arrays in C

Steffen Dettmer steffen at dett.de
Fr Nov 25 16:04:31 CET 2005


* Axel Weiß wrote on Tue, Nov 15, 2005 at 20:53 +0100:
> Steffen Dettmer schrieb:
> > Warum do {} while? {} block ist hier doch nichtmal notwendig, oder?
> 
> if (allocate_some_ressource() == SUCCESS){
> 	...
> }
> else DEBUG(("allocation failed"));
> 
> und die Fehlermeldung ist im Fehlerfall verloren.

haha, lol, gar nicht gesehen, dass nach dem Kommentar im Macro noch
weitere Anweisungen kommen und fprintf dreimal aufgerufen wird...

Na gut, dann probier ich auch mal was.

Wenn man schreiben möchte:

dbgPrintf(("%s", irgendwas));

würde ich für GNUC sowas hier probieren:

#define dbgPrintf(args)  dbgPrintfTEMP_  args
#define dbgPrintfTEMP_(level, err, fmt, args...) \
	dbgPrintf_lff_(__FILE__, _ _LINE__, __PRETTY_FUNCTION__, \
	level, err, fmt, ## args)

(lff: line file function)

Man kann debug wegdefinieren - dank der doppelten Klammer auch, wenn der
Compiler keine "va-Macros" kann:

#ifdef DEBUG
   /* wie oben */
#else /* not DEBUG */
#  define dbgPrintf(args)
#endif /* not DEBUG */

File, Line und Function kann ja der GCC, wird oben automatisch
parametriert und könnte zu einem Header in dem Stil führen:

void
dbgPrintf_lff_ (
   const char*       fileName,
   int               lineNr,
   const char*       functionName,
   int               severity,
   const char*       formatString,
   ...
) __attribute__ ((format (printf,5,6)));

der kann ja dann je Platform anders sein, insbesondere wenn man
__FUNCTION__ oder so nicht hat und __FILE__ und so nicht möchte (z.B.
wenig Speicher, kein Filesystem, ...). Minimal wäre vielleicht was wie:

void
dbgPrintf_min_ (
   int               severity,
   const char*       formatString,
   ...
);

oder sowas; wenn man severity auch nicht kann, kann man ggf. auch direkt
auf fprintf #definen; das geht natürlich auch wieder mit __FILE__ und so
weiter falls man hat und möchte.

Für'n GNU-C PC, wo malloc "billig" ist aber die Ausgaben "schick" sein
sollen, kann man sich dass dann jedoch schöner implementieren. Ich
schreib hier mal was, ist aber nichtmal Compiler-getestet :-)

   char*             myFormatString = NULL;
   va_list           vaList;
   assert(formatString != NULL);

   va_start(vaList, formatString);

   /* die Längen sind erstmal geraten :) */
   myFormatString = malloc(strlen(formatString) 
        + 12 /* "DBG-X : (): " */
        + 10 /* safe severity */
        + strlen(fileName)
        + 10 /* safe lineNr */
        + strlen(functionName)
        + strlen(errName)
	+ 1 /* EOS */
   );

   if(myFormatString != NULL) {
      sprintf(
         myFormatString,
         "DBG-%1d %s:%d (%s): ",
         severity,
         fileName,
         lineNr,
         functionName
      );
      strcat(myFormatString, formatString);
      vfprintf(
         stderr,
         myFormatString,
         vaList
      );
      free(myFormatString);
   }

   /* va_kram kann ich nicht, hab hier die man page nicht :( Fehlt hier
    * noch ein va_end oder sowas?!
    */

Wenn man Java JDK Logging style mag, kann man noch einen "logger"
einführen, severity in level umbenennen, dem logger auch einen level
zuordnen und dann nur loggen, wenn der übergebene Level grösser ist -
klar, man kann immer viel dranbasteln, aber dies würde ich persönlich
gleich pauschal mal dazu machen. Der erste Parameter wäre dann halt ein
"const struct logger_s*" oder sowas.

So viel von meinem dazugegebenen Senf :-)

oki,

Steffen

-- 
Dieses Schreiben wurde maschinell erstellt,
es trägt daher weder Unterschrift noch Siegel.



Mehr Informationen über die Mailingliste linux-l