Question
The time_calc program is executed as a command from the LINUX/UNIX command line. Its usage pattern is: time_calc conv time time_calc {add,subt,comp} time1 time2 where
The time_calc program is executed as a command from the LINUX/UNIX command line. Its usage pattern is:
time_calc conv time time_calc {add,subt,comp} time1 time2
where each of time, time1, and time2 is a "time value". A time value is either a number of seconds (an unsigned integer) less than 3155760000, or a "time specification". A time specification is a string of the form
n1y n2n n3d n4h n5m n6s
where n1 through n6 are unsigned integers (i.e. greater than 0). There can be arbitrary amounts of white space between the fields of a time spec (including none), but the fields must all be present, and must appear in the order given above. A time specification may also be called a "time spec". For a time spec to be legal or valid, n1 through n6 must be within the following bounds:
n1 < 100, n2 < 12, n3 < 31, n4 < 24, n5 < 60, n6 < 60
time_calc can perform five commands based on a "command keyword" given as the first argument:
convert between a number of seconds and a time spec (conv command);
add two time values and output the result as a time spec (add command);
subtract two time values (i.e. time1 time2) and output the result as a time spec (subt command); and
compare two time values and output a result string (comp command).
issue a help or usage message (help command).
In the case of comp, the program produces "greater" if time1 > time2, "equal" if time1 = time2, and "less" if time1 < time2. All output on successful operation is produced on the standard output.
time_calc diagnoses various potential errors with input or calculated results, and generates error messages on stderr. Input time values must be less than 3155760000 seconds, or a time spec of 99y11n30d10h30m00s. On add the resultant time value must be within these same bounds. On sub the resultant time value must be non-negative.
Internally, for converting between numbers of seconds and a time spec, the following conversion factors must be used:
seconds in a minute | 60 | |
seconds in a hour | 3600 | |
seconds in a day | 86400 | |
days in a year | 365.25 | |
days in a month | 30.4375 | |
seconds in a month | 2629800 | |
seconds in a year | 31557600 |
These numbers are reasonable approximations to the true values. (See note below.) The above numbers are simpler to work with than more modern values, and "close enough" for our purposes.
The limits on n1 through n6 and the conversion units above result in some ambiguity to time specifications. This is best illustrated by an example.
% ./time_calc cnv 0y11n30d10h30m0s 31557600 % ./time_calc cnv 31557600 1y 0n 0d 0h 0m 0s
We therefore define a "reduced time specification" to be one in which the number of years is maximized, and once that is done, the number of months is maximized. Output from add and subt commands is always a reduced time spec. The same is true for a conv command converting from a number of seconds. For example, converting 2629800 seconds to a time spec will produce 0y1n0d0h0m0s rather than 0y0n30d10h30m0s.
The files failing_cases_log.txt and succeeding_cases_log.txt that accompany this assignment specification are sample logs of a completed time_calc program in operation. Note that adequate system testing would go beyond the cases shown in these files. Also note that a student's error messages (on diagnosing an error) may be different than what is shown in these log files.
Assignment Requirements
For this assignment you must implement the following data types, functions, and unit tests for the functions in a single file called time_calc.c.
Data Types
You must implement the following data types:
bool same as an unsigned char data type. Two symbols or constants are associated with this data type, TRUE (value of 1) and FALSE (value of 0).
time_spec_t a struct for holding a time spec. It consists of six fields of type uint8_t. The fields hold the year, month, day, etc. of a time spec.
num_seconds_t the same as the uint32_t datatype.
Any and all types and constants supporting the two types above or the functions below that you think are required.
Supporting Functions
You must implement and make use of the following functions. In each case, the function name is designed to be suggestive of the module's functionality. An additional statement is given to help explain the functionality. A partial function header is given sufficient to describe the input and return data types. Any functions with return type of time_spec_t * may return NULL on error.
bool is_legal_time_spec( char * ) return TRUE if the string given as the input argument is a valid time spec; otherwise produce diagnostic messages on stderr and return FALSE. Errors diagnosed include extraneous characters and field values exceeding limits.
bool is_legal_seconds( char * ) return TRUE if the string given as the input argument is a valid number of seconds; otherwise produce diagnostic messages on stderr and return FALSE. Errors diagnosed include extraneous characters and field values exceeding the limit on the number of seconds.
num_seconds_t string_to_seconds( char * ) return the number of seconds specified by the string passed as the argument to the function. The string is known to contain a valid "number of seconds" specification.
time_spec_t *string_to_time_spec( char * ) return a pointer to a dynamically allocated struct containing the fields of a time spec specified by the string passed as the argument to the function. The string is known to contain a valid time spec. If memory for the struct cannot be allocated, the function returns NULL.
time_spec_t *seconds_to_time_spec( num_seconds_t ) convert a valid number of seconds to a time spec, and store the fields of the time spec in a dynamically allocated time_spec_t structure. On success, a pointer to the newly allocated structure is returned. If memory for the struct cannot be allocated, the function returns NULL.
num_seconds_t time_spec_to_seconds( time_spec_t *) convert a valid time spec to the corresponding number of seconds and return that number of seconds.
void print_time_spec( time_spec_t *time_spec ) output a valid time spec on stdout.
bool get_time_arg( char *in_str, num_seconds_t *seconds_p ) the function returns TRUE if it was able to convert the string pointed to by in_str to a number of seconds. In this case the number of seconds is stored in the location pointed to by seconds_p. The string pointed to by in_str could be a time spec or it could specify a number of seconds. The function returns FALSE if it was not able to convert the string pointed to by in_str to a number of seconds; for example, the string was neither a legal time spec nor a legal number of seconds. It also returns FALSE if the number of seconds is not less than the limit of 3155760000. In the latter two cases an appropriate error message is generated on stderr. If the input pointed to by in_str is neither a legal time spec nor a legal number of seconds, then no operation should be performed on the location pointed to by seconds_p.
You may need other functions as well, depending on your program design. They will be in addition to the above supporting functions.
You will also need a function
int main( int argc, char *argv[])
that analyses the command-line arguments are calls appropriate functions to complete the functionality of time_calc.
Finally, code for the following function is already provided for you. Copy it into your time_calc.c file. You can modify it, if you wish, to output to stderr rather than stdout.
void usage( void ) { puts( "Usage: time_calc help" ); puts( " time_calc conv " ); puts( " time_calc {add,subt,comp} " ); }
Documentation
Internal documentation must be present throughout your time_calc.c source file. Make sure the comments are informative, clear, and attractively laid out.
Also prepare external documentation in the style of a "programmer's manual" or "reference manual" describing the program. Remember that this external documentation will be helping the marker understand your program. Therefore make sure it is clear, well-organized, and well-written. If the marker is confused and cannot understand what you have done, your grade may suffer accordingly.
In the external documentation students may end up repeating some of what they have as internal documentation. However, the internal documentation should be discussing each function, datatype, constant, and data structure in isolation (in a "local context"). The external documentation will give the opportunity to discuss a function, data structure, data type, or constants in a more global context, in relation to the other functions, data structures, data types, and constants, and how they all fit together into a completed piece of code. External documentation should also discuss design decisions made, assumptions made, or known limitations.
The external documentation may be in any of the following forms: (plain) text, RTF, HTML, or PDF. Other types of files, included MS Word files, are not acceptable.
Use an appropriate name for the file containing your external documentation. Make sure your name, student number, and NSID appear at the beginning of the file.
Compilation Instructions
Your program must compile, without errors or warnings, with the commands
gcc -Wall -Wextra -o time_calc time_calc.c
on tuxworld.
Testing
Perform system testing on your final time_calc program. That testing should go beyond what is shown in the files succeeding_cases_log.txt and failing_cases_log.txt (which were used to generate the logs mentioned much earlier in the "Functional Requirements" portion of this assignment specification). Devise a (system) test plan. In composing the test plan consider how the integration of the various aspects of the program can be tested, what test cases will be used, what those cases will exercise, and what the correct results should be. Pay particular attention to testing the functions within When running your tests, consider whether the results are what they should be.
Your final testing documentation should consist of either (1) a test plan and run logs, or (2) annotated test log(s) where the annotations describe your test plan.
Verification
The marker may confirm the output shown in your log files.
Notes
There are different measures of year length. For simplicity, we are using a Julian year, 365.25 days. There are also:
A Gregorian year, 365.2425 days.
A tropical year, which tracks the amount of time it takes to get from spring equinox to spring equinox about 365d, 5h, 48m, and 46s, or 365.242196 days. Another source says 365.242199 days. In both cases it works out to 31,556,926 seconds. A third source says 365d, 5h, 48m, 45s (365.24219 days) which is 31,556,925 seconds. Google says 365.242 days. Looks like Google doesn't know everything.
An anomalistic year, which is the number of days it takes for the Earth to return to its perihelion, the point at which it is closest to the sun. It works out to about 365.259636 days (365d 6h 13m 52.6s) per year.
A sidereal year, the amount of time it takes for the earth to return to the same position relative to the fixed (most distant) stars. This year is 365.256363004 days (365d 6h 9m 9.76s)
All lines in your time_calc.c file are to be no more than 80 columns wide. Also remember the class material material on not intermixing tabs and spaces when formatting with white space, and the utility ofexpand(1).
If you use the assert() macro and it causes your program to abort, you may get a "core dump" created. This is a file with a name of the form core.PID on LINUX, where PID was the PID of the process which executed an abort(). These files can be used for post-mortem debugging. However, they can also clutter up your directories. You may wish to "garbage collect" (delete) them.
You may (or may not) find the following C library functions of use in writing your code: fputs(3), fprintf(3), sscanf(3), strpbrk(3), strsep(3), strcmp(3), strchr(3), isdigit(3), atoi(3), atol(3), strtoul(3), and strtoumax(3).
Even though the due date for this assignment appears to be far in the future, do not put off getting started on this assignment. It may take you longer than you think, and assignment 4 (where you will be modifying your time_calc program, will be coming right on its heels.
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started