21
edits
Changes
Created page with 'As your first assignment this semester, you are to write a multi-platform Set of Basic Input Output Functions (BIO) for direct terminal interaction and later use the BIO to creat…'
As your first assignment this semester, you are to write a multi-platform Set of Basic Input Output Functions (BIO) for direct terminal interaction and later use the BIO to create a text editor. Assignment One, like the main project is done collaboratively and is divided in two parts:
* Simple Functions
* Complex Functions
Each student must complete at least one of the Simple Functions individually and commit it to the repository and take part in the completion of at least ?? Complex Functions.
<br />
<span style="color: #FF0000; font-weight: bolder">
Note: There is a non-negotiable rule of a two character tab space, and NO use of the tab character (\t). You can find how to set these settings in the link below.
</span> <br />
[http://zenit.senecac.on.ca/wiki/index.php/How_to_set_up_tab_spaces How to set up tab spaces]<br />
<!--[http://zenit.senecac.on.ca/wiki/index.php/Changing_bg_color_brace_matching How to change the background color "Brace Matching" ]
<br />--><br />
= Basic Input Output Function Set V1.0=
== Due date ==
Due date: Sunday, October 17th at 11:59 PM
* Simple io functions due on "see you section wiki page"
** Create directories under branches named as your learn id.
** Branch trunk into your branches/learnID directory and start working.
* Complex io functions: due on "see your section wiki page"
== Tester Program and demo ==
=== [https://zenit.senecac.on.ca/svn/oop344/trunk/biotester.c biotester.c] ===
https://zenit.senecac.on.ca/svn/oop344/trunk/biotester.c
Userid: "oop344" Password: blank (no password)
===Demo===
* Use [http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe putty] only.
* In putty configuration change the settings of "terminal/keyboard" to "Xterm R6"
* Login to matrix and type:
<big>
$ ~fardad.soleimanloo/bio
</big>
== File Names ==
Save your work in bio.h for the header file and bio.c for the source of the '''''bio''''' functions.<br/>
The functions in bio.h all share the same prefix '''''bio'''''.
== Simple Functions (Platform dependent functions; conditional compilation)==
=== void bio_initscr(void) ===
Initializes the '''bio''' routines. Your application calls this function before calling any other '''bio''' function and this function is called only once before calling '''bio_endscr()'''.
=== void bio_endscr(void) ===
Shuts down the '''io''' routines and ensures that the cursor is not left in the middle of the screen, which may be partly filled with characters. Any application that has called'''bio_initscr()''' should call this function before terminating.
=== int bio_getrows(void) ===
Returns the number of rows on the screen.
=== int bio_getcols(void) ===
Returns the number of columns on the screen.
=== void bio_cls(void) ===
Clears the screen and leaves the cursor in the upper left-hand corner of the screen.
=== void bio_flush(void) ===
Ensures that any output sent to the screen is displayed on the screen (that is, this function flushes the output buffer).
=== int bio_getch(void) ===
Returns the virtual key code identifying the key pressed by the user. This function first displays all output that has been sent to the screen (if any is pending to be displayed), waits for a key to be pressed and returns an int value that uniquely identifies the key pressed. To accommodate platform dependency, define the following symbolic names for the <u>non-ASCII</u> keys in each platform:
* '''UP_KEY''' - the up arrow key value,
* '''DOWN_KEY''' - the down arrow key value,
* '''LEFT_KEY''' - the left arrow key value,
* '''RIGHT_KEY''' - the right arrow key value,
* '''PGUP_KEY''' - the Page Up key value,
* '''PGDN_KEY''' - the Page Down key value,
* '''HOME_KEY''' - the Home key value,
* '''END_KEY''' - the End key value,
* '''ENTER_KEY''' - the Enter key value,
* '''TAB_KEY''' - the Tab key value,
* '''BACKSPACE_KEY''' - the Backspace key value,
* '''ESCAPE_KEY''' - the Escape key value,
* '''DEL_KEY''' - the Delete key value,
* '''INSERT_KEY''' - the Insert key value,
* '''F1_KEY''' to '''F12_KEY''' - the function key value,
You must use platform-specific and <u>unique non-ASCII</u> values for the keys, and then you must use these specific symbolic names in your definitions.
=== void bio_movecur(int r, int c) ===
Positions the cursor at row '''r''' and column '''c''', where row 0 is the top row and column 0 is the left-most column. If either parameter is invalid, this function has undefined results. This function does not flush any output buffer.
=== void bio_putch(int c) ===
Displays the character '''c''' at the current cursor position and advances the cursor by one position to the right. If the cursor is already at the rightmost column of the screen, the advance is system dependent. This function does not flush any output buffer.
=== void bio_prnstr(const char* s) ===
Displays the null-terminated string pointed to by s starting at the current cursor position. This function leaves the cursor just after the last character displayed. If the string length exceeds the available space on the current line of output, this function has undefined results. This function does not flush any output buffer.
== Complex Functions (Platform independent functions) ==
=== void bio_display(const char* str, int row, int col, int len) ===
Outputs the null-terminated string pointed to by "str" on the screen starting at row "row" and column "col", up to "len" characters. As with bio_movecur(), 0 is the top row and 0 is the left-most column. If the string is longer than "len", then only "len" characters are displayed, but if it is shorter than "len", then the entire string is displayed left-justified in the field. However, if "len" is 0 or less, then the field length is considered to be the actual length of the string (i.e. the entire string is displayed). Afterwards, the cursor is positioned after the last character of the field. (Note that on systems where output is buffered, this function should not flush the output buffer). The results are undefined if the specified values indicate a field that does not fit on the screen.
=== Line Editor: int bio_edit(........) ===
<big>int bio_edit(char* '''str''', int '''row''', int '''col''', <br />
int '''fieldlen''', int '''maxdatalen''', int* '''insertmode''', int* '''offset''',<br />
int* '''curpos''', int '''IsTextEditor''', int '''ReadOnly''')</big>
<br />
Allows the user to perform full screen editing of the null-terminated string pointed to by '''"str"'''. The parameter '''"row"''' identifies the row of the screen for the field (0 is the top row), while '''"col"''' indicates the starting column of the field (0 is the left-most column). The parameter '''"maxdatalen"''' specifies the maximum length of the string '''"str"'''. The parameter '''"fieldlen"''' specifies the length of the field in which editing is to be performed (visible area of '''“str”'''). The pointer '''"offset"''' points to an integer holding the index of the first character of'''"str"''' shown in the field. The pointer '''"curpos"''' points to an integer holding the position of the cursor in the field (0 is the first position). '''"insertmode"''' is a pointer pointing to an integer flag that is true (1) for insert mode being on, or false (0) for insert mode being off.<br />
''If any of '''insertmode''', '''curpos''' or '''offset''' is <u>NULL</u> then a local integer variable will be used instead. If local variables are used for any of insertmode, curpos, or offset, the default values are: 1 ('''insertmode'''), 0 ('''curpos'''), and 0 ('''offset''')''
Editing begins with the display of '''"str"''' from where '''"*offset"''' is referring to, and the cursor will be standing at the position which '''"*curpos"''' is indicating.
NOTE: The following corrections should be done to '''"*curpos"''' and '''"*offset"''' in case they hold invalid values before editing begins:
# If '''"*curpos"''' is greater than or equal to the value of fieldlen, correct the '''"*curpos"''' so that cursor stands at the last position inside the field.
# If '''"*offset"''' is greater than the length of the string, set the '''"*offset"''' so the “last character of str” is hidden right before the first space in the field. (See '''“[[Iolib functions 20103 - OOP344#IsTextEditor:|IsTextEditor Section #1]]”''' for more)
# After the above, if cursor is past the last character of '''“str”''', set '''"*curpos"''' so the cursor stands right after the last character of "str".
The cursor is never allowed to be:
# before the start of the field.
# more than one position past the last character in the string.
# after the end of the field.
<u>Editing is terminated by pressing ENTER, TAB, UP, DOWN, PGUP, PGDN or any of the function keys (F1 to F12)</u>. Pressing<u>ESCAPE will terminate the bio_edit() and abort editing</u>: '''"str"'''will contain originally passed data when leaving function.
Note that the conditions of termination are changed if the '''“IsTextEditor”''' flag is true (non-zero). See '''“[[Iolib functions 20103 - OOP344#IsTextEditor:|IsTextEditor]]”'''section for detail.
If '''"ReadOnly"''' has a true value (non-zero), then any attempt to change the content of '''"str"''' should end the function and return the key. Note that all other keys should work (Function and Non-ASCII keys). This makes the '''bio_edit()''' funciton "read only", but the user still can scroll the text to left or right and etc....
The function returns an int identifying the key that was pressed to exit. (This function uses the same key codes as bio_getch())
The function takes no action if the user tries to enter too many characters (if, for example, the string is in full insert mode, or the cursor is positioned after the last character of a full string in overstrike mode). However, if the cursor reaches the end of the field and the string is not full, then after inserting, the character string will be scrolled to the left, positioning the cursor right after the last character in the string.
The function handles at least the following special keys:
* '''LEFT''' - move cursor left one character. If cursor is at the beginning of the field and there is hidden data before the cursor, then shift string to right instead.
* '''RIGHT''' - move cursor right one character. If cursor is at the end of the field but not at the end of the string, then scroll one to left.
* '''HOME''' – move cursor to the beginning of the string. Scroll all the way to right if necessary. (i.e. if there is hidden data at the beginning)
* '''END''' - go to the end of the data in the string, i.e. just past the last character in the string. Scroll all the way to left if necessary.
* '''DEL''' – eat the current character above the cursor and move all subsequent characters one position to the left.
* '''BACKSPACE''' - move the rest of the field (including the cursor) one position to the left, eating the previous character.
* '''TAB''':
** if '''IsTextEditor''' is false, TAB will simply terminate the function like a Function key
** if '''IsTextEditor''' is true, TAB will insert '''BIO_TAB_SIZE''' number of spaces into the string.'''BIO_TAB_SIZE''' should be a defined "tab size" value in bio.h. If '''BIO_TAB_SIZE''' spaces cannot be inserted into the string for any reason then the inputted tab should be ignored. (See '''“[[Iolib functions 20103 - OOP344#IsTextEditor:|IsTextEditor Section #2]]”''' for more)
* '''ESCAPE''' - Terminates bio_edit() and aborts editing: '''"str"''' will contain originally passed data when leaving function. (See '''“[[Iolib functions 20103 -OOP344#IsTextEditor:|IsTextEditor Section #3]]”''' for exception)
* '''INSERT''' - toggle Insert/Overstrike mode (toggles the value of *insertmode)
**<u>In Insert mode</u>, printable characters are inserted into the string, moving the remainder of the string to the right to make room.
**<u>In Overstrike mode</u>, printable characters overwrite existing characters (if any). Note that if you are past the end of the string, printable characters are appended to the string (as long as the string isn't full) regardless of the mode.
**Also note that, regardless of the mode, the cursor advances as printable characters are typed into the string.
**Finally, if the cursor is at the end of the field, instead of moving to right, the characters are shifted to left.
==== <big>IsTextEditor:</big> ====
'''[Section #1] IsTextEditor and *offset'''<br/>
If IsTextEditor is true, then it means that the function is being used to edit text by editing one line of text at a time. In this case, shifting a line to the left or right should not only cause the editing line to be shifted, but also the rest of the lines in the text. To do this, bio_edit() should let the calling function know that a shift has happened. Since shifting essentially means modifying '''“*offset”''' when '''“IsTextEditor”''' is true, and that there are times when you find that '''“*offset”''' needs to be modified, you should terminate the function afterwards. With termination, the function should return the terminating key.
Note that at the beginning of the execution of bio_edit(), validating '''*offset''' may require the value of '''*offset''' to change. If so, make sure to correct the offset and then terminate the function before any editing happens returning the default value of key.
'''[Section #2]'''<br/>
# The bio_edit() function always shows blanks in any the part of the field that is not occupied by the data in the string.
#<u>UNDER NO CIRCUMSTANCES DOES THE FUNCTION CHANGE ANY POSITION ON THE SCREEN OUTSIDE OF THE FIELD</u>.
'''[Section #3] IsTextEditor and ESCAPE KEY'''<br/>
# When '"IsTextEditor"' is true and ESCAPE KEY is hit, do not abort the editing, and simply terminate the function returning the ESCAPE KEY.
# If memory allocation for aborting the edit (ESCAPE KEY) fails, quit the function returning -1.
'''[Section #4] Others'''<br/>
# Any normal printable key is simply placed into the string according to the rules laid out in the discussion of the INSERT key above.(The keys from the space character to the tilde character in the ASCII table are considered "printable".)
# Like most C library functions, your bio_edit() may assume that it is the calling program's responsibility is to ensure that the array is large enough to handle the specified number of characters, and that the starting screen position provides enough room (on the screen) for the field, etc.
=== Selection Editor ===
==== void bio_displayflag(..........) ====
<big>void bio_displayflag(const char* '''format''', int '''row''', int '''col''', int '''status''');</big>
Allows the user to display a <u>checkbox</u> at '''row''' and '''col''' on the screen. Depending on the value of '''status'''; being zero or non-zero, the checkbox will be checked or unchecked respectively.
The checkbox will be always shown using 3 characters; two surrounding characters and one character in the middle as the checkmark. If the status argument is zero, then instead of the check-mark a space will be printed on the screen.
The 3 characters held in the '''“format”''' array; format[0] and format[2] are surrounding characters and format[1] is the check-mark.
The '''const char* format''' is used to specify the character used for the checkbox, so for example if the '''format'''argument is "[X]", then an ''unchecked'' checkbox will be<big><pre>[ ]</pre></big> and a ''checked'' checkbox will be<big><pre>[X]</pre></big>
After the checkbox is displayed, the cursor is always place under the check-mark (in centre).
==== int bio_flag(..........) ====
<big>int bio_flag(const char* '''format''', int '''row''', int '''col''', int* '''status''', int '''radio''');</big>
bio_flag() allows the user to make a single true/false selection. '''"status"''' points to the status of the selection, that can be zero or non-zero. If '''"*status"''' is initially set to anything but zero, bio_flag() corrects value to one.'''"format"''' holds the shape of the checkbox as bio_displayflag() function.
bio_flag() begins the selection by displaying the checkbox according to its '''“*status”'''. (Remember that the value of'''"*status"''' is corrected before the editing begins). Then the function waits for the user input.
* If the user input is any of the printable keys (' ' < key <= '~') excluding space, it should be ignored (no action taken). If the user input is any of the function keys, the function is terminated returning the key.
* If the user input is SPACE:
** If '''“radio”''' is true, then the '''"*status"''' is set to one, checkbox is displayed and function is terminated returning space.
** If '''“radio”''' is false, then the value of '''"*status"''' is toggled between 0 and 1, the checkbox is displayed and function is exited returning space.
==== void bio_displayMenuItem(..........) ====
<big>void bio_displayMenuItem(const char* '''format''', const char* '''menuItem''', int '''row''', int '''col''', int '''len''', int '''status''');</big>
Allows the user to display a menu-item at '''row''' and '''col''' on the screen with width of '''len'''. Depending on the value of '''status'''; being zero or non-zero, the menu-item will be surrounded by '''format''' characters or space respectively.
The '''menuItem''' argument will be always shown surrounded by two characters.
* <u>If status is zero</u>, then at '''row''' and '''col''' a <u>space</u> will be shown, then the '''menuItem''' followed by another <u>space</u>. If the length of '''menuItem''' is less than (len-2), then enough spaces will be printed up to make the length (len-2).
<pre>"Hello"</pre> with 10 as len will be printed as : <pre>" Hello "</pre>
* If status is non-zero, then at row and col format[0] will be shown then the menuItem and finally format[1].If the length of menuItem is less than (len-2), then enough spaces will be printed up to make the length (len-2).
<pre>"[Hello]"</pre> with 10 as len and <code>"[]"</code> as format chars, will be printed as :<pre>"[Hello ]"</pre>
After the Menu item is displayed, the cursor is always placed under the first character of menutItem. (position row and col+1)
==== int bio_menuItem(..........) ====
<big>int bio_menuItem(const char* '''format''', const char* '''menuItem''', int '''row''', int '''col''', int '''len''', int* '''status''');</big>
bio_menuItem() allows the user to make a single item selection. '''"*status"''' points to the status of the selection, that can be zero or non-zero. If '''"*status"''' is initially set to anything but zero, bio_menuItem() corrects value to one.'''"*format"''' holds the shape of the selection indicator as bio_displayMenuItem() function.
bio_menuItem() begins the selection by displaying the menu item according to its '''“*status”'''using [[#void io displayMenuItem.28...........29|bio_displayMenuItem()]]. (Remember that the value of '''"*status"''' is corrected before the editing begins). Then the function waits for the user input.
* If the user input is any of the printable keys (' ' < key <= '~') excluding space, it should be ignored (no action taken), and wait the user to input again.
* If the user input is any of the non-ASCII keys, the function is terminated returning the key.
* If the user input is SPACE, then the *status is set to one, menu item is displayed and function is terminated returning the ASCII value of space character.
== Suggested workload (task distribution) ==
* The following are suggested task distribution between team members
* Make a copy of the task distribution and add it to your project page, so I know who have done what
* When committing your work to svn, make sure comment the task you are working on
* You can exchange tasks between yourselves but make sure you have the changes reflected in your task distribution on your project page
* If anyone needs help doing their part, don't hesitate to give them hand in logic and coding and blog about the problem and how it was fixed
* If someone neglects to do their work or doesn't do the work on time , distribute his/her tasks between others, and send an email to me immediately. Those NOT doing the work will be fired from the group and have to do the project in a smaller scale alone.
* If there are questions to be clarified, book a meeting with me on IRC. (send me an email and put the time in IRC meetings table with (??) added to team name. I will put my Initials if the meeting is approved.
* If you believe I have overlooked any task or part, please add it here and I will take care of it:
=== Tasks missing ===
* No missing task so far
== Platforms ==
=== Windows Visual C++ ===
To Download Visual studio from [https://acs.senecac.on.ca/pages/download.php Seneca/ACS download page] Seneca students should first login using their Seneca account, click on MSDN and scroll down to the DVD Downloads subheading. Download the file "(Dual Layer) Visual Studio 2008 Professional Edition, MSDN Library for Visual Studio 2008 ".
(Note that the image does not include [http://www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&displaylang=en Service Pack 1])
Users also have the option of downloading Microsoft Visual C++ 2008 Express Edition from the[http://www.microsoft.com/express/download/ Microsoft Visual Studio Express Downloads page]. Users will eventually need to register the product, free of charge, in order to continue usage beyond the trial period. To register, open Visual C++, select 'Help' from the top tool bar and select 'Register Product'. Follow the instructions displayed on the screen and a registation key will be issued following successful registration.
<br/>
If you have other MS Visual Studio products (eg. Visual Basic) installed you may be asked to first uninstall them before installing the Visual C++ Express Edition.
==== Creating a Project for console application in Visual C++ 2008 ====
* Press '''Ctrl+Shift+N''' or click on '''File/New/Project'''
* In Project types select '''Visual C++/Win32''' and then in Templates select '''Win32 Console Application''' (Text Mode)
* In '''Name''' section Enter the desired name for the project
* In '''Location''' find/enter the directory in which you want the project created
* Un-check '''Create directory for solution'''
* Click on '''OK''' to set the '''Application Settings'''
** Click on '''Application Setting'''
** Check '''Empty Project''' and then click on '''Finish'''
You can now either add new files to the solution or add existing ones. If VC can't create a project, you might consider to reset your environment settings by calling "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe /ResetSettings".
=== Windows Borland C++ ===
Borland C++ Compiler 5.5 is a free version. You can download it from[https://acs.senecac.on.ca/pages/download.php ACS].
To install Borland C++ command line compiler on your computer first run the executable you downloaded to expand the compiler files into a directory.<br />
Say the installation is done in '''X:\Borland\BCC55''' <br />
Create a file called '''bcc32.cfg''' in '''X:\Borland\BCC55\Bin''' and add the following two lines to it:
<big>
-I"X:\Borland\Bcc55\include"
-L"X:\Borland\Bcc55\lib"
</big>
Create another file called '''ilink32.cfg''' in '''X:\Borland\BCC55\Bin''' and add the following line to it:
<big>
-L"X:\Borland\Bcc55\lib"
</big>
Then add '''X:\Borland\BCC55\Bin''' to the system path:<br />
Vista:
* Right-click on '''Computer''' and select properties.
* Click on '''Advanced System Settings''' on the left panel and the '''System properties''' will open with '''Advanced''' tag already selected
XP:
* Right-click on '''My Computer''' and select properties and the '''System properties''' will open
* Click on '''Advanced''' tag
Common:
* Click on '''Environment Variables''' Button
* In '''System Variables''' scroll down to '''path'''
* Select '''path''' and click on '''edit''' button
* Add ''';X:\Borland\Bcc55\bin''' to the end of the '''path''' value, click '''OK''' on all windows to close and you are done.
Compile your code as:
<big>
> bcc32 biomain.c bio.c
</big>
You must restart your computer for changes to take affect!
'''Happy Compiling!'''
=== Linux Gnu C ===
Many distro come with compiler pre-installed. If not, you can use the package manager tool (yum, apt-get, merger...) in your system to search for GCC, and install that package. Also, there are some useful tools that you may need, such as autoconf, make, ctag and etc.
Distro specified installation of compilers guilds:<br />
[https://help.ubuntu.com/community/InstallingCompilers Installing Compilers in Ubuntu]<br />
NOTE: Some compilers don't have the ncurses library. If you are getting a message that's something like this whenever you try to compile: <p><code>bio.c:51:21: error: ncurses.h: No such file or directory</code></p>It means you don't have it installed. You will need to install that library. Simply search for 'libncurses' in your Linux distro's package manager tool (yum for fedora and apt-get for Ubuntu, or simple go to Ubuntu's Software Centre and search for it) and install the latest development library, libncurses5-dev.
To compile using gcc issue the following command:<br />
<big>
gcc biomain.c bio.c -lncurses
</big>
or
<big>
cc biomain.c bio.c -lncurses
</big>
'''Also make sure you use [http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html Putty] for your telnet client and set the Temminal/keyboard / function keys to Xterm R6'''
=== Mac OS C++ ===
Mac OS, being a Unix base operating system, supports curses library. So if you follow the case study in the book (the one written for AIX)it should work on Mac too.<br />
<big>
cc biomain.c bio.c -lcurses
</big>
== How to submit your assignment ==
Close to the due date of the assignment, [https://zenit.senecac.on.ca/svn/oop344/trunk/biotester.c A tester program] called'''"biotester.c"''' will be released. This program uses your functions and does series of tests. Each test will use your functions to produce an output or perform an action. If all the output is produced or the action is performed as stated in the tester program, branch the trunk to tags under "Prj0.2". Then send me an email to checkout "Prj0.2" and mark it. latest commit to "Prj0.2" in tags indicates the time of submission and has to be before the due date/time.
Please make sure to include the project files (.vcxproj.filters & .vcxproj or .vcproj) so I can open your files easily.
<!-- To make Fardad's life easier, make sure to include the project files so he doesn't have to start a new project and add your code. --pbrown9 -->
=== Late Submission Penalty ===
10% Per day (Saturday and Sunday) counted as one day.
* Simple Functions
* Complex Functions
Each student must complete at least one of the Simple Functions individually and commit it to the repository and take part in the completion of at least ?? Complex Functions.
<br />
<span style="color: #FF0000; font-weight: bolder">
Note: There is a non-negotiable rule of a two character tab space, and NO use of the tab character (\t). You can find how to set these settings in the link below.
</span> <br />
[http://zenit.senecac.on.ca/wiki/index.php/How_to_set_up_tab_spaces How to set up tab spaces]<br />
<!--[http://zenit.senecac.on.ca/wiki/index.php/Changing_bg_color_brace_matching How to change the background color "Brace Matching" ]
<br />--><br />
= Basic Input Output Function Set V1.0=
== Due date ==
Due date: Sunday, October 17th at 11:59 PM
* Simple io functions due on "see you section wiki page"
** Create directories under branches named as your learn id.
** Branch trunk into your branches/learnID directory and start working.
* Complex io functions: due on "see your section wiki page"
== Tester Program and demo ==
=== [https://zenit.senecac.on.ca/svn/oop344/trunk/biotester.c biotester.c] ===
https://zenit.senecac.on.ca/svn/oop344/trunk/biotester.c
Userid: "oop344" Password: blank (no password)
===Demo===
* Use [http://the.earth.li/~sgtatham/putty/latest/x86/putty.exe putty] only.
* In putty configuration change the settings of "terminal/keyboard" to "Xterm R6"
* Login to matrix and type:
<big>
$ ~fardad.soleimanloo/bio
</big>
== File Names ==
Save your work in bio.h for the header file and bio.c for the source of the '''''bio''''' functions.<br/>
The functions in bio.h all share the same prefix '''''bio'''''.
== Simple Functions (Platform dependent functions; conditional compilation)==
=== void bio_initscr(void) ===
Initializes the '''bio''' routines. Your application calls this function before calling any other '''bio''' function and this function is called only once before calling '''bio_endscr()'''.
=== void bio_endscr(void) ===
Shuts down the '''io''' routines and ensures that the cursor is not left in the middle of the screen, which may be partly filled with characters. Any application that has called'''bio_initscr()''' should call this function before terminating.
=== int bio_getrows(void) ===
Returns the number of rows on the screen.
=== int bio_getcols(void) ===
Returns the number of columns on the screen.
=== void bio_cls(void) ===
Clears the screen and leaves the cursor in the upper left-hand corner of the screen.
=== void bio_flush(void) ===
Ensures that any output sent to the screen is displayed on the screen (that is, this function flushes the output buffer).
=== int bio_getch(void) ===
Returns the virtual key code identifying the key pressed by the user. This function first displays all output that has been sent to the screen (if any is pending to be displayed), waits for a key to be pressed and returns an int value that uniquely identifies the key pressed. To accommodate platform dependency, define the following symbolic names for the <u>non-ASCII</u> keys in each platform:
* '''UP_KEY''' - the up arrow key value,
* '''DOWN_KEY''' - the down arrow key value,
* '''LEFT_KEY''' - the left arrow key value,
* '''RIGHT_KEY''' - the right arrow key value,
* '''PGUP_KEY''' - the Page Up key value,
* '''PGDN_KEY''' - the Page Down key value,
* '''HOME_KEY''' - the Home key value,
* '''END_KEY''' - the End key value,
* '''ENTER_KEY''' - the Enter key value,
* '''TAB_KEY''' - the Tab key value,
* '''BACKSPACE_KEY''' - the Backspace key value,
* '''ESCAPE_KEY''' - the Escape key value,
* '''DEL_KEY''' - the Delete key value,
* '''INSERT_KEY''' - the Insert key value,
* '''F1_KEY''' to '''F12_KEY''' - the function key value,
You must use platform-specific and <u>unique non-ASCII</u> values for the keys, and then you must use these specific symbolic names in your definitions.
=== void bio_movecur(int r, int c) ===
Positions the cursor at row '''r''' and column '''c''', where row 0 is the top row and column 0 is the left-most column. If either parameter is invalid, this function has undefined results. This function does not flush any output buffer.
=== void bio_putch(int c) ===
Displays the character '''c''' at the current cursor position and advances the cursor by one position to the right. If the cursor is already at the rightmost column of the screen, the advance is system dependent. This function does not flush any output buffer.
=== void bio_prnstr(const char* s) ===
Displays the null-terminated string pointed to by s starting at the current cursor position. This function leaves the cursor just after the last character displayed. If the string length exceeds the available space on the current line of output, this function has undefined results. This function does not flush any output buffer.
== Complex Functions (Platform independent functions) ==
=== void bio_display(const char* str, int row, int col, int len) ===
Outputs the null-terminated string pointed to by "str" on the screen starting at row "row" and column "col", up to "len" characters. As with bio_movecur(), 0 is the top row and 0 is the left-most column. If the string is longer than "len", then only "len" characters are displayed, but if it is shorter than "len", then the entire string is displayed left-justified in the field. However, if "len" is 0 or less, then the field length is considered to be the actual length of the string (i.e. the entire string is displayed). Afterwards, the cursor is positioned after the last character of the field. (Note that on systems where output is buffered, this function should not flush the output buffer). The results are undefined if the specified values indicate a field that does not fit on the screen.
=== Line Editor: int bio_edit(........) ===
<big>int bio_edit(char* '''str''', int '''row''', int '''col''', <br />
int '''fieldlen''', int '''maxdatalen''', int* '''insertmode''', int* '''offset''',<br />
int* '''curpos''', int '''IsTextEditor''', int '''ReadOnly''')</big>
<br />
Allows the user to perform full screen editing of the null-terminated string pointed to by '''"str"'''. The parameter '''"row"''' identifies the row of the screen for the field (0 is the top row), while '''"col"''' indicates the starting column of the field (0 is the left-most column). The parameter '''"maxdatalen"''' specifies the maximum length of the string '''"str"'''. The parameter '''"fieldlen"''' specifies the length of the field in which editing is to be performed (visible area of '''“str”'''). The pointer '''"offset"''' points to an integer holding the index of the first character of'''"str"''' shown in the field. The pointer '''"curpos"''' points to an integer holding the position of the cursor in the field (0 is the first position). '''"insertmode"''' is a pointer pointing to an integer flag that is true (1) for insert mode being on, or false (0) for insert mode being off.<br />
''If any of '''insertmode''', '''curpos''' or '''offset''' is <u>NULL</u> then a local integer variable will be used instead. If local variables are used for any of insertmode, curpos, or offset, the default values are: 1 ('''insertmode'''), 0 ('''curpos'''), and 0 ('''offset''')''
Editing begins with the display of '''"str"''' from where '''"*offset"''' is referring to, and the cursor will be standing at the position which '''"*curpos"''' is indicating.
NOTE: The following corrections should be done to '''"*curpos"''' and '''"*offset"''' in case they hold invalid values before editing begins:
# If '''"*curpos"''' is greater than or equal to the value of fieldlen, correct the '''"*curpos"''' so that cursor stands at the last position inside the field.
# If '''"*offset"''' is greater than the length of the string, set the '''"*offset"''' so the “last character of str” is hidden right before the first space in the field. (See '''“[[Iolib functions 20103 - OOP344#IsTextEditor:|IsTextEditor Section #1]]”''' for more)
# After the above, if cursor is past the last character of '''“str”''', set '''"*curpos"''' so the cursor stands right after the last character of "str".
The cursor is never allowed to be:
# before the start of the field.
# more than one position past the last character in the string.
# after the end of the field.
<u>Editing is terminated by pressing ENTER, TAB, UP, DOWN, PGUP, PGDN or any of the function keys (F1 to F12)</u>. Pressing<u>ESCAPE will terminate the bio_edit() and abort editing</u>: '''"str"'''will contain originally passed data when leaving function.
Note that the conditions of termination are changed if the '''“IsTextEditor”''' flag is true (non-zero). See '''“[[Iolib functions 20103 - OOP344#IsTextEditor:|IsTextEditor]]”'''section for detail.
If '''"ReadOnly"''' has a true value (non-zero), then any attempt to change the content of '''"str"''' should end the function and return the key. Note that all other keys should work (Function and Non-ASCII keys). This makes the '''bio_edit()''' funciton "read only", but the user still can scroll the text to left or right and etc....
The function returns an int identifying the key that was pressed to exit. (This function uses the same key codes as bio_getch())
The function takes no action if the user tries to enter too many characters (if, for example, the string is in full insert mode, or the cursor is positioned after the last character of a full string in overstrike mode). However, if the cursor reaches the end of the field and the string is not full, then after inserting, the character string will be scrolled to the left, positioning the cursor right after the last character in the string.
The function handles at least the following special keys:
* '''LEFT''' - move cursor left one character. If cursor is at the beginning of the field and there is hidden data before the cursor, then shift string to right instead.
* '''RIGHT''' - move cursor right one character. If cursor is at the end of the field but not at the end of the string, then scroll one to left.
* '''HOME''' – move cursor to the beginning of the string. Scroll all the way to right if necessary. (i.e. if there is hidden data at the beginning)
* '''END''' - go to the end of the data in the string, i.e. just past the last character in the string. Scroll all the way to left if necessary.
* '''DEL''' – eat the current character above the cursor and move all subsequent characters one position to the left.
* '''BACKSPACE''' - move the rest of the field (including the cursor) one position to the left, eating the previous character.
* '''TAB''':
** if '''IsTextEditor''' is false, TAB will simply terminate the function like a Function key
** if '''IsTextEditor''' is true, TAB will insert '''BIO_TAB_SIZE''' number of spaces into the string.'''BIO_TAB_SIZE''' should be a defined "tab size" value in bio.h. If '''BIO_TAB_SIZE''' spaces cannot be inserted into the string for any reason then the inputted tab should be ignored. (See '''“[[Iolib functions 20103 - OOP344#IsTextEditor:|IsTextEditor Section #2]]”''' for more)
* '''ESCAPE''' - Terminates bio_edit() and aborts editing: '''"str"''' will contain originally passed data when leaving function. (See '''“[[Iolib functions 20103 -OOP344#IsTextEditor:|IsTextEditor Section #3]]”''' for exception)
* '''INSERT''' - toggle Insert/Overstrike mode (toggles the value of *insertmode)
**<u>In Insert mode</u>, printable characters are inserted into the string, moving the remainder of the string to the right to make room.
**<u>In Overstrike mode</u>, printable characters overwrite existing characters (if any). Note that if you are past the end of the string, printable characters are appended to the string (as long as the string isn't full) regardless of the mode.
**Also note that, regardless of the mode, the cursor advances as printable characters are typed into the string.
**Finally, if the cursor is at the end of the field, instead of moving to right, the characters are shifted to left.
==== <big>IsTextEditor:</big> ====
'''[Section #1] IsTextEditor and *offset'''<br/>
If IsTextEditor is true, then it means that the function is being used to edit text by editing one line of text at a time. In this case, shifting a line to the left or right should not only cause the editing line to be shifted, but also the rest of the lines in the text. To do this, bio_edit() should let the calling function know that a shift has happened. Since shifting essentially means modifying '''“*offset”''' when '''“IsTextEditor”''' is true, and that there are times when you find that '''“*offset”''' needs to be modified, you should terminate the function afterwards. With termination, the function should return the terminating key.
Note that at the beginning of the execution of bio_edit(), validating '''*offset''' may require the value of '''*offset''' to change. If so, make sure to correct the offset and then terminate the function before any editing happens returning the default value of key.
'''[Section #2]'''<br/>
# The bio_edit() function always shows blanks in any the part of the field that is not occupied by the data in the string.
#<u>UNDER NO CIRCUMSTANCES DOES THE FUNCTION CHANGE ANY POSITION ON THE SCREEN OUTSIDE OF THE FIELD</u>.
'''[Section #3] IsTextEditor and ESCAPE KEY'''<br/>
# When '"IsTextEditor"' is true and ESCAPE KEY is hit, do not abort the editing, and simply terminate the function returning the ESCAPE KEY.
# If memory allocation for aborting the edit (ESCAPE KEY) fails, quit the function returning -1.
'''[Section #4] Others'''<br/>
# Any normal printable key is simply placed into the string according to the rules laid out in the discussion of the INSERT key above.(The keys from the space character to the tilde character in the ASCII table are considered "printable".)
# Like most C library functions, your bio_edit() may assume that it is the calling program's responsibility is to ensure that the array is large enough to handle the specified number of characters, and that the starting screen position provides enough room (on the screen) for the field, etc.
=== Selection Editor ===
==== void bio_displayflag(..........) ====
<big>void bio_displayflag(const char* '''format''', int '''row''', int '''col''', int '''status''');</big>
Allows the user to display a <u>checkbox</u> at '''row''' and '''col''' on the screen. Depending on the value of '''status'''; being zero or non-zero, the checkbox will be checked or unchecked respectively.
The checkbox will be always shown using 3 characters; two surrounding characters and one character in the middle as the checkmark. If the status argument is zero, then instead of the check-mark a space will be printed on the screen.
The 3 characters held in the '''“format”''' array; format[0] and format[2] are surrounding characters and format[1] is the check-mark.
The '''const char* format''' is used to specify the character used for the checkbox, so for example if the '''format'''argument is "[X]", then an ''unchecked'' checkbox will be<big><pre>[ ]</pre></big> and a ''checked'' checkbox will be<big><pre>[X]</pre></big>
After the checkbox is displayed, the cursor is always place under the check-mark (in centre).
==== int bio_flag(..........) ====
<big>int bio_flag(const char* '''format''', int '''row''', int '''col''', int* '''status''', int '''radio''');</big>
bio_flag() allows the user to make a single true/false selection. '''"status"''' points to the status of the selection, that can be zero or non-zero. If '''"*status"''' is initially set to anything but zero, bio_flag() corrects value to one.'''"format"''' holds the shape of the checkbox as bio_displayflag() function.
bio_flag() begins the selection by displaying the checkbox according to its '''“*status”'''. (Remember that the value of'''"*status"''' is corrected before the editing begins). Then the function waits for the user input.
* If the user input is any of the printable keys (' ' < key <= '~') excluding space, it should be ignored (no action taken). If the user input is any of the function keys, the function is terminated returning the key.
* If the user input is SPACE:
** If '''“radio”''' is true, then the '''"*status"''' is set to one, checkbox is displayed and function is terminated returning space.
** If '''“radio”''' is false, then the value of '''"*status"''' is toggled between 0 and 1, the checkbox is displayed and function is exited returning space.
==== void bio_displayMenuItem(..........) ====
<big>void bio_displayMenuItem(const char* '''format''', const char* '''menuItem''', int '''row''', int '''col''', int '''len''', int '''status''');</big>
Allows the user to display a menu-item at '''row''' and '''col''' on the screen with width of '''len'''. Depending on the value of '''status'''; being zero or non-zero, the menu-item will be surrounded by '''format''' characters or space respectively.
The '''menuItem''' argument will be always shown surrounded by two characters.
* <u>If status is zero</u>, then at '''row''' and '''col''' a <u>space</u> will be shown, then the '''menuItem''' followed by another <u>space</u>. If the length of '''menuItem''' is less than (len-2), then enough spaces will be printed up to make the length (len-2).
<pre>"Hello"</pre> with 10 as len will be printed as : <pre>" Hello "</pre>
* If status is non-zero, then at row and col format[0] will be shown then the menuItem and finally format[1].If the length of menuItem is less than (len-2), then enough spaces will be printed up to make the length (len-2).
<pre>"[Hello]"</pre> with 10 as len and <code>"[]"</code> as format chars, will be printed as :<pre>"[Hello ]"</pre>
After the Menu item is displayed, the cursor is always placed under the first character of menutItem. (position row and col+1)
==== int bio_menuItem(..........) ====
<big>int bio_menuItem(const char* '''format''', const char* '''menuItem''', int '''row''', int '''col''', int '''len''', int* '''status''');</big>
bio_menuItem() allows the user to make a single item selection. '''"*status"''' points to the status of the selection, that can be zero or non-zero. If '''"*status"''' is initially set to anything but zero, bio_menuItem() corrects value to one.'''"*format"''' holds the shape of the selection indicator as bio_displayMenuItem() function.
bio_menuItem() begins the selection by displaying the menu item according to its '''“*status”'''using [[#void io displayMenuItem.28...........29|bio_displayMenuItem()]]. (Remember that the value of '''"*status"''' is corrected before the editing begins). Then the function waits for the user input.
* If the user input is any of the printable keys (' ' < key <= '~') excluding space, it should be ignored (no action taken), and wait the user to input again.
* If the user input is any of the non-ASCII keys, the function is terminated returning the key.
* If the user input is SPACE, then the *status is set to one, menu item is displayed and function is terminated returning the ASCII value of space character.
== Suggested workload (task distribution) ==
* The following are suggested task distribution between team members
* Make a copy of the task distribution and add it to your project page, so I know who have done what
* When committing your work to svn, make sure comment the task you are working on
* You can exchange tasks between yourselves but make sure you have the changes reflected in your task distribution on your project page
* If anyone needs help doing their part, don't hesitate to give them hand in logic and coding and blog about the problem and how it was fixed
* If someone neglects to do their work or doesn't do the work on time , distribute his/her tasks between others, and send an email to me immediately. Those NOT doing the work will be fired from the group and have to do the project in a smaller scale alone.
* If there are questions to be clarified, book a meeting with me on IRC. (send me an email and put the time in IRC meetings table with (??) added to team name. I will put my Initials if the meeting is approved.
* If you believe I have overlooked any task or part, please add it here and I will take care of it:
=== Tasks missing ===
* No missing task so far
== Platforms ==
=== Windows Visual C++ ===
To Download Visual studio from [https://acs.senecac.on.ca/pages/download.php Seneca/ACS download page] Seneca students should first login using their Seneca account, click on MSDN and scroll down to the DVD Downloads subheading. Download the file "(Dual Layer) Visual Studio 2008 Professional Edition, MSDN Library for Visual Studio 2008 ".
(Note that the image does not include [http://www.microsoft.com/downloads/details.aspx?FamilyId=FBEE1648-7106-44A7-9649-6D9F6D58056E&displaylang=en Service Pack 1])
Users also have the option of downloading Microsoft Visual C++ 2008 Express Edition from the[http://www.microsoft.com/express/download/ Microsoft Visual Studio Express Downloads page]. Users will eventually need to register the product, free of charge, in order to continue usage beyond the trial period. To register, open Visual C++, select 'Help' from the top tool bar and select 'Register Product'. Follow the instructions displayed on the screen and a registation key will be issued following successful registration.
<br/>
If you have other MS Visual Studio products (eg. Visual Basic) installed you may be asked to first uninstall them before installing the Visual C++ Express Edition.
==== Creating a Project for console application in Visual C++ 2008 ====
* Press '''Ctrl+Shift+N''' or click on '''File/New/Project'''
* In Project types select '''Visual C++/Win32''' and then in Templates select '''Win32 Console Application''' (Text Mode)
* In '''Name''' section Enter the desired name for the project
* In '''Location''' find/enter the directory in which you want the project created
* Un-check '''Create directory for solution'''
* Click on '''OK''' to set the '''Application Settings'''
** Click on '''Application Setting'''
** Check '''Empty Project''' and then click on '''Finish'''
You can now either add new files to the solution or add existing ones. If VC can't create a project, you might consider to reset your environment settings by calling "C:\Program Files\Microsoft Visual Studio 10.0\Common7\IDE\devenv.exe /ResetSettings".
=== Windows Borland C++ ===
Borland C++ Compiler 5.5 is a free version. You can download it from[https://acs.senecac.on.ca/pages/download.php ACS].
To install Borland C++ command line compiler on your computer first run the executable you downloaded to expand the compiler files into a directory.<br />
Say the installation is done in '''X:\Borland\BCC55''' <br />
Create a file called '''bcc32.cfg''' in '''X:\Borland\BCC55\Bin''' and add the following two lines to it:
<big>
-I"X:\Borland\Bcc55\include"
-L"X:\Borland\Bcc55\lib"
</big>
Create another file called '''ilink32.cfg''' in '''X:\Borland\BCC55\Bin''' and add the following line to it:
<big>
-L"X:\Borland\Bcc55\lib"
</big>
Then add '''X:\Borland\BCC55\Bin''' to the system path:<br />
Vista:
* Right-click on '''Computer''' and select properties.
* Click on '''Advanced System Settings''' on the left panel and the '''System properties''' will open with '''Advanced''' tag already selected
XP:
* Right-click on '''My Computer''' and select properties and the '''System properties''' will open
* Click on '''Advanced''' tag
Common:
* Click on '''Environment Variables''' Button
* In '''System Variables''' scroll down to '''path'''
* Select '''path''' and click on '''edit''' button
* Add ''';X:\Borland\Bcc55\bin''' to the end of the '''path''' value, click '''OK''' on all windows to close and you are done.
Compile your code as:
<big>
> bcc32 biomain.c bio.c
</big>
You must restart your computer for changes to take affect!
'''Happy Compiling!'''
=== Linux Gnu C ===
Many distro come with compiler pre-installed. If not, you can use the package manager tool (yum, apt-get, merger...) in your system to search for GCC, and install that package. Also, there are some useful tools that you may need, such as autoconf, make, ctag and etc.
Distro specified installation of compilers guilds:<br />
[https://help.ubuntu.com/community/InstallingCompilers Installing Compilers in Ubuntu]<br />
NOTE: Some compilers don't have the ncurses library. If you are getting a message that's something like this whenever you try to compile: <p><code>bio.c:51:21: error: ncurses.h: No such file or directory</code></p>It means you don't have it installed. You will need to install that library. Simply search for 'libncurses' in your Linux distro's package manager tool (yum for fedora and apt-get for Ubuntu, or simple go to Ubuntu's Software Centre and search for it) and install the latest development library, libncurses5-dev.
To compile using gcc issue the following command:<br />
<big>
gcc biomain.c bio.c -lncurses
</big>
or
<big>
cc biomain.c bio.c -lncurses
</big>
'''Also make sure you use [http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html Putty] for your telnet client and set the Temminal/keyboard / function keys to Xterm R6'''
=== Mac OS C++ ===
Mac OS, being a Unix base operating system, supports curses library. So if you follow the case study in the book (the one written for AIX)it should work on Mac too.<br />
<big>
cc biomain.c bio.c -lcurses
</big>
== How to submit your assignment ==
Close to the due date of the assignment, [https://zenit.senecac.on.ca/svn/oop344/trunk/biotester.c A tester program] called'''"biotester.c"''' will be released. This program uses your functions and does series of tests. Each test will use your functions to produce an output or perform an action. If all the output is produced or the action is performed as stated in the tester program, branch the trunk to tags under "Prj0.2". Then send me an email to checkout "Prj0.2" and mark it. latest commit to "Prj0.2" in tags indicates the time of submission and has to be before the due date/time.
Please make sure to include the project files (.vcxproj.filters & .vcxproj or .vcproj) so I can open your files easily.
<!-- To make Fardad's life easier, make sure to include the project files so he doesn't have to start a new project and add your code. --pbrown9 -->
=== Late Submission Penalty ===
10% Per day (Saturday and Sunday) counted as one day.