Merge from vendor branch GCC:
[dragonfly.git] / contrib / file / print.c
1 /*
2  * print.c - debugging printout routines
3  *
4  * Copyright (c) Ian F. Darwin, 1987.
5  * Written by Ian F. Darwin.
6  *
7  * This software is not subject to any license of the American Telephone
8  * and Telegraph Company or of the Regents of the University of California.
9  *
10  * Permission is granted to anyone to use this software for any purpose on
11  * any computer system, and to alter it and redistribute it freely, subject
12  * to the following restrictions:
13  *
14  * 1. The author is not responsible for the consequences of use of this
15  *    software, no matter how awful, even if they arise from flaws in it.
16  *
17  * 2. The origin of this software must not be misrepresented, either by
18  *    explicit claim or by omission.  Since few users ever read sources,
19  *    credits must appear in the documentation.
20  *
21  * 3. Altered versions must be plainly marked as such, and must not be
22  *    misrepresented as being the original software.  Since few users
23  *    ever read sources, credits must appear in the documentation.
24  *
25  * 4. This notice may not be removed or altered.
26  */
27
28 #include "file.h"
29 #include <string.h>
30 #include <stdarg.h>
31 #include <stdlib.h>
32 #ifdef HAVE_UNISTD_H
33 #include <unistd.h>
34 #endif
35 #include <time.h>
36
37 #ifndef lint
38 FILE_RCSID("@(#)$Id: print.c,v 1.39 2002/07/09 15:46:23 christos Exp $")
39 #endif  /* lint */
40
41 #define SZOF(a) (sizeof(a) / sizeof(a[0]))
42
43 #ifndef COMPILE_ONLY
44 void
45 mdump(struct magic *m)
46 {
47         static const char *typ[] = { "invalid", "byte", "short", "invalid",
48                                      "long", "string", "date", "beshort",
49                                      "belong", "bedate", "leshort", "lelong",
50                                      "ledate", "pstring", "ldate", "beldate",
51                                      "leldate", "regex" };
52         static const char optyp[] = { '@', '&', '|', '^', '+', '-', 
53                                       '*', '/', '%' };
54         (void) fputc('[', stderr);
55         (void) fprintf(stderr, ">>>>>>>> %d" + 8 - (m->cont_level & 7),
56                        m->offset);
57
58         if (m->flag & INDIR) {
59                 (void) fprintf(stderr, "(%s,",
60                                /* Note: type is unsigned */
61                                (m->in_type < SZOF(typ)) ? 
62                                         typ[m->in_type] : "*bad*");
63                 if (m->in_op & OPINVERSE)
64                         (void) fputc('~', stderr);
65                 (void) fprintf(stderr, "%c%d),",
66                                ((m->in_op&0x7F) < SZOF(optyp)) ? 
67                                         optyp[m->in_op&0x7F] : '?',
68                                 m->in_offset);
69         }
70         (void) fprintf(stderr, " %s%s", (m->flag & UNSIGNED) ? "u" : "",
71                        /* Note: type is unsigned */
72                        (m->type < SZOF(typ)) ? typ[m->type] : "*bad*");
73         if (m->mask_op & OPINVERSE)
74                 (void) fputc('~', stderr);
75         if (m->mask) {
76                 ((m->mask_op&0x7F) < SZOF(optyp)) ? 
77                         (void) fputc(optyp[m->mask_op&0x7F], stderr) :
78                         (void) fputc('?', stderr);
79                 if(STRING != m->type || PSTRING != m->type)
80                         (void) fprintf(stderr, "%.8x", m->mask);
81                 else {
82                         if (m->mask & STRING_IGNORE_LOWERCASE) 
83                                 (void) fputc(CHAR_IGNORE_LOWERCASE, stderr);
84                         if (m->mask & STRING_COMPACT_BLANK) 
85                                 (void) fputc(CHAR_COMPACT_BLANK, stderr);
86                         if (m->mask & STRING_COMPACT_OPTIONAL_BLANK) 
87                                 (void) fputc(CHAR_COMPACT_OPTIONAL_BLANK,
88                                 stderr);
89                 }
90         }
91
92         (void) fprintf(stderr, ",%c", m->reln);
93
94         if (m->reln != 'x') {
95                 switch (m->type) {
96                 case BYTE:
97                 case SHORT:
98                 case LONG:
99                 case LESHORT:
100                 case LELONG:
101                 case BESHORT:
102                 case BELONG:
103                         (void) fprintf(stderr, "%d", m->value.l);
104                         break;
105                 case STRING:
106                 case PSTRING:
107                 case REGEX:
108                         showstr(stderr, m->value.s, -1);
109                         break;
110                 case DATE:
111                 case LEDATE:
112                 case BEDATE:
113                         (void)fprintf(stderr, "%s,", fmttime(m->value.l, 1));
114                         break;
115                 case LDATE:
116                 case LELDATE:
117                 case BELDATE:
118                         (void)fprintf(stderr, "%s,", fmttime(m->value.l, 0));
119                         break;
120                 default:
121                         (void) fputs("*bad*", stderr);
122                         break;
123                 }
124         }
125         (void) fprintf(stderr, ",\"%s\"]\n", m->desc);
126 }
127 #endif
128
129 /*
130  * ckfputs - fputs, but with error checking
131  * ckfprintf - fprintf, but with error checking
132  */
133 void
134 ckfputs(const char *str, FILE *fil)
135 {
136         if (fputs(str,fil) == EOF)
137                 error("write failed.\n");
138 }
139
140 /*VARARGS*/
141 void
142 ckfprintf(FILE *f, const char *fmt, ...)
143 {
144         va_list va;
145
146         va_start(va, fmt);
147         (void) vfprintf(f, fmt, va);
148         if (ferror(f))
149                 error("write failed.\n");
150         va_end(va);
151 }
152
153 /*
154  * error - print best error message possible and exit
155  */
156 /*VARARGS*/
157 void
158 error(const char *f, ...)
159 {
160         va_list va;
161
162         va_start(va, f);
163         /* cuz we use stdout for most, stderr here */
164         (void) fflush(stdout); 
165
166         if (progname != NULL) 
167                 (void) fprintf(stderr, "%s: ", progname);
168         (void) vfprintf(stderr, f, va);
169         va_end(va);
170         exit(1);
171 }
172
173 /*VARARGS*/
174 void
175 magwarn(const char *f, ...)
176 {
177         va_list va;
178
179         va_start(va, f);
180         /* cuz we use stdout for most, stderr here */
181         (void) fflush(stdout); 
182
183         if (progname != NULL) 
184                 (void) fprintf(stderr, "%s: %s, %d: ", 
185                                progname, magicfile, lineno);
186         (void) vfprintf(stderr, f, va);
187         va_end(va);
188         fputc('\n', stderr);
189 }
190
191
192 #ifndef COMPILE_ONLY
193 char *
194 fmttime(long v, int local)
195 {
196         char *pp, *rt;
197         time_t t = (time_t)v;
198         struct tm *tm;
199
200         if (local) {
201                 pp = ctime(&t);
202         } else {
203 #ifndef HAVE_DAYLIGHT
204                 static int daylight = 0;
205 #ifdef HAVE_TM_ISDST
206                 static time_t now = (time_t)0;
207
208                 if (now == (time_t)0) {
209                         struct tm *tm1;
210                         (void)time(&now);
211                         tm1 = localtime(&now);
212                         daylight = tm1->tm_isdst;
213                 }
214 #endif /* HAVE_TM_ISDST */
215 #endif /* HAVE_DAYLIGHT */
216                 if (daylight)
217                         t += 3600;
218                 tm = gmtime(&t);
219                 pp = asctime(tm);
220         }
221
222         if ((rt = strchr(pp, '\n')) != NULL)
223                 *rt = '\0';
224         return pp;
225 }
226 #endif