]>
git.saurik.com Git - apple/libc.git/blob - gen/FreeBSD/fmtmsg.c
2 * Copyright (c) 2002 Mike Barcroft <mike@FreeBSD.org>
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD: src/lib/libc/gen/fmtmsg.c,v 1.5 2003/05/01 19:03:13 nectar Exp $");
35 /* Default value for MSGVERB. */
36 #define DFLT_MSGVERB "label:severity:text:action:tag"
38 /* Maximum valid size for a MSGVERB. */
39 #define MAX_MSGVERB sizeof(DFLT_MSGVERB)
41 static char *printfmt(char *, long, const char *, int, const char *,
42 const char *, const char *);
43 static char *nextcomp(const char *);
46 static int validmsgverb(const char *);
48 static const char *validlist
[] = {
49 "label", "severity", "text", "action", "tag", NULL
53 fmtmsg(long class, const char *label
, int sev
, const char *text
,
54 const char *action
, const char *tag
)
57 char *env
, *msgverb
, *output
;
59 if (class & MM_PRINT
) {
60 if ((env
= getenv("MSGVERB")) != NULL
&& *env
!= '\0' &&
61 strlen(env
) <= strlen(DFLT_MSGVERB
)) {
62 if ((msgverb
= strdup(env
)) == NULL
)
64 else if (validmsgverb(msgverb
) == 0) {
70 if ((msgverb
= strdup(DFLT_MSGVERB
)) == NULL
)
73 output
= printfmt(msgverb
, class, label
, sev
, text
, action
,
80 fprintf(stderr
, "%s", output
);
84 if (class & MM_CONSOLE
) {
85 output
= printfmt(DFLT_MSGVERB
, class, label
, sev
, text
,
89 if (*output
!= '\0') {
90 if ((fp
= fopen("/dev/console", "a")) == NULL
) {
94 fprintf(fp
, "%s", output
);
102 #define INSERT_COLON \
103 if (*output != '\0') \
104 strlcat(output, ": ", size)
105 #define INSERT_NEWLINE \
106 if (*output != '\0') \
107 strlcat(output, "\n", size)
108 #define INSERT_SPACE \
109 if (*output != '\0') \
110 strlcat(output, " ", size)
113 * Returns NULL on memory allocation failure, otherwise returns a pointer to
114 * a newly malloc()'d output buffer.
117 printfmt(char *msgverb
, long class, const char *label
, int sev
,
118 const char *text
, const char *act
, const char *tag
)
125 if (label
!= MM_NULLLBL
)
126 size
+= strlen(label
);
127 if ((sevname
= sevinfo(sev
)) != NULL
)
128 size
+= strlen(sevname
);
129 if (text
!= MM_NULLTXT
)
130 size
+= strlen(text
);
131 if (text
!= MM_NULLACT
)
133 if (tag
!= MM_NULLTAG
)
136 if ((output
= malloc(size
)) == NULL
)
139 while ((comp
= nextcomp(msgverb
)) != NULL
) {
140 if (strcmp(comp
, "label") == 0 && label
!= MM_NULLLBL
) {
142 strlcat(output
, label
, size
);
143 } else if (strcmp(comp
, "severity") == 0 && sevname
!= NULL
) {
145 strlcat(output
, sevinfo(sev
), size
);
146 } else if (strcmp(comp
, "text") == 0 && text
!= MM_NULLTXT
) {
148 strlcat(output
, text
, size
);
149 } else if (strcmp(comp
, "action") == 0 && act
!= MM_NULLACT
) {
151 strlcat(output
, "TO FIX: ", size
);
152 strlcat(output
, act
, size
);
153 } else if (strcmp(comp
, "tag") == 0 && tag
!= MM_NULLTAG
) {
155 strlcat(output
, tag
, size
);
163 * Returns a component of a colon delimited string. NULL is returned to
164 * indicate that there are no remaining components. This function must be
165 * called until it returns NULL in order for the local state to be cleared.
168 nextcomp(const char *msgverb
)
170 static char lmsgverb
[MAX_MSGVERB
], *state
;
173 if (*lmsgverb
== '\0') {
174 strlcpy(lmsgverb
, msgverb
, sizeof(lmsgverb
));
175 retval
= strtok_r(lmsgverb
, ":", &state
);
177 retval
= strtok_r(NULL
, ":", &state
);
203 * Returns 1 if the msgverb list is valid, otherwise 0.
206 validmsgverb(const char *msgverb
)
212 while ((msgcomp
= nextcomp(msgverb
)) != NULL
) {
214 for (i
= 0; validlist
[i
] != NULL
; i
++) {
215 if (strcmp(msgcomp
, validlist
[i
]) == 0)