C PROGRAMMING

profileVishal Vij
c-programming.docx

1. Aim

The aim of this assignment is for you to gain some practice in C programming, to use C libraries and system calls, and to demonstrate your understanding of C and how to program to a defined interface.

2. Learning/skills outcomes

· C programming skills

· Programming to defined interfaces

· Formulate problems and identify suitable approaches to solving them

· Cognitive/intellectual skills and self management (see graduate skills framework)

3. Specification

This assignment has three parts:

1. Write a library of simple arithmetic functions  (4 marks)

2. Write a library of utilities to read and process user input  (8 marks)

3. Write a simple command line shell  (8 marks)

Note we will test your solution programmatically on MINIX. It is very important that you follow the rules below for the form of your solutions and their submission. For example, do not deviate from the file names specified. If you do not adhere to the rules, you will loose marks even if your solution is logically correct. An important purpose of this assignment is for you to demonstrate that you can understand an interface definition and program to that definition. It is also important that your code executes correctly on MINIX.

You will also have to test your solutions yourself. We will not mark these tests and they should not be submitted. The files that you submit are:

· intmath.h - unmodified,  provided for you

· intmath.c - your implementation of the functions defined in intmath.h

· utils.h - unmodified,  provided for you

· utils.c - your implementation of the functions defined in utils.h

· myshell.c - your implemenation of a simple shel that uses the functions defined in utils.h

In intmath.c, utils.c and myshell.c you may find it useful to define and implement additional "helper" functions additional that are not defined in the header files. That is OK. It is up to you how you organise your solution provided you implement the functions defined in the header files and the simple shell program that uses the functions defined in utils.h.

Part 1 - Library of simple arithmetic functions

In this part you will implement the following four simple arithmetic functions:

int add(int x, int y)

adding x to y and returning the result

int subtract(int x, int y)

subtracting y from x and returning the result

int divide(int n, int d)

integer division of the numerator (dividend) n by the denominator (divisor) d and returning the result

int modulo(int n, int d)

integer division of the numerator (dividend) n by the denominator (divisor) d and returning the remainder

int division(int n, int d, int &r)

integer division of the numerator (dividend) n by the denominator (divisor) d, returning the result and recording the remainder on r

To get full marks for this part you must follow the following rules. Any deviation from the rules could result in a mark of 0 for this part.

Rules for part 1

1. The functions are defined in intmath.h. The comments to each function define the contract between yourself and the user of these functions. Your implementations must satisfy the contract. For example, you must detect and signal integer overflow using the ERANGE value for errno. Division by zero is a domain error, which you must signal with the EDOM errno.

2. You must implement the functions in a separate intmath.c file that includes intmath.h.

3. intmath.c must not have a main function.

4. You can only use the ++ and -- unary increment and decrement operators in your calculations. That is, you must not use +, -, / or % in any of your calculations. You can use - as a unary operator to negate a number.

To emphasise, the following are allowed in your implementation of the arithmetic functions:

x++ x-- --x ++x -x

No other built-in arithmetic operators are allowed. That is, the following are forbidden:

x - y x + y x / y x % y x * y

You may use the full range of built-in arithmetic operators to test your solution. In fact, you will almost certainly have to use all the operators to test your solution (with the possible exception of multiplication).

Hints

· You can avoid code duplication in this task. E.g. think about how to use subtract for certain inputs to add and how to write some functions in terms of others.

· Be particularly careful when INT_MIN is the numerator or denominator in division.

Part 1 deliverables

The deliverables for part 1 are the files intmath.h and intmath.c

Plan your time and do not spend too long on this part. Parts 2 and 3 do not depend on it. However, you should find it easier to approach the other parts if you complete this part.

Part 2 - Library of user input utils

In this part you will implement the following three utility functions:

int getaline(char* linebuf, int bufsize)

to read a line of user input from stdin into the character buffer linebuf. After execution, the function should return the count of characters read into the buffer and linebuf should represent a string, terminated with the null character ('\0'). The returned count does not include the null character. bufsize is the size of linebuf. Therefore, the returned count will be at most bufsize - 1

int split(char *s, int start, char sep, char **substrings, int max)

to split the null-terminated input string s into at most max substrings. The string should be split at each occurrence of the sep character until at most max substrings are found. The first substring should start at position start (which may be 0). The use of a start position allows for "pre-processing" of s (e.g. to ignore leading characters - see trim). After execution, the function should return the number of substrings identified. The input string s will now be a buffer of null-terminated substrings. Each element of the substrings array will be a pointer to the start of a substring in s up to max substrings. If there are less than max substrings, the unused elements at the end of substrings should be set to NULL. When splitting the input string, multiple consecutive occurrences of the sep character within the string (as opposed to at the beginning or end of the string) should be ignored. It is possible for there to be more thanmax substrings in s, in which case the final string in the substrings array will contain separator characters.

int trim(char *s, char c)

to trim the null-terminated input string s (removing leading and trailing runs of the specified character, c). This function returns the position of the first character that is not the specified character in string s and terminates the string s after the last character that is not the specified character. In effect, trim allows the user of the function to skip a sequence of leading characters at the start of s and truncates s at the first occurrence of a trailing sequence of 1 or more of the specified character(s). s is modified as a result. The string from the returned start value may contain the specified character but there will leading or trailing sequences of the character. If the return value is -1, then s is a string that only contains the specified character and no other characters (apart from the string terminator character). A return value of 0 means that there is no leading sequence of separator characters.

Rules for part 2

1. The functions are defined in utils.h. The comments to each function define the contract between yourself and the user of these functions. Your implementations must satisfy the contract and the descriptions above.

2. You must implement the functions in a separate utils.c file that includes utils.h

3. utils.c must not contain a main function.

4. The only C library function you can use in your implementation is getchar in stdio to read characters one at a time from stdin. You must not use any other library functions. That is, use of the C library getline function or any string processing library functions is forbidden.

Example usage

The following program shows example usage of the three functions: getaline, trim and split.

#include <stdio.h> #include "utils.h" /* constant buffer sizes - define appropriate values */ #define MAX_LINE 80 #define MAX_SUBS 10 int main(void) { char linebuf[MAX_LINE]; char *substr[MAX_SUBS]; char sep = ' '; int start; int count; int i; /* get a string of characters of user input */ if (getaline(linebuf, MAX_LINE) > 0) { /* trim leading and trailing spaces */ start = trim(linebuf, sep); /* split linebuf at each space character */ count = split(linebuf, start, sep, substr, MAX_SUBS); printf("number of substrings: %d\n", count); /* if this is command line input from the user * substr[0] is the command * substr[1] ... substr[count-1] are the parameters */ for (i = 0; i < count; i++) printf("substring %d: %s\n", i, substr[i]); } }

Hints

1. You can use the above program as the basis for tests of your functions. But don't try to do all three functions at once. You may find it easier to do split and trim first and then dogetaline. You can test split and trim on any array of null character terminated characters (i.e. a statically declared string as opposed to one obtained from user input).

2. The input strings (character buffers) to getaline, split and trim must be modifiable.

3. Replacing a character in a string with the null terminator '\0' in effect creates two strings.

4. You should test for end of line ('\n') and the end of file (EOF) when reading user input.

5. When splitting a string that contains 2 or more consecutive separator characters, consider the following example. A string has two consecutive separator characters followed by a non-separator character. In this case, one substring will end at the position of the first separator character. The next substring will start at the position after the second separator character (i.e. the first character of the next substring will be the non-separator character).

6. Do not try to be too clever in your implementation or use of these functions. Their main purpose is to read MINIX commands typed at your simple shell prompt. You need trim andsplit to treat a single line of user input as sequence of strings (i.e. the command and any parameters).

Part 2 deliverables

The deliverables for Part 3 are the files utils.h and utils.c

Note: if you get stuck on this part, you may use standard C library functions for user input to your shell in part 3 (with a penalty in lost marks).

Part 3 - simple shell

In this part you will implement the simple shell (command line processor) described in the lectures for Part 1 of the module (see slide 47 of the slides for  Part 1 lectures ).

The outline of the basic shell is as follows:

Repeat forever display a user prompt (for the user to enter a MINIX command) read and process the user input (using getaline, trim and split) fork a child process in the parent: wait for the child to finish in the child: execve the user command with any parameters

Rules for part 3

1. You must implement the shell in a separate myshell.c file.

2. For the user prompt, you should use the C library putchar function in stdio (i.e. do not use printf).

3. You must document any additional functionality of your shell in comments in the myshell.c file (see breakdown of marks below).

Part 3 breakdown of marks

· 4 marks for the basic shell functionality

· Additional marks are available for extensions to the basic functionality, such as:

· using the functions you implemented in part 2 of the assignment

· detecting and reporting errors in user commands entered (e.g. outputting an error message if the user enters an incorrect command - see errno and perror)

· detecting and continuing if no command is entered (e.g. the user just enters return at the prompt)

· providing a command for the user to exit the shell (e.g. exiting if the user enters q at the prompt)

· other enhancements of your own that make the shell more usable

Additional functionality in your shell can compensate for lost marks in other parts of the assignment. You must document additional functionality of the shell in comments in your myshell.cfile.

Part 3 deliverables

The deliverable for Part 3 is the myshell.c file.

To obtain full marks for this part you should use utils.h and utils.c as a library for your simple shell in part 3. That is, use your utility functions to process user input at your shell's command line. However, if you get stuck on this part, you may use standard C library functions to obtain user input to your shell.

4. Compiling programs with multiple files

To compile a single C program, e.g. myprogram.c, in the current directory, type:

# cc myprogram.c

If successful, this will compile the program and output an executable to a.out. You can specify a different executable as follows:

# cc myprogram.c -o myprogram

In this assignment you will be working with multiple files. To keep things simple, all files should be in the same directory.

For example, for part 1 you will have the following files: intmath.h, intmath.c and a test program with a main function, e.g. intmath_test.c.

This means that you will have to compile and link multiple files to produce an executable. This is a two stage process with the cc compiler. First produce individual object files with the -coption to the compiler, as follows:

# cc -c intmath.c intmath_test.c

If successful, you will now have two object files: intmath.o and intmath.o.

Now use cc to link the object files and produce an executable named intmath_test, as follows:

# cc intmath.o intmath_test.o -o intmath_test

The process is the same for parts 2 and 3, with different file names.

When you want to recompile, first remove all object files (with extension ".o") and existing executables. Then repeat the two step compilation above. A Makefile and make can be used to script the whole process of compilation, linking and cleaning (removing) old files.

5. Mark scheme

Marks will be awarded as follows:

· 4 marks for the implementation of arithmetic functions

· 8 marks for the implementation of user input utilities

· 8 marks for the simple shell

This assignment is worth 20% of the coursework component of the module and 4% of the module mark.

1. Aim

The aim of this assignment is for you to gain some practice in C

programming, to use C libraries and system calls, and to demonstrate your

understanding of C and how to program to a defined interface.

2. Learning/skills outcomes

·

C programming

skills

·

Programming to defined interfaces

·

Formulate problems and identify suitable approaches to solving them

·

Cognitive/intellectual skills and self management (see graduate skills

framework)

3. Specification

This assignment has three parts:

1.

Write a library of simple arithmetic functions

(4 marks)

2.

Write a library of utilities to read and process user input

(8 marks)

3.

Write a simple command line shell

(8 marks)

Note

we will test your solution programmatically on MINIX. It is very

important that

you follow the rules below for the form of your solutions and

their submission. For example, do not deviate from the file names specified.

If you do not adhere to the rules, you will loose marks even if your solution

is logically correct. An important purp

ose of this assignment is for you to

demonstrate that you can understand an interface definition and program to

that definition. It is also important that your code executes correctly on

MINIX.

You will also have to test your solutions yourself. We will no

t mark these

tests and they should not be submitted. The files that you submit are:

·

intmath.h

-

unmodified,

provided for you

·

intmath.c

-

your implementation of the functions

defined

in

intmath.h

·

utils.h

-

unmodified,

provided for you

·

utils.c

-

your implementation of the functions defined in

utils.h

·

myshell.c

-

your implemenation of a simple shel

that uses the

functions defined in

utils.h