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