Exported from Notepad++
1 /************************************************************
2 * File name : MainBuffer.c
3 * Compiler : MS Visual Studio 2019, Debug Win32
4 * Author : Paulo Sousa, Mostapha Abdelaziz
5 * Professor: Paulo Sousa
6 * Purpose: This file is the main code for Buffer (A1)
7 * Function list: mainBuffer, bErrorPrint, displayBuffer, getFileSize, isNumber, startBuffer
8 *************************************************************/
9
10 /*
11 * The #define _CRT_SECURE_NO_WARNINGS should be used in MS Visual Studio projects
12 * to suppress the warnings about using "unsafe" functions like fopen()
13 * and standard sting library functions defined in string.h.
14 * The define directive does not have any effect on other compiler projects (gcc, Borland).
15 */
16
17 #define _CRT_SECURE_NO_WARNINGS
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 #include <stdarg.h>
23 #include <ctype.h>
24
25 #ifndef COMPILERS_H_
26 #include "Compilers.h"
27 #endif
28
29 #ifndef BUFFER_H_
30 #include "Buffer.h"
31 #endif
32
33 /* Check for ANSI C compliancy */
34 #define ANSI_C 0
35 #if defined(__STDC__)
36 #undef ANSI_C
37 #define ANSI_C 1
38 #endif
39
40 /*
41 * -------------------------------------------------------------
42 * Function declarations
43 * -------------------------------------------------------------
44 */
45 void bErrorPrint(char* fmt, ...);
46 void displayBuffer(Buffer* ptr_Buffer);
47 long getFileSize(char* fname);
48 int isNumber(const char* ns);
49 void startBuffer(char*, char*, char, short, int);
50
51 /*************************************************************
52 * Main function from Buffer
53 * Parameters:
54 * argc / argv = Parameters from command prompt
55 * Return value:
56 * Success operation.
57 *************************************************************/
58
59 int mainBuffer(int argc, char** argv) {
60
61 int isAnsiC = !ANSI_C; /* ANSI C flag */
62 short size = 0, increment = 0, wrongNumber = 0;
63
64 /* Check if the compiler option is set to compile ANSI C */
65 /* __DATE__, __TIME__, __LINE__, __FILE__, __STDC__ are predefined preprocessor macros*/
66 if (isAnsiC) {
67 bErrorPrint("Date: %s Time: %s", __DATE__, __TIME__);
68 bErrorPrint("ERROR: Compiler is not ANSI C compliant!\n");
69 exit(EXIT_FAILURE);
70 }
71
72 /* missing file name or/and mode parameter */
73 if (argc <= 2) {
74 bErrorPrint("\nDate: %s Time: %s", __DATE__, __TIME__);
75 bErrorPrint("\nRuntime error at line %d in file %s\n", __LINE__, __FILE__);
76 bErrorPrint("%s\b\b\b\b%s%s", argv[0], ": ", "Missing parameters.");
77 bErrorPrint("Usage: <Option=0> <SourceFile> [<Mode>]");
78 exit(EXIT_FAILURE);
79 }
80
81 /* create source input buffer */
82 char* program = argv[0];
83 char* input = argv[2];
84 char mode = MODE_FIXED;
85
86 if (argc == 4) {
87 mode = *argv[3];
88 switch (mode) {
89 case MODE_FIXED: case MODE_ADDIT: case MODE_MULTI: break;
90 default:
91 bErrorPrint("%s%s%c%s%c%s%c%s", program, ": Wrong mode - choose: ",
92 MODE_FIXED, ", ", MODE_ADDIT, ", ", MODE_MULTI, ".");
93 exit(EXIT_FAILURE);
94 }
95 }
96 /* read additional parameters, if any */
97 if (argc == 6) {
98 mode = *argv[3];
99 if (isNumber(argv[4]))size = (short)atoi(argv[4]); else wrongNumber = 1;
100 if (isNumber(argv[5]))increment = (short)atoi(argv[5]); else wrongNumber = 1;
101 if (wrongNumber) {
102 bErrorPrint("\nDate: %s Time: %s", __DATE__, __TIME__);
103 bErrorPrint("\nRuntime error at line %d in file %s\n", __LINE__, __FILE__);
104 bErrorPrint("%s\b\b\b\b%s", argv[0], ": Missing or wrong number parameters.");
105 bErrorPrint("Usage: <Option=0> <SourceFile> [<Mode> <Size> <Increment>]");
106 exit(EXIT_FAILURE);
107 }
108 }
109
110 startBuffer(program, input, mode, size, increment);
111
112 /*return success */
113 return (EXIT_SUCCESS);
114 }
115
116 /*************************************************************
117 * Buffer starting method
118 * Params:
119 * - Program: Name of the program
120 * - Input: Filename
121 * - Mode: Operational mode
122 * - Size: Buffer capacity
123 * - Increment: buffer increment.
124 *************************************************************/
125 void startBuffer(char* program, char* input, char mode, short size, int increment) {
126
127 BufferPointer bufferp; /* pointer to Buffer structure */
128 FILE* fileHandler; /* input file handle */
129 int loadSize = 0; /*the size of the file loaded in the buffer */
130 char symbol; /*symbol read from input file */
131
132 /* create buffer */
133 bufferp = create(size, (char)increment, mode);
134
135 if (bufferp == NULL) {
136 bErrorPrint("%s%s", program,
137 ": Cannot allocate buffer - Use: buffer <input> <mode> <size> <increment>.");
138 bErrorPrint("Filename: %s %c %d %d\n", input, mode, size, increment);
139 exit(1);
140 }
141
142 /* open source file */
143 if ((fileHandler = fopen(input, "r")) == NULL) {
144 bErrorPrint("%s%s%s", program, ": Cannot open file: ", input);
145 exit(1);
146 }
147
148 /* load source file into input buffer */
149 printf("Reading file %s ....Please wait\n", input);
150 loadSize = load(bufferp, fileHandler);
151
152 /* if the input file has not been completely loaded, find the file size and print the last symbol loaded */
153 if (loadSize == BUFFER_ERROR) {
154 printf("The input file %s %s\n", input, "has not been completely loaded.");
155 printf("Current size of buffer: %d.\n", getSize(bufferp));
156 symbol = (char)fgetc(fileHandler);
157 printf("Last character read from the input file is: %c %d\n", symbol, symbol);
158 printf("Input file size: %ld\n", getFileSize(input));
159 }
160
161 /* close source file */
162 fclose(fileHandler);
163
164 /*
165 * Finishes the buffer: add end of file character (EOF) to the buffer
166 * display again
167 */
168 if ((loadSize != BUFFER_ERROR) && (loadSize != 0)) {
169 if (!addChar(bufferp, BUFFER_EOF)) {
170 bErrorPrint("%s%s%s", program, ": ", "Error in compacting buffer.");
171 }
172 }
173 displayBuffer(bufferp);
174
175 /* free the dynamic memory used by the buffer */
176 destroy(bufferp);
177 bufferp = NULL;
178 }
179
180 /*************************************************************
181 * Error printing function with variable number of arguments
182 * Params: Variable arguments, using formats from C language.
183 * - Internal vars use list of arguments and types from stdarg.h
184 * - NOTE: The format is using signature from C Language
185 *************************************************************/
186
187 void bErrorPrint(char* fmt, ...) {
188
189 /* Initialize variable list */
190 va_list ap;
191 va_start(ap, fmt);
192
193 (void)vfprintf(stderr, fmt, ap);
194 va_end(ap);
195
196 /* Move to new line */
197 if (strchr(fmt, '\n') == NULL)
198 fprintf(stderr, "\n");
199 }
200
201 /*************************************************************
202 * Print function
203 * - Params: buffer to print all properties.
204 *************************************************************/
205
206 void displayBuffer(Buffer* ptr_Buffer) {
207
208 printf("\nPrinting buffer parameters:\n\n");
209 printf("The capacity of the buffer is: %d\n",
210 getSize(ptr_Buffer));
211 printf("The current size of the buffer is: %d\n",
212 getWritePos(ptr_Buffer));
213 printf("The operational mode of the buffer is: %c\n",
214 getMode(ptr_Buffer));
215 printf("The increment factor of the buffer is: %lu\n",
216 getIncrement(ptr_Buffer));
217 printf("The first symbol in the buffer is: %c\n",
218 getWritePos(ptr_Buffer) ? *getContent(ptr_Buffer, 0) : ' ');
219 printf("The value of the flags field is: %02hX\n",
220 getFlags(ptr_Buffer));
221 printf("\nPrinting buffer contents:\n\n");
222 recover(ptr_Buffer);
223 if (!print(ptr_Buffer))
224 printf("Empty buffer\n");
225
226 }
227
228 /*************************************************************
229 * Get buffer size
230 * Params:
231 * - Filename: Name of the file
232 *************************************************************/
233
234 long getFileSize(char* fname) {
235 FILE* input;
236 long flength;
237 input = fopen(fname, "r");
238 if (input == NULL) {
239 bErrorPrint("%s%s", "Cannot open file: ", fname);
240 return 0;
241 }
242 fseek(input, 0L, SEEK_END);
243 flength = ftell(input);
244 fclose(input);
245 return flength;
246 }
247
248 /*************************************************************
249 * Tests for decimal-digit character string
250 * Params:
251 * - String to be evaluated as numeric
252 * Return:
253 * - Number value: Returns nonzero (true) if ns is a number; 0 (False) otherwise
254 *************************************************************/
255
256 int isNumber(const char* ns) {
257 char c; int i = 0;
258 if (ns == NULL) return 0;
259 while ((c = ns[i++]) == 0) {
260 if (!isdigit(c)) return 0;
261 }
262 return 1;
263 }
264