# The RTF output is optimized for Word 97 and may not look very pretty with
# other RTF readers or editors.
-GENERATE_RTF = NO
+GENERATE_RTF = YES
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
# generate man pages
-GENERATE_MAN = NO
+GENERATE_MAN = YES
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
APP_NAME=ldc2
-APP_OBJECTS= main.o silent_code.o argument_reader.o configuration_manager.o
+APP_OBJECTS= main.o silent_code.o configuration_manager.o tool.o config.o
CCFLAGS+=-Wall
BLOCK_OBJECTS=data_block_0_10.o data_block_0_14.o data_block_0_1.o data_block_0_24.o\
data_block_0_2.o data_block_0_30.o data_block_0_3.o data_block_0_4.o\
##All objects depend on all headers. simple but works
#*.o: $(SRC_DIR)/*.hh
-nothing% %.dep : $(SRC_DIR)/%.cpp
+%.dep : $(SRC_DIR)/%.cpp
@ echo Building dependencies for $<.
@$(SHELL) -c "g++ -M $<" | awk 'BEGIN {N=0}{if(N==0)printf("%s %s\n","$@",$$0);else printf("%s\n", $$0);N+=1;}' > $@
SUBR BLUME,BLU
REL
ORG '1000
- NOP
- NOP
-BLU NOP
-SUN NOP
+ ICA
+ ICA
+BLU LDA 0
+SUN LDA 1
END
\ No newline at end of file
\section{Implementation Specification}
---- To be done ---
+
+\subsection{Building \pname}
+
+\subsubsection{Build environment}
+The program has been successfully built under Linux with the following
+programs:
+\begin{itemize}
+\item GCC version 4.1.2
+\item GNU make version 3.81
+\item Doxygen version 1.4.2
+\item Debian teTex package, version 3.0
+\item Graphviz dot version 2.8
+\end{itemize}
+At least the the software (without docs) should be compile on any
+POSIX compatible system with a fairly recent GCC and GNU make
+installed.
+
+\subsubsection{Build instructions}
+There is a simple \verb|Makefile| which eases the standard build
+process for the application and documentation. Changes may be
+necessary to compile on a system other than stated in the last
+paragraph.
+\\
+
+To build the application, follow these easy steps:
+\begin{itemize}
+
+\item Change directory to the \pname direcory.\\
+(Hint: That is the directory containing the subdirs \verb|src|
+and \verb|doc|.)
+
+\item Run \emph{make} (or \emph{gmake}).
+
+\item If you like, put the resulting binary somewhere in your system.
+\end{itemize}
+
+
+Further useful targets in the \verb|Makefile|:
+\begin{itemize}
+
+\item \verb|doc|: Build the Latex documentation (this document) in the
+\verb|doc| subfolder.
+
+\item \verb|doxy|: Build Doxygen source code documentation.\\
+The Doxygen output is placed in the subdir \verb|doxy|.
+
+\item \verb|clean|: Delete all files generated by the make process,
+including binaries and documentation.
+
+\end{itemize}
\bibliographystyle{unsrt}
\sffamily
+\parindent0pt
\pagestyle{empty}
\pagenumbering{roman}
+++ /dev/null
-#include "argument_reader.hh"
-#include <stdio.h>
-
-/*!
- *\brief Constructor.
- *
- * This constructor makes a new argument_reader ready to use.
- *\arg name Name of the application as mentioned in the
- * "Use: <appname> ..." help message.
- */
-argument_reader::argument_reader(string name){
- app_name=app_name;
-}
-
-
-/*!
- *\brief Add a new parameter to be searched for.
- *\param shortname A character for the short form.
- * For example the 'h' in -h
- *\param longname The double dash longname. For example
- * "input_file=" in --input_file= or
- * "ignore_errors" in --ignore--errors
- *\param description A detailed parameter description.
- *\param status Pointer to an integer. Will be set to 1 if arg found.
- *\target Pointer to a value should be read.
- * If no value is needed, pass NULL.
- *\placeholder A placeholder for the documentation.
- * For example "<filename>" in -f<filename>
- */
-void argument_reader::add_param (string shortname, string longname,
- string description, int * status,
- string * target, string placeholder){
-
- if(status!=NULL) opt_v.insert(opt_v.end(),
- opt_t(shortname,longname, description,
- status,target,placeholder)
- );
-}
-
-
-/*!
- *\brief Add an accepted argument to the argument reader.
- *\param placeholder Something like "<input-file>".
- *\param description Text describing the argument.
- *\param status A pointer to a status variable. Will be set to 0 immediately.
- * If the argument is filled in, it will be set to 1.
- *\param target A pointer to a c++ string where the argument goes to.
- *
- *\note Arguments are filled in the order of adding them to the
- * argument reader.
- * There would be no other way to determine the order.
- */
-void argument_reader::add_argument(string placeholder, string description, int * status, string * target){
- if (target!=NULL) if(status!=NULL)
- arg_v.insert(arg_v.end(),arg_t(placeholder,description,status,target));
-}
-
-
-/*!
- *\Read in the args passed to main().
- *\returns empty vector on success or the error messages to be output.
- */
-vector<string> argument_reader::read_args(int argc, char ** args){
- vector<string> result;
- vector<string> argv;
- for (char ** akt=args; *akt ;akt++) argv.insert(argv.end(),string(*akt));
-
- unsigned int free_parms_count=0;
- for (vector<string>::iterator akt_p=argv.begin()+1;akt_p<argv.end();akt_p++){ //Argument loop
-
- // Look for long argument
- if ((akt_p->substr(0,2)=="--")&&(free_parms_count==0)){
- int found=0;
- for (vector<opt_t>::iterator parm_p=opt_v.begin();parm_p<opt_v.end();parm_p++){
- if (akt_p->substr(2,parm_p->longname.length())==parm_p->longname){
- found=1;
- *(parm_p->status)=1;
- if (parm_p->target){
- if (akt_p->length()>2+parm_p->longname.length()){
- *(parm_p->target)=akt_p->substr(2+parm_p->longname.length());
-
- } else // Word not long enough
- if (akt_p+1<argv.end()) { // If next word existend
- *(parm_p->status)=1;
- *(parm_p->target)=*(++akt_p);
- } else { // No next word :-(
- result.insert(result.end(),
- "Parameter --"+parm_p->longname+parm_p->placeholder+" needs an Argument!");
- }
- } // arg needed
- }
- } // search for loop
- if (!found) result.insert(result.end(),"Unknown parameter: "+*akt_p);
- } else { // No -- param, now look for switches
- if (((*akt_p)[0]=='-')&&(free_parms_count==0)){
- int stop_char_loop=0;
- for (unsigned int pos=1; pos<akt_p->length()&& !stop_char_loop ;pos++){
- int found=0;
- for (vector<opt_t>::iterator parm_p=opt_v.begin();parm_p<opt_v.end();parm_p++){
- if (parm_p->shortname[0]==(*akt_p)[pos]){
- found=1;
- (*parm_p->status)=1;
- if (parm_p->target){ // Need argument
- if (akt_p->length()>pos+1){
- *(parm_p->target)=akt_p->substr(pos+1);
- stop_char_loop=1;
- } else { // Word not long enough
- if (akt_p+1<argv.end()) { // If next word existend
- *(parm_p->target)=*(++akt_p);
- stop_char_loop=1;
- } else { // No next word :-(
- result.insert(result.end(),
- "Parameter --"+parm_p->longname+parm_p->placeholder+" needs an Argument!");
- }
- }
- } // arg needed
- } //if match
- } //args loop
- if (!found) result.insert(result.end(),"Unknown switch: "+akt_p->substr(pos,1));
- } // char loop
- }// switch found
- else{ // no switch found
- if (free_parms_count<arg_v.size()){
- *(arg_v[free_parms_count].target)=*akt_p;
- *(arg_v[free_parms_count].status)=1;
- }
- free_parms_count++;
- }
- } //looking for not -- args
- } // argv loop
- if (free_parms_count>arg_v.size()) result.insert(result.begin(),"Too many arguments!");
- if (!result.empty()){
- result.insert(result.begin(),"Error!");
- result.insert(result.begin(),"");
- }
- return result;
-}
-
-/*!
- *\brief Generate help.
- *\arg target Reference to a vector<string> to which lots of helpful
- * strings are appended.
- */
-void argument_reader::get_help(vector<string> & target){
- target.insert(target.end(),"");
- string line="Usage: "+app_name;
- for (vector<opt_t>::iterator parm_p=opt_v.begin();parm_p<opt_v.end();parm_p++){
- string addstr=" [-"+parm_p->shortname;
- if (parm_p->target!=0) addstr+=parm_p->placeholder;
- addstr+="]";
- if (line.length()+addstr.length()>79){
- target.insert(target.end(),line);
- line=string(7+app_name.length(),' ');
- }
- line+=addstr;
- }
-
- for (vector<arg_t>::iterator parm_p=arg_v.begin();parm_p<arg_v.end();parm_p++){
- if (line.length()+parm_p->placeholder.length()>79){
- target.insert(target.end(),line);
- line=string(7+app_name.length(),' ');
- }
- line+=" ["+parm_p->placeholder+"]";
- }
- target.insert(target.end(),line);
-
- /*******************************/
-
- vector<string> left,right;
- for (vector<opt_t>::iterator parm_p=opt_v.begin();parm_p<opt_v.end();parm_p++){
- line=parm_p->description;
- string st2=" -"+parm_p->shortname;
- if (parm_p->target)st2+=" "+parm_p->placeholder;
- st2+=", --"+parm_p->longname;
- if (parm_p->target)st2+=parm_p->placeholder;
- left.insert(left.end(),st2);
- right.insert(right.end(),line);
- }
-
- for (vector<arg_t>::iterator parm_p=arg_v.begin();parm_p<arg_v.end();parm_p++){
- string st2;
- line=parm_p->description;
- st2+=" "+parm_p->placeholder;
- left.insert(left.end(),st2);
- right.insert(right.end(),line);
- }
-
- if (opt_v.size()){
- target.insert(target.end(),"");
- target.insert(target.end(),"Options:");
- }
-
- unsigned int max_width=0;
- for (unsigned int c=0; c<opt_v.size();c++)
- if(left[c].length()>max_width) max_width=left[c].length();
- for (unsigned int c=0; c<opt_v.size();c++){
- string nl(max_width,' ');
- nl.replace(0,left[c].length(),left[c]);
- nl+=" "+right[c];
- while (nl.length()>80){ // Too long???
- int limit=nl.find_last_of(' ',80);
- target.insert(target.end(),nl.substr(0,limit));
- nl=string(max_width+2,' ')+nl.substr(limit+1);
- }
- target.insert(target.end(),nl);
- }
-
- if (arg_v.size()){
- target.insert(target.end(),"");
- target.insert(target.end(),"Arguments:");
- }
-
- max_width=0;
- for (unsigned int c=opt_v.size(); c<opt_v.size()+arg_v.size();c++)
- if(left[c].length()>max_width) max_width=left[c].length();
- for (unsigned int c=opt_v.size(); c<opt_v.size()+arg_v.size();c++){
- string nl(max_width,' ');
- nl.replace(0,left[c].length(),left[c]);
- nl+=" "+right[c];
-
- while (nl.length()>80){ // Too long???
- int limit=nl.find_last_of(' ',80);
- printf("limit:%i\n",limit);
- target.insert(target.end(),nl.substr(0,limit));
- nl=string(max_width+2,' ')+nl.substr(limit+1);
- }
-
- target.insert(target.end(),nl);
- }
- target.insert(target.end(),"");
-}
-
-/*!
- *\brief Generate help.
- *\return A vector containing many helpful strings for the user.
- */
-vector<string> argument_reader::get_help(){
- vector<string> result;
- get_help(result);
- return result;
-}
-
-
-/**************************************************/
-
-argument_reader::opt_t::opt_t(string n_shortname, string n_longname,string n_description, int * n_status,
- string * n_target, string n_placeholder){
- shortname=n_shortname;
- longname=n_longname;
- description=n_description;
- status=n_status;
- target=n_target;
- placeholder=n_placeholder;
- if (status) *status=0;
-}
-
-argument_reader::arg_t::arg_t( string n_placeholder, string n_description,
- int * n_status, string * n_target){
- description=n_description;
- status=n_status;
- target=n_target;
- placeholder=n_placeholder;
- if (status) *status=0;
-}
+++ /dev/null
-#ifndef ARGUMENT_READER_H
-#define ARGUMENT_READER_H
-
-#include <vector>
-#include <string>
-
-using namespace std;
-
-/*!
- *\brief Hachti's wonderful commandline parser.
- *
- * This class is designed to do all the work with the parameters passed to
- * the main() routine of a program.\n
- * Usage:\n
- * - Create an instance.
- * - Add Parameters/switches with add_param().
- * - Add Arguments with add_argument().
- * - Call read_args() with your main routine's arguments.
- * The vector returned by read_args() contains all error
- * messages. When it's empty, everything is fine!
- * - Call get_help() if you want nice formatted help output.
- * (You want!!!)
- * Sould be easy to use..... Enjoy.
- */
-class argument_reader{
-
-public:
- argument_reader(string name);
-
- void add_param (string shortname,
- string longname,
- string description,
- int *status,
- string *target=NULL,
- string placeholder=string("<string>")
- );
-
- vector<string> read_args(int argc, char ** args);
-
- void get_help(vector<string> & target);
- vector<string> get_help();
-
- void add_argument(string placeholder, string description, int * status, string * target);
-
-private:
- /*!
- *\brief Container for one command line option.
- */
- class opt_t{
- public:
- opt_t (string shortname, string longname,string description, int * status,
- string * target=NULL, string placeholder=string("<string>"));
- string shortname;
- string longname;
- int * status;
- string * target;
- string description;
- string placeholder;
- };
-
- /*!
- *\brief Container for one command line argument.
- */
- class arg_t{
- public:
- arg_t (string placeholder,string description,
- int * status, string * target);
- int * status;
- string * target;
- string description;
- string placeholder;
- };
- vector<opt_t>opt_v;
- vector<arg_t>arg_v;
- string app_name;
-
-}; // class argument_reader
-
-
-#endif
--- /dev/null
+/*
+ * Program configuration management
+ */
+
+#include <vector>
+#include <string>
+
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "configuration_manager.hh"
+#include "tool.hh"
+
+/* Global configuration data */
+string cfg_infile;
+string cfg_outfile;
+int cfg_infile_set=0;
+int cfg_outfile_set=0;
+int cfg_config_file_set=0;
+
+int cfg_do_help=0;
+int cfg_output_info=0;
+int cfg_output_called=0;
+int cfg_output_exported=0;
+int cfg_output_unsatisfied=0;
+int cfg_splitobjects=0;
+int cfg_splitobjects_numbered=0;
+int cfg_ignoreblock_errors=0;
+int cfg_ignorechecksum_errors=0;
+int cfg_pause_on_checksum_error=0;
+int cfg_ignore_unknown_block_errors=0;
+int cfg_ignore_object_integrity_errors=0;
+int cfg_list_contents=1;
+int cfg_verbose=0;
+
+int in_fd=0; //! File descriptor for data input
+int out_fd=1; //! File descriptor for text output
+
+
+void do_config(int argc, char ** args){
+
+ string cfg_config_file;
+ configuration_manager ar("ldc2");
+
+ /* Here come the configuration switches */
+ ar.add_option_switch("h","help",
+ "Output this help text and exit.",
+ &cfg_do_help,false,true);
+
+ ar.add_option_switch("a","output_info",
+ "Print tape data information",
+ &cfg_output_info,true,true);
+
+ ar.add_option_switch("c","output_called",
+ "Print all called symbols from the object(s).",
+ &cfg_output_called,true,true);
+
+ ar.add_option_switch("e","output_exported",
+ "Print all exported symbols from the object(s).",
+ &cfg_output_exported,true,true);
+
+ ar.add_option_switch("u","output_unsatisfied",
+ "List all unsatisfied symbols.",
+ &cfg_output_unsatisfied,true,true);
+
+ ar.add_option_switch("S","split_objects_numbered",
+ "Split input data into distinct numbered files",
+ &cfg_splitobjects_numbered,true,true);
+
+ ar.add_option_switch("s","split_objects",
+ "Split input data into distinct object files.",
+ &cfg_splitobjects,true,true);
+
+ ar.add_option_switch("b","ignore_block_errors",
+ "Ignore block integrity errors. This will output broken blocks,too",
+ &cfg_ignoreblock_errors,true,true);
+
+ ar.add_option_switch("k","ignore_checksum_errors",
+ "Ignore block checksum errors. Errors will be converted to warnings.",
+ &cfg_ignorechecksum_errors,true,true);
+
+ ar.add_option_switch("p","pause_on_checksum_error",
+ "Wait for user input on checksum error.",
+ &cfg_pause_on_checksum_error,true,true);
+
+ ar.add_option_switch("n","ignore_unknown_block_errors",
+ "Ignore errors caused by unknown block types. Errors will be converted to warnings.",
+ &cfg_ignore_unknown_block_errors,true,true);
+
+ ar.add_option_switch("g","ignore_object_integrity_errors",
+ "Ignore errors caused by objects without proper end block. \
+Errors will be converted to warnings.",
+ &cfg_ignore_object_integrity_errors,true,true);
+
+ ar.add_option_switch("v","verbose",
+ "Be a bit more verbose.",
+ &cfg_verbose,true,true);
+
+ ar.add_option_value("i","in_file",
+ "specify input file",
+ &cfg_infile_set,&cfg_infile,
+ "<input-file>",true,false);
+
+ ar.add_option_value("o","out_file",
+ "Specify output file.",
+ &cfg_outfile_set,&cfg_outfile,
+ "<output_file>",true,true);
+
+ ar.add_argument("File from where data is read",
+ &cfg_infile_set,&cfg_infile,
+ "<input-file>");
+
+ ar.add_argument("File to where output is redirected",
+ &cfg_outfile_set,&cfg_outfile,
+ "<output-file>");
+
+ ar.add_option_value("F","cfg_config_file",
+ "Use the specified configuration file.",
+ &cfg_config_file_set,&cfg_config_file,
+ "<file-name>",false,true);
+
+
+ // If there's a config file mentioned in the environment, take it!
+ char * env_ldc_config=getenv("LDC_CONFIG");
+ if(env_ldc_config){
+ fprintf(stderr,"Using config file: \"%s\"\n",env_ldc_config);
+ if(dump_vector_err(ar.read_file(env_ldc_config))){
+ dump_vector_err(ar.get_help());
+ exit(1);
+ }
+ }
+
+ // Process command line first time
+ if(dump_vector_err(ar.read_args(argc,args))){
+ dump_vector_err(ar.get_help());
+ exit(7);
+ }
+
+ if (cfg_do_help) {
+ dump_vector_err(ar.get_help());
+ exit(0);
+ }
+
+ // If user has a config file, use it.
+ if (cfg_config_file_set){
+ fprintf(stderr,"Using config file: \"%s\"\n",cfg_config_file.c_str());
+ if(dump_vector_err(ar.read_file(cfg_config_file))){
+ dump_vector_err(ar.get_help());
+ exit(7);
+ }
+
+ // Process command line a second time to override values from config file.
+ if(dump_vector_err(ar.read_args(argc,args))||cfg_do_help){
+ dump_vector_err(ar.get_help());
+ exit(7);
+ }
+ }
+
+ if (cfg_infile_set==1){
+ fprintf(stderr,"Opening file for input: \"%s\"\n",cfg_infile.c_str());
+ in_fd=open(cfg_infile.c_str(),O_RDONLY);
+ if (in_fd<0){
+ fprintf(stderr,"Error: could not open file \"%s\" for reading!\n",cfg_infile.c_str());
+ exit (1);
+ }
+ }
+
+ if (cfg_outfile_set==1){
+ fprintf(stderr,"Opening file for output: \"%s\"\n",cfg_outfile.c_str());
+ out_fd=open(cfg_outfile.c_str(),O_WRONLY|O_TRUNC);
+ if (out_fd<0){
+ fprintf(stderr,"Error: could not open file \"%s\" for writing!\n",cfg_outfile.c_str());
+ exit (1);
+ }
+ }
+
+ // The configuration implications according to /cfg007/
+ if (in_fd==0) cfg_pause_on_checksum_error=0;
+ if (cfg_pause_on_checksum_error==1) cfg_ignorechecksum_errors=1;
+
+ if (cfg_output_info||cfg_output_called||cfg_output_exported||cfg_output_unsatisfied)
+ cfg_list_contents=0;
+}
+
+
--- /dev/null
+#ifndef CONFIG_HH
+#define CONFIG_HH
+
+#include <string>
+using namespace std;
+
+/* Global configuration data */
+
+extern string cfg_infile;
+extern string cfg_outfile;
+extern int cfg_infile_set;
+extern int cfg_outfile_set;
+extern int cfg_config_file_set;
+
+extern int cfg_do_help;
+extern int cfg_output_info;
+extern int cfg_output_called;
+extern int cfg_output_exported;
+extern int cfg_output_unsatisfied;
+extern int cfg_splitobjects;
+extern int cfg_splitobjects_numbered;
+extern int cfg_ignoreblock_errors;
+extern int cfg_ignorechecksum_errors;
+extern int cfg_pause_on_checksum_error;
+extern int cfg_ignore_unknown_block_errors;
+extern int cfg_ignore_object_integrity_errors;
+extern int cfg_list_contents;
+extern int cfg_verbose;
+
+extern int in_fd; //! File descriptor for data input
+extern int out_fd; //! File descriptor for text output
+
+extern void do_config(int argc, char ** args);
+
+#endif
* output_file in --output_file=
*\param description A detailed description of the value.
*\param status Pointer to an integer. Will be set to 1 if arg found.
- *\target Pointer to string to put the value in.
- *\placeholder A placeholder for the documentation.
+ *\param target Pointer to string to put the value in.
+ *\param placeholder A placeholder for the documentation.
* For example <filename> in -f<filename>
*/
void configuration_manager::add_option_value (const string & shortname,
return result;
}
+/*!
+ *\brief Determine if the block marks the end of an object
+ *\retval true The block marks the end of an object.
+ *\retval false The block does not mark the end of an object.
+ */
+bool data_block::get_obj_end(){
+ return false;
+}
+
/*!
*\brief Extract 6 byte symbol name from word memory.
*
int get_type();
int get_word_size();
virtual vector<string> get_description();
+ virtual bool get_obj_end();
protected:
string extract_label(int);
};
/*!
*\brief Abstract class providing label extraction for some data_block_0 subtypes.
+ *
* This class cannot be instantiated.\n
*/
class data_block_0_label_extractor
#include <vector>
#include <string>
-#include <stdio.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+#include "config.hh"
+#include "tool.hh"
#include "tape_block.hh"
#include "data_block_0.hh"
-#include "configuration_manager.hh"
-
using namespace std;
-static int in_fd, out_fd;
-
-
-int dump_vector(vector<string> arguments){
- int res=0;
- for (vector<string>::iterator iter=arguments.begin();iter<arguments.end();iter++){
- char buffer[2000];
- snprintf(buffer,2000,"%s\n",(*iter).c_str());
- write (out_fd,buffer,strlen(buffer));
- res=1;
- }
- return res;
-}
-
-
/*!
*\brief The main routine.
- *
- * Here we do the configuration management and process the data.
- *
*/
int main(int argc, char ** args){
-
- /* Configuration data */
- string config_file;
- string infile, outfile;
- int infile_set=0, outfile_set=0, config_file_set=0;
-
- int
- do_help=0,
- output_info=0,
- output_called=0,
- output_exported=0,
- output_unsatisfied=0,
- split_objects=0,
- split_objects_numbered=0,
- ignore_block_errors=0,
- ignore_checksum_errors=0,
- pause_on_checksum_error=0,
- ignore_unknown_block_errors=0,
- ignore_object_integrity_errors=0,
- list_contents=1,
- verbose=0;
-
- in_fd=0; /* stdin {O _ \ */
- out_fd=1; /* stdout {O ^ / */
-
- configuration_manager ar("ldc2");
-
- /* Here come the configuration switches */
- ar.add_option_switch("h","help",
- "Output this help text and exit.",
- &do_help,false,true);
-
- ar.add_option_switch("a","output_info",
- "Print tape data information (default)",
- &output_info,true,true);
-
- ar.add_option_switch("c","output_called",
- "Print all called symbols from the object(s).",
- &output_called,true,true);
-
- ar.add_option_switch("e","output_exported",
- "Print all exported symbols from the object(s).",
- &output_exported,true,true);
-
- ar.add_option_switch("u","output_unsatisfied",
- "List all unsatisfied symbols.",
- &output_unsatisfied,true,true);
-
- ar.add_option_switch("S","split_objects_numbered",
- "Split input data into distinct numbered files",
- &split_objects_numbered,true,true);
-
- ar.add_option_switch("s","split_objects",
- "Split input data into distinct object files.",
- &split_objects,true,true);
-
- ar.add_option_switch("b","ignore_block_errors",
- "Ignore block integrity errors. This will output broken blocks,too",
- &ignore_block_errors,true,true);
-
- ar.add_option_switch("k","ignore_checksum_errors",
- "Ignore block checksum errors. Errors will be converted to warnings.",
- &ignore_checksum_errors,true,true);
-
- ar.add_option_switch("p","pause_on_checksum_error",
- "Wait for user input on checksum error.",
- &pause_on_checksum_error,true,true);
-
- ar.add_option_switch("n","ignore_unknown_block_errors",
- "Ignore errors caused by unknown block types. Errors will be converted to warnings.",
- &ignore_unknown_block_errors,true,true);
-
- ar.add_option_switch("g","ignore_object_integrity_errors",
- "Ignore errors caused by objects without proper end block. \
-Errors will be converted to warnings.",
- &ignore_object_integrity_errors,true,true);
-
- ar.add_option_switch("v","verbose",
- "Be a bit more verbose.",
- &verbose,true,true);
-
- ar.add_option_value("i","in_file",
- "specify input file",
- &infile_set,&infile,
- "<input-file>",true,false);
-
- ar.add_option_value("o","out_file",
- "Specify output file.",
- &outfile_set,&outfile,
- "<output_file>",true,true);
-
- ar.add_argument("File from where data is read",
- &infile_set,&infile,
- "<input-file>");
- ar.add_argument("File to where output is redirected",
- &outfile_set,&outfile,
- "<output-file>");
-
- ar.add_option_value("F","config_file",
- "Use the specified configuration file.",
- &config_file_set,&config_file,
- "<file-name>",false,true);
-
-
- // If there's a config file mentioned in the environment, take it!
- char * env_ldc_config=getenv("LDC_CONFIG");
- if(env_ldc_config){
- fprintf(stderr,"Using config file:\"%s\"\n",env_ldc_config);
- if(dump_vector(ar.read_file(env_ldc_config))){
- dump_vector(ar.get_help());
- exit(1);
- }
- }
-
- // Process command line first time
- if(dump_vector(ar.read_args(argc,args))){
- dump_vector(ar.get_help());
- exit(7);
- }
-
- if (do_help) {
- dump_vector(ar.get_help());
- exit(0);
- }
-
- // If user has a config file, use it.
- if (config_file_set){
- fprintf(stderr,"Using config file:\"%s\"\n",config_file.c_str());
- if(dump_vector(ar.read_file(config_file))){
- dump_vector(ar.get_help());
- exit(7);
- }
-
- // Process command line a second time to override values from config file.
- if(dump_vector(ar.read_args(argc,args))||do_help){
- dump_vector(ar.get_help());
- exit(7);
- }
- }
+ // Do all the configuration stuff
+ do_config(argc,args);
- if (infile_set==1){
- fprintf(stderr,"Opening file for input:%s\n",infile.c_str());
- in_fd=open(infile.c_str(),O_RDONLY);
- if (in_fd<0){
- fprintf(stderr,"Error: could not open file \"%s\" for reading!\n",infile.c_str());
- exit (1);
- }
- }
+ // Now we go to read the data!
- if (outfile_set==1){
- fprintf(stderr,"Opening file for output:%s\n",outfile.c_str());
- out_fd=open(outfile.c_str(),O_WRONLY|O_TRUNC);
- if (out_fd<0){
- fprintf(stderr,"Error: could not open file \"%s\" for writing!\n",outfile.c_str());
- exit (1);
- }
- }
- // The configuration implications according to /cfg007/
- if (in_fd==0) pause_on_checksum_error=0;
- if (pause_on_checksum_error==1) ignore_checksum_errors=1;
- if (output_info||output_called||output_exported||output_unsatisfied)
- list_contents=0;
-
-
- // Now we go to read the data!
-
vector<tape_block*> tape;
vector<vector<tape_block *> > objects;
vector<tape_block *> current_object;
if (!in_object){
fprintf(stderr,"File successfully read.\n");
} else {
- if (ignore_object_integrity_errors){
+ if (cfg_ignore_object_integrity_errors){
fprintf(stderr,"Warning: Object integrity check failed!\n");
warnings++;
} else {
break;
case tape_block::TBS_EOF_ILLEGAL:
delete block;
- if (ignore_block_errors){
+ if (cfg_ignoreblock_errors){
fprintf(stderr,"Warning: Block integrity check failed!\n");
warnings++;
} else {
break;
case tape_block::TBS_CHECKSUM:
delete block;
- if (ignore_checksum_errors){
+ char buffer[200];
+ snprintf(buffer,200,"Block No. %3i: Start(hex):%5x End(hex):%5x Size(hex):%3x\n",
+ blocks_read-1,
+ block_start,
+ block_end,
+ block->get_raw_size());
+ if (cfg_ignorechecksum_errors){
+ char buffer[200];
+ snprintf(buffer,200,"Block No. %3i: Start(hex):%5x End(hex):%5x Size(hex):%3x\n",
+ blocks_read-1,
+ block_start,
+ block_end,
+ block->get_raw_size());
+ write (out_fd,buffer,strlen(buffer));
fprintf(stderr,"Warning: Block checksum wrong!\n");
+ fprintf(stderr,buffer);
warnings++;
} else {
fprintf(stderr,"Error: Block checksum wrong!\n");
+ fprintf(stderr,buffer);
errors++;
read_ahead=false;
errcode=4;
case tape_block::TBS_IOERR:
delete block;
if (in_fd){
- fprintf(stderr,"Error: Could not read from \"%s\"!\n",infile.c_str());
+ fprintf(stderr,"Error: Could not read from \"%s\"!\n",cfg_infile.c_str());
} else {
fprintf(stderr,"Error: Could not read from stdin!\n");
}
tape.insert(tape.end(),block);
blocks_read++;
- if (verbose){
+ if (cfg_verbose){
char buffer[200];
snprintf(buffer,200,"Block No. %3i: Start(hex):%5x End(hex):%5x Size(hex):%3x\n",
blocks_read-1,
write (out_fd,buffer,strlen(buffer));
}
- if(list_contents)
+ if(cfg_list_contents)
dump_vector(block->get_description());
if (block->get_type()==0x10){ // Unknown data block!
- if (ignore_unknown_block_errors){
+ if (cfg_ignore_unknown_block_errors){
fprintf(stderr,"Warning: Unknown block type!\n");
warnings++;
}else {
char buffer[200];
sprintf(buffer,"Bytes read:%i Blocks read:%i\nErrors:%i Warnings:%i\n",
read_pointer,blocks_read,errors,warnings);
- if(output_info){
+ if(cfg_output_info){
write (out_fd,buffer,strlen(buffer));
- } else {
- fprintf(stderr,buffer);
+// } else {
+// fprintf(stderr,buffer);
}
if (errors>0){
--- /dev/null
+#include <vector>
+#include <string>
+
+#include <stdio.h>
+
+#include "config.hh"
+
+using namespace std;
+
+/*!
+ *\brief Output a vector of strings to out_fd.
+ *\arg strings A vector containing text.
+ *\retval 0 The vector was empty.
+ *\retval 1 The vector contained text.
+ */
+int dump_vector(vector<string> strings){
+ int res=0;
+ for (vector<string>::iterator iter=strings.begin();iter<strings.end();iter++){
+ char buffer[50000];
+ snprintf(buffer,50000,"%s\n",(*iter).c_str());
+ write (out_fd,buffer,strlen(buffer));
+ res=1;
+ }
+ return res;
+}
+
+/*!
+ *\brief Output a vector of strings to stderr.
+ *\arg strings A vector containing text.
+ *\retval 0 The vector was empty.
+ *\retval 1 The vector contained text.
+ */
+int dump_vector_err(vector<string> strings){
+ int res=0;
+ for (vector<string>::iterator iter=strings.begin();iter<strings.end();iter++){
+ char buffer[50000];
+ snprintf(buffer,50000,"%s\n",(*iter).c_str());
+ write (2,buffer,strlen(buffer));
+ res=1;
+ }
+ return res;
+}
--- /dev/null
+#ifndef TOOL_HH
+#define TOOL_HH
+
+#include <vector>
+#include <string>
+
+using namespace std;
+
+extern int dump_vector(vector<string> strings);
+extern int dump_vector_err(vector<string> strings);
+
+#endif