*** READ EVERYTHING BEFORE DOING ANYTHING ***
DUE DATE: THURSDAY SEPT. 20, 11:00:00 PM
For this assignment you will work in teams of two that you have
picked.
If you did not properly pick your partners, we assigned them to
you.
In order to complete this assignment you will be using a some of
the
functions from the UNIX "curses" library. A simple description
of the
curses library and how it makes terminal programs easy to write
is
provided below from:
http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Curses.html
There seems to be some problems with the above html page on some
browsers.
If you have problems go to the directory below to find other formats.
http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/
-----------------------------START OF EXCERPT--------------------------------
Many widely-used programs need to make use of a terminal's cursor-movement
capabilities. A familiar example is vi; most of its commands make
use of
such capabilities. For example, hitting the `j' key while in vi
will make
the cursor move up one line. Typing `dd' will result in the current
line
being erased, the lines below it moving up one line each, and the
lines
above it remaining unchanged.
A potential problem with all this is that different terminals have
different
ways in which to specify a given type of cursor motion. For example,
if a
program wants to make the cursor move up one line on a VT100 terminal,
the
program needs to send the characters Escape, `[', and `A':
printf("%c%c%c",27,'[','A');
(the character code for the Escape key is 27). But for a Televideo
920C
terminal, the program would have to send the ctrl-K character,
which has
code 11:
printf("%c",11);
Clearly, the authors of programs like vi would go crazy trying to
write
different versions for every terminal, and worse yet, anyone else
writing
a program which needed cursor movement would have to ``re-invent
the
wheel,'' i.e. do the same work that the vi-writers did, a big waste
of time.
That is why the curses library was developed. When you log on, you
have a
terminal type, in the environment variable TERM. The curses library
consists of a number of functions which your program can call.
Those
functions know the various cursor-movement character sequences
for a large
variety of terminals (this information is in the file /etc/termcap).
The
important implication of that is that your program does not have
to know
that information; it simply calls the curses functions, and those
functions will use your TERM value to check the /etc/termcap file
and then
send the proper cursor-movement characters.
For example, if your program wanted to clear the screen, it would
not
(directly) use any character sequences like those above. Instead,
it would
simply make the call
clear();
and curses would do the work on the program's behalf.
Here are some of the (curses) functions you can call:
initscr() -- REQUIRED; initializes the whole screen for curses
endwin() -- REQUIRED; resets the terminal, e.g. restores echo,
cooked (non-cbreak) mode, etc.
cbreak() -- read characters from keyboard as they are typed,
without waiting for carriage return; backspace
and other control characters (including the carriage
return itself) lose their meaning;
nocbreak() -- restores normal mode
noecho() -- don't echo the input characters to the screen
echo() -- restores echo
clear() -- clear screen, and place cursor in upper-left corner
move(int,int) -- move the cursor to the indicated row (top
row is 0) and column (leftmost column is 0)
addch(char) -- write the given character at the current cursor
position, overwriting what was there before,
and moving the cursor to the right by one
position
insch(char) -- same as addch(), but insert instead of overwrite;
all characters to the right move one space to the
right
delch() -- delete character at the current cursor position,
causing all characters to the right moving one space
to the left; cursor position does not change
char getch() -- read in one character from the keyboard
char inch() -- returns the character currently under the cursor
scanw(), printw() -- work just like scanf() and printf(), but
in a curses environment; avoid use of
scanf() and printf() in such an environment,
which can lead to bizarre results; note
that printw() [and scanw() if echo is on]
will do repeated addch() calls, so it will
insert, not overwrite
refresh() -- update the screen to reflect all changes we have
requested since the last call to this function
-----------------------------END OF EXCERPT---------------------------------
HOW TO BUILD YOUR PROGRAMS:
You may use C, lex/flex, and bison/yacc on this lab, though it
is
not required. (The majority if not all of it is easier using just
C.)
To build a program that uses the curses library you must compile
with the
curses.h file included and link the curses and terminalcap libraries
( -lcurses -ltermcap ). The termcap is critical because it provides
the specific ways the terminal your machine has works to the curses
library.
We expect your program to compile without warning with the following
compile
line.
You will be making an executable called "smd". This stands for Signature
Manager Deluxe. Here are a couple examples how you might you might
compile. Replace <sources> with the names of your .c files.
ACME:
gcc -L/usr/lib/ -o smd -ansi -pedantic -02 -Wall <sources> -lcurses
-ltermcap
We will be telneting in from a NT box in the states cluster using
putty,
available at:
ftp://ftp.chiark.greenend.org.uk/users/sgtatham/putty-latest/putty.exe
If you decide to use lex/flex you must compile it to an object file
first
without the -ansi -pedantic -O2 -Wall and supply the lex.yy.o to
the above
command.
Compiling lex.yy.c to an object file: gcc -c lex.yy.c -ll
CORE DUMP RULE:
- If your program core dumps at all -5 (Not including the next
rule)
- Each stage your program core dumps in the points earned are cut
in half.
E.G. If you made 20 points in the section you get 10 points.
REGRADE POLICY:
- If you are unsatisfied with your grade first you must discuss
it with your
TA within 7 days of when your grade is posted. If you are still
unsatisfied and would like a regrade here is how regrades work.
- One of the senior TA's will regrade the assignment WITHOUT
ANY KNOWLEDGE OF YOUR GRADE OR WHAT POINTS WERE TAKEN OFF FOR.
The score
on the regrade is FINAL. This means you get the grade of the regrade,
not the higher of the two scores. If your assignment was graded
by one
of the senior TA's the other senior TA conducts the regrade.
TURNIN INSTRUCTIONS:
Turn in a makefile that compiles your code with NO WARNINGS when
we type "make" on acme in the workon environment. Any warning will
get
you a grande ol' grade of 0 on the assignment. Anytime your program
dumps core in an option, we will take half off for the rest of
that main
menu option.
See the top of this file for what to type to compile this. Use
all the extra warning flags used at the top of the file.
Make sure you AND your partner do getback. Make sure you test
your program thouroughly. We expect your user interface to be free
of
defects, especially ones that cause the program to core.
This program is supposed to compile down to an exe called "smd".
Please do this.
One member of your group is to turn in your work via JAWS turnin.
You must include all of your source code and your makefile, and
your file
called .sigmanagerdeluxe. However, ALL group members should run
getback
to verify that the lab was turned in successfully.
CURSES LIBRARY REFERENCES:
- On acme - man -s3x curses
-http://heather.cs.ucdavis.edu/~matloff/UnixAndC/CLanguage/Curses.html
-http://www.mor.itesm.mx/AIX/en_US/a_doc_lib/aixprggd/genprogc/curses.htm
OTHER REFERENCES BESIDE MAN:
-http://www.iu.hio.no/~mark/unix/unix_toc.html
-http://www.cs.cf.ac.uk/Dave/C/
Oooh Ooh....Random Numbers:
---------------------------
Okay, here is where we are going to learn about random numbers
in C.
There are funtions in stdlib.h called rand and srand. rand takes
no
params and will return a number between 0 and 2^15...which is around
32000. To use the rand function, you must have called the srand
function
since the invocation of the program. This means seed random. You
pass it
an integer. I usually just use the return value of time() when
I need a
seed, because it will be differnet for every program invocation
that does
not occur on the same second. Only call it once in the beginning
of the
program.
Look at the man page or at K&R if you have any more questions
about the function...here is a sample prog that shows off random
numbers.
I have made it only show numbers between 0 and 478.
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int num;
srand(time());
do
{
num = rand();
printf("Number: %d\n", num % 478);
}while(getchar()!='q');
return 0;
}
************************************
Here begins the project description:
************************************
Now you know everything that you need to know to do your assignment.
What would that assignment be? In senior design(cs3911), they have
you
find a customer so you have real world requirements rather then
arbitrary features thrown in for their pure educational value.
Well you are going to have a customer for this assignment, and that
customer is me.
If you look at my newsgroup postings, and emails that I send out,
you will
notice that my signature will change very often. The way my signature
varies is that it randomly appends a quote to the identifying information
that you need to know on the left.
| "Need to know(id)" |"Random Quote (quote)"
V V
Michael James Langford| If you risk nothing,
random@cc.gatech.edu | then you risk everything.
(404) 733-6844 | --Geena Davis
cs2335 Program Dev. TA|
You are going to be writing a program to do this sort of thing.
My program
is a horrible example of software engineering (it was written during
office hours one week using shell scripts). You are going to do
this
program right. And yours will be prettier then mine.
So here is how the program will work:
You will type smd. It will bring up the following menu:
--------------------------------------------------------------------------------
.-------------------.
| SigManager Deluxe
|
'-------------------'
1. Edit/View Current Signature
2. Select New Signature
3. Edit Quotes
4. Edit Identities
5. Edit Settings
Q. Quit SigManager Deluxe
-------------------------------------------------------------------------------
And on this menu...you will make a little cursor that shows the
user what
he is selecting. This will be a little arrow that will look like
this:
->
This is a dramatazation of the arrow in action:
--------------------------------------------------------------------------------
.-------------------.
| SigManager Deluxe |
'-------------------'
-> 1. Edit/View Current Signature
2. Select New Signature
3. Edit Quotes
4. Edit Identities
5. Edit Settings
Q. Quit SigManager Deluxe
-------------------------------------------------------------------------------
Pushing the down arrow on the keyboard is to move the arrow down
one
option, and the resulting screen will look like this:
--------------------------------------------------------------------------------
.-------------------.
| SigManager Deluxe |
'-------------------'
1. Edit/View Current Signature
-> 2. Select New Signature
3. Edit Quotes
4. Edit Identities
5. Edit Settings
Q. Quit SigManager Deluxe
-------------------------------------------------------------------------------
Pushing the up arrow at the top will move the arrow to the bottom
menu
choice and pushing the down arrow on the bottom choice will move
the
arrow to the top choice.
Typeing the character before the period (e.g. '6' or 'Q') or moving
the
cursor to that selection and hitting return will make that selection
and
bring up the appropriate screen to do that feature. For directions
on
implementing each menu section, see the detailed section below.
Before we start though, I will give you the lowdown on the configuratrion
files that your program must maintain.
file: .quotes
This is a list of each filename that contains a quote, relative
to the users
home directory. This should be newline delimited(i.e. one file
per line),
with no other whitespace.
file: .quote
This is the currently selected quote
file: .id
This is the currently selected id box
file: .ids
This is the list of possible ids that the user can select from.
Newline
delimited, no other whitespace.
file: .sigmanagerdeluxe
This is the general-purpose file that you will store all the other
settings in. Some important settings are:
id width: How many characters do we show of the Ident box per line?
quote width: How many characters do we show of the quote per line?
sig height: How many lines long is the signature?
1. Edit/View Current Signature
-------------------------
This will bring up the current signature and display it to the
screen.
It will also display the bounding box. Here is the bounding
box:
.---------------------------------------------------------------------------.
|
|
|
|
|
|
|
|
`---------------------------------------------------------------------------`
This draws a box around a 4 X 74 area of characters.
The idea is that a signature of the type that we will be making
will fit
in the bounding box...the following would be what my sig might
look like.
The screen should look something like:
-----------------------------------------------------------------------------
.---------------------------------------------------------------------------.
|Michael James Langford| Absence diminishes mediocre passions and
|
|random@cc.gatech.edu | increases great ones, as the wind
blows
|
|(404) 733-6844 | out
candles and fans fires.
|
|cs2335 Program Dev. TA| --La Rochefoucauld
|
`---------------------------------------------------------------------------`
1. Edit Signature
-> M. Goto Main Menu
------------------------------------------------------------------------------
When you select the edit option, a cursor should appear in the upper
left
corner of the editable area. It should move similar to the one
in pico, up
when you push the up arrow, down when you push the down arrow,
etc. It
should NOT leave the interior of the bounding box. If the user
wishes to
save it, they should type Control-X, at which point a message box
should
pop up and say that the signature was saved. If they wish to revert
the
box to its prior state, they should type Control-C. Either one
should pass
control back to the menu after the user hits okay. You might wanna
print
that on the screen somewhere.
Just like in pico, when you hit a letter and your cursor is
already on a letter, the new letter should be inserted and the
rest of
the line should be moved over. Do not worry about keeping letters
that
are pushed past the end of the box they are allowed to type in.
You will
not be tested on their behavior.
2. Select New Signature
-----------------------
******You will do this part improperly unless you understand all
the later main menu options. Read the rest of the nfo
file before continuing********
-----------------------------------------------------------------------------
.-------------------------------------------------------------------------.
|Michael Langford | In the old days,
|
|random@cc | You could
have
|
|404 733-6844 | Lunch in your modem
|
|cs2335TA | --Vince
Stanford
|
'-------------------------------------------------------------------------'
1. Change ID
2. Change Quote
-> M. Goto Main Menu
------------------------------------------------------------------------------
Bring up a screen that looks like the above. Load the .id file
into the
left box of the above form. Selecting option 1 or 2 should bring
up a
list. The list should only be of the part of the filename left
of the
final slash from the .quotes file. The arrow should move to lists
of
quote or id files are. The first choice should be random choice,
formatted as in the diagram. If the user selects it, you should
randomly
choose a valid option from the list below and load it.
-----------------------------------------------------------------------------
.-------------------------------------------------------------------------.
|Michael Langford | In the old days,
|
|random@cc | You could
have
|
|404 733-6844 | Lunch in your modem
|
|cs2335TA | --Vince
Stanford
|
'-------------------------------------------------------------------------'
.-Choices:------------------------------.
| -> [Random Choice]
|
1. Change ID
| TouchyFeelyQuote
|
| Epititus
|
2. Change Quote
| ClubbingBabySeals
|
| ZenQuote
|
M. Goto Main Menu |
TorturingMusician
|
| [More...]
|
'---------------------------------------'
------------------------------------------------------------------------------
The up and down arrow will now move up and down the appropriate
list until a selection is made, when the user hits "return".
If there are more items then there are lines to display them, you
will up the phrase "[More...]" as the last option. If the arrow
is moved
down to that item, you will "scroll" that column up 5 names, placing
the
arrow on the first "new" item. You will also put "[More...]" as
the top
menu item that is displayed, indicating to the user that there
are more
options up. Once you have reached the vertical end of the list,
and the
user pushes down yet again, you will move the arrow all the way
to the top
of the initial list.
When a user makes a selection for either part, you should load
that id or signature into the appropriate field, move the arrow
back over
to the menu option that was selected, and erase the choices box
from the
screen. Afterwards the screen should look like:
-----------------------------------------------------------------------------
.-------------------------------------------------------------------------.
|Michael Langford | You risk everything
|
|random@cc | if you risk
nothing
|
|404 733-6844 |
|
|cs2335TA | --Geena
Davis
|
'-------------------------------------------------------------------------'
1. Change ID
-> 2. Change Quote
M. Goto Main Menu
------------------------------------------------------------------------------
If the user picks "[Random Choice]", randomly select an item of
the appropriate type, and load it into the appropriate box. Do
not load
an id or quote that has non-whitespace characters past the edge
of the
appropriate box in either the vertical or horizontal directions.
This
means if the Signature Height of the program is currently 4, don't
load a
5 line id into the ID box. Randomly select another 3 times, then
load
any signature, reguardless of size, cropping it to fit in the box.
When the user selects "M. Goto Main Menu", write the item in the
id field to the .id file, and write the item in the quote field
to the
.quote file.
3. Edit Quotes
--------------
This screen should be laid out like the prior screens have been,
with the box at the top and the menu options below. There should
be a box
surrounding an area of the size selected in the settings section.
The menu
options should be:
1. Add New Quote
2. Remove Quote
3. Edit Exsisting Quote
M. Return to Main Menu
Adding a quote will allow you edit the area bounded by the box in
a
manner similar to the way that you did for option 1 of the main
menu.
When you pick save, make a small box appear that allows you to
edit a
name. It should look something like:
.-Save to File:---------------.
|
|
'-----------------------------'
The user should then be able to type in the box until they hit return.
Left and Right arrows should work in the box. You may pick a place
for it
to appear on the screen, but don't put it somewhere it will overwrite
text that area is on the screen.
When this is added, you should add this filename to the file
called .quotes that is in the user's home directory. You should
get this
directory from the environment.
Remove quote should bring up the Choices box and allow the user
to select a quote to remove. This quote should NOT be removed from
the
disk, but the line it is in should be removed from the .quotes
file.
Edit Existing Quote should bring up the Choices box and allow the
user to select a quote. This quote should be loaded to the upper
box on
the screen, and the user should be able to edit it like in all
the other
screens that the uer can edit stuff on. ^c and ^x should be the
way the
user can exit the box, just like before.
4. Edit Identities
------------------
This should operate just like edit quote, except it should operate
on the
id field and the associated files.
5. Edit Settings
----------------
These are certain configuration variables that affect the running
of the
entire program. These should be stored in the .sigmanagerdeluxe
file.
These should be modifiable via this menu:
1. Change Signature Height
2. Change Identifcation Block Width
3. Change Quote Width
M. Goto Main Menu
For each, display the old value in the manner demonstrated below.
Do not
allow them to type anything but numbers in the new field. Return
to the
menu when they hit return. If they enter a value that doesn't make
sense,
leave the old value intact. The left and right arrows should function
in
the box.
Here is what the 2nd option might look like. Put these somewhere
on the screen they don't write over stuff.
.-Current ID Width:-.
| 17
|
'-------------------'
.-New Id Width:-.
|
|
'---------------'
Command line option
-------------------
SigManagerDeluxe has one command line option. That option is --random
or
-r. When this is given to the program, it will randomly select
an ID and
a quote, load them into the .id an .quote files, and make a signature
out
of them, with a vertical seperator of "|", and record this signature
into
the .signature file. The user interface will *not* be brought up,
and this
is all that will happen.
The file might look a little something like this:
Michael James Langford| The great man is he who does not lose his
child-heart.
random@cc.gatech.edu | He does not think beforehand that his words
shall be
(404) 733-6844 | sincere, nor that his acts shall be resolute;
he simply
cs2335 Program Dev. TA| abides in the right. --Mencius
OH NO!!! This looks hard!!!!
----------------------------
What, did you think that we would be playing around with RCS all
semester? I know that this is a BIG project. You have two weeks
to do it,
and with good design, its NOT that hard to do.
I really suggest making routines that do stuff like draw all the
boxes, make menus, and keep track of valid places for the arrow
to be.
You really might find yourself using more then one "window" as
far as
curses calls them, although there are perfectly vaild ways of doing
this
assignment that don't. ( I didn't use multiple windows while playing
around, and the other TA's haven't either, but Bob did it awhile
ago and
remembers it is possible).
Ending Notes:
-------------
If I find out that you put all your code in one file, I will
personally come in and make you eat your source code. Put conceptually
seperate code in seperate .c files, and expose the functions you
need via
.h files. Make the functions static that do not need to be called
outside
their file. Read a good C book if this paragraph looks like nonsense
to
you.
Turn in your source code, makefile, and .sigmanagerdeluxe file.
Note that this means all the other .files MUST meet our standard,
as
we are using OUR .quotes and .ids files, along with our own darn
quotes
to test this.
Up, down, left and right are three character codes, not just
one...attached is a neat little program I used to figure out what
they
are. Try pushing each direction while running the program.
Good luck...and don't hate me...I really am a nice man...and this
is nothing compared with what's coming in later labs. Start early.
I don't
plan on staying up late wednesday night before this is due answering
newsgroup posts.