home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ERRABORT.ZIP / ERRABORT.DOC < prev    next >
Text File  |  1989-09-11  |  10KB  |  216 lines

  1. =========================================================================
  2. errabort.c - A debugging tool for OS/2 programmers.
  3. =========================================================================
  4.  
  5. Description:
  6.  
  7. This DLL is to be called after first calling any OS/2 function and
  8. testing for expected return codes.  "Testing for expected return
  9. codes" means, for example, testing for zero (successful completion)
  10. IN EVERY CASE, and testing for errors that your program anticipates
  11. and has code to handle, such as "File not found" when calling
  12. 'DosOpen ()'.
  13.  
  14. Any other error return presumably is one that your program did not
  15. anticipate and cannot properly handle.  In that case, a call to this
  16. DLL will result in the display of an error message, and a termination
  17. of your program.  The error message includes your program's name,
  18. the name of the function within your program that made the call to an
  19. OS/2 function, the line number where the call to this program originated
  20. (which should be the line immediately following the call to the OS/2
  21. function that returned an unexpected error code), the name of the OS/2
  22. function being called, the number of the error code, and a message
  23. associated with the error code.
  24.  
  25. If you are not presently testing EVERY OS/2 function call's return
  26. value, then you may be surprised by some of the error messages (and
  27. program aborts) that calls to this program will give you.  I have
  28. found return codes that are not documented as being among those
  29. returned by certain functions, for example.  In other cases, return
  30. codes that I anticipated (such as 'ERROR_FILE_NOT_FOUND' and
  31. 'ERROR_PATH_NOT_FOUND' from 'DosFindFirst ()') were NOT returned;
  32. instead I got 'ERROR_NO_MORE_FILES' (it surprised me; maybe it
  33. wouldn't surprise you).
  34.  
  35. Since this program is a DLL, it is certainly cheap enough to include
  36. a call to it after every  OS/2 call, at least during debugging.  I
  37. modify the ERRCHK macro (included as part of this package) to
  38. conditionally generate code depending on the state of a global
  39. debugging flag, which makes it easy to remove the calls.
  40.  
  41. =========================================================================
  42.  
  43. Example output (produced by included program TEST.C):
  44.  
  45.     Test routine for 'errabort ()' has just begun.
  46.  
  47.     Unexpected error return 18 from OS/2 function "DosFindFirst ()".
  48.     "No more files"
  49.     Caller program:  "test".
  50.     Caller function:  "main".
  51.     Near line number:  32.
  52.  
  53. =========================================================================
  54.  
  55. Package contents:
  56.     ERRABORT.DOC    This file
  57.     ERRABORT.C      The complete source code to 'errabort ()'
  58.     ERRABORT        The makefile for 'errabort ()'
  59.     ERRABORT.DEF    Definition file to make a DLL
  60.     ERRABORT.OBJ    My compiled version of ERRABORT.C
  61.     DEBUG.DLL       The completed DLL containing 'errabort ()'
  62.     DEBUG.LIB       The IMPLIB containing 'errabort ()'
  63.     TEST.C          A program that illustrates how to use 'errabort ()'
  64.     TESTDBG         The makefile for 'test ()'
  65.     TEST.OBJ        My compiled version of TEST.C
  66.     TEST.EXE        My linked version of TEST.C
  67.     OS2LOCAL.H      '#include' file with function prototype and macros
  68.  
  69. =========================================================================
  70.  
  71. Instructions for using 'errabort ()' with your own programs:
  72.  
  73. (It may be helpful to print a copy of TEST.C and follow along in it;
  74. very experienced C and OS/2 programmers can probably get all they need
  75. from just that code and the other sources alone, without reading this
  76. section.  However, don't be lured into doing that just to PROVE that
  77. you are a very experienced C and OS/2 programmer ...)
  78.  
  79. You must '#include' the supplied file 'OS2LOCAL.H' in each program that
  80. will call 'errabort ()'.  You can of course rename OS2LOCAL.H to
  81. whatever you like, or you can simply incorporate its contents into
  82. your own usually-included local file.  OS2LOCAL.H has the function
  83. prototype for 'errabort ()' that will be needed by your program, and
  84. it has the 'ERRCHK ()' macro that automates calling 'errabort ()'.
  85.  
  86. The 'ERRCHK ()' macro looks like this:
  87.  
  88.     #define ERRCHK(os2name)    if (usRC != 0) { \
  89.         errabort (pszProgramName, #os2name, \
  90.                   pszFunctionName, __LINE__, usRC) ; \
  91.                }
  92.  
  93. You must have the following data elements defined in your program, using
  94. the same data type and name (unless you change the macro):
  95.  
  96.     PSZ pszProgramName ;
  97.     PSZ pszFunctionName ;
  98.     USHORT usRC ;
  99.  
  100. I declare 'pszProgramName' as a static global, initialized to my program's
  101. name, just for safety; however, I then change it to point to 'argv [0]',
  102. to get the actual execution name.
  103.  
  104. 'pszFunctionName' is declared as a static variable within each function
  105. that might call 'errabort ()', initialized to the name of the function.
  106. 'errabort ()' itself supplies '()' when it prints the error message, so
  107. you can save a little static string space by omitting the parentheses.
  108.  
  109. 'usRC' is used as the target of every call to an OS/2 system function,
  110. to receive the return code.  After calling the OS/2 function, test
  111. 'usRC' for the values that your program is set up to expect and handle,
  112. then write 'ERRCHK (OS2FunctionName)' as the next statement.  Note that
  113. the 'ERRCHK' macro is defined in such a way that you can code it either
  114. as if it is a macro, or as if it is a function call (that is, you can
  115. include or omit the terminating semicolon).
  116.  
  117. The '__LINE__' preprocessor variable used by the macro may not be
  118. available to you, depending on how old or how lousy your compiler is;
  119. Microsoft C 5.1 has it, as did (I believe) 5.0.  If it is not available
  120. to you, you will have to change the macro and ERRABORT.C, an exercise
  121. left to the reader.
  122.  
  123. You may also note that 'ERRCHK' does NOT call 'errabort ()' if 'usRC == 0';
  124. thus, you can simply add the 'ERRCHK' macro after every one of your
  125. existing OS/2 function calls, and it will be benign unless you have
  126. an error that you had previously not known about.
  127.  
  128. Finally, you may wish to change 'ERRCHK' to do nothing at all unless you
  129. have '#define'd some global debugging variable.  In fact, the 'ERRCHK'
  130. that I actually use looks more like this:
  131.  
  132.     #if defined FULL_ERRCHK
  133.     #define ERRCHK(os2name)    if (usRC != 0) { \
  134.         errabort (pszProgramName, #os2name, \
  135.                   pszFunctionName, __LINE__, usRC) ; \
  136.                }
  137.     #else
  138.     #define ERRCHK(os2name)
  139.     #endif /* #if defined FULL_ERRCHK */
  140.  
  141. This way, your MAKE file can control the cautiousness of your code, and
  142. thus the quantity of code generated.  In practice, though, I have tended
  143. to let 'ERRCHK' generate the call even in "fully-debugged" programs,
  144. because the overhead is really very small, and because I have never
  145. yet been able to write a "fully-debugged" program that does more than
  146. 'HELLO.C' is capable of.
  147.  
  148. Experienced OS/2 programmers may also note that the ERRABORT.DEF module
  149. definition file does not specify an ordinal number as part of the
  150. 'EXPORTS' statement.  This was a deliberate choice on my part, because
  151. doing so precludes using BIND to create a family-mode application.
  152.  
  153. (Yes, I sometimes do that, in spite of the fact that in family-mode you
  154. lose all of the benefits that a DLL makes possible, the most obvious of
  155. which is that 'errabort ()' in family mode makes every program you write a
  156. total pig for memory and disk space.  It is useful for debugging even
  157. in that environment, though, and it is easily replaced with a routine
  158. that omits the text; alternately, it can be removed altogether for that
  159. mythical "fully-debugged" application, as described above.)
  160.  
  161. In actual practice, though, 'errabort ()' is just one member of a larger
  162. DLL that I use, and it does have an ordinal in that larger library.
  163. I hope that pointing this out doesn't cause any trauma for chronic
  164. decision-avoiders ... especially since it took me three days to decide
  165. whether to mention it or not ...
  166.  
  167. =========================================================================
  168.  
  169. Instructions for use of supplied files:
  170.  
  171. Before you do anything at all, read the source files and the make files
  172. carefully.  I am posting this collection of stuff to BIX, and I know
  173. that it is in good condition there.  However, it is folly to simply
  174. compile and execute ANYTHING you receive from any source outside your
  175. direct control, without first studying it to verify that it is benign.
  176. This particular program is extremely simple, but if you are unfamiliar
  177. with OS/2 and therefore find that it is not simple for you, have
  178. someone who is take a look at it.  (Not someone who is simple; someone
  179. who is familiar with OS/2.  Of course, becoming familiar with OS/2 can
  180. make you simple.  It worked for me.)
  181.  
  182. First, examine the MAKE files very carefully, to be certain that you
  183. are not going to write over some of your own important files.  In
  184. particular, note that the ERRABORT makefile will do a copy of its
  185. DEBUG.DLL and DEBUG.LIB output to a directory on the C: drive.  It
  186. works fine on my system, but it is highly unlikely that it is correct
  187. for yours.
  188.  
  189. After adjusting the MAKE files appropriately, simply do this:
  190.  
  191.         make errabort
  192.         make testdbg
  193.         test    (or 'cvp test' if you want to use CodeView)
  194.  
  195. (Note:  the sources were created using Brief, and tabs are set at every
  196. four spaces from 9 through 45.  This may help you in either editing or
  197. printing these sources.)
  198.  
  199. =========================================================================
  200.  
  201. This program with all its associated materials is explicitly placed into
  202. the public domain.  Feel free to use it, modify it, or incorporate it
  203. into your own programs, whether for your own use or for sale; in short,
  204. enjoy.  And if you have something of your own that is useful but was
  205. equally tedious to produce, please share it with the rest of us.
  206.  
  207. =========================================================================
  208. If you have questions or comments about this program, I am:
  209.  
  210. Author:  Wayne Kovsky               BIX:            wkovsky
  211.          Pinnacle Software          CompuServe:     76164,3504
  212.          299 Village Street
  213.          Millis, MA  02054
  214. =========================================================================
  215.  
  216.