1 |
//$Header$ |
//$Header$ |
2 |
|
//{723c099f-de0c-46b4-93a9-ca89bc796de7} |
3 |
//------------------------------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
4 |
//This file is part of "David T. Ashley's Shared Source Code", a set of shared components |
//This file is part of "Embedded Tool Set", a tool set designed to facilitate embedded system |
5 |
//integrated into many of David T. Ashley's projects. |
//software and hardware development. |
6 |
//------------------------------------------------------------------------------------------------- |
//------------------------------------------------------------------------------------------------- |
7 |
//This source code and any program in which it is compiled/used is provided under the MIT License, |
//This source code and any program in which it is compiled/used is provided under the MIT License, |
8 |
//reproduced below. |
//reproduced below. |
29 |
|
|
30 |
#include <assert.h> |
#include <assert.h> |
31 |
#include <stdio.h> |
#include <stdio.h> |
32 |
|
#include <stdint.h> |
33 |
#include <string.h> |
#include <string.h> |
34 |
#include <time.h> |
#include <time.h> |
35 |
|
|
36 |
#include "fcmiof.h" |
#include "fcmiof.h" |
37 |
|
|
|
|
|
38 |
#define FCMIOF_HORIZONTAL_BAR_SEP_CHAR ('-') |
#define FCMIOF_HORIZONTAL_BAR_SEP_CHAR ('-') |
|
#define FCMIOF_LINE_LEN (78) |
|
|
|
|
39 |
|
|
|
//08/16/01: Visual inspection OK. |
|
|
int FCMIOF_get_line_len(void) |
|
|
{ |
|
|
return(FCMIOF_LINE_LEN); |
|
|
} |
|
40 |
|
|
41 |
|
int FCMIOF_stream_repchar(FILE *s, char c, size_t n) |
42 |
|
{ |
43 |
|
int rv = 0; |
44 |
|
|
|
//08/16/01: Visual inspection OK. |
|
|
void FCMIOF_stream_repchar(FILE *s, char c, unsigned n) |
|
|
{ |
|
45 |
assert(s != NULL); |
assert(s != NULL); |
46 |
|
|
47 |
while(n--) |
while ((n--) && (rv >= 0)) |
48 |
fprintf(s, "%c", c); |
{ |
49 |
|
rv = fprintf(s, "%c", c); |
50 |
} |
} |
51 |
|
|
52 |
|
return(rv); |
53 |
|
} |
54 |
|
|
|
//08/16/01: Visual inspection OK. |
|
|
void FCMIOF_repchar(char c, unsigned n) |
|
|
{ |
|
|
while(n--) |
|
|
printf("%c", c); |
|
|
} |
|
55 |
|
|
56 |
|
int FCMIOF_repchar(char c, size_t n) |
57 |
|
{ |
58 |
|
int rv = 0; |
59 |
|
|
60 |
//08/16/01: Visual inspection OK. |
while ((n--) && (rv >= 0)) |
|
void FCMIOF_hline(void) |
|
61 |
{ |
{ |
62 |
FCMIOF_repchar(FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN); |
rv = printf("%c", c); |
|
printf("\n"); |
|
63 |
} |
} |
64 |
|
|
65 |
|
return(rv); |
66 |
|
} |
67 |
|
|
68 |
|
|
69 |
|
int FCMIOF_stream_hline(FILE *s, size_t line_len) |
70 |
|
{ |
71 |
|
int rv; |
72 |
|
|
|
//08/16/01: Visual inspection OK. |
|
|
void FCMIOF_stream_hline(FILE *s) |
|
|
{ |
|
73 |
assert(s != NULL); |
assert(s != NULL); |
74 |
|
|
75 |
FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, FCMIOF_LINE_LEN); |
rv = FCMIOF_stream_repchar(s, FCMIOF_HORIZONTAL_BAR_SEP_CHAR, line_len); |
|
fprintf(s, "\n"); |
|
|
} |
|
76 |
|
|
77 |
|
if (rv >= 0) |
78 |
|
rv = fprintf(s, "\n"); |
79 |
|
|
80 |
//08/16/01: Visual inspection OK. |
return(rv); |
81 |
void FCMIOF_stream_bannerheading(FILE *f, |
} |
|
char *s, |
|
|
int n_extra_lines) |
|
|
{ |
|
|
const int lr_padding = 3; |
|
|
/* The number of spaces on each side of what is printed. |
|
|
*/ |
|
|
int i; |
|
|
/* General iteration variable. |
|
|
*/ |
|
82 |
|
|
|
int n_asterisks; |
|
|
int input_arg_len; |
|
|
int n_left_spaces; |
|
|
int n_right_spaces; |
|
83 |
|
|
84 |
/* Check the file pointer, string pointer, and other par. |
int FCMIOF_hline(size_t line_len) |
85 |
*/ |
{ |
86 |
|
int rv; |
87 |
|
|
88 |
|
rv = FCMIOF_repchar(FCMIOF_HORIZONTAL_BAR_SEP_CHAR, line_len); |
89 |
|
|
90 |
|
if (rv >= 0) //If no error from previous output attempts. |
91 |
|
rv = printf("\n"); //Do the final printf(). |
92 |
|
|
93 |
|
return(rv); |
94 |
|
} |
95 |
|
|
96 |
|
|
97 |
|
int FCMIOF_stream_bannerheading(FILE *f, |
98 |
|
char *s, |
99 |
|
size_t line_len, |
100 |
|
size_t n_extra_lines) |
101 |
|
{ |
102 |
|
size_t lr_padding = 4; |
103 |
|
//The number of spaces on each side of what is printed. |
104 |
|
size_t i; |
105 |
|
//General iteration variable. |
106 |
|
size_t length_limit; |
107 |
|
//The maximum length-related value that will be used for |
108 |
|
//calculation. This is to prevent overflow and incorrect |
109 |
|
//results in logical expressions. |
110 |
|
size_t input_arg_len; |
111 |
|
//Length of the banner heading provided by the caller. May |
112 |
|
//be clipped to prevent logical errors. |
113 |
|
size_t total_padding_chars, total_padding_chars_left, total_padding_chars_right; |
114 |
|
//The total number of characters available for padding, and the |
115 |
|
//number that will be used on the left, and on the right. This |
116 |
|
//includes asterisks, and spaces. |
117 |
|
size_t n_left_asterisks, n_right_asterisks; |
118 |
|
//The number of asterisks that will be printed on the left and right, respectively. |
119 |
|
|
120 |
|
int rv = 0; |
121 |
|
|
122 |
|
//Check the file pointer, string pointer, and other parameters. |
123 |
assert(f != NULL); |
assert(f != NULL); |
124 |
assert(s != NULL); |
assert(s != NULL); |
|
assert(n_extra_lines >= 0); |
|
125 |
|
|
126 |
/* Print the right number of solid lines of asterisks to the |
//Figure out how many asterisks to print on each side of the |
127 |
** standard output. |
//argument, and how many spaces. We also need to figure out |
128 |
*/ |
//how many characters of the input argument to print--if there |
129 |
for (i=0; i<n_extra_lines; i++) |
//are too many characters, we need to truncate. |
130 |
{ |
|
131 |
FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN); |
//Figure out the length of the string passed by the caller. |
|
fprintf(f, "\n"); |
|
|
} |
|
|
|
|
|
/* Figure out how many asterisks to print on each side of the |
|
|
** argument, and how many spaces. We also need to figure out |
|
|
** how many characters of the input argument to print--if there |
|
|
** are too many characters, we need to truncate. |
|
|
*/ |
|
132 |
input_arg_len = strlen(s); |
input_arg_len = strlen(s); |
|
if(input_arg_len > (FCMIOF_LINE_LEN - 2 * lr_padding - 2)) |
|
|
input_arg_len = FCMIOF_LINE_LEN - 2 * lr_padding - 2; |
|
133 |
|
|
134 |
n_asterisks = (FCMIOF_LINE_LEN - 2*lr_padding - input_arg_len)/2; |
//We must trim the parameters involving length to a sane value, otherwise |
135 |
|
//the arithemtic expressions below will break down. There are other ways |
136 |
|
//to handle this, with more branches and less clarity. The C standard |
137 |
|
//specifies that SIZE_MAX must be at least 65535, so SIZE_MAX/32 >= 2047. |
138 |
|
length_limit = SIZE_MAX / 32; |
139 |
|
if (line_len > length_limit) |
140 |
|
line_len = length_limit; |
141 |
|
if (lr_padding > length_limit) |
142 |
|
lr_padding = length_limit; |
143 |
|
if (input_arg_len > length_limit) |
144 |
|
input_arg_len = length_limit; |
145 |
|
|
146 |
|
//Figure out the number of characters available for padding on the left |
147 |
|
//and right. If the total number of characters available is odd, we want |
148 |
|
//few characters on the right. |
149 |
|
if (line_len > input_arg_len) |
150 |
|
total_padding_chars = line_len - input_arg_len; |
151 |
|
else |
152 |
|
total_padding_chars = 0; |
153 |
|
|
154 |
|
if ((total_padding_chars % 2) == 0) |
155 |
|
{ |
156 |
|
//Even. |
157 |
|
total_padding_chars_left = total_padding_chars_right = total_padding_chars / 2; |
158 |
|
} |
159 |
|
else |
160 |
|
{ |
161 |
|
//Odd. |
162 |
|
total_padding_chars_left = total_padding_chars / 2; |
163 |
|
total_padding_chars_right = total_padding_chars_left + 1; |
164 |
|
} |
165 |
|
|
166 |
n_left_spaces = lr_padding; |
//Figure out the number of asterisks on the left. |
167 |
|
if (total_padding_chars_left > lr_padding) |
168 |
|
n_left_asterisks = total_padding_chars_left - lr_padding; |
169 |
|
else |
170 |
|
n_left_asterisks = 0; |
171 |
|
|
172 |
if ((FCMIOF_LINE_LEN - 2*lr_padding - input_arg_len) % 2) |
//Figure out the number of asterisks on the right. |
173 |
{ |
if (total_padding_chars_right > lr_padding) |
174 |
/* Odd, need to pad the right by one. */ |
n_right_asterisks = total_padding_chars_right - lr_padding; |
|
n_right_spaces = lr_padding+1; |
|
|
} |
|
175 |
else |
else |
176 |
{ |
n_right_asterisks = 0; |
177 |
n_right_spaces = lr_padding; |
|
178 |
} |
// Print the correct number of solid lines of asterisks to the |
179 |
|
// standard output. |
180 |
/* Print the text. */ |
for (i = 0; (i < n_extra_lines) && (rv >= 0); i++) |
181 |
FCMIOF_stream_repchar(f, '*', n_asterisks); |
{ |
182 |
FCMIOF_stream_repchar(f, ' ', n_left_spaces); |
rv = FCMIOF_stream_repchar(f, '*', line_len); |
183 |
for (i=0; i<input_arg_len; i++) |
if (rv >= 0) |
184 |
fprintf(f, "%c", s[i]); |
rv = fprintf(f, "\n"); |
185 |
FCMIOF_stream_repchar(f, ' ', n_right_spaces); |
} |
186 |
FCMIOF_stream_repchar(f, '*', n_asterisks); |
|
187 |
fprintf(f, "\n"); |
//return(0); |
188 |
|
|
189 |
|
//If there has been an error in the printing, return. |
190 |
|
if (rv < 0) |
191 |
|
return(rv); |
192 |
|
|
193 |
|
//Left asterisks of banner. |
194 |
|
rv = FCMIOF_stream_repchar(f, '*', n_left_asterisks); |
195 |
|
if (rv < 0) |
196 |
|
return(rv); |
197 |
|
|
198 |
|
//return(0); |
199 |
|
|
200 |
|
//Left spaces of banner. |
201 |
|
rv = FCMIOF_stream_repchar(f, ' ', lr_padding); |
202 |
|
if (rv < 0) |
203 |
|
return(rv); |
204 |
|
|
205 |
|
//The banner text itself. |
206 |
|
for (i = 0; (i < input_arg_len) && (rv >= 0); i++) |
207 |
|
{ |
208 |
|
rv = fprintf(f, "%c", s[i]); |
209 |
|
} |
210 |
|
|
211 |
|
if (rv < 0) |
212 |
|
return(rv); |
213 |
|
|
214 |
|
//Right spaces of banner. |
215 |
|
rv = FCMIOF_stream_repchar(f, ' ', lr_padding); |
216 |
|
if (rv < 0) |
217 |
|
return(rv); |
218 |
|
|
219 |
|
//Right asterisks of banner. |
220 |
|
rv = FCMIOF_stream_repchar(f, '*', n_right_asterisks); |
221 |
|
if (rv < 0) |
222 |
|
return(rv); |
223 |
|
|
224 |
|
//Terminating newline. |
225 |
|
rv = fprintf(f, "\n"); |
226 |
|
if (rv < 0) |
227 |
|
return(rv); |
228 |
|
|
229 |
/* Print the right number of solid lines of asterisks to the |
/* Print the right number of solid lines of asterisks to the |
230 |
** standard output. |
** standard output. |
231 |
*/ |
*/ |
232 |
for (i=0; i<n_extra_lines; i++) |
for (i = 0; (i < n_extra_lines) && (rv >= 0); i++) |
233 |
{ |
{ |
234 |
FCMIOF_stream_repchar(f, '*', FCMIOF_LINE_LEN); |
rv = FCMIOF_stream_repchar(f, '*', line_len); |
235 |
fprintf(f, "\n"); |
if (rv >= 0) |
236 |
} |
rv = fprintf(f, "\n"); |
237 |
} |
} |
238 |
|
|
239 |
|
return(rv); |
240 |
|
} |
241 |
|
|
242 |
//08/16/01: Visual inspection OK. |
int FCMIOF_bannerheading(char *s, size_t line_len, size_t n_extra_lines) |
|
void FCMIOF_bannerheading(char *s, int n_extra_lines) |
|
243 |
{ |
{ |
244 |
|
int rv; |
245 |
|
|
246 |
assert(s != NULL); |
assert(s != NULL); |
|
assert(n_extra_lines >= 0); |
|
247 |
|
|
248 |
FCMIOF_stream_bannerheading(stdout, s, n_extra_lines); |
rv = FCMIOF_stream_bannerheading(stdout, s, line_len, n_extra_lines); |
|
} |
|
249 |
|
|
250 |
|
return(rv); |
251 |
|
} |
252 |
|
|
253 |
void FCMIOF_time_stream(FILE *s, time_t ltime) |
void FCMIOF_time_stream(FILE *s, time_t ltime) |
254 |
{ |
{ |