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