Systems Programming (XMUT)
Assignment 2: C programming

  • Due 20 October, 18:59

What To Hand In

  • editor.c

Do not rename these files.

This part will test your application of the conceptual knowledge of C fundamentals to solve practical programming tasks. You may only use the Standard C Library to perform the tasks in this part. You must implement the functions in a file named editor.c. You are free to implement other functions within this file that you think are needed to fulfil the tasks.

The programming tasks involve the implementation of several basic text editor operations: insert, delete, replace, etc. An important component of a text editor is the editing buffer which can be viewed as a one-dimensional array of characters.

You will implement functions to manipulate the contents of the editing buffer:
  1. for Core (Tasks 1 and 2), you will implement editor_insert_string and editor_delete_string;
  2. for Completion (Task 3), you will implement editor_replace_str; and
  3. for Challenge, you will implement editor_view.

Sample code showing an example of how you can test your code are provided under the files directory in the archive that contains this file.

Commenting

You should provide appropriate comments to make your source code readable. If your code does not work and there are no comments, you may lose all marks.

Coding Style

You should follow a consistent coding style when writing your source code. Coding style (aka coding standard) refers to the use of appropriate indentation, proper placement of braces, proper formatting of control constructs, and many others. Following a particular coding style consistently will make your source code more readable.

There are many coding standards available (search "C coding style"), but we suggest you consult the lightweight Linux kernel coding style (see coding-style). The relevant sections are Sections 1, 2, 3, 4, 6, and 8. Note that you do not have to follow every recommendation you can find in a coding style document, you just have to apply that style consistently.

Task 1: Core [20 Marks]

Implement a function with the prototype
    int editor_insert_string(char editing_buffer[], int editing_buflen, const char* to_insert, int pos);

which will insert the string to_insert at index pos of editing_buffer. The size of editing_buffer is editing_buflen. When a string is inserted at index pos, each of the original characters at index pos until the end of the buffer must be moved to the right to make room for the characters in to_insert. The last character is thrown out. The function should return 1 if the string insertion occurred, otherwise it should return 0. Ensure that the last character in the buffer is always the null character.

For example, if editing_buflen is 16 and the contents of editing_buffer are

pic1.png

after executing
    int r = editor_insert_string(editing_buffer, 16, "s!", 12);
the value of r should be 1 and contents of editing_buffer should be

pic2.png

Task 2: Core [25 Marks]

Implement a function with the prototype
    int editor_delete_string(char editing_buffer[], int editing_buflen, const char *to_delete, int offset);

which will delete the first occurrence of the string to_delete. The search should start from index offset of editing_buffer. The size of editing_buffer is editing_buflen. When a string is deleted at index pos, each of the original characters at index pos until the end of the buffer must be moved by the length of string to_delete to the left. Multiple null characters ('\0') might be inserted at the end of the buffer. The function should return 1 if the string deletion occurred, otherwise, it should return 0.

For example, if editing_buflen is 16 and the contents of editing_buffer are

pic1.png

after executing
    int r = editor_delete_string(editing_buffer, 16, "rld", 9);
the value of r should be 1 and the contents of editing_buffer should be

pic3.png

Task 3: Completion [15 Marks]

Implement a function with the prototype
    int editor_replace_str(char editing_buffer[], int editing_buflen, const char *str, const char *replacement, int offset);
which will replace the first occurrence of the string str with replacement. The search for the first occurrence should start from index offset of editing_buffer. The size of editing_buffer is editing_buflen.

Note: str and replacement are pointers to arrays of characters. You can access each element of the array by its index.

The replacement should not overwrite other contents in the buffer. This means that if replacement is longer than str, there is a need to move the characters after str to the right. Likewise, if replacement is shorter than str, there is a need to move the characters after str to the left. When moving characters to the right, throw out characters that will not fit in the buffer and when moving characters to the left, insert null characters in the vacated positions.

The question mark ? is a placeholder for a single character. In other words, if str is n?t, it finds the first occurrence of one of these words: nut, not, or net.

If str is empty (regardless of the value of replacement), no string replacement should occur. If replacement is empty, then it deletes the first occurrence of string str.

If the replacement text will go beyond the limits of editing_buffer, then replacement should only occur until the end of editing_buffer.

Ensure that the last character in the buffer is always the null character.

If the string replacement occurred, the function should return the index corresponding to the last letter of replacement in editing_buffer, otherwise, it should return -1. If the replacement text will go beyond the limits of editing_buffer, the function should return editing_buflen-1.

For example, if editing_buflen is 16 and the contents of editing_buffer are

pic1.png

After executing
  int r = editor_replace_str(editing_buffer, 16, "W??ld!", "there", 0);
the value of r should be 11 (which is the index of the last 'e' in "there") and the contents of editing_buffer should be

pic05.png

Another example if editing_buflen is 16 and the contents of editing_buffer are

pic1.png

After executing
  int r = editor_replace_str(editing_buffer, 16, "W??ld!", "NWEN 214!", 0);
the value of r should be 15 (which is the index of the last '4' in "NWEN 214!") and the contents of editing_buffer should be

replaceOverflowExample.png

Note: "NWEN 214!" will go beyond the limits of editing_buffer, then replacement should only occur until the end of editing_buffer. The last character in the buffer is also the null character.

Task 4: Challenge [10 Marks]

Implement a function with the prototype
    void editor_view(int rows, int cols, char* viewing_buffer, const char editing_buffer[], int editing_buflen, int wrap);
which will copy the contents of the editing_buffer to the viewing_buffer for display to the user. Note that the viewing_buffer is a two-dimensional array, with dimensions cols columns and rows rows. Prior to the copying, the function must set every character in the viewing_buffer to the null character.

The argument wrap controls the behaviour of the copying process from editing_buffer to viewing_buffer as follows:

  • Regardless of the value of wrap, whenever a newline character is encountered in editing_buffer, the text after the newline character is copied to the next row in viewing_buffer. Note that the newline character is not copied to viewing_buffer.

  • When wrap is 0, the text is not wrapped. This means that when the newline character is not encountered before the end of the current row (at column cols-1), the rest of the text in the editing_buffer are discarded until a newline is encountered which will cause the rest of the text to be copied to the next row. Note that column cols-1 in viewing_buffer is never filled and will retain the null character.

  • When wrap is non-zero, the text must be wrapped. This means that when the newline character is not encountered before the end of the current row (at column cols-1 in viewing_buffer), the text after is copied to the next row. Note that column cols-1 in viewing_buffer is never filled and will retain the null character.

The copying process should terminate when a null character in the editing_buffer is encountered.

For example, if editing_buflen is 48 and the contents of editing_buffer are

pic06.png

and cols and rows are 11 and 8, respectively. After executing
    editor_view(8, 11, viewing_buffer, editing_buffer, 48, 0);
the resulting contents of viewing_buffer should be

pic07.png

Alternatively, after executing
    editor_view(8, 11, viewing_buffer, editing_buffer, 48, 1);
the resulting contents of viewing_buffer should be

pic08.png

Marking Criteria for Tasks 1 -- 4:

Criteria Weight Expectations for Full Marks
Compilation 5% Compiles without warnings
Comments 10% Sufficient and appropriate comments
Code Quality 15% Consistent coding style
Correctness 70% Handles all test cases correctly
  100%