\section{Appendix}
% \clearpage
% \addcontentsline{toc}{section}{dddde}
-\bibliography{literature}
-The mentioned Honeywell documents can be found on
-\verb|http://www.series16.adrianwise.co.uk|.
-\newpage
\listoftables
\listoffigures
+\bibliography{literature}
+The mentioned Honeywell documents can be found on
+\verb|http://www.series16.adrianwise.co.uk|.
\bibliographystyle{unsrt}
\sffamily
+
\pagestyle{empty}
\pagenumbering{roman}
-\section{Requirements Specification}
+\section{Functional Specification}
%*******************************************************************************
\subsection{Data input processing}
The tape data shall be checked against the Honeywell tape block specification
found in \cite{ser16:progref:bformats}.
-\rd{chk001}{Block completeness check}{
- Every data block's completeness shall be checked by the means of
+\rd{chk001}{Block integrity check}{
+ Every data block's integrity shall be checked by the means of
detecting unexpected end of file while reading in the block.
}
}
%*******************************************************************************
+\subsection{Additional features}
+
+\rd{h001}{Print help message}{
+ A help message is output to standard error.
+}
+
+%*******************************************************************************
+\newpage
\subsection{Data analysis}
\rd{da001}{List tape contents}{
}
%*******************************************************************************
+\newpage
\subsection{Data processing}
\rd{dp001}{Split into object files}{
a zero-padded three digit number and EOT blocks are not suppressed.
}
-%*******************************************************************************
-\subsection{Additional features}
-
-\rd{h001}{Print help message}{
- A help message shall be output to standard error.
-}
-
%*******************************************************************************
+\newpage
\subsection{Program configuration}
\rd{cfg001}{Configuration process}{
- The following sequence shall be used to acquire the working configuration:
+ The following sequence shall be used to acquire the working
+ configuration:
\begin{enumerate}
\item Configuration file according to environment variable:\\
If the environment variable LDC\_CONFIG is set, that
file is found,
the specified configuration file is parsed.\\
Any values in this configuration file
- override values found in the previously read configuration
- file.
+ override values found in the previously read
+ configuration file.
\item Configuration parameters passed via the command line:\\
Parameters passed on the command line will override
values from previously read configuration files.
The program shall accept two types of parameters:
\begin{itemize}
\item Switches:\\
- A switch is a binary value which can have the value true or false.
+ A switch is a binary value which can have the value true or
+ false.
\item Strings:\\
A string parameter is a parameter requiring a string value.\\
A typical use would be a file name for input or output.
\end{itemize}
}
+\newpage
\rd{cfg003}{Switch parameters}{
The following switch parameters shall be accepted:
\begin{table}[H]\begin{center}
- \begin{tabular}{|r|p{2.5em}|l|}
+ \begin{tabular}{|r|p{2.5em}|p{23em}|}
\hline
\bf Long Form & \bf Short form & \bf Description\\
\hline
help & h & Show help message (\req{h001})\\
- output\_info & a & Output data info according to \req{da005}.\\
- output\_called & c & Output a list of called symbols (\req{dp003}).\\
- output\_exported & e & Output a list of exported symbols (\req{dp002}).\\
- output\_unsatisfied & u & Output a list of unsatisfied dependencies (\req{dp004}).\\
- split\_objects & s & Split into object files (\req{dp006}.\\
- split\_objects\_numbered & S & Split into numbered object files (\req{dp007}).\\
- ignore\_block\_errors & b & Ignore block integrity errors (\req{err001}).\\
- ignore\_checksum\_errors & k & Ignore Checksum errors (\req{err001}).\\
- pause\_on\_checksum\_error & p & Wait for user input on checksum error (\req{err003}).\\
- ignore\_unknown\_block\_errors & n & Ignore errors causes by datablocks of
- unknown type (\req{err001}).\\
- ignore\_object\_integrity\_errors & g & Ignore errors caused by objects without
- proper end block (\req{err001}.)\\
+ output\_info & a & Output data info (\req{da005}) .\\
+ output\_called & c & Output a list of called symbols
+ (\req{da003}).\\
+ output\_exported & e & Output a list of exported symbols
+ (\req{da002}).\\
+ output\_unsatisfied & u & Output a list of unsatisfied
+ dependencies (\req{da004}).\\
+ split\_objects & s & Split into object files
+ (\req{dp001}).\\
+ split\_objects\_numbered & S & Split into numbered object files
+ (\req{dp002}).\\
+ ignore\_block\_errors & b & Ignore block integrity errors
+ (\req{err001},\req{chk001}).\\
+ ignore\_checksum\_errors & k & Ignore Checksum errors
+ (\req{err001}\req{chk002}).\\
+ pause\_on\_checksum\_error & p & Wait for user input on checksum error
+ (\req{chk005}).\\
+ ignore\_unknown\_block\_errors & n & Ignore errors causes by
+ datablocks of unknown type
+ (\req{err001}\req{chk003}).\\
+ ignore\_object\_integrity\_errors & g & Ignore errors caused by objects
+ without proper end block
+ (\req{err001}\req{chk004}).\\
\hline
\end{tabular}\end{center}
\caption{Configuration switches}
\hline
\bf Long Form & \bf Short form & \bf Description\\
\hline
- in\_file & i & Set input file (\req{inp001}) \\
- out\_file & o & Set output file for text output.(\req{dp008})\\
+ in\_file & i & Set input file (\req{inp001}). \\
+ out\_file & o & Set output file for text output(\req{dp008}).\\
\hline
\end{tabular}\end{center}
\caption{Configuration strings}
\end{table}
}
-
+\newpage
\rd{cfg005}{Configuration file syntax}{
The configuration file must comply two the following grammar, given in EBNF:
}
String = { ? Every character except newline ?} ;
TrueStr = "yes" | "1" | "true" ;
FalseStr = | "no" | "0" | "false" ;
- \end{verbatim};
+ \end{verbatim}
-\rd{cfg006}{Commandline syntax}{
+\rd{cfg006}{Command Line syntax}{
The command line must comply to the following grammar, given in EBNF:
}
\begin{verbatim}
LongSwitch = "--" SwLong [ "=" BoolValue ] ;
ShortParam = "-" StrShort String ;
LongParam = "--" StrLong "=" String ;
- SwShort = "a" | "c" | "e" | "u" | "s" | "S"
+ SwShort = "h" | "a" | "c" | "e" | "u" | "s" | "S"
| "b" | "k" | "p" | "n" | "g" ;
- SwLong = "output_info" | "ouput_called" | "output_exported"
+ SwLong = "help"
+ | "output_info" | "ouput_called" | "output_exported"
| "output_unsatisfied" | "split_objects" [ _"numbered" ]
- | "ignore_block_errors" | "ignore_checksum_errors
+ | "ignore_block_errors" | "ignore_checksum_errors"
| "pause_on_checksum_error"
| "ignore_unknown_block_errors"
| "ignore_object_integrity" ;
- StrShort = "o";
+ StrShort = "o" ;
StrLong = "out_file" ;
\end{verbatim}
+\newpage
\rd{cfg007}{Configuration implications}{
\begin{itemize}
\item pause\_on\_checksum\_errors implies ignore\_checksum\_errors.
}
%*******************************************************************************
+\newpage
\subsection{Error handling}
Caused by failed check according to \req{chk004}.\\
\esup
\item Usage error:\\
- Error caused by errors in the program configuration i.e.wrong
+ Error caused by errors in the program configuration i.e. wrong
parameters or impossible combinations of parameters.\\
\enosup \\
Additionally, the help (\req{h001}) message is output.
Checksum error & Block checksum wrong!\\
Unknown block type & Unknown block type!\\
Object integrity & Object integrity check failed!\\
- Usage error & $<$Error message describing the problem$>$\\
+ Usage error & $<$Specific message describing the problem$>$\\
\hline
\end{tabular}
\end{center}
*\brief Constructor.
*
* This constructor makes a new argument_reader ready to use.
- *\arg app_name Name of the application as mentioned in the
+ *\arg name Name of the application as mentioned in the
* "Use: <appname> ..." help message.
*/
-argument_reader::argument_reader(string app_name){
- progname=app_name;
+argument_reader::argument_reader(string name){
+ app_name=app_name;
}
string description, int * status,
string * target, string placeholder){
- if(status!=NULL) arguments.insert(arguments.end(),
- parameter(shortname,longname, description,
+ if(status!=NULL) opt_v.insert(opt_v.end(),
+ opt_t(shortname,longname, description,
status,target,placeholder)
);
}
*/
void argument_reader::add_argument(string placeholder, string description, int * status, string * target){
if (target!=NULL) if(status!=NULL)
- free_arguments.insert(free_arguments.end(),free_parameter(placeholder,description,status,target));
+ 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.
+ *\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;
// Look for long argument
if ((akt_p->substr(0,2)=="--")&&(free_parms_count==0)){
int found=0;
- for (vector<parameter>::iterator parm_p=arguments.begin();parm_p<arguments.end();parm_p++){
+ 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;
int stop_char_loop=0;
for (unsigned int pos=1; pos<akt_p->length()&& !stop_char_loop ;pos++){
int found=0;
- for (vector<parameter>::iterator parm_p=arguments.begin();parm_p<arguments.end();parm_p++){
+ 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;
} // char loop
}// switch found
else{ // no switch found
- if (free_parms_count<free_arguments.size()){
- *(free_arguments[free_parms_count].target)=*akt_p;
+ 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>free_arguments.size()) result.insert(result.begin(),"Too many arguments!");
+ 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(),"");
}
-// if (!result.empty()){
-// get_help(result);
-// }
return result;
}
*\arg target Reference to a vector<string> to which lots of helpful
* strings are appended.
*/
-void argument_reader::get_help(vector<string> & result){
-
- result.insert(result.end(),"");
- string line="Usage: "+progname;
- for (vector<parameter>::iterator parm_p=arguments.begin();parm_p<arguments.end();parm_p++){
+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){
- result.insert(result.end(),line);
- line=string(7+progname.length(),' ');
+ target.insert(target.end(),line);
+ line=string(7+app_name.length(),' ');
}
line+=addstr;
}
- for (vector<free_parameter>::iterator parm_p=free_arguments.begin();parm_p<free_arguments.end();parm_p++){
+ 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){
- result.insert(result.end(),line);
- line=string(7+progname.length(),' ');
+ target.insert(target.end(),line);
+ line=string(7+app_name.length(),' ');
}
line+=" ["+parm_p->placeholder+"]";
}
- result.insert(result.end(),line);
+ target.insert(target.end(),line);
/*******************************/
vector<string> left,right;
- for (vector<parameter>::iterator parm_p=arguments.begin();parm_p<arguments.end();parm_p++){
+ 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;
right.insert(right.end(),line);
}
- for (vector<free_parameter>::iterator parm_p=free_arguments.begin();parm_p<free_arguments.end();parm_p++){
+ 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;
right.insert(right.end(),line);
}
- if (arguments.size()){
- result.insert(result.end(),"");
- result.insert(result.end(),"Options:");
+ if (opt_v.size()){
+ target.insert(target.end(),"");
+ target.insert(target.end(),"Options:");
}
unsigned int max_width=0;
- for (unsigned int c=0; c<arguments.size();c++)
+ 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<arguments.size();c++){
+ 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);
- printf("limit:%i\n",limit);
- result.insert(result.end(),nl.substr(0,limit));
+ target.insert(target.end(),nl.substr(0,limit));
nl=string(max_width+2,' ')+nl.substr(limit+1);
}
- result.insert(result.end(),nl);
+ target.insert(target.end(),nl);
}
- if (free_arguments.size()){
- result.insert(result.end(),"");
- result.insert(result.end(),"Arguments:");
+ if (arg_v.size()){
+ target.insert(target.end(),"");
+ target.insert(target.end(),"Arguments:");
}
max_width=0;
- for (unsigned int c=arguments.size(); c<arguments.size()+free_arguments.size();c++)
+ 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=arguments.size(); c<arguments.size()+free_arguments.size();c++){
+ 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);
- result.insert(result.end(),nl.substr(0,limit));
+ target.insert(target.end(),nl.substr(0,limit));
nl=string(max_width+2,' ')+nl.substr(limit+1);
}
- result.insert(result.end(),nl);
+ target.insert(target.end(),nl);
}
- result.insert(result.end(),"");
+ target.insert(target.end(),"");
}
/*!
/**************************************************/
-argument_reader::parameter::parameter(string n_shortname, string n_longname,string n_description, int * n_status,
+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;
if (status) *status=0;
}
-argument_reader::free_parameter::free_parameter( string n_placeholder, string n_description,
+argument_reader::arg_t::arg_t( string n_placeholder, string n_description,
int * n_status, string * n_target){
description=n_description;
status=n_status;
* - 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 \
+ * - 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. \
+ * - 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 n_name);
+ argument_reader(string name);
- void add_param (string shortname,
- string longname,
- string description,
- int * status,
- string * target=NULL,
+ void add_param (string shortname,
+ string longname,
+ string description,
+ int *status,
+ string *target=NULL,
string placeholder=string("<string>")
);
void add_argument(string placeholder, string description, int * status, string * target);
private:
- class parameter{
+ /*!
+ *\brief Container for one command line option.
+ */
+ class opt_t{
public:
- parameter (string shortname, string longname,string description, int * status,
+ opt_t (string shortname, string longname,string description, int * status,
string * target=NULL, string placeholder=string("<string>"));
string shortname;
string longname;
string placeholder;
};
- class free_parameter{
+ /*!
+ *\brief Container for one command line argument.
+ */
+ class arg_t{
public:
- free_parameter (string placeholder,string description,
+ 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;
- vector<parameter>arguments;
- vector<free_parameter>free_arguments;
-
- string progname;
-};
+}; // class argument_reader
#endif
--- /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
*/
vector<string> eot_block:: get_description(){
vector<string> result;
- string r_string=" (EOT) End of Tape mark";
+ string r_string="***********(EOT)*****End of Tape mark **********************";
result.insert(result.end(),r_string);
return result;
}
#include <stdio.h>
#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include "tape_block.hh"
-#include "data_block.hh"
-
#include "argument_reader.hh"
using namespace std;
-void tape_start(void* m){
- printf("tape_start\n");
-}
-
-void tape_stop(void* m){
- printf("tape_stop\n");
-}
-
-void dump_vector(vector<string> arguments){
+int dump_vector(vector<string> arguments){
+ int res=0;
for (vector<string>::iterator iter=arguments.begin();iter<arguments.end();iter++){
printf("%s\n",(*iter).c_str());
+ res=1;
}
+ return res;
}
+
+
int main(int argc, char ** args){
- int help_needed;
- int name_set;
- int file_set;
- string name="Philipp";
- string filename;
+
+ string infile, outfile;
+ int infile_set, outfile_set;
+ int help_wanted;
+
+ int greet_want;
+ string greetings;
+
+ int in_fd, out_fd;
+
+ in_fd=0; //stdin {O _ \
+ out_fd=1; //stdout {O ^ /
argument_reader ar("ldc2");
- ar.add_param("h","help","Give help",&help_needed);
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name Gelaber Gelaber Gelaber Gelaber M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_param("n","name=","Enter other name",&name_set,&name,"<name>");
- ar.add_argument("<input-blaaaaaaaaaaaaaaa-filename>","File to read data from",&file_set,&filename);
-
- dump_vector(ar.read_args(argc,args));
-
- if (help_needed){
+ ar.add_param("h","help","Output this help text.",&help_wanted);
+ ar.add_param("g","greet","Wonderful bla bla. It is here only to test the output\
+capabilities of the arg_reader.",&greet_want);
+
+ ar.add_argument("<input-file>","File from where data is read",&infile_set,&infile);
+ ar.add_argument("<output-file>","File to where output is redirected",&outfile_set,&outfile);
+
+
+ if((dump_vector(ar.read_args(argc,args))||help_wanted)){
dump_vector(ar.get_help());
exit(1);
}
+ if(greet_want)printf("Hallo!\n");
+
+ if (infile_set==1){
+ printf("Opening file for input:%s\n",infile.c_str());
+ in_fd=open(infile.c_str(),O_RDONLY);
+ if (in_fd<0){
+ printf("Error: could not open file:%s\n",infile.c_str());
+ exit (3);
+ }
+ }
+
+ vector<tape_block*> tape;
+
+
+ tape_block * block=0;
+ while(1){
+ block=tape_block::gen_from_fd(in_fd);
+ if (block->get_state()==tape_block::TBS_OK){
+ tape.insert(tape.end(),block);
+ dump_vector(block->get_description());
+ }
+ else break;
+ }
- printf("\n\n\nHallo %s!\n",name.c_str());
- exit(0);
- tape_block * myblock=0;
- do{
- if (myblock) delete myblock;
- myblock=tape_block::gen_from_fd(0);
-
- vector<string> desc=myblock->get_description();
- for (vector<string>::iterator iter=desc.begin();
- iter!=desc.end();iter++)
- printf("%s\n",(*iter).c_str());
- } while (myblock->get_state()==tape_block::TBS_OK);
- return 0;
-}
+ switch(block->get_state()){
+ case tape_block::TBS_EOF_LEGAL: printf("File successfully read.\n");
+ break;
+ case tape_block::TBS_EOF_ILLEGAL: printf("EOF while in block!\n");
+ break;
+ case tape_block::TBS_CHECKSUM:
+ printf("Checksum error!\n");
+ break;
+ case tape_block::TBS_DEFAULT:
+ printf("TBS_DEFAULT encountered ->> SEVERY INTERNAL ERROR!\n");
+ exit(88);
+ case tape_block::TBS_IOERR:
+ printf("I/O Error... Why?\n");
+ exit (43);
+ }
+
+ return 0;
+} // main()