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