*** empty log message ***
[h316.git] / pc-tools / ldc2 / src / main.cpp
CommitLineData
798b0c1d 1/* ldc2 preliminary main program */
2
7880ae2d 3
798b0c1d 4#include <vector>
5#include <string>
f9d603d2 6
ea4c19a4 7#include "config.hh"
8#include "tool.hh"
97b26985 9
10#include "tape_block.hh"
fed2c751 11#include "data_block_0.hh"
12
798b0c1d 13using namespace std;
14
7880ae2d 15#ifndef BUILD_STAMP
16#define BUILD_STAMP ""
17#endif
18
19#ifndef VERSION
20#define VERSION "0.0"
21#endif
22
874a2bd8 23#define ID_STRING "\n ldc2 - The X16 object tape analyser\n\
7880ae2d 24 (C) 2007 Philipp Hachtmann\n\n\
25 Version %s, built %s\n %s\n\n"
26
874a2bd8 27/******************************************************************************/
7880ae2d 28
874a2bd8 29static FILE * stdwarn; //! Suppressable warning output file pointer.
30static vector<tape_block*> tape; //! Represents the whole tape contents.
31static vector<vector<tape_block*> > objects; //! Tape content in objects.
7880ae2d 32
874a2bd8 33static int errors=0;
34static int warnings=0;
35static int errcode=0; //! Variable for error codes.
7880ae2d 36
874a2bd8 37
38void exit_on_error(){
39 if (errors){
40 fprintf(stderr,"Failed. (%i)\n",errcode);
41 exit(errcode);
7880ae2d 42 }
874a2bd8 43}
909d3603 44
874a2bd8 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 */
55void 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.
ad324d29 63
874a2bd8 64 bool spaced=false; //! Help flag for spaced messages.
65
66 string message; //! A warning or help message.
7880ae2d 67
874a2bd8 68
fed2c751 69 while(read_ahead){
874a2bd8 70
71 bool err_checksum=false;
72 bool err_integrity=false;
73
74 bool warning=false;
75 bool error=false;
76
7880ae2d 77 try{
78 block=tape_block::gen_from_fd(in_fd);
7880ae2d 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){
fed2c751 87 if (in_fd){
7880ae2d 88 fprintf(stderr,"Error: Could not read from \"%s\"!\n",cfg_infile.c_str());
fed2c751 89 } else {
7880ae2d 90 fprintf(stderr,"Error: Could not read from stdin!\n");
fed2c751 91 }
874a2bd8 92 error=true;
fed2c751 93 errcode=2;
7880ae2d 94 break; // Immediately leave read loop.
95 }
96
97 catch(tape_block::eof_illegal_exception &e){
98 block=e.get_block();
874a2bd8 99 err_integrity=true;
100 read_ahead=false;
7880ae2d 101 if (cfg_ignore_block_errors){
874a2bd8 102 message="Warning: Block integrity check failed!\n";
103 warning=true;
7880ae2d 104 } else {
874a2bd8 105 message="Error: Block integrity check failed!\n";
106 error=true;
7880ae2d 107 errcode=3;
fed2c751 108 }
7880ae2d 109 }
110
111 catch(tape_block::checksum_error_exception &e){
112 block=e.get_block();
874a2bd8 113 err_checksum=true;
7880ae2d 114 if (cfg_ignore_checksum_errors){
874a2bd8 115 message="Warning: Block checksum wrong!\n";
116 warning=true;
fed2c751 117 } else {
874a2bd8 118 message="Error: Block checksum wrong!\n";
119 error=true;
7880ae2d 120 read_ahead=false;
121 errcode=4;
fed2c751 122 }
7880ae2d 123 }
124
874a2bd8 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 }
7880ae2d 165
874a2bd8 166 if (error||warning||cfg_verbose){
167 fprintf(fp,"\n");
168 spaced=true;
169 }
170 if (error) errors++;
171 if (warning) warnings++;
172 } // while....
7880ae2d 173 if (cfg_verbose){
874a2bd8 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
182void 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 }
7880ae2d 210 }
874a2bd8 211} // type_check()
ad324d29 212
874a2bd8 213/******************************************************************************/
214/*!
215 *\brief The main routine.
216 */
217int main(int argc, char ** args){
7880ae2d 218
219
874a2bd8 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 }
7880ae2d 243
fed2c751 244
ad324d29 245 return 0;
246} // main()
798b0c1d 247