Corning Community College
CSCS1730 UNIX/Linux Fundamentals
~~TOC~~
======Project: INFORMATION REFERENCE TABLE (irt0)======
=====Errata=====
* any bugfixes or project updates will be posted here
=====Objective=====
To create a script that can, with information provided by the user, display useful reference data.
=====Background=====
We've encountered many things in our UNIX journey so far, and have been readily building upon past experiences as we achieve newer and better successes. Of particular focus, we've been looking at shell scripting, and that will be the primary focus of this week's project.
There are collections of information quite useful to anyone journeying in a discipline, and computing is no different. We often encounter information represented in certain units more than others, or various quantities, or even particular number bases.
====binary/octal/hex====
One particular collection of information involves that of binary, octal, decimal (in signed and unsigned capacities) and hexadecimal numbers. We may encounter a tool that gives us information in octal and we need to feed it into another tool as binary or decimal; these sorts of transactions are common and crop up time and time again.
Having a strong handle on this information is vital for on-going success in the computing field.
As such, it is important to have close at hand the knowledge of the following number bases:
* base 2 (binary)
* base 8 (octal)
* base 10 (decimal, specifically signed and unsigned quantities)
* base 16 (hexadecimal)
While we don't need to have hundreds of values memorized, it IS a good idea to have a rather quick recollection of enough values that can be used for debugging purposes. The first 16 values of each of these is such a preferred range. Not only does it give us a range of information, but for the powers-of-two bases, can actually fit in and be propagated quite nicely with little added effort.
=====Process=====
It is your task to write a script that, when run without any arguments, produces the following table of information (and displayed/formatted in this very manner):
lab46:~/src/unix/irt0$ ./irt0
base 2 | base 8 | base10 | base16
----------+----------+----------+----------
0000 | 000 | 0 | 0x00
0001 | 001 | 1 | 0x01
0010 | 002 | 2 | 0x02
0011 | 003 | 3 | 0x03
0100 | 004 | 4 | 0x04
0101 | 005 | 5 | 0x05
0110 | 006 | 6 | 0x06
0111 | 007 | 7 | 0x07
1000 | 010 | 8 | 0x08
1001 | 011 | 9 | 0x09
1010 | 012 | 10 | 0x0A
1011 | 013 | 11 | 0x0B
1100 | 014 | 12 | 0x0C
1101 | 015 | 13 | 0x0D
1110 | 016 | 14 | 0x0E
1111 | 017 | 15 | 0x0F
lab46:~/src/unix/irt0$
Additionally, your script should take the following arguments (in this order):
* $1- starting value (some value greater than or equal to 0, and below ending value)
* $2- ending value (some value higher than starting value)
* $3- display signed decimal (with the parameter "signed")
Numerical arguments are to be given in decimal.
If provided, they should adjust the script's output accordingly.
Some additional constraints/assumptions you can make:
* octal values MUST have at least 1 leading zero; that is the standard convention for displaying numbers in that base (to help distinguish them from decimal)
* hexadecimal values start with a leading "0x" prefix, this is among the more common ways of showing a hex value; also, the "lettered" digits for this project must be **UPPERCASE**.
* the maximum upper limit you can implement for is 255 (base 10), or **0xFF** hexadecimal. This will keep your output tidy (you're welcome).
====Only specifying starting value====
In the event only the starting value is specified, assume a count of 16 (so display 16 values, starting at the starting value). Note that for binary and octal, all numbers should be displayed in a block, so if an additional place value comes into the picture, leading zeros must be visible on the preceding values.
For example:
lab46:~/src/unix/irt0$ ./irt0 12
base 2 | base 8 | base10 | base16
----------+----------+----------+----------
01100 | 014 | 12 | 0x0C
01101 | 015 | 13 | 0x0D
01110 | 016 | 14 | 0x0E
01111 | 017 | 15 | 0x0F
10000 | 020 | 16 | 0x10
10001 | 021 | 17 | 0x11
10010 | 022 | 18 | 0x12
10011 | 023 | 19 | 0x13
10100 | 024 | 20 | 0x14
10101 | 025 | 21 | 0x15
10110 | 026 | 22 | 0x16
10111 | 027 | 23 | 0x17
11000 | 030 | 24 | 0x18
11001 | 031 | 25 | 0x19
11010 | 032 | 26 | 0x1A
11011 | 033 | 27 | 0x1B
lab46:~/src/unix/irt0$
====Specifying starting and ending value====
We can adjust the range displayed by specifying an ending value as well:
lab46:~/src/unix/irt0$ ./irt0 37 42
base 2 | base 8 | base10 | base16
----------+----------+----------+----------
100101 | 045 | 37 | 0x25
100110 | 046 | 38 | 0x26
110001 | 047 | 39 | 0x27
101000 | 050 | 40 | 0x28
101001 | 051 | 41 | 0x29
101010 | 052 | 42 | 0x2A
lab46:~/src/unix/irt0$
With a specified starting/ending value pair, we can display as little as 1 value and (theoretically) as many as we want.
====Specifying signed column====
With the word "signed" given as the third parameter (ie starting and ending values are required), the following will occur:
lab46:~/src/unix/irt0$ ./irt0 2 14 signed
base 2 | base 8 | base10 | signed | base16
----------+----------+----------+----------+----------
0010 | 002 | 2 | +2 | 0x02
0011 | 003 | 3 | +3 | 0x03
0100 | 004 | 4 | +4 | 0x04
0101 | 005 | 5 | +5 | 0x05
0110 | 006 | 6 | +6 | 0x06
0111 | 007 | 7 | +7 | 0x07
1000 | 010 | 8 | -8 | 0x08
1001 | 011 | 9 | -7 | 0x09
1010 | 012 | 10 | -6 | 0x0A
1011 | 013 | 11 | -5 | 0x0B
1100 | 014 | 12 | -4 | 0x0C
lab46:~/src/unix/irt0$
Signed values are how the computer represents negative numbers. The convention in common use is to reference the most significant bit (the left-most): if it is a 1, it is considered negative, and 0, it is positive.
The actual process of representing a number as a negative value is known as **two's complement**. In it, we invert the bits and add one.
For instance, if we had 4-bit values and we wanted to display a 1 as a negative value:
0001 <-- value
1110 <-- inversion of value's bits
+1 <-- adding 1
====
1111 <-- -1
=====Specifications=====
Evaluation will be based on correctness of values as well as on formatting/spacing.
You'll notice that everything lines up and is positioned similarly:
* each column exists within 8 characters of on-screen real estate, with one addition space padding the left and the right margins of the column.
* The values are right justified with each column, with all bases but decimal being exactly the same length (prepending leading zeroes if necessary)
* The dashes and vertical bars set up an ASCII art-like table pattern that helps make the data more readable.
* You are to manually print out no more than 2 consecutive spaces at a time in your output statements. If you need more, use one of the formatting tools to generate spaces for you.
* Obviously you'll need end results that occupy some sequence of spaces. The distinction I'm making is you're not to do stuff like: **echo " $value"**
* I suggest getting cozy with the **printf(1)** tool
* The signed functionality is **optional**; I will consider its implementation for extra credit. Implemented or otherwise, however, your script should not generate any errors should a third argument in proper form be given.
* You need to check your arguments to ensure they are present and valid. Some examples:
* starting value is a valid (whole) number, and it is greater than or equal to 0
* ending value is a valid (whole) number, and it is:
* greater than or equal to the starting value, AND
* less than or equal to 255
* signed third argument is just that, the word, present or not present
* any invalid arguments (invalid number, NOT the word **signed** as an optional third argument), should result in an error message being generated.
=====Submission=====
By successfully performing this project, you should have a set of task#.cli files (one for each task). You will want to submit these, along with a **upf1steps** file.
To submit this project to me using the **submit** tool, run the following command at your lab46 prompt:
$ submit unix upf1 upf1steps task*.cli
Submitting unix project "upf1":
-> upf1steps(OK)
-> task0.cli(OK)
-> task1.cli(OK)
-> task2.cli(OK)
-> task3.cli(OK)
...
SUCCESSFULLY SUBMITTED
You should get some sort of confirmation indicating successful submission if all went according to plan. If not, check for typos and or locational mismatches.
I'll be looking for the following:
78:upf1:final tally of results (78/78)
*:upf1:upf1steps submitted via submit tool [2/2]
*:upf1:upf1steps covers steps from copy until submit [4/4]
*:upf1:upf1steps squelches any STDERR output [4/4]
*:upf1:upf1steps only displays required STDOUT output [4/4]
*:upf1:task0.cli produces correct result [2/2]
*:upf1:task0.cli uses specified input_value [1/1]
*:upf1:task0.cli uses specified input_unit [1/1]
*:upf1:task0.cli solution in specified output_unit [2/2]
*:upf1:task0.cli solution using specified precision [1/1]
*:upf1:task0.cli solution using specified delimiter [1/1]
*:upf1:task1.cli produces correct result [2/2]
*:upf1:task1.cli uses specified input_value [1/1]
*:upf1:task1.cli uses specified input_unit [1/1]
*:upf1:task1.cli solution in specified output_unit [2/2]
*:upf1:task1.cli solution using specified precision [1/1]
*:upf1:task1.cli solution using specified delimiter [1/1]
*:upf1:task2.cli produces correct result [2/2]
*:upf1:task2.cli uses specified input_value [1/1]
*:upf1:task2.cli uses specified input_unit [1/1]
*:upf1:task2.cli solution in specified output_unit [2/2]
*:upf1:task2.cli solution using specified precision [1/1]
*:upf1:task2.cli solution using specified delimiter [1/1]
*:upf1:task3.cli produces correct result [2/2]
*:upf1:task3.cli uses specified input_value [1/1]
*:upf1:task3.cli uses specified input_unit [1/1]
*:upf1:task3.cli solution in specified output_unit [2/2]
*:upf1:task3.cli solution using specified precision [1/1]
*:upf1:task3.cli solution using specified delimiter [1/1]
*:upf1:task4.cli produces correct result [2/2]
*:upf1:task4.cli uses specified input_value [1/1]
*:upf1:task4.cli uses specified input_unit [1/1]
*:upf1:task4.cli solution in specified output_unit [2/2]
*:upf1:task4.cli solution using specified precision [1/1]
*:upf1:task4.cli solution using specified delimiter [1/1]
*:upf1:task5.cli produces correct result [2/2]
*:upf1:task5.cli uses specified input_value [1/1]
*:upf1:task5.cli uses specified input_unit [1/1]
*:upf1:task5.cli solution in specified output_unit [2/2]
*:upf1:task5.cli solution using specified precision [1/1]
*:upf1:task5.cli solution using specified delimiter [1/1]
*:upf1:task6.cli produces correct result [2/2]
*:upf1:task6.cli uses specified input_value [1/1]
*:upf1:task6.cli uses specified input_unit [1/1]
*:upf1:task6.cli solution in specified output_unit [2/2]
*:upf1:task6.cli solution using specified precision [1/1]
*:upf1:task6.cli solution using specified delimiter [1/1]
*:upf1:task7.cli produces correct result [2/2]
*:upf1:task7.cli uses specified input_value [1/1]
*:upf1:task7.cli uses specified input_unit [1/1]
*:upf1:task7.cli solution in specified output_unit [2/2]
*:upf1:task7.cli solution using specified precision [1/1]
*:upf1:task7.cli solution using specified delimiter [1/1]