*** empty log message ***
[h316.git] / pc-tools / ldc2 / src / main.cpp
1 /* ldc2 preliminary main program */
2
3
4 #include <vector>
5 #include <string>
6
7 #include "config.hh"
8 #include "tool.hh"
9
10 #include "tape_block.hh"
11 #include "data_block_0.hh"
12
13 using namespace std;
14
15 #ifndef BUILD_STAMP
16 #define BUILD_STAMP ""
17 #endif
18
19 #ifndef VERSION
20 #define VERSION "0.0"
21 #endif
22
23 #define ID_STRING "\n ldc2 - The X16 object tape analyser\n\
24 (C) 2007 Philipp Hachtmann\n\n\
25 Version %s, built %s\n %s\n\n"
26
27 /******************************************************************************/
28
29 static FILE * stdwarn; //! Suppressable warning output file pointer.
30 static vector<tape_block*> tape; //! Represents the whole tape contents.
31 static vector<vector<tape_block*> > objects; //! Tape content in objects.
32
33 static int errors=0;
34 static int warnings=0;
35 static int errcode=0; //! Variable for error codes.
36
37
38 void exit_on_error(){
39 if (errors){
40 fprintf(stderr,"Failed. (%i)\n",errcode);
41 exit(errcode);
42 }
43 }
44
45 /******************************************************************************/
46 /*!
47 *\brief Read in Tape data and do some checks and messages.
48 *
49 * This routine reads in the tape data.
50 * During reading in, checksums are checked and
51 * /da001/ information is generated. No object integrity test.
52 * Tape block object pointers are put into the global vector
53 * tape.
54 */
55 void read_tape(){
56
57 tape_block * block=0; //! Pointer to current block.
58 bool read_ahead=true; //! Continue scanning for blocks.
59 int read_pointer=0; //! Read position in input.
60 int block_start=0; //! Start of block position in input.
61 int block_end=0; //! End of block position in input.
62 int blocks_read=0; //! Number of blocks read in.
63
64 bool spaced=false; //! Help flag for spaced messages.
65
66 string message; //! A warning or help message.
67
68
69 while(read_ahead){
70
71 bool err_checksum=false;
72 bool err_integrity=false;
73
74 bool warning=false;
75 bool error=false;
76
77 try{
78 block=tape_block::gen_from_fd(in_fd);
79 }
80
81 catch(tape_block::eof_legal_exception &e){
82 read_pointer+=e.get_consumed();
83 break; // Immediately leave read loop.
84 }
85
86 catch(tape_block::io_error_exception){
87 if (in_fd){
88 fprintf(stderr,"Error: Could not read from \"%s\"!\n",cfg_infile.c_str());
89 } else {
90 fprintf(stderr,"Error: Could not read from stdin!\n");
91 }
92 error=true;
93 errcode=2;
94 break; // Immediately leave read loop.
95 }
96
97 catch(tape_block::eof_illegal_exception &e){
98 block=e.get_block();
99 err_integrity=true;
100 read_ahead=false;
101 if (cfg_ignore_block_errors){
102 message="Warning: Block integrity check failed!\n";
103 warning=true;
104 } else {
105 message="Error: Block integrity check failed!\n";
106 error=true;
107 errcode=3;
108 }
109 }
110
111 catch(tape_block::checksum_error_exception &e){
112 block=e.get_block();
113 err_checksum=true;
114 if (cfg_ignore_checksum_errors){
115 message="Warning: Block checksum wrong!\n";
116 warning=true;
117 } else {
118 message="Error: Block checksum wrong!\n";
119 error=true;
120 read_ahead=false;
121 errcode=4;
122 }
123 }
124
125 // Now let's check for block type
126 if ((!error)&&(!warning)&&!block->has_known_type()){
127 if (cfg_ignore_unknown_block_errors){
128 message="Warning: Unknown Block type!";
129 warning=true;
130 }else{
131 message="Error: Unknown Block type!";
132 error=true;
133 read_ahead=false;
134 errcode=5;
135 }
136 }
137
138 // Count block.
139 blocks_read++;
140 tape.insert(tape.end(),block);
141 block_start=read_pointer+block->get_discarded_bytes();
142 block_end=block_start+block->get_raw_size()-1;
143 read_pointer=block_end+1;
144
145 FILE * fp=stdwarn;
146 if (error) fp=stderr;
147
148 if (cfg_verbose||error||warning){
149 if (!spaced) fprintf(fp,"\n");
150 spaced=false;
151 fprintf(fp,"Block No.%03i: Start:0x%04x End:0x%04x Size:0x%02x\n",
152 blocks_read-1,
153 block_start,
154 block_end,
155 block->get_raw_size());
156 }
157
158 if (error) fprintf(stderr,message.c_str());
159 if (warning) fprintf(stdwarn,message.c_str());
160
161 if(cfg_list_contents){
162 dump_vector(block->get_description());
163 if (!error&&!warning) spaced=false;
164 }
165
166 if (error||warning||cfg_verbose){
167 fprintf(fp,"\n");
168 spaced=true;
169 }
170 if (error) errors++;
171 if (warning) warnings++;
172 } // while....
173 if (cfg_verbose){
174 close(in_fd);
175 fprintf(stderr,"Reading finished.\n");
176 fprintf(stderr,"Bytes read:%i, Blocks read:%i\n",read_pointer,blocks_read);
177 }
178 } // read_tape()
179
180 /******************************************************************************/
181
182 void type_check(){
183 bool warning=false;
184 bool error=false;
185
186 for (unsigned int i=0; i<tape.size();i++){
187 bool spaced=false;
188 if (!tape[i]->has_known_type()){
189 FILE * fp;
190 if (cfg_ignore_unknown_block_errors){
191 fp=stdwarn;
192 warning=true;
193 } else {
194 fp=stderr;
195 error=true;
196 }
197 if (!spaced) {
198 spaced=false;fprintf(fp,"\n");
199 fprintf(fp,"Warning: Unknown Block type! Block No.%i\n",i);
200 dump_vector_fp(tape[i]->get_description(),fp);
201 fprintf(fp,"\n");
202 spaced=true;
203 }
204 if (!cfg_ignore_unknown_block_errors){
205 int errcode=5;
206 fprintf(stdwarn,"Failed. (%i)\n",errcode);
207 exit(errcode);
208 }
209 }
210 }
211 } // type_check()
212
213 /******************************************************************************/
214 /*!
215 *\brief The main routine.
216 */
217 int main(int argc, char ** args){
218
219
220 // Do all the configuration stuff
221 do_config(argc,args);
222
223 // Output a version message if desired
224 if (cfg_version){
225 fprintf(stderr, ID_STRING, VERSION, BUILD_DATE, BUILD_STAMP);
226 exit(0);
227 }
228
229 // Assign warning output according to configuration
230 if (cfg_quiet) stdwarn=fopen("/dev/null","w");
231 else stdwarn=stderr;
232
233 read_tape(); // Process input to completion.
234 exit_on_error();
235
236
237
238 if (cfg_split_objects){
239 for (unsigned int i=0; i<tape.size();i++){
240 tape[i]->dump_to_fd(out_fd);
241 }
242 }
243
244
245 return 0;
246 } // main()
247