Project Assignment - Part 0 Option and Argument Processing Due Date: by 6:00 PM on Friday, April 17, 1998 (Late programs will receive a grade of Zero) Purpose: This assignment is intended to provide a simple, intro- ductory "tour" of some of the features of the C language, and to give some examples of how they are used. In particular, it is intended to illustrate ways of dealing with some of the more troublesome and less easily understood aspects of the language. These would include the following topics: Topic Section Pages Type definitions 2.10 29 Enumerated Types 7.7 159-161 Dynamic Allocation 7.9.1 163-164 Strings 8.7 194-202 Pointer arrays 8.14 209-214 Structure arrays and pointers 9.2 228-234 Unions 9.8.2 247-248 A thorough understanding of all these topics is not really necessary to successfully complete this assign- ment. However, it is expected that sufficient time should be spent looking over the examples in the sup- plied code and in the book, as this will lead to a better understanding of these features when they are discussed in more detail later. Readings: Read the sections cited above, plus the information on Command Line Arguments (pp. 353-358). Also, look over the material on Dangerous Stuff (pp 207-208). Stub Code: The sample code (which can be compiled to create a functional program) should have been unpacked along with this document. Here are the names of the files in the archive and descriptions of their contents: 0README.ps this file (PostScript version) 0README.txt this file (text version) Makefile rules for compiling this assignment defs.h header file for #includes, typedefs, macros, etc. options.c source code for option processing functions optmain.c the "main" function for this assignment In addition to the above, the following executables can be found in the ~cs2430/pub/fsh/bin directory: jkg_showopts executable version of the final production code showopts executable version of the original (as distributed) code. The optmain.c routine will be used to drive the func- tions you write as part of your submitted code. Your files you turn in will be recompiled with a different optmain.c for the purposes of testing and grading. Make sure that you do not change any of the function proto- type declarations within optmain.c - these define the interface that is expected from your routines. _____________________________________________________________ | Programs that do not compile as a result of modifications | | to the supplied prototype definitions will be considered | | "uncompileable" programs and will be graded accordingly. | |___________________________________________________________| You are encouraged to devise more stringent and exhaus- tive test suites to make sure that your program works, but don't assume that your program is working correctly just because it matches the output from the production version. Your grade will be based on how well your program performs when compiled with the grader's version of optmain.c. Modifications: Make the following modifications to the existing ver- sion of options.c: 1. Add a function with the following prototype: void SetOpt ( char OptChar ) This function will search the OptArgs array to find an entry whose OptChoice matches the supplied OptChar. If no matching entry is found, then a new OptChar entry is created at the first empty slot in the OptArgs array. Once the supplied OptChar entry has been found (or created, as appropriate), then the OptFlag is SET for that entry. If the supplied OptChar is invalid, then no action is taken. 2. Add a function with the following prototype: void UnsetOpt ( char OptChar ) This function will search the OptArgs array to find an entry whose OptChoice matches the supplied OptChar. If a matching entry is found, then the OptFlag is UNSET for that entry. If no matching entry is found, then no action is taken. 3. Add a function with the following prototype: int GetOptState ( char OptChar ) This function will return the current state of the OptFlag for the supplied OptChar. If the supplied OptChar is not found in the OptArgs array, then GetOptState returns a value of UNSET. 4. Add a function with the following prototype: char * GetOptString ( void ) This function will return a pointer to a string that contains all the individual OptChoice characters for which OptFlag is SET. If no OptFlag values are set, then GetOptString ( ) returns a pointer to an empty string. The option string must be stored in a private data area within your GetOptString ( ) function. Do not malloc ( ) space for this string - just re-use the private data area and update its contents appropriately each time that GetOptString ( ) is called. (if you have not done so already, please read the section of the Weiss book on Dangerous Stuff). 5. Add a function with the following prototype: char * GetArgString ( int ArgNum ) This function returns the entry in the argument list given by ArgNum (the array of argument string pointers is pointed to by the OptList field in OptArgs[ 0 ]). If the requested ArgNum is out of range for the number of arguments stored in the list, then GetArgString ( ) returns a pointer to an empty string. 6. Add a function with the following prototype: char * GetArgCount ( void ) This function returns a pointer to a string that represents the number of arguments in the argument list (the array of argument string pointers is pointed to by the OptList field in OptArgs[ 0 ]). The count string must be stored in a private data area within your GetArgCount ( ) function. Do not malloc ( ) space for this string - just re-use the private data area and update its contents appropri- ately each time that GetArgCount ( ) is called. (if you have not done so already, please read the sec- tion of the Weiss book on Dangerous Stuff). 7. Modify the main while loop in the ProcessOpts ( ) function so that it calls your SetOpt ( ) function to update the OptArgs array. Extra Credit: For 10% extra credit on this part only, add a function with the following prototype: static void InitOpts ( void ) This function should be called once from within the ProcessOpts ( ) function, and is used to initialize any sort of application specific "dependencies" that may be required for the other parts of the project. For this part of the project, you must add code to handle the following cases: 1. If the "basename" of your executable name starts with the `-' character, then the `i' option must be set. The basename is that portion of the executable name that comes at the end, exclusive of any path component that may precede it (i.e. the basename of a command that was invoked as foo/bar/baz would be baz). 2. If the `i' option has been set (either directly from the command line, or indirectly from the "basename" rule), then the `H' option must also be set.