1 #include "cado.h" // IWYU pragma: keep
2 #include <stdio.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include "mf.h"
6 #include "params.h" // param_list
7
8
usage(int rc)9 void usage(int rc)
10 {
11 fprintf(stderr,
12 "######## THIS PROGRAM IS DEPRECATED ##########################\n"
13 "## It is only useful when converting to/from ascii ##\n"
14 "## If you only want to create .rw and .cw files from binary ##\n"
15 "## matrix files, use the better program mf_scan2. ##\n"
16 "##############################################################\n"
17 "This program make one reading pass through a matrix, producing one or\n"
18 "several output files. Depending on the arguments given, the behaviour\n"
19 "differs.\n"
20 "\n"
21 "read an ascii matrix, produce a binary one as well as the companion\n"
22 ".rw and .cw files:\n"
23 "\n"
24 "./mf-scan --ascii-in mfile=<infile> --binary-out ofile=<outfile> --freq\n"
25 "\n"
26 "read a binary matrix, produce an ascii one, and no frequency files.\n"
27 "(NOTE though that the produced ascii file lacks a header !)\n"
28 "\n"
29 "./mf-scan --binary-in mfile=<infile> --ascii-out ofile=<outfile> --nofreq\n"
30 "\n"
31 "produce only the frequency files corresponding to an existing binary\n"
32 "matrix.\n"
33 "\n"
34 "./mf-scan --binary-in mfile=<infile> --freq\n"
35 "\n"
36 "\n"
37 "Recognized options"
38 " (<option_name>=<value>, or --<option_name> <value>:\n"
39 " mfile matrix file (can also be given freeform)\n"
40 " rwfile row weight file\n"
41 " cwfile col weight file\n"
42 " ofile output file name ; no output if unspecified\n"
43 "Recognized flags:\n"
44 " --ascii-in mfile in ascii\n"
45 " --ascii-out ofile in ascii\n"
46 " --binary-in mfile in binary\n"
47 " --binary-out ofile in binary\n"
48 " --quiet no progress info\n"
49 " --nofreq no .rw and .cw files\n"
50 " --freq output .rw and .cw files\n"
51 " --ascii-freq .rw and .cw files in ascii\n"
52 " --binary-freq .rw and .cw files in binary\n"
53 );
54 exit(rc);
55 }
56
57 const char * file_ext[2] = { ".txt", ".bin" };
58
autodetection_error(const char * what)59 static void autodetection_error(const char * what)
60 {
61 fprintf(stderr, "Error: cannot auto-detect format for %s. Please use the options.\n", what);
62 exit(1);
63 }
64
main(int argc,char * argv[])65 int main(int argc, char * argv[])
66 {
67 param_list pl;
68
69 const char * rwfile = NULL;
70 const char * cwfile = NULL;
71 const char * mfile = NULL;
72 const char * ofile = NULL;
73
74 unsigned int wild = 0;
75
76 /* many flags -- several are mutually incompatible */
77 unsigned int rskip = 0;
78 unsigned int cskip = 0;
79 int quiet = 0;
80
81 int ascii_in = 0;
82 int ascii_out = 0;
83 int binary_in = 0;
84 int binary_out = 0;
85
86 int freq = 0;
87 int nofreq = 0;
88 int ascii_freq = 0;
89 int binary_freq = 0;
90
91 int withlongcoeffs = 0;
92 int withshortcoeffs = 0;
93
94 param_list_init(pl);
95 argv++,argc--;
96
97 param_list_configure_switch(pl, "--quiet", &quiet);
98 param_list_configure_switch(pl, "--ascii-in", &ascii_in);
99 param_list_configure_switch(pl, "--binary-in", &binary_in);
100 param_list_configure_switch(pl, "--ascii-out", &ascii_out);
101 param_list_configure_switch(pl, "--binary-out", &binary_out);
102 param_list_configure_switch(pl, "--ascii-freq", &ascii_freq);
103 param_list_configure_switch(pl, "--binary-freq", &binary_freq);
104 param_list_configure_switch(pl, "--nofreq", &nofreq);
105 param_list_configure_switch(pl, "--freq", &freq);
106 param_list_configure_switch(pl, "--withcoeffs", &withshortcoeffs);
107
108 for(;argc;) {
109 if (param_list_update_cmdline(pl, &argc, &argv)) continue;
110 if (argv[0][0] != '-' && wild == 0) {
111 mfile = argv[0];
112 wild++;
113 argv++,argc--;
114 continue;
115 }
116 fprintf(stderr, "unknown option %s\n", argv[0]);
117 usage(1);
118 }
119
120 param_list_parse_int(pl, "with-long-coeffs", &withlongcoeffs);
121 if (withshortcoeffs) {
122 if (withlongcoeffs) {
123 fprintf(stderr, "Error, with-long-coeffs and --withcoeffs must not be passed together\n");
124 exit(1);
125 }
126 withlongcoeffs=1;
127 }
128
129 const char * tmp;
130 if ((tmp = param_list_lookup_string(pl, "mfile")) != NULL) {
131 mfile = tmp;
132 }
133 if ((tmp = param_list_lookup_string(pl, "rwfile")) != NULL) {
134 rwfile = tmp;
135 }
136 if ((tmp = param_list_lookup_string(pl, "cwfile")) != NULL) {
137 cwfile = tmp;
138 }
139 if ((tmp = param_list_lookup_string(pl, "ofile")) != NULL) {
140 ofile = tmp;
141 }
142
143 param_list_parse_uint(pl, "rskip", &rskip);
144 param_list_parse_uint(pl, "cskip", &cskip);
145
146 if (ascii_in && binary_in) usage(1);
147 if (ascii_out && binary_out) usage(1);
148 if (ascii_freq && binary_freq) usage(1);
149 if (ascii_freq || binary_freq) freq=1;
150 if (rwfile || cwfile) freq=1;
151 if (freq && nofreq) usage(1);
152 if ((ascii_out || binary_out) && !ofile) usage(1);
153
154 const char * freq_default_prefix = NULL;
155
156 /* Start with the input */
157
158 struct mf_io_file m_in[1];
159 memset(m_in, 0, sizeof(struct mf_io_file));
160
161 if (!mfile) usage(1);
162 /* special case to mean stdin */
163 if (strcmp(mfile, "-") == 0) {
164 mfile = NULL;
165 m_in->f = stdin;
166 } else {
167 #ifdef HAVE_MINGW
168 if (ascii_in) {
169 m_in->f = fopen(mfile, "r");
170 } else if (binary_in) {
171 m_in->f = fopen(mfile, "rb");
172 } else {
173 fprintf(stderr, "Under MinGW, please specify explicitly --binary-in or --ascii-in\n");
174 exit(1);
175 }
176 #else
177 /* Then we probably don't care */
178 m_in->f = fopen(mfile, "rb");
179 #endif
180 if (m_in->f == NULL) { perror(mfile); exit(1); }
181 }
182 if (mfile) freq_default_prefix=mfile;
183
184 if (ascii_in || binary_in) {
185 m_in->ascii = ascii_in;
186 } else if (matrix_autodetect_input(m_in, mfile) < 0) {
187 autodetection_error("input");
188 }
189
190 /* Now the output, if there is one. */
191 struct mf_io_file m_out[1];
192 memset(m_out, 0, sizeof(struct mf_io_file));
193
194 if (ofile) {
195 if (strcmp(ofile, "-") == 0) {
196 ofile = NULL;
197 m_out->f = stdout;
198 } else {
199 #ifdef HAVE_MINGW
200 if (ascii_out) {
201 m_out->f = fopen(ofile, "w");
202 } else if (binary_out) {
203 m_out->f = fopen(ofile, "wb");
204 } else {
205 fprintf(stderr, "Under MinGW, please specify explicitly --binary-out or --ascii-out\n");
206 exit(1);
207 }
208 #else
209 /* Then we probably don't care */
210 m_out->f = fopen(ofile, "wb");
211 #endif
212 }
213 if (ascii_out || binary_out) {
214 m_out->ascii = ascii_out;
215 } else if (ofile) {
216 /* try to auto-detect */
217 if (has_suffix(ofile, file_ext[0])) m_out->ascii = 1;
218 else if (has_suffix(ofile, file_ext[1])) { m_out->ascii = 0; }
219 else autodetection_error("output");
220 } else {
221 autodetection_error("output");
222 }
223 if (ofile) freq_default_prefix=ofile;
224 }
225
226 struct mf_io_file rw[1];
227 struct mf_io_file cw[1];
228 memset(rw, 0, sizeof(struct mf_io_file));
229 memset(cw, 0, sizeof(struct mf_io_file));
230 /* nofreq is the default */
231 if (freq) {
232 if (!rwfile || !cwfile) {
233 if (!freq_default_prefix) {
234 fprintf(stderr, "Cannot figure out names for .rw and .cw files\n");
235 exit(1);
236 }
237 }
238 if (ascii_freq || binary_freq) rw->ascii=ascii_freq;
239 else if (rwfile && has_suffix(rwfile, file_ext[0])) rw->ascii = 1;
240 else if (rwfile && has_suffix(rwfile, file_ext[1])) rw->ascii = 0;
241 else rw->ascii=ofile ? m_out->ascii : m_in->ascii;
242
243 if (ascii_freq || binary_freq) cw->ascii=ascii_freq;
244 else if (cwfile && has_suffix(cwfile, file_ext[0])) cw->ascii = 1;
245 else if (cwfile && has_suffix(cwfile, file_ext[1])) cw->ascii = 0;
246 else cw->ascii=ofile ? m_out->ascii : m_in->ascii;
247
248 if (!rwfile) {
249 char * leakme;
250 rwfile = leakme = build_mat_auxfile(freq_default_prefix, "rw", file_ext[!rw->ascii]);
251 }
252
253 if (!cwfile) {
254 char * leakme;
255 cwfile = leakme = build_mat_auxfile(freq_default_prefix, "cw", file_ext[!cw->ascii]);
256 }
257 }
258
259 if (rwfile) rw->f = fopen(rwfile, "wb");
260 if (cwfile) cw->f = fopen(cwfile, "wb");
261
262 matrix_read_pass(m_in,
263 m_out->f ? m_out : NULL,
264 rw->f ? rw : NULL,
265 cw->f ? cw : NULL,
266 rskip,
267 cskip,
268 !quiet,
269 withlongcoeffs);
270
271 if (m_out->f && m_out->ascii) {
272 fprintf(stderr, "\nWarning: output matrix is headerless\n");
273 }
274
275
276 if (rwfile) fclose(rw->f);
277 if (cwfile) fclose(cw->f);
278 if (mfile) fclose(m_in->f);
279 if (ofile) fclose(m_out->f);
280
281 param_list_clear(pl);
282 return 0;
283 }
284