[4.0] Use strip (instead of eu-strip) to support --strip-debug of *.so at build time
[platform/upstream/rpm.git] / rpmio / rpmlog.c
index 6f8576f..8023d5c 100644 (file)
@@ -3,28 +3,52 @@
  */
 
 #include "system.h"
-
 #include <stdarg.h>
-
-#include "rpmlog.h"
-
-/*@access rpmlogRec @*/
+#include <stdlib.h>
+#include <rpm/rpmlog.h>
+#include "debug.h"
 
 static int nrecs = 0;
-static /*@only@*/ /*@null@*/ rpmlogRec recs = NULL;
+static rpmlogRec recs = NULL;
+
+struct rpmlogRec_s {
+    int                code;           /* unused */
+    rpmlogLvl  pri;            /* priority */ 
+    char * message;            /* log message string */
+};
 
 int rpmlogGetNrecs(void)
 {
     return nrecs;
 }
 
+int rpmlogCode(void)
+{
+    if (recs != NULL && nrecs > 0)
+       return recs[nrecs-1].code;
+    return -1;
+}
+
+
 const char * rpmlogMessage(void)
 {
-    if (nrecs > 0)
+    if (recs != NULL && nrecs > 0)
        return recs[nrecs-1].message;
     return _("(no error)");
 }
 
+const char * rpmlogRecMessage(rpmlogRec rec)
+{
+    assert(rec != NULL);
+    return (rec->message);
+}
+
+rpmlogLvl rpmlogRecPriority(rpmlogRec rec)
+{
+    assert(rec != NULL);
+    return (rec->pri);
+}
+
 void rpmlogPrint(FILE *f)
 {
     int i;
@@ -32,10 +56,11 @@ void rpmlogPrint(FILE *f)
     if (f == NULL)
        f = stderr;
 
+    if (recs)
     for (i = 0; i < nrecs; i++) {
        rpmlogRec rec = recs + i;
        if (rec->message && *rec->message)
-           fprintf(f, "    %s\n", rec->message);
+           fprintf(f, "    %s", rec->message);
     }
 }
 
@@ -43,25 +68,25 @@ void rpmlogClose (void)
 {
     int i;
 
+    if (recs)
     for (i = 0; i < nrecs; i++) {
        rpmlogRec rec = recs + i;
-       if (rec->message) {
-           free((void *)rec->message);
-           rec->message = NULL;
-       }
+       rec->message = _free(rec->message);
     }
-    free(recs);
-    recs = NULL;
+    recs = _free(recs);
     nrecs = 0;
 }
 
-void rpmlogOpen (/*@unused@*/ const char *ident, /*@unused@*/ int option,
-               /*@unused@*/ int facility)
+void rpmlogOpen (const char *ident, int option,
+               int facility)
 {
 }
 
-static int rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
-static /*@unused@*/ int rpmlogFacility = RPMLOG_USER;
+static unsigned rpmlogMask = RPMLOG_UPTO( RPMLOG_NOTICE );
+
+#ifdef NOTYET
+static unsigned rpmlogFacility = RPMLOG_USER;
+#endif
 
 int rpmlogSetMask (int mask)
 {
@@ -71,16 +96,55 @@ int rpmlogSetMask (int mask)
     return omask;
 }
 
-static /*@null@*/ rpmlogCallback _rpmlogCallback = NULL;
+static rpmlogCallback _rpmlogCallback = NULL;
+static rpmlogCallbackData _rpmlogCallbackData = NULL;
 
-rpmlogCallback rpmlogSetCallback(rpmlogCallback cb)
+rpmlogCallback rpmlogSetCallback(rpmlogCallback cb, rpmlogCallbackData data)
 {
     rpmlogCallback ocb = _rpmlogCallback;
     _rpmlogCallback = cb;
+    _rpmlogCallbackData = data;
     return ocb;
 }
 
-static char *rpmlogMsgPrefix[] = {
+static FILE * _stdlog = NULL;
+
+static int rpmlogDefault(rpmlogRec rec)
+{
+    FILE *msgout = (_stdlog ? _stdlog : stderr);
+
+    switch (rec->pri) {
+    case RPMLOG_INFO:
+    case RPMLOG_NOTICE:
+        msgout = (_stdlog ? _stdlog : stdout);
+        break;
+    case RPMLOG_EMERG:
+    case RPMLOG_ALERT:
+    case RPMLOG_CRIT:
+    case RPMLOG_ERR:
+    case RPMLOG_WARNING:
+    case RPMLOG_DEBUG:
+    default:
+        break;
+    }
+
+    (void) fputs(rpmlogLevelPrefix(rec->pri), msgout);
+
+    (void) fputs(rec->message, msgout);
+    (void) fflush(msgout);
+
+    return (rec->pri <= RPMLOG_CRIT ? RPMLOG_EXIT : 0);
+}
+
+
+FILE * rpmlogSetFile(FILE * fp)
+{
+    FILE * ofp = _stdlog;
+    _stdlog = fp;
+    return ofp;
+}
+
+static const char * const rpmlogMsgPrefix[] = {
     N_("fatal error: "),/*!< RPMLOG_EMERG */
     N_("fatal error: "),/*!< RPMLOG_ALERT */
     N_("fatal error: "),/*!< RPMLOG_CRIT */
@@ -91,79 +155,76 @@ static char *rpmlogMsgPrefix[] = {
     "D: ",             /*!< RPMLOG_DEBUG */
 };
 
-static void vrpmlog (unsigned code, const char *fmt, va_list ap)
+const char * rpmlogLevelPrefix(rpmlogLvl pri)
 {
-    int pri = RPMLOG_PRI(code);
-    int mask = RPMLOG_MASK(pri);
-    /*@unused@*/ int fac = RPMLOG_FAC(code);
-    char msgbuf[BUFSIZ], *msg;
-    FILE * msgout = stderr;
-    rpmlogRec rec;
-
-    if ((mask & rpmlogMask) == 0)
-       return;
+    const char * prefix = "";
+    if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri]) 
+       prefix = _(rpmlogMsgPrefix[pri]);
+    return prefix;
+}
 
-    /*@-unrecog@*/ vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); /*@=unrecog@*/
-    msgbuf[sizeof(msgbuf) - 1] = '\0';
-    msg = msgbuf;
+/* FIX: rpmlogMsgPrefix[] dependent, not unqualified */
+/* FIX: rpmlogMsgPrefix[] may be NULL */
+static void dolog (struct rpmlogRec_s *rec)
+{
+    int cbrc = RPMLOG_DEFAULT;
+    int needexit = 0;
 
     /* Save copy of all messages at warning (or below == "more important"). */
-    if (pri <= RPMLOG_WARNING) {
-
-       if (recs == NULL)
-           recs = xmalloc((nrecs+2) * sizeof(*recs));
-       else
-           recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
+    if (rec->pri <= RPMLOG_WARNING) {
+       recs = xrealloc(recs, (nrecs+2) * sizeof(*recs));
+       recs[nrecs].code = rec->code;
+       recs[nrecs].pri = rec->pri;
+       recs[nrecs].message = xstrdup(rec->message);
        recs[nrecs+1].code = 0;
        recs[nrecs+1].message = NULL;
-       rec = recs + nrecs;
        ++nrecs;
-
-       rec->code = code;
-       rec->message = xstrdup(msg);
-
-       if (_rpmlogCallback) {
-           _rpmlogCallback();
-           return;     /* XXX Preserve legacy rpmError behavior. */
-       }
     }
 
-    /* rpmMessage behavior */
-
-    switch (pri) {
-    case RPMLOG_INFO:
-    case RPMLOG_NOTICE:
-       msgout = stdout;
-       break;
-
-    case RPMLOG_EMERG:
-    case RPMLOG_ALERT:
-    case RPMLOG_CRIT:
-    case RPMLOG_ERR: /* XXX Legacy rpmError behavior used stdout w/o prefix. */
-    case RPMLOG_WARNING:
-    case RPMLOG_DEBUG:
-       break;
+    if (_rpmlogCallback) {
+       cbrc = _rpmlogCallback(rec, _rpmlogCallbackData);
+       needexit += cbrc & RPMLOG_EXIT;
     }
 
-    /* Silly FORTRAN-like carriage control. */
-    if (*msg == '+')
-       msg++;
-    else if (rpmlogMsgPrefix[pri] && *rpmlogMsgPrefix[pri])
-       fputs(_(rpmlogMsgPrefix[pri]), msgout);
-
-    fputs(msg, msgout);
-    if (pri == RPMLOG_ERR) /* XXX Legacy rpmError behavior appends newline. */
-       fputs("\n", msgout);
-    fflush(msgout);
-    if (pri <= RPMLOG_CRIT)
+    if (cbrc & RPMLOG_DEFAULT) {
+       cbrc = rpmlogDefault(rec);
+       needexit += cbrc & RPMLOG_EXIT;
+    }
+    
+    if (needexit)
        exit(EXIT_FAILURE);
 }
 
 void rpmlog (int code, const char *fmt, ...)
 {
+    unsigned pri = RPMLOG_PRI(code);
+    unsigned mask = RPMLOG_MASK(pri);
     va_list ap;
+    int n;
+
+    if ((mask & rpmlogMask) == 0)
+       return;
 
     va_start(ap, fmt);
-    vrpmlog(code, fmt, ap);
+    n = vsnprintf(NULL, 0, fmt, ap);
     va_end(ap);
+
+    if (n >= -1) {
+       struct rpmlogRec_s rec;
+       size_t nb = n + 1;
+       char *msg = xmalloc(nb);
+
+       va_start(ap, fmt);
+       n = vsnprintf(msg, nb, fmt, ap);
+       va_end(ap);
+
+       rec.code = code;
+       rec.pri = pri;
+       rec.message = msg;
+
+       dolog(&rec);
+
+       free(msg);
+    }
 }
+