From d65ad4d76066646927175a9896fe348bc0691e68 Mon Sep 17 00:00:00 2001 From: hachti Date: Mon, 26 Mar 2007 03:20:31 +0000 Subject: [PATCH] *** empty log message *** --- pc-tools/ldc2/Doxyfile | 25 ++++----- pc-tools/ldc2/data/README | 1 + pc-tools/ldc2/doc/body.tex | 2 +- pc-tools/ldc2/doc/cover.tex | 7 +-- pc-tools/ldc2/doc/impl_spec.tex | 81 +++++++++++++++++++++++++--- pc-tools/ldc2/doc/req_spec.tex | 2 +- pc-tools/ldc2/doc/test_spec.tex | 4 +- pc-tools/ldc2/src/main.cpp | 91 +++++++++++++++++++++----------- pc-tools/ldc2/src/tape_block.cpp | 15 +++--- 9 files changed, 166 insertions(+), 62 deletions(-) create mode 100644 pc-tools/ldc2/data/README diff --git a/pc-tools/ldc2/Doxyfile b/pc-tools/ldc2/Doxyfile index cf8d1c8..2581d0a 100644 --- a/pc-tools/ldc2/Doxyfile +++ b/pc-tools/ldc2/Doxyfile @@ -106,7 +106,7 @@ INLINE_INHERITED_MEMB = NO # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. -FULL_PATH_NAMES = YES +FULL_PATH_NAMES = NO # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is @@ -442,13 +442,13 @@ WARN_NO_PARAMDOC = YES # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) -WARN_FORMAT = "$file:$line: $text" +WARN_FORMAT = "WARNING $file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. -WARN_LOGFILE = +WARN_LOGFILE = doxy_warnings #--------------------------------------------------------------------------- # configuration options related to the input files @@ -561,7 +561,7 @@ SOURCE_BROWSER = YES # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. -INLINE_SOURCES = YES +INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code @@ -767,7 +767,7 @@ MAKEINDEX_CMD_NAME = makeindex # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. -COMPACT_LATEX = NO +COMPACT_LATEX = YES # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, a4wide, letter, legal and @@ -792,13 +792,13 @@ LATEX_HEADER = # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. -PDF_HYPERLINKS = NO +PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. -USE_PDFLATEX = NO +USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep @@ -821,7 +821,7 @@ LATEX_HIDE_INDICES = NO # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. -GENERATE_RTF = YES +GENERATE_RTF = NO # 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 @@ -1089,7 +1089,7 @@ CLASS_DIAGRAMS = YES # inheritance and usage relations if the target is undocumented # or is not a class. -HIDE_UNDOC_RELATIONS = YES +HIDE_UNDOC_RELATIONS = NO # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization @@ -1126,7 +1126,7 @@ UML_LOOK = YES # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. -TEMPLATE_RELATIONS = NO +TEMPLATE_RELATIONS = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented @@ -1201,7 +1201,8 @@ MAX_DOT_GRAPH_WIDTH = 1024 # the specified constraint. Beware that most browsers cannot cope with very # large images. -MAX_DOT_GRAPH_HEIGHT = 1024 +#MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_HEIGHT = 2000 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable @@ -1228,7 +1229,7 @@ DOT_TRANSPARENT = NO # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. -DOT_MULTI_TARGETS = NO +DOT_MULTI_TARGETS = YES # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and diff --git a/pc-tools/ldc2/data/README b/pc-tools/ldc2/data/README new file mode 100644 index 0000000..0772267 --- /dev/null +++ b/pc-tools/ldc2/data/README @@ -0,0 +1 @@ +This directory contains test data for ldc2. \ No newline at end of file diff --git a/pc-tools/ldc2/doc/body.tex b/pc-tools/ldc2/doc/body.tex index 83d4402..f740f7f 100644 --- a/pc-tools/ldc2/doc/body.tex +++ b/pc-tools/ldc2/doc/body.tex @@ -4,7 +4,7 @@ \input req_spec \newpage \input impl_spec -%\newpage +\newpage \input test_spec \newpage \input appendix diff --git a/pc-tools/ldc2/doc/cover.tex b/pc-tools/ldc2/doc/cover.tex index e03f60d..fef18d3 100644 --- a/pc-tools/ldc2/doc/cover.tex +++ b/pc-tools/ldc2/doc/cover.tex @@ -5,8 +5,9 @@ \vspace{1.5cm} \Large -- Projektbericht --\\ \vspace{4cm} - -\Huge {\tt $\star$\hspace{0.5cm}LDC2\footnote{Name may be subject of change}\hspace{0.5cm}$\star$}\\ + +\Huge {\tt $\star$\hspace{0.5cm}LDC2\hspace{0.5cm}$\star$}\\ +%\footnote{Name may be subject of change} \vspace{1cm} \large Honeywell Series 16\\ Object Program Analysis Tool\\ @@ -14,7 +15,7 @@ Object Program Analysis Tool\\ \vspace{3cm} \large Philipp Hachtmann, Mat.-Nr. 124370 \\ \vspace{0.5cm} -10. Dezember 2006\\ +26. März 2007\\ \vspace{3.5cm} \normalsize Labor Softwaretechnik 2\\ Prof. Andreas Spillner\\ diff --git a/pc-tools/ldc2/doc/impl_spec.tex b/pc-tools/ldc2/doc/impl_spec.tex index 474f722..466e78b 100644 --- a/pc-tools/ldc2/doc/impl_spec.tex +++ b/pc-tools/ldc2/doc/impl_spec.tex @@ -1,16 +1,84 @@ \section{Implementation Specification} -\subsection{Building \pname} +\subsection{Theory of operation} +\subsubsection{Overview} + +The program is implemented using standard C++. + +While the data structures according to \cite{ser16:progref} +are designed consequently object oriented, +most of the actual processing of the data after reading in is done +by the routines contained in +\verb|main.cpp|, \verb|config.cpp| and \verb|tool.cpp|. + +Program configuration is capsuled into the class \verb|configuration_manager|, +used by the routines in \verb|config.cpp|. + +\subsubsection{Program flow} +The \verb|main()| routine sets up the working environment using the \verb|do_config()| +subroutine contained in \verb|config.cpp|. This contains parsing the command line, +reading a configuration file, and setting the global \verb|cfg_*| flags. The input and +output file descriptors \verb|in_fd| and \verb|out_fd| are assigned to 0 and 1 respective +files as stated in the configuration (command line option or configuration file). +The \verb|configuration_manager| is able to dynamically generate help output for all +options. + +The next call is \verb|read_tape()|, the data input routine. In \verb|read_tape()|, +the static factory method \verb|tape_block::gen_from_fd()| is used to create and +check blocks, taking data directly from the global file descriptor \verb|in_fd|.\\ +At the end of \verb|read_tape()|, the vector \verb|tape| has been filled with +pointers to instances of \verb|tape_block|. + +In the next step, the routine \verb|process_tape()| is called, in which +integrity checks on object level and splitting to files (if desired) +are accomplished. Every valid and complete object consist of either one +single \verb|eot_block| or a series of \verb|data_block|s, while the last block +of each object must be one of the types which mark the end of an object. + +After all that, \verb|process_symbols()| is called. This routine generates three vectors +containing symbol names: \verb|exported|, \verb|called|, and \verb|unsatisfied|. +The latter is the difference of \verb|called| and \verb|exported|.\\ +If desired, those vectors are written out to \verb|out_fd|, one symbol per line. +\subsubsection{Block factory} +The software makes use of C++ virtual methods allowing for convinient processing of +multiple kinds of blocks without knowing much about the block type currently worked +on.\\ +The block factory consists of the static factory method \verb|tape_block::gen_from_fd()| +and a corresponding private constructor of class \verb|tape_block|. The constructor +creates a block and reads data from the given file descriptor. The factory method +then tries to determine the block's type and recreate an object of the most accurate +subtype applying to the block. Information about the block types is contained in +the block data itself. A pointer to the newly created object is returned or one +of the exception defined in class \verb|tape_block| is thrown. + + +\subsection{Detailed documentation} +\subsubsection{Doxygen} +The source code has been documented using Doxygen and appropriate +comments throughout the program code. Doxygen generates a very useful +html documentation containing very usable diagrams (not strictly UML, but +very fine anyway), lists and detailed documentation. + +The Doxygen configuration also creates man pages, latex sources with +makefile for PostScript and PDF output. + +\subsubsection{Not in this document} +I have decided not to create UML class and collaboration diagrams because +in my opinion the Doxygen documentation perfectly covers those needs. + +The project already took several times the time I allocated in my schedule.... + +\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 GNU 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 +\item Graphviz dot tool, 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 @@ -21,7 +89,6 @@ 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} @@ -49,3 +116,5 @@ The Doxygen output is placed in the subdir \verb|doxy|. including binaries and documentation. \end{itemize} + +% End of the show.... \ No newline at end of file diff --git a/pc-tools/ldc2/doc/req_spec.tex b/pc-tools/ldc2/doc/req_spec.tex index e81c23d..ba089c5 100644 --- a/pc-tools/ldc2/doc/req_spec.tex +++ b/pc-tools/ldc2/doc/req_spec.tex @@ -358,7 +358,7 @@ O$PLDR (0-50) Subprogram Entry Point Definition without proper end block (\req{err001}\req{chk004}).\\ quiet & q & Suppress all non-critical messages - to standard error (warnings, informatianal)\\ + (warnings, informational text)\\ \hline \end{tabular}\end{center} \caption{Configuration switches} diff --git a/pc-tools/ldc2/doc/test_spec.tex b/pc-tools/ldc2/doc/test_spec.tex index 6e73a85..c5805c3 100644 --- a/pc-tools/ldc2/doc/test_spec.tex +++ b/pc-tools/ldc2/doc/test_spec.tex @@ -1,2 +1,4 @@ \section{Test Specification} ---- To be done --- \ No newline at end of file +There is currently no test specification. Most of the functionality +has been tested manually using the objects contained in the \verb|/data| +subdirectory.\\ diff --git a/pc-tools/ldc2/src/main.cpp b/pc-tools/ldc2/src/main.cpp index dc2d124..35f4ce6 100644 --- a/pc-tools/ldc2/src/main.cpp +++ b/pc-tools/ldc2/src/main.cpp @@ -2,11 +2,14 @@ * * LDC2 source code * - * $Date: 2007/03/26 01:15:21 $ + * $Date: 2007/03/26 03:20:31 $ * $Author: hachti $ * * $Log: main.cpp,v $ - * Revision 2.1 2007/03/26 01:15:21 hachti + * Revision 2.2 2007/03/26 03:20:31 hachti + * *** empty log message *** + * + * Revision 2.1 2007-03-26 01:15:21 hachti * *** empty log message *** * * Revision 2.0 2007-03-26 01:00:40 hachti @@ -44,13 +47,14 @@ using namespace std; /******************************************************************************/ -static FILE * stdwarn; //! Suppressable warning output file pointer. -static vector tape; //! Represents the whole tape contents. +static FILE * stdwarn; //! Suppressable warning output file pointer. +static vector tape; //! The whole tape contents. static vector > objects; //! Tape content in objects. -static int errors=0; -static int warnings=0; -static int errcode=0; //! Variable for error codes. +static int errors = 0; //! Global error counter. +static int warnings= 0; //! Global warning counter. +static int errcode = 0; //! Error code for error exit routine. + /******************************************************************************/ /*! @@ -65,6 +69,7 @@ void exit_on_error(){ exit(errcode); } } + /******************************************************************************/ /*! @@ -92,12 +97,13 @@ void read_tape(){ while(read_ahead){ - bool err_checksum=false; - bool err_integrity=false; + bool err_checksum=false; //! Checksum error flag. + bool err_integrity=false; //! Integrity error flag. - bool warning=false; - bool error=false; + bool warning=false; //! Warning flag. + bool error=false; //! Error flag. + // Try to generate block try{ block=tape_block::gen_from_fd(in_fd); } @@ -109,7 +115,8 @@ void read_tape(){ catch(tape_block::io_error_exception){ if (in_fd){ - fprintf(stderr,"Error: Could not read from \"%s\"!\n",cfg_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"); } @@ -208,8 +215,11 @@ void read_tape(){ /******************************************************************************/ +/*! + *\brief Do integrity test and object or block dumps. + */ void process_tape(){ - if (cfg_verbose) fprintf(stdwarn,"Processing Tape.\n"); + if (cfg_verbose) fprintf(stdwarn,"\nProcessing Data.\n"); bool in_object=false; char filename[100]; @@ -227,7 +237,8 @@ void process_tape(){ objname="EOT"; if (in_object){ if (cfg_ignore_object_integrity_errors){ - fprintf(stdwarn,"Warning: Object integrity error!\n"); + fprintf(stdwarn,"Warning: Object integrity error!\ + (Object no %i, Block %i unexpected)\n",obj_no,i); warnings++; } else { fprintf(stderr,"Error: Object integrity error!\ @@ -238,8 +249,8 @@ void process_tape(){ } } } - if (!in_object){ // object begin + obj_no++; obj_start_block=i; @@ -253,7 +264,6 @@ void process_tape(){ objname=objname.substr(0,objname.find_last_not_of(" ")+1); unknown_count--; break; - } } @@ -263,11 +273,12 @@ void process_tape(){ // Open file for split objects if (cfg_split_objects && (block->get_type()!=tape_block::TBT_EOT)){ - if (objname=="UNKNOWN")snprintf(filename,99,"UNKNOWN%02i.obj",unknown_count); + if (objname=="UNKNOWN")snprintf(filename,99,"UNKNOWN%02i.obj", + unknown_count); else snprintf(filename,99,"%s.obj",objname.c_str()); if (fd>-1) close (fd); + if (cfg_verbose) fprintf(stdwarn,"Writing file: %s\n",filename); fd=open(filename,O_WRONLY|O_CREAT|O_TRUNC,0666); - printf("opening \"%s\"\n",filename); if (fd<0){ fprintf(stderr,"Error: could not open file \"%s\" for writing!\n", filename); @@ -280,7 +291,8 @@ void process_tape(){ // Open file for split objects numbered snprintf(filename_numbered,99,"%03i0-%s.obj",obj_no,objname.c_str()); if (cfg_split_objects_numbered){ - if (fd_numbered>-1) close (fd_numbered); + close (fd_numbered); + if (cfg_verbose) fprintf(stdwarn,"Writing file: %s\n",filename_numbered); fd_numbered=open(filename_numbered,O_WRONLY|O_CREAT|O_TRUNC,0666); if (fd_numbered<0){ fprintf(stderr,"Error: could not open file \"%s\" for writing!\n", @@ -325,13 +337,17 @@ void process_tape(){ // Output individual block file if desired if (cfg_split_blocks){ char fname[100]; - snprintf(fname,99,"%03i0-%s-%03i.block",obj_no,objname.c_str(),i-obj_start_block); + snprintf(fname,99,"%03i0-%s-%03i.block",obj_no,objname.c_str(), + i-obj_start_block); + if (cfg_verbose) fprintf(stdwarn,"Writing file: %s\n",fname); int fd_block=open(fname,O_WRONLY|O_TRUNC|O_CREAT,0666); if (fd_block<0){ fprintf(stderr,"Error: could not open file \"%s\" for writing!\n", fname); errors++; errcode=1; + close(fd); + close(fd_numbered); return; } try{ @@ -342,6 +358,8 @@ void process_tape(){ fname); errors++; errcode=1; + close(fd); + close(fd_numbered); return; } close(fd_block); @@ -349,19 +367,21 @@ void process_tape(){ if (block->is_endblock()||(block->get_type()==tape_block::TBT_EOT)) { in_object=false; - if (fd!=-1) close(fd); - if (fd_numbered!=-1) close(fd_numbered); + close(fd); + close(fd_numbered); } } // for (...) if (in_object){ if (cfg_ignore_object_integrity_errors){ - fprintf(stdwarn,"Warning: Object integrity error!\n"); + fprintf(stdwarn,"Warning: Object integrity error! Last object incomplete!\n"); warnings++; } else { - fprintf(stdwarn,"Error: Object integrity error!\n"); + fprintf(stdwarn,"Error: Object integrity error! Last Object incomplete!\n"); errors++; errcode=6; + if (fd!=-1) close(fd); + if (fd_numbered!=-1) close(fd_numbered); return; } } @@ -371,11 +391,13 @@ void process_tape(){ /*! *\brief Everything that has to do with symbol listing. */ -void process_called_imports(){ +void process_symbols(){ vectorexported; vectorcalled; vector unsatisfied; - + + if (cfg_verbose) fprintf(stdwarn,"\nProcessing Symbols.\n"); + for (unsigned int i=0; iget_exported_symbols()); merge_vector_unique(called,tape[i]->get_called_symbols()); @@ -415,7 +437,7 @@ void process_called_imports(){ dump_vector_fp(unsatisfied,outp); } -} +} // process_symbols() /******************************************************************************/ /*! @@ -443,15 +465,22 @@ int main(int argc, char ** args){ process_tape(); exit_on_error(); - process_called_imports(); + process_symbols(); exit_on_error(); - - + if (warnings>0){ fprintf(stdwarn,"Warnings:%i\n",warnings); return 99; } - if (cfg_verbose) fprintf(stdwarn,"Success.\n"); + if (cfg_verbose) fprintf(stdwarn,"\nSuccess.\n"); return 0; + + /* + * All over this program, no memory is freed. This is not necessary because + * everything is allocated once and that's it. + * The classes support proper freeing of their internal buffers. + */ + } // main() +/******************************************************************************/ diff --git a/pc-tools/ldc2/src/tape_block.cpp b/pc-tools/ldc2/src/tape_block.cpp index f2e60d8..8ba9dde 100644 --- a/pc-tools/ldc2/src/tape_block.cpp +++ b/pc-tools/ldc2/src/tape_block.cpp @@ -2,17 +2,18 @@ * * LDC2 source code * - * $Date: 2007/03/26 01:00:40 $ + * $Date: 2007/03/26 03:20:31 $ * $Author: hachti $ * * $Log: tape_block.cpp,v $ - * Revision 2.0 2007/03/26 01:00:40 hachti + * Revision 2.1 2007/03/26 03:20:31 hachti + * *** empty log message *** + * + * Revision 2.0 2007-03-26 01:00:40 hachti * *** empty log message *** * * ******************************************************************************/ - - #include #include @@ -158,8 +159,8 @@ int tape_block::get_discarded_bytes(){ /*! *\brief Access internal raw data buffer * - * The raw data buffer contains all block data except the \ \ - * block start delimiter and block end delimiter. + * The raw data buffer contains all block data except the + * block start and end delimiters. *\return Pointer to internal raw data buffer of the block */ unsigned char * tape_block::get_raw_data(){ @@ -633,7 +634,7 @@ eof_legal_exception(int bytes_consumed){ /***************************************************************/ /*! *\brief Get amount of consumed data before EOF came along. - *\return Amound of bytes read from fd while looking for + *\return Amount of bytes read from fd while looking for * new block or EOF. */ int tape_block::eof_legal_exception::get_consumed(){ -- 2.32.0