JMU CS 239 - Spring 2010

Hello, World - Revisited

See UPDATE log

Background

Most likely, your first program was some variant of Hello, World, in which you printed a message.  In this variant, you will print Hello World, but your application will take in command line arguments to alter how this message will print.  In addition, you will build a tool that can be used for all programs accepting Unix-like command line arguments.  

Specifically

The Hello program outputs a hello message. The default is for the program to output Hello World. to System.out. If one or more data command-line arguments are specified, those arguments replace "World" in the message. For example,

java Hello Professor Harris
outputs Hello Professor Harris..

The Hello program recognizes the following flags.

u   Output the message in all uppercase.
e   Output the message to System.err.
x   Terminate message with a exclamation point instead of a period.
c Color   Output message in color Color, where Color is one of the digits 0 to 7. Those digits represent the following colors: 0=black, 1=red, 2=green, 3=brown/yellow, 4=blue, 5=magenta, 6=cyan, and 7=white. This feature only works on Linux, it will not work on Windows XP/Vista.

Error Messages

  1. If the program is called with improper command-line arguments, the ArgsChecker printError method (see stubbed out ArgsChecker) should be used to output the appropriate error message to System.err and exit.
  2. If the command-line arguments are of proper form, but the value of the Color parameter is specified and is not a digit 0 to 7, output the error message Usage error: Invalid Color parameter "%s", the Color parameter must be a digit 0 to 7.\n(where the %s is replaced with the actual Color parameter) to System.err and exit.

Notes

Existing Components

The following drivers are provided for you to test the components of the system as you implement them. 

Build.java - This has been partially built for you.  You may add additional tests as you find necessary.  See suggested approaches below.

Check.java - This utility program will provide you with expect methods to compare the results of your test and expected results.  You will need this to compile Build.  Feel free to add the Check methods to the Toolkit class that you made in CS 139 (if you attended our CS 139 class).

New Components

The ArgsChecker class: You must write an ArgsChecker class which will create a specific instance of an ArgsChecker object specific to the program at hand, and check the argument list for valid command line arguments for this application.  It should print appropriate error messages if the argument list is invalid.

Use the following stubbed out class as a starter.  ArgsChecker.java.

The Hello class: You must write a Hello class which will instantiate an ArgsChecker object initialized specifically for Hello, and then display the Hello World message altered as shown above.

Process Issues

A Suggested Process - As always, you should work on one piece of the application at a time and carefully test each piece before moving on to the next.
  1. Understand the problem (Part 1).  While we have worked some with Linux in the CS 139 labs, we have not really delved into what the standard Linux command arguments look like.  Be sure that you review the linux command-line argument convention document and complete the linux command-line argument homework before proceeding with this problem.  Do not focus on understanding the arguments for this problem, as ArgsChecker will be used throughout the semester.
  2. Understand the problem (Part 2).  Get to know the materials that have been provided for you.  The ArgsChecker class provides some of the error output for you and some of the data structures that you will use.  Some highlights:
    1. The simpleFlag and paramFlag are arrays and should be built to 128 elements.  Each element corresponds to one of the characters that are possible flag values (plus some other unused space).  The array indices will represent the character values (since as you recall, the character data type is implemented as an integer value), since characters can be used as indexes.  So the flag 'x' would be found in the xth position of the array.  
    2. The values stored in the arrays are character strings describing that flag's usage.  These values are used in the printHelp method which is provided to you.
    3. The flagsUsed array will be set in a corresponding fashion to the flags, but instead of a String value, the array holds integers.  If a flag is used with a particular application run, the value of that flag's array element is set to the argument index in which it is found (recall that one argument might hold multiple flags).  The argument number is important in the case of parameterized flags in that the next argument will always hold the data value for that argument.
  3. Below are recommended steps for implementing main and ArgsChecker. You can work on main first and then do ArgsChecker, you can work on ArgsChecker first and then do main, or you can switch back and forth between the two. But work on the individual steps within main and ArgsChecker one at a time. If you do not follow this procedure and run into trouble writing your programming assignment, do not expect the professors or teaching assistants to help you.
    1. Main 
      1. Write a version of the program ignoring command-line flags. Just have it output Hello World. if no command-line arguments exist, or replace "World" with the command line arguments if command-line arguments exist. If the program is called with java Hello Professor Harris, it would output Hello Professor Harris.. If the program is called with java Hello -u Harris, it would output HELLO HARRIS..
      2. When ArgsChecker is complete, you will use ArgsChecker to provide information about the command-line arguments. But at this point, we can write main without using ArgsChecker at all. In Hello, change the previous version of main (if necessary) to have a variable that contains the index of the first data argument. Set that variable to 2. Have the rest of the code refer to that variable in the command-line argument array as the start of the data arguments. Now if your program is called with java Hello arg1 arg2 arg3 arg4, it would output Hello arg3 arg4.. If your program is called with java Hello -u -x Harris, it would output HELLO HARRIS!.
      3. Experiment with different values for your variable. Set the variable to 0 for now.
      4. Create a boolean variable that indicates if the e flag is set. Adjust the program so it generates the correct output depending on how that boolean variable is set. "Hardcode" the variable to be true or false to test your code. (For now, you will not use a command line argument command-line argument to set this flag; your program outputs to System.out or System.err depending on whether or not you assigned the variable to be true or false.)
        • Normally, output to System.out and System.err both are sent to the terminal screen. So how do you know if your program is working correctly? From the command-line (this has to be done from the Linux or DOS command line, it will not work in jGrasp), run you java program with its standard and error output "redirected" to different files (instead of going to the screen). This is done by adding the following to the end of the command line: >filename1 2>filename2. Your program's System.out output will be sent to the file whose name is whatever you specified for filename1 and your program's System.err output will be sent to the file whose name is whatever you specified for filename2. Thus, the command java Hello redirect test >norm.txt 2>err.txt would send no output to the screen, System.out would be found in file norm.txt and System.err would be found in file err.txt. Note that the redirection arguments are NOT sent to your program in the string array passed into main. So the command java Hello redirect test >norm.txt 2&gt2>err.txt would result in main's string array parameter having only two elements, "redirect" and "test". So your code cannot include the redirection arguments in what it outputs (which is as it should be) because it never "sees" those arguments.
      5. Repeat the previous step but for a boolean variable that indicates if the u flag is set.
      6. Repeat the previous step but for a boolean variable that indicates if the x flag is set.
      7. Create an int variable that indicates the index of an argument that specifies a color. If that variable is not negative, have your program check the zero'th command-line argument as a color parameter and generate output appropriate for that color. Be sure to include outputting an error message if the string is not a one character string with its zero'th character being one of the digits 0 to 7). Test your program with this variable set to -1 and with the variable that specifies the index of the first data argument (from step B/C above) set to 0. Test your program with this variable set to 0 and with the variable that specifies the index of the first data argument set to 1. In this case, you will execute your program with something like this java Hello 2 arg which would output Hello arg. in green (if run on Linux). (Note, this is not the way Hello will be called when flag argument processing is installed but it is how we can execute this preliminary version of Hello to test that it can output colors.)
      8. Experiment with your program with various settings of the four variables for the four flags.

    2. ArgsChecker
      1. Create a driver for testing ArgsChecker. The driver should have the testing method testArgsChecker and a main that calls the testing method. Such a driver to help you build ArgsChecker has been started: Build.java. (Note that Build uses Check so you will need a copy of Check.java to compile Build.  You can add the methods in Check to your Toolkit from last semester or to another utility program that you use.)
      2. Look at the code in testArgsChecker for testing the constructor. (You would normally have to create this code but we have already done this for you.)
      3. Implement the constructor. Compile ArgsChecker.java, Build.java, and Check.java. Run Build and verify it passes the tests in testArgsChecker.
      4. Add code into the testing method for testing addSimpleFlag. (This has already been done for you.)
      5. Implement the addSimpleFlag method and test with Build.
      6. Add code into the testing method for testing addParamFlag. (This has already been done for you.)
      7. Implement the addParamFlag method and test with Build.
      8. Add code into the testing method for testing isSimpleFlag. (This has already been done for you.)
      9. Implement the isSimpleFlag method and test with Build.
      10. Add code into the testing method for testing isParamFlag.
      11. Implement the isParamFlag method and test with Build.
      12. Add code into the testing method for testing checkArg. This step is more complicated than previous ones. You will need to construct in Build one or more arrays of strings to use in your test cases. You might also need to create more ArgsChecker objects. You will need to test not only that the method makes the appropriate changes in the state of the ArgsChecker object, but also that it returns the appropriate value. On the otherhand do not make this more complicated than it needs to be. The checkArg method only checks ONE argument.
      13. Implement the checkArg method and test with Build. To test with build, you must temporarily change the method from private to public. In our opinion, this is the most difficult method to implement.
      14. Add code into the testing method for testing checkArgs.
      15. Implement the checkArgs method and test with Build. Note that the method checkArg does most of the work for checkArgs.
      16. Comment out (do not erase) the lines in Build that use checkArg and set checkArg back to being private.
      17. Add code into the testing method for testing getBadFlagLetter.
      18. Implement the getBadFlagLetter method and test with Build.
      19. Add code into the testing method for testing getFlag.
      20. Implement the getFlag method and test with Build.
      21. Add code into the testing method for testing getStatus.
      22. Implement the getStatus method and test with Build.

    3. Modify main to use ArgsChecker.

Due Dates

This program is due by Monday February 1, 11pm in submit.  Hardcopy is due in class on Thursday February 4.  Your pdf report should only include Hello and ArgsChecker, but you should print a text copy of your Build program.  The late penalties are as follows.

If submitted after 2/1/2010 but before this date at 11pm:
2/2/2010 - 5pts
2/3/2010 - 15pts
2/4/2010 - 25pts
2/5/2010 - 35pts
2/7/2010 - 45pts
2/8/2010 - 100pts

Grading Scheme

You will receive 70% of the credit for a successful submission run implementing ArgsChecker according to specifications.  You will receive 10% of the credit for adequately testing your components in the Build.java program.  The final 20% will be based on your conformance to good coding practice and to your instructor's standards.

Honor Declaration

This as well as all other work for this course must conform to the JMU Honor Code.  For this assignment, you may get help ONLY from the instructor for your sections, the textbook or other reference book, or from any TA assigned to CS 139 or CS 239.  Help from a TA must be acknowledged in the references section of the Hello program.  

Update Log

Date Description of change or clarification
01/20/2010 Clarification - If a parameterized flag has an error, either it is not the last character of the argument or there is no data argument following it, you should return the index of the argument in which the flag is found.
01/20/2010 ArgsChecker.java - Added a statement to the @return of the checkArgs method to indicate that if there are no data parameters, checkArgs should return a -1.