1 /*
2     psftools: Manipulate console fonts in the .PSF format
3     Copyright (C) 2001  John Elliott
4 
5     This program is free software; you can redistribute it and/or modify
6     it under the terms of the GNU General Public License as published by
7     the Free Software Foundation; either version 2 of the License, or
8     (at your option) any later version.
9 
10     This program is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13     GNU General Public License for more details.
14 
15     You should have received a copy of the GNU General Public License
16     along with this program; if not, write to the Free Software
17     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18 */
19 
20 /* This is a mini version of CNVSHELL.C, that handles a single file only.
21  * It is used in loading PSF fonts.
22  */
23 
24 
25 #include "cnvshell.h"
26 
27 /* Is an argument an option? */
28 
isarg(char * s)29 static int isarg(char *s)
30     {
31     if (s[0] == '-') return 1;
32 #ifdef __MSDOS__
33     if (s[0] == '/') return 1;
34 #endif
35 #ifdef CPM
36     if (s[0] == '[' || s[0] == '/') return 1;
37 #endif
38     return 0;
39     }
40 
41 /* Case-insensitive string comparison */
42 
43 #ifndef HAVE_STRICMP
44 
stricmp(char * s,char * t)45 int stricmp(char *s, char *t)
46     {
47     char a,b;
48 
49     while (*s && *t)
50         {
51         a = *s; b = *t;
52         if (isupper(a)) a = tolower(a);
53         if (isupper(b)) b = tolower(b);
54 
55         if (a != b) return (a-b);
56      	++s;
57 	++t;
58         }
59     return (*s) - (*t);
60     }
61 
62 #endif
63 
64 /* Display help screen */
65 
help(void)66 static void help(void)
67     {
68     printf("%s\n", cnv_help());
69     exit(0);
70     }
71 
72 /* Having received an option, parse it as "variable" or "variable=value"
73  * and pass it to the program. */
74 
handle_option(int ddash,char * s)75 static char *handle_option(int ddash, char *s)
76     {
77     char *var, *val, *eq, *term;
78     /* Option is of the form: VARIABLE=VALUE  or  VARIABLE */
79     /* Under CP/M, may be followed by a comma or ] */
80 
81     var = malloc(1 + strlen(s));
82     val = malloc(1 + strlen(s));
83 
84     if (!var || !val)
85         {
86         if (var) free(var);
87         if (val) free(val);
88         fprintf(stderr, "%s: Out of memory while parsing arguments.\n", cnv_progname);
89         return s + strlen(s);
90         }
91     strcpy(var, s);
92     val[0] = 0;
93 
94 #ifdef CPM
95     /* Check for ] */
96     eq = strchr(var, ']');
97     if (eq) *eq = 0;        /* Blank out ] */
98     eq = strchr(var, ',');
99     if (eq) *eq = 0;        /* Blank out , */
100 #endif
101 
102     eq = strchr(var, '=');
103     if (eq)
104         {
105         strcpy(val, eq + 1);
106         *eq = 0;
107         }
108     term = cnv_set_option(ddash, var, val);
109     free(var);
110     free(val);
111 #ifdef CPM
112     eq = strchr(s,','); if (eq) return eq;
113     eq = strchr(s,']'); if (eq) return eq;
114 #endif
115     if (term) { fprintf(stderr, "%s: %s.\n", cnv_progname, term); exit(1); }
116     return s + strlen(s);
117     }
118 
119 
120 /* main() parses arguments, opens files, calls the converter. */
121 
main(int argc,char ** argv)122 int main(int argc, char **argv)
123     {
124     int n;
125     int stoparg = 0;
126     char *fname1 = NULL;
127     FILE *fpin   = stdin;
128     char *s;
129 
130     /* Some CP/M and DOS compilers don't support argv[0] */
131     if (argv[0][0]) cnv_progname = argv[0];
132     /* Argument parsing */
133     for (n = 1; n < argc; n++) if (isarg(argv[n]) && !stoparg)
134         {
135         if (!strcmp(argv[n], "--")) { stoparg = 1; continue; }
136 
137         /* Check for likely help commands */
138         if (!stricmp(argv[n],   "--help")) help();
139         if (!stricmp(argv[n]+1, "h"     )) help();
140 #ifdef __MSDOS__
141         if (!stricmp(argv[n]+1, "?"     )) help();
142 #endif
143 #ifdef CPM
144         if (!stricmp(argv[n]+1, "?"     )) help();
145         if (!stricmp(argv[n],   "//"    )) help();
146         if (!stricmp(argv[n],   "[help]")) help();
147         if (!stricmp(argv[n],   "[h]"   )) help();
148 #endif
149         /* OK, it isn't a help command. */
150         if (argv[n][0] == '-' && argv[n][1] == '-')
151             {
152             handle_option(1, argv[n]+2);
153             continue;
154             }
155         /* CP/M-style [VARIABLE=VALUE,VARIABLE=VALUE] options */
156 #ifdef CPM
157         if (argv[n][0] == '[')
158             {
159             char *s;
160 
161             do
162                 {
163                 s = handle_option(1, argv[n]+2);
164                 } while ( s && (*s) && (*s != ']'));
165             continue;
166             }
167 #endif
168         /* Short option */
169         handle_option(0, argv[n]+1);
170         }
171     else
172         {
173         if      (!fname1) fname1 = argv[n];
174         else
175             {
176             fprintf(stderr, "%s: This program takes one filenames, so '%s' is ignored.\n",
177                             cnv_progname, argv[n]);
178             }
179         }
180     /* Options parsed */
181     if (fname1)
182         {
183         fpin = fopen(fname1, "rb");
184         if (!fpin)
185             {
186             perror(fname1);
187             exit(1);
188             }
189         }
190     else fname1 = "<stdin>";
191 
192     s = cnv_execute(fpin, stdout);
193 
194     if (fpin  != stdin)  fclose(fpin);
195 
196     if (!s) return 0;
197 
198     fprintf(stderr, "%s: %s\n", cnv_progname, s);
199     return 1;
200     }
201 
202