C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
Field Editor

File mapping, user input, command processing, and display logic. More...

Functions

int field_editor (Form *form)
 Accept input for a field.
int form_display_field (Form *form)
 Display current field.
int form_display_field_n (Form *form, uint n)
 Display field n.
int form_fmt_field (Form *form, char *s)
 Format field according to its format type.
int form_validate_field (Form *form)
 Validate current field based on flags.
bool is_valid_date (uint yyyy, uint mm, uint dd)
 Check if a given date is valid, including leap years.
bool is_valid_time (uint hh, uint mm, uint ss)
 Check if a given time is valid.
void left_justify (char *s)
 Left justify string by removing leading spaces.
void numeric (char *d, char *s)
 Extract numeric characters from source string to destination string.
void right_justify (char *, uint)
 Right justify string by removing trailing spaces and adding leadingspaces.

Detailed Description

File mapping, user input, command processing, and display logic.

Main loop for field editing and entry

This function handles the main loop for field editing and entry. It processes user input, including character input, navigation keys, and mouse events, to allow the user to edit the content of a field. The function validates input based on the field's specified format and updates the display accordingly. It returns the key code of the action taken, such as accepting the field, tabbing to the next field, or breaking out of the input loop.

Function Documentation

◆ field_editor()

int field_editor ( Form * form)

Accept input for a field.

Parameters
formPointer to Form structure
Returns
int Key code of action taken

Handles character input, navigation keys, and mouse events for field editing. Validates input based on field format and updates display. Returns key code of action taken (e.g., accept field, tab to next field, break out of input loop).

UIKEY_F10 is the default key for accepting the field and moving to the next field

UIKEY_F09 Cancels the current operation

UIKEY_UP, UIKEY_BTAB moves to the previous field

UIKEY_DOWN, TAB moves to the next field

UIKEY_END moves cursor to end of field

< Enter accepts the field and moves to the next field if form->f_erase_remainder is set, it will clear the remaining characters above and after the current cursor location

UIKEY_IC toggles insert mode

UIKEY_DC deletes character at cursor

UIKEY_HOME moves cursor to start of field

UIKEY_BACKSPACE deletes character before cursor

UIKEY_LEFT moves cursor left one character

UIKEY_RIGHT moves cursor right one character

Handles mouse events for field editing

Validates fields based on format

FF_STRING accepts all printable characters and spaces

FF_DECIMAL_INT accepts digits 0 through 9 and decimal point ('.')

FF_HEX_INT accepts digits 0 through 9 and letters A through F (case-insensitive)

FF_FLOAT accepts digits 0 through 9 and decimal point ('.') and negative operator ('-') at the start of the field

FF_DOUBLE accepts digits 0 through 9 and decimal point ('.') and negative operator ('-') at the start of the field

FF_CURRENCY accepts digits 0 through 9 and decimal point ('.') and negative operator ('-') at the start of the field

FF_YYYYMMDD accepts digits 0 through 9

FF_HHMMSS accepts digits 0 through 9

FF_APR accepts digits 0 through 9 and decimal point ('.')

Definition at line 47 of file fields.c.

47 {
48 bool f_insert = false;
49 int in_key;
50 char *s, *d;
52 UiEvent event;
53 uint maxy;
54 if (form->fidx >= form->fcnt)
55 form->fcnt = 0;
56 uint flin = form->field[form->fidx]->line;
57 uint fcol = form->field[form->fidx]->col;
58 uint flen = form->field[form->fidx]->len;
59 uint ff = form->field[form->fidx]->ff;
60 char *accept_s = form->field[form->fidx]->accept_s;
61 form_fmt_field(form, accept_s);
62 click_x = click_y = -1;
63 char *fstart = accept_s;
64 char *fend = fstart + flen;
65 uint x = fcol;
66 char *p = fstart = accept_s;
67 char *str_end = p + strlen(p);
68 in_key = 0;
69 if (f_insert)
71 else
72 ui_set_chyron_key_cb(form->chyron, 18, "INS", UIKEY_IC, cell_nt_rev);
73 ui_compile_chyron(form->chyron);
74 ui_display_chyron(sfc, 1, form->chyron, form->lines - 1, form->chyron->l);
75
76 while (1) {
77 if (in_key == 0) {
78 form_fmt_field(form, accept_s);
80 tcflush(0, TCIFLUSH);
81
82 ui_cursor_enable_yx(sfc, WIN, flin, x, true);
83 ui_render();
84 in_key = ui_get_event(sfc, WIN, form->chyron, &event, -1);
85 ui_cursor_enable_yx(sfc, WIN, flin, x, false);
86
87 maxy = ui_getmaxy(sfc, WIN);
88 if (event.in_win == WIN && event.y == maxy - 1)
89 in_key = ui_get_chyron_key(form->chyron, event.x);
90 }
91 ui_curs_set(0);
92 switch (in_key) {
95 case UIKEY_F10:
96 form_fmt_field(form, accept_s);
98 if (form_validate_field(form) != 0)
99 continue;
100 return (in_key);
102 case UIKEY_F09:
104 in_key = UIKEY_F09;
105 return (in_key);
107 case 'H':
108 case UIKEY_F01:
109 return (in_key);
110 case UIKEY_UP:
111 form_fmt_field(form, accept_s);
113 in_key = UIKEY_UP;
114 return (in_key);
116 case '\t':
117 case UIKEY_DOWN:
118 form_fmt_field(form, accept_s);
120 in_key = UIKEY_DOWN;
121 return (in_key);
123 case UIKEY_END:
124 case Ctrl('e'):
125 while (*p != '\0')
126 p++;
127 x = fcol + (p - fstart);
128 in_key = 0;
129 continue;
133 case '\n':
134 case UIKEY_ENTER:
135 if (form->f_erase_remainder)
136 *p = '\0';
137 form_fmt_field(form, accept_s);
139 in_key = UIKEY_ENTER;
140 return (in_key);
142 case UIKEY_IC:
143 if (f_insert) {
144 f_insert = false;
145 ui_set_chyron_key_cb(form->chyron, 18, "INS", UIKEY_IC, cell_nt_rev);
146 } else {
147 f_insert = true;
148 ui_set_chyron_key_cb(form->chyron, 18, "INS", UIKEY_IC,
150 }
151 ui_compile_chyron(form->chyron);
152 ui_display_chyron(sfc, 1, form->chyron, form->lines - 1,
153 form->chyron->l);
154 in_key = 0;
155 continue;
157 case UIKEY_DC:
158 s = p + 1;
159 d = p;
160 while (*s != '\0')
161 *d++ = *s++;
162 *d = '\0';
163 str_end = d;
164 f_insert = false;
165 in_key = 0;
166 continue;
168 case UIKEY_HOME:
169 case Ctrl('a'):
170 p = fstart;
171 x = fcol;
172 in_key = 0;
173 continue;
175 case UIKEY_BACKSPACE:
176 if (p > fstart) {
177 p--;
178 x--;
179 }
180 s = p + 1;
181 d = p;
182 while (*s != '\0')
183 *d++ = *s++;
184 *d = '\0';
185 str_end = d;
186 in_key = 0;
187 continue;
189 case UIKEY_LEFT:
190 if (p > fstart) {
191 p--;
192 x--;
193 }
194 in_key = 0;
195 continue;
197 case UIKEY_RIGHT:
198 if (p < fend && p < str_end) {
199 p++;
200 x++;
201 }
202 in_key = 0;
203 continue;
205 case UIKEY_BUTTON1:
207 x = click_x;
208 flin = click_y;
209 flen = form->field[form->fidx]->len;
210 ff = form->field[form->fidx]->ff; /* ff - field forat */
211 accept_s = form->field[form->fidx]->accept_s;
212 // filler_s = form->field[form->fidx]->filler_s;
213 form_fmt_field(form, accept_s);
214 fstart = accept_s;
215 fend = fstart + flen;
216 str_end = fstart + strlen(fstart);
217 p = fstart + (x - form->field[form->fidx]->col);
218 if (p > str_end)
219 x -= p - str_end;
220 p = min(p, str_end);
221 in_key = 0;
222 continue;
223 default:
224 if (p >= fend) {
225 in_key = 0;
226 continue;
227 }
229 switch (ff) {
231 case FF_STRING:
232 break;
235 case FF_DECIMAL_INT:
236 if ((in_key >= '0' && in_key <= '9') || in_key == '.')
237 break;
238 in_key = 0;
239 continue;
242 case FF_HEX_INT:
243 if ((in_key >= '0' && in_key <= '9') ||
244 (in_key >= 'A' && in_key <= 'F') ||
245 (in_key >= 'a' && in_key <= 'f'))
246 break;
247 in_key = 0;
248 continue;
251 case FF_FLOAT:
252 if ((in_key >= '0' && in_key <= '9') || in_key == '.' ||
253 (in_key == '-' && p == fstart))
254 break;
255 in_key = 0;
256 continue;
259 case FF_DOUBLE:
260 if ((in_key >= '0' && in_key <= '9') || in_key == '.' ||
261 (in_key == '-' && p == fstart))
262 break;
263 in_key = 0;
264 continue;
268 case FF_CURRENCY:
269 if ((in_key >= '0' && in_key <= '9') || in_key == '.' ||
270 (in_key == '-' && p == fstart))
271 break;
272 in_key = 0;
273 continue;
275 case FF_YYYYMMDD:
276 if (in_key >= '0' && in_key <= '9')
277 break;
278 in_key = 0;
279 continue;
281 case FF_HHMMSS:
282 if (in_key >= '0' && in_key <= '9')
283 break;
284 in_key = 0;
285 continue;
287 case FF_APR:
288 if ((in_key >= '0' && in_key <= '9') || in_key == '.')
289 break;
290 in_key = 0;
291 continue;
292 default:
293 ui_perror(_("field_editor() invalid format"));
294 break;
295 }
296 if (in_key < ' ' || in_key > '~') {
297 in_key = 0;
298 continue;
299 }
300 if (f_insert) {
301 if (str_end < fend) {
302 s = str_end - 1;
303 d = str_end;
304 while (s >= p)
305 *d-- = *s--;
306 *p++ = in_key;
307 str_end++;
308 x++;
309 }
310 } else {
311 if (p < fend) {
312 if (p < str_end) {
313 if (p == accept_s && in_key == ' ') {
314 d = accept_s;
315 s = accept_s + 1;
316 while (*s != '\0')
317 *d++ = *s++;
318 *d = '\0';
319 in_key = 0;
320 continue;
321 }
322 *p++ = in_key;
323 x++;
324 } else if (p == str_end) {
325 *p++ = in_key;
326 *p = '\0';
327 str_end = p;
328 x++;
329 }
330 }
331 }
332 in_key = 0;
333 continue;
334 }
335 }
336}
@ FF_DECIMAL_INT
Definition form.h:50
@ FF_STRING
Definition form.h:48
@ FF_HEX_INT
Definition form.h:52
@ FF_YYYYMMDD
Definition form.h:61
@ FF_HHMMSS
Definition form.h:63
@ FF_CURRENCY
Definition form.h:58
@ FF_FLOAT
Definition form.h:54
@ FF_DOUBLE
Definition form.h:56
@ FF_APR
Definition form.h:65
#define min(x, y)
min macro evaluates two expressions, returning least result
Definition cm.h:104
#define Ctrl(c)
Definition cm.h:67
void ui_render()
Render the UI by updating panels and refreshing the display.
Definition ui_ncurses.c:884
UiCell cell_nt_hl_rev
Definition ui_common.c:109
int ui_cursor_enable_yx(UiSurface *s, ss_t w, uint y, uint x, bool visible)
Enable or disable the cursor at a specific position within a UiSurface.
Definition ui_ncurses.c:855
int ui_getmaxy(UiSurface *s, ss_t w)
Get the maximum number of lines (rows) of a UiSurface.
Definition ui_ncurses.c:701
int click_x
Definition ui_common.c:30
int sfc_ptr
Definition ui_ncurses.c:42
int ui_curs_set(int visibility)
Set the visibility of the cursor.
Definition ui_ncurses.c:840
int click_y
Definition ui_common.c:29
UiCell cell_nt_rev
Definition ui_common.c:107
#define UIKEY_DC
#define UIKEY_BACKSPACE
#define UIKEY_LEFT
#define UIKEY_F09
#define UIKEY_IC
#define UIKEY_END
#define UIKEY_F01
#define UIKEY_BUTTON1
#define UIKEY_RIGHT
#define UIKEY_UP
#define UIKEY_F10
#define UIKEY_HOME
#define UIKEY_ENTER
#define UIKEY_DOWN
int ui_get_event(UiSurface *s, ss_t w, UiChyron *chyron, UiEvent *ev, int timeout_ms)
Read input events.
void ui_display_chyron(UiSurface *sfc, ss_t w, UiChyron *chyron, uint line, uint col)
Display chyron on the specified line and column of the surface.
Definition ui_common.c:837
void ui_set_chyron_key_cb(UiChyron *chyron, uint k, char *s, uint kc, UiCell cell_base)
Set chyron key with color pair (cp).
Definition ui_common.c:693
int ui_get_chyron_key(UiChyron *chyron, uint x)
Get keycode from chyron.
Definition ui_common.c:861
void ui_compile_chyron(UiChyron *chyron)
construct the chyron string from the chyron structure
Definition ui_common.c:782
UiSurface * ui_surface[UI_SFC_MAX]
Definition ui_ncurses.c:40
Form * form
Definition mem.c:37
uint form_yx_to_fidx(Form *, uint, uint)
#define _(String)
Definition amort.c:23
int form_display_accept_field(Form *)
Definition fields.c:388
int form_fmt_field(Form *form, char *s)
Format field according to its format type.
Definition fields.c:449
int form_display_field(Form *)
Display current field.
Definition fields.c:370
int form_validate_field(Form *)
Validate current field based on flags.
Definition fields.c:545
int ui_perror(char *emsg_str)
Display a simple error message window or print to stderr.
Definition ui_common.c:1257
ss_t in_win
Definition ui_backend.h:112

References Field::accept_s, cell_nt_hl_rev, cell_nt_rev, Form::chyron, click_x, click_y, Field::col, Form::f_erase_remainder, Form::fcnt, Field::ff, FF_APR, FF_CURRENCY, FF_DECIMAL_INT, FF_DOUBLE, FF_FLOAT, FF_HEX_INT, FF_HHMMSS, FF_STRING, FF_YYYYMMDD, Form::fidx, Form::field, form_display_accept_field(), form_display_field(), form_fmt_field(), form_validate_field(), form_yx_to_fidx(), UiEvent::in_win, Field::len, Field::line, Form::lines, sfc_ptr, ui_compile_chyron(), ui_curs_set(), ui_cursor_enable_yx(), ui_display_chyron(), ui_get_chyron_key(), ui_get_event(), ui_getmaxy(), ui_perror(), ui_render(), ui_set_chyron_key_cb(), ui_surface, UiEvent::x, and UiEvent::y.

Referenced by field_navigator().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ form_display_field()

int form_display_field ( Form * form)

Display current field.

Parameters
formPointer to Form structure
Returns
0 on success, non-zero on error

This function displays the current field based on the form's current field index (fidx). It retrieves the line and column information for the current field, displays any brackets if set, and then displays the field's content using the display_s string. The function ensures that the field is displayed correctly within the form's window and refreshes the display to show the updated field content.

Definition at line 370 of file fields.c.

370 {
372 uint y = form->field[form->fidx]->line;
373 uint x = form->field[form->fidx]->col;
374
375 uint pos = 0;
376 ui_mbstr_to_cellstr(sfc, WIN, form->field[form->fidx]->filler_cc, form->field[form->fidx]->filler_s, &cell_nt, &pos,
377 form->field[form->fidx]->len + 1);
378 ui_mvwadd_wchnstr(sfc, WIN, y, x, form->field[form->fidx]->filler_cc, form->field[form->fidx]->len);
379 ui_render();
380
381 pos = 0;
382 ui_mbstr_to_cellstr(sfc, WIN, form->field[form->fidx]->display_cc, form->field[form->fidx]->display_s, &cell_nt, &pos,
383 form->field[form->fidx]->len + 1);
384 ui_mvwadd_wchnstr(sfc, WIN, y, x, form->field[form->fidx]->display_cc, form->field[form->fidx]->len);
385 ui_render();
386 return 0;
387}
UiCell cell_nt
Definition ui_common.c:106
uint ui_mbstr_to_cellstr(UiSurface *sfc, ss_t w, UiCell *cmplx_buf, const char *str, const UiCell *cell_base, uint *p, const uint atmost)
Convert multibyte string to complex character array (Notcurses version).
int ui_mvwadd_wchnstr(UiSurface *s, ss_t w, uint y, uint x, const UiCell *cmplx_buf, uint n)
Draw a complex character string at a specific position in a surface window, with a maximum length.

References cell_nt, Field::col, Field::display_cc, Field::display_s, Form::fidx, Form::field, Field::filler_cc, Field::filler_s, Field::len, Field::line, sfc_ptr, ui_mvwadd_wchnstr(), ui_render(), and ui_surface.

Referenced by field_editor(), and form_display_field_n().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ form_display_field_n()

int form_display_field_n ( Form * form,
uint n )

Display field n.

Parameters
formPointer to Form structure
nField index to display
Returns
0 on success, non-zero on error

This function temporarily sets the form's current field index (fidx) to n, calls form_display_field() to display that field, and then restores the original fidx value. This allows for displaying a specific field without permanently changing the form's current field index.

Definition at line 348 of file fields.c.

348 {
349 uint fidx = form->fidx;
350 form->fidx = n;
352 form->fidx = fidx;
353 return 0;
354}

References Form::fidx, and form_display_field().

Here is the call graph for this function:

◆ form_fmt_field()

int form_fmt_field ( Form * form,
char * s )

Format field according to its format type.

Parameters
formPointer to Form structure
sInput string to format
Returns
0 on success, non-zero on error

takes the input string for the current field and formats it according to the field's specified format type (ff). It updates the accept_s and display_s strings for the field based on the formatted value. Handles various format types, including strings, decimal integers, hexadecimal integers, floating-point numbers, currency, dates, and times. Uses helper functions for validation and formatting, such as is_valid_date(), is_valid_time(), numeric(), right_justify(), left_justify(), and strnzcpy(). The function ensures that the formatted output fits within the field's length and creates a filler string for the field as needed. The function also handles error cases, such as invalid formats, and provides feedback through error messages. It is designed to be extensible, allowing for additional format types to be added in the future as needed. Assumes that the input string is well-formed and does not contain malicious content. Input validation and sanitization should be performed at a higher level in the application to ensure security and robustness. The function currently does not handle localization or internationalization of number formats, such as different decimal separators or currency symbols. Future enhancements may include support for locale-specific formatting. Error handling is basic; future versions may include more detailed error reporting and logging mechanisms. Performance optimizations may be considered for handling large volumes of data or high-frequency updates in real-time applications. The following variables and structures are used in this function:

char field_s[FIELD_MAXLEN];
int decimal_int_n = 0;
int hex_int_n = 0;
float float_n = 0.0;
double double_n = 0.0;
double currency_n = 0.0;
struct Date { int yyyy; int mm; int dd; };
struct Time { int hh; int mm; int ss; };
#define FIELD_MAXLEN
Definition form.h:18
Definition cm.h:70
uint mm
Definition cm.h:72
uint dd
Definition cm.h:73
uint yyyy
Definition cm.h:71
Definition cm.h:76
uint hh
Definition cm.h:77
uint mm
Definition cm.h:78
uint ss
Definition cm.h:79

Definition at line 449 of file fields.c.

449 {
450 strnz__cpy(form->field[form->fidx]->input_s, s, FIELD_MAXLEN - 1);
451 char *input_s = form->field[form->fidx]->input_s;
452 char *accept_s = form->field[form->fidx]->accept_s;
453 char *display_s = form->field[form->fidx]->display_s;
454 // char *filler_s = form->field[form->fidx]->filler_s;
455 uint ff = form->field[form->fidx]->ff;
456 uint fl = form->field[form->fidx]->len;
457
458 char field_s[FIELD_MAXLEN];
459 uint decimal_int_n = 0;
460 uint hex_int_n = 0;
461 float float_n = 0.0;
462 double double_n = 0.0;
463 double currency_n = 0.0;
464 Date date;
465 date.yyyy = date.mm = date.dd = 0;
466 Time time;
467 time.hh = time.mm = time.ss = 0;
468
469 strnz(accept_s, fl);
470 switch (ff) {
471 case FF_STRING:
472 left_justify(s);
473 trim(s);
474 strnz__cpy(input_s, s, FIELD_MAXLEN - 1);
475 strnz__cpy(accept_s, s, FIELD_MAXLEN - 1);
476 strnz__cpy(display_s, s, FIELD_MAXLEN - 1);
477 break;
478 case FF_DECIMAL_INT:
479 sscanf(input_s, "%d", &decimal_int_n);
480 sprintf(accept_s, "%d", decimal_int_n);
481 sprintf(display_s, "%d", decimal_int_n);
482 right_justify(display_s, fl);
483 break;
484 case FF_HEX_INT:
485 sscanf(input_s, "%x", &hex_int_n);
486 sprintf(accept_s, "%d", hex_int_n);
487 sprintf(display_s, "%x", hex_int_n);
488 right_justify(display_s, fl);
489 break;
490 case FF_FLOAT:
491 sscanf(input_s, "%f", &float_n);
492 sprintf(accept_s, "%f", float_n);
493 sprintf(display_s, "%f", float_n);
494 right_justify(display_s, fl);
495 break;
496 case FF_DOUBLE:
497 sscanf(input_s, "%lf", &double_n);
498 sprintf(accept_s, "%lf", double_n);
499 sprintf(display_s, "%lf", double_n);
500 right_justify(display_s, fl);
501 break;
502 case FF_CURRENCY:
503 numeric(field_s, input_s);
504 sscanf(field_s, "%lf", &currency_n);
505 sprintf(accept_s, "%.2lf", currency_n);
506 sprintf(display_s, "%'.2lf", currency_n);
507 right_justify(display_s, fl);
508 break;
509 case FF_YYYYMMDD:
510 date.yyyy = date.mm = date.dd = 0;
511 strnz__cpy(field_s, input_s, FIELD_MAXLEN - 1);
512 sscanf(field_s, "%4d%2d%2d", &date.yyyy, &date.mm, &date.dd);
513 sprintf(accept_s, "%04d%02d%02d", date.yyyy, date.mm, date.dd);
514 if (is_valid_date(date.yyyy, date.mm, date.dd))
515 sprintf(display_s, "%04d-%02d-%02d", date.yyyy, date.mm, date.dd);
516 break;
517 case FF_HHMMSS:
518 time.hh = time.mm = time.ss = 0;
519 strnz__cpy(field_s, input_s, FIELD_MAXLEN - 1);
520 sscanf(field_s, "%2d%2d%2d", &time.hh, &time.mm, &time.ss);
521 sprintf(accept_s, "%02d%02d%02d", time.hh, time.mm, time.ss);
522 if (is_valid_time(time.hh, time.mm, time.ss))
523 sprintf(display_s, "%02d:%02d:%02d", time.hh, time.mm, time.ss);
524 break;
525 case FF_APR:
526 sscanf(input_s, "%lf", &double_n);
527 sprintf(accept_s, "%lf", double_n);
528 sprintf(display_s, "%0.3lf", double_n);
529 right_justify(display_s, fl);
530 break;
531 default:
532 ui_perror(_("form_fmt_field() invalid format"));
533 break;
534 }
535 strnz(accept_s, fl);
536 left_justify(accept_s);
537 return 0;
538}
bool is_valid_date(uint yyyy, uint mm, uint dd)
Check if a given date is valid, including leap years.
Definition fields.c:612
void numeric(char *d, char *s)
Extract numeric characters from source string to destination string.
Definition fields.c:649
bool is_valid_time(uint hh, uint mm, uint ss)
Check if a given time is valid.
Definition fields.c:633
void right_justify(char *, uint)
Right justify string by removing trailing spaces and adding leadingspaces.
Definition fields.c:586
void left_justify(char *s)
Left justify string by removing leading spaces.
Definition fields.c:573
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition whence.c:291
size_t trim(char *)
Trims leading and trailing spaces from string s in place.
Definition futil.c:361
size_t strnz(char *, size_t)
terminates string at New Line, Carriage Return, or max_len
Definition futil.c:599

References Field::accept_s, Date::dd, Field::display_s, Field::ff, FF_APR, FF_CURRENCY, FF_DECIMAL_INT, FF_DOUBLE, FF_FLOAT, FF_HEX_INT, FF_HHMMSS, FF_STRING, FF_YYYYMMDD, Form::fidx, Form::field, Time::hh, Field::input_s, is_valid_date(), is_valid_time(), left_justify(), Field::len, Date::mm, Time::mm, numeric(), right_justify(), Time::ss, strnz(), strnz__cpy(), trim(), ui_perror(), and Date::yyyy.

Referenced by field_editor(), and form_read_data().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ form_validate_field()

int form_validate_field ( Form * form)

Validate current field based on flags.

Parameters
formPointer to Form structure
Returns
0 if valid, 1 if invalid

Very underdeveloped - only checks F_NOTBLANK and F_NOMETAS

Definition at line 545 of file fields.c.

545 {
546 uint n = form->fidx;
547 char *p = form->field[n]->accept_s;
548 if (form->field[n]->ff & F_NOTBLANK) {
549 char *s = form->field[n]->accept_s;
550 while (*s++ == ' ')
551 ;
552 if (*s == '\0') {
553 ui_perror(_("blank field not allowed"));
554 return (1);
555 }
556 }
557 if (form->field[n]->ff & F_NOMETAS) {
558 if (strpbrk(p, "*?[]") != 0) {
559 ui_perror(_("metacharacters not allowed"));
560 return (1);
561 }
562 }
563 return (0);
564}
#define F_NOTBLANK
Definition form.h:21
#define F_NOMETAS
Definition form.h:20

References Field::accept_s, Field::ff, Form::fidx, Form::field, and ui_perror().

Referenced by field_editor().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ is_valid_date()

bool is_valid_date ( uint yyyy,
uint mm,
uint dd )

Check if a given date is valid, including leap years.

Parameters
yyyyYear
mmMonth
ddDay
Returns
true if the date is valid, false otherwise

This function checks if the provided year, month, and day constitute a valid date. It accounts for leap years when determining the number of days in February. The function returns true if the date is valid and false if it is not.

Definition at line 612 of file fields.c.

612 {
613 if (yyyy < 1 || mm < 1 || mm > 12 || dd < 1)
614 return false;
615 uint days_in_month[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
616 if ((yyyy % 4 == 0 && yyyy % 100 != 0) || (yyyy % 400 == 0))
617 days_in_month[2] = 29;
618 if (dd > days_in_month[mm])
619 return false;
620 return true;
621}

◆ is_valid_time()

bool is_valid_time ( uint hh,
uint mm,
uint ss )

Check if a given time is valid.

Parameters
hhHour
mmMinute
ssSecond
Returns
true if the time is valid, false otherwise

This function checks if the provided hour, minute, and second constitute a valid time. It ensures that hours are between 0 and 23, minutes and seconds are between 0 and 59. The function returns true if the time is valid and false if it is not.

Definition at line 633 of file fields.c.

633 {
634 if (hh > 23 || mm > 59 || ss > 59)
635 return false;
636 return true;
637}

◆ left_justify()

void left_justify ( char * s)

Left justify string by removing leading spaces.

Parameters
sString to left justify

This function takes a string s and removes any leading spaces, effectively left-justifying the text. It does this by finding the first non-space character and shifting the string to the left, overwriting the leading spaces. The resulting string is null-terminated.

Definition at line 573 of file fields.c.

573{ trim(s); }

◆ numeric()

void numeric ( char * d,
char * s )

Extract numeric characters from source string to destination string.

Parameters
dDestination string
sSource string

This function takes a source string s and extracts only the numeric characters (digits 0-9), as well as dashes ('-') and periods ('.'), copying them into the destination string d. The resulting string in d is null-terminated. This is useful for processing input that may contain non-numeric characters, allowing the application to focus on the numeric content for further processing or validation.

Definition at line 649 of file fields.c.

649 {
650 while (*s != '\0') {
651 if (*s == '-' || *s == '.' || (*s >= '0' && *s <= '9'))
652 *d++ = *s++;
653 else
654 s++;
655 }
656 *d = '\0';
657}

◆ right_justify()

void right_justify ( char * s,
uint fl )

Right justify string by removing trailing spaces and adding leadingspaces.

Parameters
sString to right justify
flField length

This function takes a string s and right-justifies it within a field of length fl. It first removes any trailing spaces from the string, then shifts the characters to the right end of the field, filling the left side with spaces. The resulting string is null-terminated and fits within the specified field length.

Definition at line 586 of file fields.c.

586 {
587 char *p = s;
588 char *d = s + fl;
589 trim(s);
590 *d = '\0';
591 while (*s != '\0') {
592 s++;
593 }
594 while (s != p) {
595 *(--d) = *(--s);
596 }
597 while (d != p) {
598 *(--d) = ' ';
599 }
600}