Add/update copyright notice in all source code files.
[mmh] / sbr / fmt_new.c
1
2 /*
3  * fmt_new.c -- read format file/string and normalize
4  *
5  * $Id$
6  *
7  * This code is Copyright (c) 2002, by the authors of nmh.  See the
8  * COPYRIGHT file in the root directory of the nmh distribution for
9  * complete copyright information.
10  */
11
12 #include <h/mh.h>
13
14 #define QUOTE '\\'
15
16 static char *formats = 0;
17
18 /*
19  * static prototypes
20  */
21 static void normalize (char *);
22
23
24 /*
25  * Get new format string
26  */
27
28 char *
29 new_fs (char *form, char *format, char *default_fs)
30 {
31     struct stat st;
32     register FILE *fp;
33
34     if (formats)
35         free (formats);
36
37     if (form) {
38         if ((fp = fopen (etcpath (form), "r")) == NULL)
39             adios (form, "unable to open format file");
40
41         if (fstat (fileno (fp), &st) == -1)
42             adios (form, "unable to stat format file");
43
44         if (!(formats = malloc ((size_t) st.st_size + 1)))
45             adios (form, "unable to allocate space for format");
46
47         if (read (fileno(fp), formats, (int) st.st_size) != st.st_size)
48             adios (form, "error reading format file");
49
50         formats[st.st_size] = '\0';
51
52         fclose (fp);
53     } else {
54         formats = getcpy (format ? format : default_fs);
55     }
56
57     normalize (formats);        /* expand escapes */
58
59     return formats;
60 }
61
62
63 /*
64  * Expand escapes in format strings
65  */
66
67 static void
68 normalize (char *cp)
69 {
70     char *dp;
71
72     for (dp = cp; *cp; cp++) {
73         if (*cp != QUOTE) {
74             *dp++ = *cp;
75         } else {
76             switch (*++cp) {
77                 case 'b':
78                     *dp++ = '\b';
79                     break;
80
81                 case 'f':
82                     *dp++ = '\f';
83                     break;
84
85                 case 'n':
86                     *dp++ = '\n';
87                     break;
88
89                 case 'r':
90                     *dp++ = '\r';
91                     break;
92
93                 case 't':
94                     *dp++ = '\t';
95                     break;
96
97                 case '\n':
98                     break;
99
100                 case 0: 
101                     cp--;       /* fall */
102                 default: 
103                     *dp++ = *cp;
104                     break;
105             }
106         }
107     }
108     *dp = '\0';
109 }