C-Menu 0.2.9
A User Interface Toolkit
Loading...
Searching...
No Matches
Form Engine

Parses Form Descriptions, Handles User Input, and Integrates with External Commands for Calculations and Data Processing. More...

Functions

unsigned int display_form (Init *init)
 Display the form on the screen, including text elements and fields, and set up the form window based on the form configuration.
int field_navigator (Form *form)
 Handle user input for field entry, allowing navigation between fields and looping until an exit action is selected.
int form_desc_error (int in_line_num, char *in_buf, char *em)
 Handle errors encountered while parsing the form description file, providing detailed error messages that include the file name, line number, and the specific error encountered.
void form_display_fields (Form *form)
 Display form fields on the screen, populating field values and formatting them according to the form configuration.
int form_engine (Init *init)
 Form main processing loop.
int form_exec_cmd (Form *form)
 Execute a command specified in the form description file, passing form field values as arguments, and optionally redirecting output to a file.
int form_exec_receiver (Init *init)
 Execute a command specified by the -R option on the form command line.
int form_parse_desc (Form *form)
 Parse the form description file to populate the Form data structure with field definitions, text elements, and other configuration specified in the description file.
int form_post (Init *init)
 Handle post-processing after field entry, allowing user to edit data, execute a provider command, or write data to an output file.
int form_process (Init *init)
 Handle integration with a getter program which will provide field data.
int form_read_data (Form *form)
 Read initial data for form fields from a specified input source, such as a file or standard input, and populate the form fields with the data.
int form_write (Form *form)
 Write form field values to a specified output destination, such as a file or standard output, based on the form configuration and user input.
int init_form (Init *init, int argc, char **argv, int begy, int begx)
 Initialize form data structure and parse description file.

Detailed Description

Parses Form Descriptions, Handles User Input, and Integrates with External Commands for Calculations and Data Processing.

Function Documentation

◆ display_form()

unsigned int display_form ( Init * init)

Display the form on the screen, including text elements and fields, and set up the form window based on the form configuration.

Parameters
initA pointer to the Init structure containing form data and state.
Returns
0 on success, or a non-zero value if an error occurs while creating the form window or rendering the form elements.

Definition at line 486 of file form_engine.c.

486 {
487 int n, flin, fcol;
488 char tmp_str[MAXLEN];
489
490 form = init->form;
491 form->lines = 0;
492 for (n = 0; n < form->dcnt; n++)
493 if (form->text[n]->line > form->lines)
494 form->lines = form->text[n]->line;
495 for (n = 0; n < form->fcnt; n++)
496 if (form->field[n]->line > form->lines)
497 form->lines = form->field[n]->line;
498 form->lines += 3;
499 if (form->lines > (LINES - form->begy))
500 form->lines = LINES - form->begy;
501 for (n = 0; n < form->fcnt; n++) {
502 if (form->field[n]->line >= (form->lines - 2))
503 form->fcnt = n;
504 }
505 form->cols += 2;
506 if (form->cols > (COLS - form->begx - 3))
507 form->cols = COLS - form->begx - 3;
508 if (box_new(form->lines, form->cols, form->begy, form->begx, form->title,
509 true)) {
510 strnz__cpy(tmp_str, "box_new failed: ", MAXLEN - 1);
511 strnz__cat(tmp_str, form->title, MAXLEN - 1);
512 Perror(tmp_str);
513 return (1);
514 }
515#ifdef DEBUG_IMMEDOK
516 immedok(form->win, TRUE);
517#endif
518 form->box = win_box[win_ptr];
519 form->win = win_win[win_ptr];
520 wnoutrefresh(form->win);
521 for (form->fidx = 0; form->fidx < form->fcnt; form->fidx++) {
522 if (form->brackets[0] != '\0' && form->brackets[1] != '\0') {
523 flin = form->field[form->fidx]->line + 1;
524 fcol = form->field[form->fidx]->col;
525 // mvwadd_wch(form->box, flin, fcol, &form->brktl);
526 mvwaddch(form->box, flin, fcol, form->brackets[0]);
527 fcol += form->field[form->fidx]->len + 1;
528 // mvwadd_wch(box, flin, fcol, &form->brktr);
529 mvwaddch(form->box, flin, fcol, form->brackets[1]);
530 }
531 }
532 wnoutrefresh(form->box);
533 for (n = 0; n < form->dcnt; n++) {
534 strnz(form->text[n]->str, form->cols - 3);
535 mvwaddstr(form->win, form->text[n]->line, form->text[n]->col,
536 form->text[n]->str);
537 wnoutrefresh(form->win);
538 }
540 return 0;
541}
Form * form
Definition mem.c:47
Init * init
Definition init.c:74
#define TRUE
Definition iloan.c:19
#define MAXLEN
Definition curskeys.c:15
WINDOW * win_win[MAXWIN]
Definition dwin.c:122
int win_ptr
Definition dwin.c:130
WINDOW * win_box[MAXWIN]
Definition dwin.c:124
int box_new(int, int, int, int, char *, bool)
Create a new window with optional box and title.
Definition dwin.c:745
int Perror(char *)
Display a simple error message window or print to stderr.
Definition dwin.c:1162
void form_display_fields(Form *)
Display form fields on the screen, populating field values and formatting them according to the form ...
size_t strnz__cpy(char *, const char *, size_t)
safer alternative to strncpy
Definition futil.c:435
size_t strnz(char *, size_t)
terminates string at New Line, Carriage Return, or max_len
Definition futil.c:506
size_t strnz__cat(char *, const char *, size_t)
safer alternative to strncat
Definition futil.c:464

References Form::begx, Form::begy, Form::box, box_new(), Form::brackets, Field::col, Text::col, Form::cols, Form::dcnt, Form::fcnt, Form::fidx, Form::field, form, Init::form, form_display_fields(), Field::len, Field::line, Text::line, Form::lines, Perror(), Text::str, strnz(), strnz__cat(), strnz__cpy(), Form::text, Form::title, Form::win, win_box, win_ptr, and win_win.

Referenced by form_engine().

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

◆ field_navigator()

int field_navigator ( Form * form)

Handle user input for field entry, allowing navigation between fields and looping until an exit action is selected.

Parameters
formA pointer to the Form structure containing form data and state.
Returns
An integer status code indicating the next action for the form processing loop (e.g., FA_ACCEPT, FA_HELP, FA_CALC, FA_CANCEL).

This function manages user input for field entry, including navigation between fields and handling of special keys for accepting, canceling, requesting help, or performing calculations. The function loops until the user selects an exit action (e.g., accept or cancel).

Definition at line 426 of file form_engine.c.

426 {
427
428 if (form->fidx < 0)
429 return (-1);
430 while (1) {
432
433 switch (cmd_key) {
434 case KEY_F(10):
435 return (FA_ACCEPT);
436 case KEY_F(1):
437 return (FA_HELP);
438 case KEY_F(5):
439 if (form->f_process)
440 return (FA_CALC);
441 break;
442 case KEY_F(9):
443 return (FA_CANCEL);
444 case 'k':
445 case KEY_UP:
446 if (form->fidx != 0)
447 form->fidx--;
448 break;
449 case '\r':
450 case KEY_ENTER:
451 if (form->fidx < form->fcnt - 1)
452 form->fidx++;
453 else if (form->fidx == form->fcnt - 1)
454 return (FA_ACCEPT);
455 break;
456 case 'j':
457 case KEY_DOWN:
458 if (form->fidx < form->fcnt - 1)
459 form->fidx++;
460 else if (form->fidx == form->fcnt - 1)
461 return (FA_ACCEPT);
462 break;
463 case KEY_MOUSE:
464 break;
465 default:
466 break;
467 }
468 }
469}
@ FA_ACCEPT
Definition form.h:30
@ FA_CALC
Definition form.h:38
@ FA_HELP
Definition form.h:32
@ FA_CANCEL
Definition form.h:34
unsigned int cmd_key
Definition dwin.c:126
int field_editor(Form *)
Accept input for a field.
Definition fields.c:55

References cmd_key, Form::f_process, FA_ACCEPT, FA_CALC, FA_CANCEL, FA_HELP, Form::fcnt, Form::fidx, and field_editor().

Referenced by form_engine().

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

◆ form_desc_error()

int form_desc_error ( int in_line_num,
char * in_buf,
char * em )

Handle errors encountered while parsing the form description file, providing detailed error messages that include the file name, line number, and the specific error encountered.

Parameters
in_line_numThe line number in the description file where the error occurred.
in_bufThe content of the line that caused the error, for context.
emA specific error message describing the nature of the error.
Returns
An integer status code indicating how the user responded to the error message (e.g., which key they pressed to acknowledge the error).

Definition at line 1086 of file form_engine.c.

1086 {
1087 int cmd_key;
1088
1089 ssnprintf(em0, MAXLEN - 1, "%s: %s", __FILE__, em);
1090 ssnprintf(em1, MAXLEN - 1, "Desc file: %s, line: %d", form->mapp_spec,
1091 in_line_num);
1092 strnz__cpy(em2, in_buf, MAXLEN - 1);
1093 cmd_key = display_error(em0, em1, em2, nullptr);
1094 return cmd_key;
1095}
char em1[MAXLEN]
Definition dwin.c:142
char em0[MAXLEN]
Definition dwin.c:141
char em2[MAXLEN]
Definition dwin.c:143
int display_error(char *em0, char *em1, char *em2, char *em3)
Display an error message window or print to stderr.
Definition dwin.c:1102
size_t ssnprintf(char *, size_t, const char *,...)
ssnprintf was designed to be a safer alternative to snprintf.
Definition futil.c:311

References display_error(), em0, em1, em2, form, Form::mapp_spec, ssnprintf(), and strnz__cpy().

Referenced by form_parse_desc().

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

◆ form_display_fields()

void form_display_fields ( Form * form)

Display form fields on the screen, populating field values and formatting them according to the form configuration.

Parameters
formA pointer to the Form structure containing form data and state.

This function iterates through the defined form fields, formats their display values based on the specified fill character and field length, and renders them on the form window. It also updates the chyron with available commands for user interaction.

Definition at line 551 of file form_engine.c.

551 {
552 int flin, fcol;
553 char fill_char = form->fill_char[0];
554 for (form->fidx = 0; form->fidx < form->fcnt; form->fidx++) {
555 if (form->field[form->fidx]->col + form->field[form->fidx]->len + 2 >
556 form->cols)
557 form->field[form->fidx]->len =
558 form->cols - (form->field[form->fidx]->col + 2);
559 strnfill(form->field[form->fidx]->filler_s, fill_char,
560 form->field[form->fidx]->len);
561 strnz(form->field[form->fidx]->display_s, form->field[form->fidx]->len);
562 flin = form->field[form->fidx]->line;
563 fcol = form->field[form->fidx]->col;
564 mvwaddstr(form->win, flin, fcol, form->field[form->fidx]->filler_s);
565 mvwaddstr(form->win, flin, fcol, form->field[form->fidx]->display_s);
566 wnoutrefresh(form->win);
567 }
568 return;
569}
bool strnfill(char *, char, int)
Fills string s with character c n.
Definition futil.c:606

References Field::col, Form::cols, Field::display_s, Form::fcnt, Form::fidx, Form::field, Form::fill_char, Field::filler_s, Field::len, Field::line, strnfill(), strnz(), and Form::win.

Referenced by display_form(), and form_process().

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

◆ form_engine()

int form_engine ( Init * init)

Form main processing loop.

Parameters
initA pointer to the Init structure containing form data and state.
Returns
0 on successful completion, or a non-zero value if the user cancels the form or if an error occurs during processing.
  1. Parse the form description file to populate the form data structure.
  2. Read any initial data for the form fields from a specified input source.
  3. Display the form on the screen with the initial field values.
  4. Enter a loop to handle user input for field entry, calculation, help, and cancellation: a. If the user selects the accept action, perform any necessary calculations or post-processing, and then either return to field entry or exit the loop if the form is accepted. b. If the user selects the help action, display the help screen and return to the form after the user exits the help screen. c. If the user selects the cancel action, exit the loop and return a cancel status.

Definition at line 120 of file form_engine.c.

120 {
121 char tmp_str[MAXLEN];
122 int form_action;
123 char *eargv[MAXARGS];
124 int eargc;
125
126 form = init->form;
127 if (form == nullptr) {
128 Perror("FORM: form data structure is nullptr");
129 }
130 if (form_parse_desc(form)) {
131 return 0;
132 }
133
136 form->chyron = new_chyron();
137 set_chyron_key(form->chyron, 1, "F1 Help", KEY_F(1));
138 set_chyron_key(form->chyron, 9, "F9 Cancel", KEY_F(9));
139 set_chyron_key(form->chyron, 10, "F10 Continue", KEY_F(10));
140 compile_chyron(form->chyron);
141 display_chyron(form->win, form->chyron, form->lines - 1, form->chyron->l);
142 form->fidx = 0;
143 form_action = 0;
144 while (1) {
145 if (form_action == 0 || form_action == FA_CONTINUE)
146 form_action = field_navigator(form);
147 switch (form_action) {
148 case FA_ACCEPT:
149 if (form->f_process || form->f_calculate || form->f_query)
150 form_action = form_process(init);
151 else
152 form_action = form_post(init);
153 if (form_action == FA_HELP || form_action == FA_CANCEL ||
154 form_action == FA_CONTINUE || form_action == FA_END)
155 continue;
156 if (form_action == FA_ACCEPT) {
157 form_action = FA_END;
158 continue;
159 }
160 break;
161 case FA_END:
162 if (form->f_out_spec || form->out_spec[0] != '\0')
164 if (form->f_receiver_cmd || form->receiver_cmd[0] != '\0')
166 break;
167 case FA_HELP:
168 if (form->f_help_spec && form->help_spec[0] != '\0')
169 strnz__cpy(tmp_str, form->help_spec, MAXLEN - 1);
170 else {
171 strnz__cpy(tmp_str, init->mapp_help, MAXLEN - 1);
172 strnz__cat(tmp_str, "/", MAXLEN - 1);
173 strnz__cat(tmp_str, FORM_HELP_FILE, MAXLEN - 1);
174 }
175 eargc = 0;
176 eargv[eargc++] = strdup("view");
177 eargv[eargc++] = strdup("-Nf");
178 eargv[eargc++] = strdup(tmp_str);
179 eargv[eargc] = nullptr;
180 init->lines = 30;
181 init->cols = 66;
182 init->begy = form->begy + 1;
183 init->begx = form->begx + 1;
184 strnz__cpy(init->title, "Form Help", MAXLEN - 1);
185 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
186 init->begx);
188 form_action = FA_CONTINUE;
189 break;
190 case FA_CANCEL:
191 return FA_CANCEL;
192 default:
193 form_action = FA_CONTINUE;
194 break;
195 }
196 if (form_action == FA_END)
197 break;
198 }
199 return 0;
200}
@ FA_END
Definition form.h:43
@ FA_CONTINUE
Definition form.h:28
#define FORM_HELP_FILE
Definition common.h:35
int popup_view(Init *, int, char **, int, int, int, int)
instantiate a view popup window
Definition popups.c:146
#define MAXARGS
Definition cm.h:30
int eargc
Definition futil.c:51
char * eargv[MAXARGS]
Definition futil.c:52
void set_chyron_key(Chyron *, int, char *, int)
Set chyron key with default color pair (cp_nt_rev).
Definition dwin.c:1411
void display_chyron(WINDOW *win, Chyron *chyron, int line, int col)
Display chyron on window.
Definition dwin.c:1476
void compile_chyron(Chyron *)
construct the chyron string from the chyron structure
Definition dwin.c:1436
Chyron * new_chyron()
Create and initialize Chyron structure.
Definition dwin.c:1336
int form_exec_receiver(Init *)
Execute a command specified by the -R option on the form command line.
int form_read_data(Form *)
Read initial data for form fields from a specified input source, such as a file or standard input,...
int form_parse_desc(Form *)
Parse the form description file to populate the Form data structure with field definitions,...
int form_write(Form *)
Write form field values to a specified output destination, such as a file or standard output,...
int form_process(Init *)
Handle integration with a getter program which will provide field data.
int form_post(Init *)
Handle post-processing after field entry, allowing user to edit data, execute a provider command,...
int field_navigator(Form *)
Handle user input for field entry, allowing navigation between fields and looping until an exit actio...
unsigned int display_form(Init *)
Display the form on the screen, including text elements and fields, and set up the form window based ...
int destroy_argv(int argc, char **argv)
Deallocates memory allocated for argument strings in argv.
Definition futil.c:385

References Form::begx, Init::begx, Form::begy, Init::begy, Form::chyron, Init::cols, compile_chyron(), destroy_argv(), display_chyron(), display_form(), Form::f_calculate, Form::f_help_spec, Form::f_out_spec, Form::f_process, Form::f_query, Form::f_receiver_cmd, FA_ACCEPT, FA_CANCEL, FA_CONTINUE, FA_END, FA_HELP, Form::fidx, field_navigator(), form, Init::form, form_exec_receiver(), form_parse_desc(), form_post(), form_process(), form_read_data(), form_write(), Form::help_spec, Chyron::l, Form::lines, Init::lines, Init::mapp_help, new_chyron(), Form::out_spec, Perror(), popup_view(), Form::receiver_cmd, set_chyron_key(), strnz__cat(), strnz__cpy(), Init::title, and Form::win.

Referenced by init_form().

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

◆ form_exec_cmd()

int form_exec_cmd ( Form * form)

Execute a command specified in the form description file, passing form field values as arguments, and optionally redirecting output to a file.

Parameters
formA pointer to the Form structure containing form data and state.
Returns
0 on success, or a non-zero value if an error occurs while constructing or executing the command.

Definition at line 848 of file form_engine.c.

848 {
849 char earg_str[MAXLEN + 1];
850 int i;
851 strnz__cpy(earg_str, form->receiver_cmd, MAXLEN - 1);
852 for (i = 0; i < form->fcnt; i++) {
853 strnz__cat(earg_str, " ", MAXLEN - 1);
854 strnz__cat(earg_str, form->field[i]->accept_s, MAXLEN - 1);
855 }
856 if (form->f_out_spec && form->f_process) {
857 strnz__cat(earg_str, " >", MAXLEN - 1);
858 strnz__cat(earg_str, form->out_spec, MAXLEN - 1);
859 }
861 return 0;
862}
char earg_str[MAXLEN]
Definition futil.c:50
int shell(char *)
Execute a shell command.
Definition exec.c:82

References Field::accept_s, Form::f_out_spec, Form::f_process, Form::fcnt, Form::field, Form::out_spec, Form::receiver_cmd, shell(), strnz__cat(), and strnz__cpy().

Here is the call graph for this function:

◆ form_exec_receiver()

int form_exec_receiver ( Init * init)

Execute a command specified by the -R option on the form command line.

Parameters
initA pointer to the Init structure
Returns
0 on success, or a non-zero value if an error occurs while constructing or executing the command.

This function constructs a command by taking the receiver_cmd appending field values as arguments, and handling special cases such as multiple command arguments or placeholder substitution. It then executes the command, either displaying the output in a popup view if the command is "view", or executing it directly in a child process for other commands. The function also handles error cases and ensures that resources are properly freed.

This is the line that gets the selected objects

initialize popup_view arguments and execute popup_view to display command output within form interface

fork failed, free eargv and return error

Prevent child process from writing to terminal

Child process to execute command

If execvp returns, it means execution failed, so free eargv and print error message before exiting

Definition at line 875 of file form_engine.c.

875 {
876 int rc = -1;
877 int eargc;
878 char *eargv[MAXARGS];
879 char tmp_str[MAXLEN] = {'\0'};
880 char title[MAXLEN];
881 char sav_arg[MAXLEN];
882 char *out_s;
883 int eargx = 0;
884 int i = 0;
885 pid_t pid = 0;
886 bool f_append_values = false;
887
888 title[0] = '\0';
889 if (form->receiver_cmd[0] == '\0')
890 return -1;
891 // Eliminate leading and trailing quotes
892 if (form->receiver_cmd[0] == '\\' || form->receiver_cmd[0] == '\"') {
893 size_t len = strlen(form->receiver_cmd);
894 if (len > 1 && form->receiver_cmd[len - 1] == '\"') {
895 memmove(form->receiver_cmd, form->receiver_cmd + 1, len - 2);
896 form->receiver_cmd[len - 2] = '\0';
897 }
898 }
899 eargc = str_to_args(eargv, form->receiver_cmd, MAXARGS - 1);
900 tmp_str[0] = '\0';
901 if (form->f_multiple_cmd_args) {
902 // concatenate fields into a single argument
903 for (i = 0; i < form->fcnt; i++) {
904 if (form->field[i]->accept_s[0] && eargc < MAXARGS) {
905 if (tmp_str[0] != '\0')
906 strnz__cat(tmp_str, " ", MAXLEN - 1);
907 strnz__cat(tmp_str, form->field[i]->accept_s, MAXLEN - 1);
908 }
909 }
910 eargv[eargc++] = strdup(tmp_str);
911 } else {
912 f_append_values = false;
913 // find lines with "%%" to determine where to insert field values
914 i = 0;
915 while (i < eargc) {
917 if (strstr(eargv[i], "%%") != nullptr) {
918 tmp_str[0] = '\0';
919 f_append_values = true;
920 strnz__cpy(sav_arg, eargv[i], MAXLEN - 1);
921 eargx = i;
922 break;
923 }
924 i++;
925 }
926 for (i = 0; i < form->fcnt; i++) {
927 // concatenate field values onto tmp_str
928 if (form->field[i]->accept_s[0] && eargc < MAXARGS - 1) {
929 if (f_append_values == true) {
930 if (tmp_str[0] != '\0')
931 strnz__cat(tmp_str, " ", MAXLEN - 1);
932 strnz__cat(tmp_str, form->field[i]->accept_s, MAXLEN - 1);
933 continue;
934 }
935 eargv[eargc++] = strdup(form->field[i]->accept_s);
936 }
937 }
938 // replace "%%" with concatenated field values
939 if (f_append_values == true) {
940 if (eargv[eargx] != nullptr) {
941 free(eargv[eargx]);
942 eargv[eargx] = nullptr;
943 }
944 out_s = rep_substring(sav_arg, "%%", tmp_str);
945 if (out_s == nullptr || out_s[0] == '\0') {
946 i = 0;
947 while (i < eargc) {
948 if (eargv[i] != nullptr)
949 free(eargv[i]);
950 i++;
951 }
952 Perror("rep_substring() failed in form_exec_objects");
953 return 1;
954 }
955 strnz__cpy(title, out_s, MAXLEN - 1);
956 eargv[eargx] = strdup(out_s);
957 if (out_s != nullptr) {
958 free(out_s);
959 out_s = nullptr;
960 }
961 }
962 }
963 if (eargc > 0)
964 eargv[eargc] = nullptr;
965 base_name(tmp_str, eargv[0]);
966 if (tmp_str[0] != '\0' && (strcmp(tmp_str, "view") == 0)) {
969 init->lines = 60;
970 init->cols = 80;
971 init->begy = form->begy + 1;
972 init->begx = form->begx + 1;
973 if (title[0] != '\0')
974 strnz__cpy(init->title, title, MAXLEN - 1);
975 else
976 strnz__cpy(init->title, eargv[eargc], MAXLEN - 1);
977 popup_view(init, eargc, eargv, init->lines, init->cols, init->begy,
978 init->begx);
979 i = 0;
980 while (i < eargc) {
981 if (eargv[i] != nullptr)
982 free(eargv[i]);
983 i++;
984 }
985 return 0;
986 } else {
987 if ((pid = fork()) == -1) {
989 i = 0;
990 while (i < eargc) {
991 if (eargv[i] != nullptr)
992 free(eargv[i]);
993 i++;
994 }
995 Perror("fork() failed in form_exec_objects");
996 return (1);
997 }
998 if (pid == 0) {
1000 int dev_null = open("/dev/null", O_WRONLY);
1001 if (dev_null == -1) {
1002 Perror("open(/dev/null) failed in init_form child process");
1003 exit(EXIT_FAILURE);
1004 }
1005 dup2(dev_null, STDERR_FILENO);
1006 close(dev_null);
1008 execvp(eargv[0], eargv);
1011 strnz__cpy(tmp_str, "Can't exec form cmd: ", MAXLEN - 1);
1012 strnz__cat(tmp_str, eargv[0], MAXLEN - 1);
1013 Perror(tmp_str);
1014 exit(EXIT_FAILURE);
1015 }
1016 }
1017 waitpid(pid, nullptr, 0);
1020 sig_prog_mode();
1021 werase(stdscr);
1022 wrefresh(stdscr);
1023 restore_wins();
1024 return rc;
1025}
void restore_wins()
Restore all windows after a screen resize.
Definition dwin.c:933
char * rep_substring(const char *, const char *, const char *)
Replace all occurrences of "tgt_s" in "org_s" with "rep_s".
Definition futil.c:1301
bool base_name(char *, char *)
Returns the base name of a file specification.
Definition futil.c:984
int str_to_args(char **, char *, int)
Converts a string into an array of argument strings.
Definition futil.c:331
bool restore_curses_tioctl()
restore_curses_tioctl() - restore curses terminal settings
Definition scriou.c:81
void sig_prog_mode()
Set up signal handlers for interrupt signals.
Definition sig.c:62

References Field::accept_s, base_name(), Form::begx, Init::begx, Form::begy, Init::begy, Init::cols, destroy_argv(), Form::f_multiple_cmd_args, Form::fcnt, Form::field, form, Init::lines, Perror(), popup_view(), Form::receiver_cmd, rep_substring(), restore_curses_tioctl(), restore_wins(), sig_prog_mode(), str_to_args(), strnz__cat(), strnz__cpy(), and Init::title.

Referenced by form_engine().

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

◆ form_parse_desc()

int form_parse_desc ( Form * form)

Parse the form description file to populate the Form data structure with field definitions, text elements, and other configuration specified in the description file.

Parameters
formA pointer to the Form structure containing form data and state.
Returns
0 on success, or a non-zero value if an error occurs while parsing the description file (e.g., file not found, invalid format, missing directives).

Definition at line 579 of file form_engine.c.

579 {
580 FILE *form_desc_fp;
581 char *token;
582 char *s;
583 int cols = 0;
584 int i, l;
585 int in_line_num = 0;
586 char in_buf[BUFSIZ];
587 char tmp_buf[BUFSIZ];
588 char *tmp_buf_p;
589 char tmp_str[BUFSIZ];
590 char delim[5];
591 char directive;
592
593 form_desc_fp = fopen(form->mapp_spec, "r");
594 if (form_desc_fp == nullptr) {
595 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__, __LINE__ - 2);
596 strnz__cpy(em1, "fopen ", MAXLEN - 1);
597 strnz__cat(em1, form->mapp_spec, MAXLEN - 1);
598 strerror_r(errno, em2, MAXLEN);
599 display_error(em0, em1, em2, nullptr);
600 return (1);
601 }
602 for (i = 0; i < FIELD_MAXCNT; i++) {
603 form->field[i] = calloc(1, sizeof(Field));
604 if (!form->field[i]) {
605 sprintf(tmp_str, "FORM: calloc failed for fields");
606 abend(EXIT_FAILURE, tmp_str);
607 }
608 }
609 for (i = 0; i < FIELD_MAXCNT; i++) {
610 form->text[i] = calloc(1, sizeof(Text));
611 if (!form->text[i]) {
612 sprintf(tmp_str, "FORM: calloc failed for text");
613 abend(EXIT_FAILURE, tmp_str);
614 }
615 }
616 form->didx = 0;
617 form->fidx = 0;
618 form->fcnt = 0;
619 form->cols = 34;
620 while ((fgets(in_buf, MAXLEN, form_desc_fp)) != nullptr) {
621 s = in_buf;
622 in_line_num++;
623 l = trim(in_buf);
624 if (l == 0)
625 continue;
626 if (*s == D_COMMENT)
627 continue;
628 delim[0] = '\n';
629 delim[1] = in_buf[1];
630 delim[2] = '\0';
631 strnz__cpy(tmp_buf, in_buf, MAXLEN - 1);
632 tmp_buf_p = tmp_buf;
633 if (!(token = strtok(tmp_buf_p, delim))) {
634 continue;
635 }
636 directive = *token;
637 switch ((int)directive) {
638 case D_COMMENT:
639 break;
640 case D_CALC:
641 form->f_calculate = true;
642 break;
643 case D_QUERY:
644 form->f_query = true;
645 break;
646 case D_GETTER:
647 form->f_process = true;
648 break;
649 case D_CMD:
650 if (!(token = strtok(nullptr, delim))) {
651 form_desc_error(in_line_num, in_buf,
652 "FORM: receiver_cmd delimiter");
653 continue;
654 }
655 strnz__cpy(form->receiver_cmd, token, MAXLEN - 1);
656 break;
657 case D_HELP:
658 if (!(token = strtok(nullptr, delim))) {
659 form_desc_error(in_line_num, in_buf,
660 "FORM: help_spec delimiter");
661 }
662 strnz__cpy(form->help_spec, token, MAXLEN - 1);
663 break;
664 case D_FIELD:
665 if (form->field[form->fidx] == nullptr) {
666 sprintf(tmp_str, "FORM: calloc failed for fields");
667 abend(EXIT_FAILURE, tmp_str);
668 }
669 if (!(token = strtok(nullptr, delim))) {
670 form_desc_error(in_line_num, in_buf,
671 "FORM: line number delimiter");
672 return 1;
673 }
674 form->field[form->fidx]->line = atoi(token);
675 if (form->field[form->fidx]->line < 0 ||
676 form->field[form->fidx]->line >= FIELD_MAXCNT) {
677 form_desc_error(in_line_num, in_buf,
678 "FORM: invalid line number");
679 return 1;
680 }
681 if (!(token = strtok(nullptr, delim))) {
682 form_desc_error(in_line_num, in_buf,
683 "FORM: column number delimiter");
684 return 1;
685 }
686 form->field[form->fidx]->col = atoi(token);
687 if (form->field[form->fidx]->col < 0 ||
688 form->field[form->fidx]->col >= FIELD_MAXLEN) {
689 form_desc_error(in_line_num, in_buf,
690 "FORM: invalid column number");
691 break;
692 }
693 if (!(token = strtok(nullptr, delim))) {
694 strnz__cpy(tmp_str, in_buf, MAXLEN - 1);
695 form_desc_error(in_line_num, tmp_str, "FORM: length delimiter");
696 break;
697 }
698 form->field[form->fidx]->len = atoi(token);
699 if (form->field[form->fidx]->len < 0 ||
700 form->field[form->fidx]->len > FIELD_MAXLEN) {
701 form_desc_error(in_line_num, in_buf, "FORM: invalid length");
702 break;
703 }
704 if (!(token = strtok(nullptr, delim))) {
705 form_desc_error(in_line_num, in_buf,
706 "FORM: validation code delimiter");
707 break;
708 }
709 form->field[form->fidx]->ff = -1;
710 for (i = 0; i < FF_INVALID; i++) {
711 str_to_lower(token);
713 if (!strcmp(token, ff_tbl[i])) {
714 form->field[form->fidx]->ff = i;
715 break;
716 }
717 }
718 if (form->field[form->fidx]->ff < 0 ||
719 form->field[form->fidx]->ff >= FF_INVALID) {
720 form_desc_error(in_line_num, in_buf,
721 "FORM: invalid format code");
722 break;
723 }
724 cols =
725 form->field[form->fidx]->col + form->field[form->fidx]->len + 1;
726 if (cols > form->cols)
727 form->cols = cols;
728 form->fidx++;
729 form->fcnt = form->fidx;
730 break;
731 case D_TEXT:
732 if (form->text[form->didx] == nullptr) {
733 sprintf(tmp_str, "FORM: calloc failed for text");
734 abend(EXIT_FAILURE, tmp_str);
735 }
736 if (!(token = strtok(nullptr, delim))) {
737 form_desc_error(in_line_num, in_buf,
738 "FORM: line number delimiter");
739 break;
740 }
741 form->text[form->didx]->line = atoi(token);
742 if (form->text[form->didx]->line < 0 ||
743 form->text[form->didx]->line >= FIELD_MAXCNT) {
744 form_desc_error(in_line_num, in_buf,
745 "FORM: invalid line number");
746 break;
747 }
748 if (!(token = strtok(nullptr, delim))) {
749 form_desc_error(in_line_num, in_buf,
750 "FORM: column number delimiter");
751 break;
752 }
753 form->text[form->didx]->col = atoi(token);
754 if (form->text[form->didx]->col < 0 ||
755 form->text[form->didx]->col >= FIELD_MAXLEN) {
756 form_desc_error(in_line_num, in_buf,
757 "FORM: invalid column number");
758 break;
759 }
760 if (!(token = strtok(nullptr, delim))) {
761 form_desc_error(in_line_num, in_buf, "FORM: text delimiter");
762 break;
763 }
764 strnz__cpy(form->text[form->didx]->str, token, MAXLEN - 1);
765 form->text[form->didx]->len = strlen(form->text[form->didx]->str);
766 if (form->text[form->didx]->len < 0 ||
767 form->text[form->didx]->len > FIELD_MAXLEN) {
768 form_desc_error(in_line_num, in_buf, "FORM: invalid length");
769 break;
770 }
771 cols =
772 form->text[form->didx]->col + form->text[form->didx]->len + 1;
773 if (cols > form->cols)
774 form->cols = cols;
775 form->didx++;
776 form->dcnt = form->didx;
777 break;
778 case D_HEADER:
779 if ((token = strtok(nullptr, delim))) {
780 strnz__cpy(form->title, token, MAXLEN - 1);
781 }
782 break;
783 default:
784 form_desc_error(in_line_num, in_buf, "invalid directive");
785 break;
786 }
787 }
788 fclose(form_desc_fp);
789 if (form->didx < 1 && form->fidx < 1) {
790 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__, __LINE__);
791 ssnprintf(em1, MAXLEN - 1, "%s", "Error in description file:");
792 ssnprintf(em2, MAXLEN - 1, "%s", form->mapp_spec);
793 display_error(em0, em1, em2, nullptr);
794 return (1);
795 }
796 return (0);
797}
#define FIELD_MAXLEN
Definition form.h:18
@ FF_INVALID
Definition form.h:69
#define FIELD_MAXCNT
Definition form.h:19
int cols
#define BUFSIZ
Definition view.h:29
#define D_CMD
Definition form_engine.c:26
#define D_FIELD
Definition form_engine.c:27
#define D_CALC
Definition form_engine.c:31
#define D_TEXT
Definition form_engine.c:28
#define D_HELP
Definition form_engine.c:29
#define D_QUERY
Definition form_engine.c:32
#define D_COMMENT
Definition form_engine.c:25
#define D_HEADER
Definition form_engine.c:30
#define D_GETTER
Definition form_engine.c:33
char ff_tbl[][26]
Definition fields.c:26
void abend(int, char *)
Abnormal program termination.
Definition dwin.c:1588
int form_desc_error(int, char *, char *)
Handle errors encountered while parsing the form description file, providing detailed error messages ...
size_t trim(char *)
Trims leading and trailing spaces from string s in place.
Definition futil.c:282
bool str_to_lower(char *)
Converts a string to lowercase.
Definition futil.c:399
structure for form fields
Definition form.h:101
structure for form fields
Definition form.h:114

References abend(), Field::col, Text::col, Form::cols, Form::dcnt, Form::didx, display_error(), em0, em1, em2, Form::f_calculate, Form::f_process, Form::f_query, Form::fcnt, Field::ff, FF_INVALID, ff_tbl, Form::fidx, Form::field, form_desc_error(), Form::help_spec, Field::len, Text::len, Field::line, Text::line, Form::mapp_spec, Form::receiver_cmd, ssnprintf(), Text::str, str_to_lower(), strnz__cat(), strnz__cpy(), Form::text, Form::title, and trim().

Referenced by form_engine().

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

◆ form_post()

int form_post ( Init * init)

Handle post-processing after field entry, allowing user to edit data, execute a provider command, or write data to an output file.

Parameters
initA pointer to the Init structure containing form data and state.
Returns
An integer status code indicating the next action for the form processing loop (e.g., FA_CONTINUE, FA_CANCEL, FA_ACCEPT, FA_HELP).

Definition at line 207 of file form_engine.c.

207 {
208 bool loop = true;
209 int c, rc;
210 click_y = click_x = -1;
211 form = init->form;
212 wmove(form->win, form->lines - 1, 0);
213 wclrtoeol(form->win);
214 unset_chyron_key(form->chyron, 18);
215 set_chyron_key(form->chyron, 8, "F8 Edit", KEY_F(8));
216 set_chyron_key(form->chyron, 10, "F10 Commit", KEY_F(10));
217 compile_chyron(form->chyron);
218 rc = -1;
219 while (loop) {
220 if (rc == -1) {
221 display_chyron(form->win, form->chyron, form->lines - 1,
222 form->chyron->l);
223 tcflush(2, TCIFLUSH);
224 wrefresh(form->box);
225 c = xwgetch(form->win, form->chyron, -1);
226 }
227 switch (c) {
228 case KEY_F(1):
229 return FA_HELP;
230 case KEY_F(8):
231 if (is_set_chyron_key(form->chyron, 8)) {
232 loop = false;
233 rc = FA_CONTINUE;
234 break;
235 }
236 continue;
237 case KEY_F(9):
238 loop = false;
239 rc = FA_CANCEL;
240 break;
241 case KEY_F(10):
242 loop = false;
243 rc = FA_ACCEPT;
244 break;
245 case KEY_MOUSE:
246 continue;
247 default:
248 break;
249 }
250 }
251 unset_chyron_key(form->chyron, 8);
252 return rc;
253}
int click_x
Definition dwin.c:49
int click_y
Definition dwin.c:48
int xwgetch(WINDOW *, Chyron *, int)
Wrapper for wgetch that handles signals, mouse events, checks for clicks on the chyron line,...
Definition dwin.c:1651
bool is_set_chyron_key(Chyron *, int)
Check if function key label is set.
Definition dwin.c:1372
void unset_chyron_key(Chyron *, int)
Unset chyron key.
Definition dwin.c:1425

References Form::box, Form::chyron, click_x, click_y, compile_chyron(), display_chyron(), FA_ACCEPT, FA_CANCEL, FA_CONTINUE, FA_HELP, form, Init::form, is_set_chyron_key(), Chyron::l, Form::lines, set_chyron_key(), unset_chyron_key(), Form::win, and xwgetch().

Referenced by form_engine().

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

◆ form_process()

int form_process ( Init * init)

Handle integration with a getter program which will provide field data.

Parameters
initA pointer to the Init structure containing form data and state.
Returns
An integer status code indicating the next action for the form processing loop (e.g., FA_CONTINUE, FA_CANCEL, FA_ACCEPT, FA_HELP).

This function provides integration with getter programs. The requirements are:

  1. The form description file must have a line containing only 'C' (calculate), 'Q' (query), org 'G' (getter) to indicate that the form supports a getter.
  2. The form description file must specify the provider command using a line starting with '!' followed by the command and its arguments.
  3. The getter program must be able to accept field data from a file, from standard input, or as command line parameters.
  4. The getter program must output field values in a format that can be read by the form (e.g., one value per line), either to a file or to standard output.
     The sequence of operations is as follows:
    
     1. The 'C', 'Q', or 'G' option causes Form to pause and display an
    
    KEY_F(5) Calculate, Query, or Getter. option on the chyron.
  1. The user can then cancel the operation by pressing KEY_F(9) or activate the getter option by pressing KEY_F(5).
  2. Form outputs its data to file, standard output, or as command line parameters.
  3. Form executes the getter program.
  4. The getter program processes the data and outputs the results.
  5. Form reads the results and populates the appropriate form fields.
  6. Form presents the user with an option to edit the data, and the sequence restarts at 1.

This function forks and executes the getter executable as a child process, creates a pipe to read the output from the provider command, reads the output, and updates the Form fields.

Prevent child process from writing to terminal

Definition at line 292 of file form_engine.c.

292 {
293 int i, c, rc;
294 char tmp_str[MAXLEN];
295 char earg_str[MAXLEN + 1];
296 char *eargv[MAXARGS];
297 int eargc;
298 char file_spec[MAXLEN];
299 bool loop = true;
300 pid_t pid;
301 int pipe_fd[2];
302
303 form = init->form;
304 wmove(form->win, form->lines - 1, 0);
305 wclrtoeol(form->win);
306 unset_chyron_key(form->chyron, 18);
307 unset_chyron_key(form->chyron, 10);
308 strnz__cpy(tmp_str, "F5 ", MAXLEN - 1);
309
310 if (form->f_process)
311 strnz__cat(tmp_str, "Process", MAXLEN - 1);
312 else if (form->f_calculate)
313 strnz__cat(tmp_str, "Calculate", MAXLEN - 1);
314 else if (form->f_query)
315 strnz__cat(tmp_str, "Query", MAXLEN - 1);
316 set_chyron_key_cp(form->chyron, 5, tmp_str, KEY_F(5), cp_nt_hl_rev);
317
318 while (loop) {
319 compile_chyron(form->chyron);
320 display_chyron(form->win, form->chyron, form->lines - 1,
321 form->chyron->l);
322 click_y = click_x = -1;
323 tcflush(2, TCIFLUSH);
324 wrefresh(form->box);
325 c = xwgetch(form->win, form->chyron, -1);
326 switch (c) {
327 case KEY_F(1):
328 return FA_HELP;
329 case KEY_F(5):
330 if (form->f_out_spec)
332 if (form->f_provider_cmd) {
333 strnz__cpy(earg_str, form->provider_cmd, MAXLEN - 1);
334 for (i = 0; i < form->fcnt; i++) {
335 strnz__cat(earg_str, " ", MAXLEN - 1);
336 strnz__cat(earg_str, form->field[i]->accept_s, MAXLEN - 1);
337 }
339 strnz__cpy(file_spec, eargv[0], MAXLEN - 1);
340 base_name(eargv[0], file_spec);
341 if (pipe(pipe_fd) == -1) {
343 Perror("pipe(pipe_fd) failed in init_form");
344 return (1);
345 }
346 if ((pid = fork()) == -1) {
348 Perror("fork() failed in init_form");
349 return (1);
350 }
351 if (pid == 0) { // Child
353 int dev_null = open("/dev/null", O_WRONLY);
354 if (dev_null == -1) {
355 Perror("open(/dev/null) failed in init_pick child "
356 "process");
357 exit(EXIT_FAILURE);
358 }
359 dup2(dev_null, STDERR_FILENO);
360 close(dev_null);
361 close(pipe_fd[P_READ]);
362 dup2(pipe_fd[P_WRITE], STDOUT_FILENO);
363 close(pipe_fd[P_WRITE]);
364 execvp(eargv[0], eargv);
365 ssnprintf(em0, MAXLEN, "%s, line: %d", __FILE__,
366 __LINE__ - 2);
367 strnz__cpy(em1, "execvp(", MAXLEN - 1);
368 strnz__cat(em1, eargv[0], MAXLEN - 1);
369 strnz__cat(em1, ", ", MAXLEN - 1);
371 strnz__cat(em1, ")", MAXLEN - 1);
372 strerror_r(errno, em2, MAXLEN);
373 display_error(em0, em1, em2, nullptr);
374 exit(EXIT_FAILURE);
375 } // Back to parent
376 close(pipe_fd[P_WRITE]);
377 form->in_fp = fdopen(pipe_fd[P_READ], "rb");
378 form->f_in_pipe = true;
380 close(pipe_fd[P_READ]);
384 set_chyron_key_cp(form->chyron, 5, "F5 Edit", KEY_F(5),
386 set_chyron_key(form->chyron, 10, "F10 Commit", KEY_F(10));
387 compile_chyron(form->chyron);
388 continue;
389 }
390 break;
391 case KEY_F(8):
392 if (is_set_chyron_key(form->chyron, 8)) {
393 loop = false;
394 rc = FA_CONTINUE;
395 break;
396 }
397 continue;
398 case KEY_F(9):
399 loop = false;
400 rc = FA_CANCEL;
401 break;
402 case KEY_F(10):
403 loop = false;
404 rc = FA_ACCEPT;
405 break;
406 case KEY_MOUSE:
407 break;
408 default:
409 break;
410 }
411 }
412 unset_chyron_key(form->chyron, 8);
413 unset_chyron_key(form->chyron, 5);
414 return rc;
415}
#define P_READ
Definition common.h:47
#define P_WRITE
Definition common.h:48
int wait_timeout
Definition futil.c:144
int pipe_fd[2]
Definition pick_engine.c:40
int cp_nt_hl_rev
Definition dwin.c:151
bool waitpid_with_timeout(pid_t pid, int timeout)
Wait for a process to finish with a timeout and optional user cancellation.
Definition dwin.c:1603
void set_chyron_key_cp(Chyron *, int, char *, int, int)
Set chyron key with color pair (cp).
Definition dwin.c:1388

References Field::accept_s, base_name(), Form::box, Form::chyron, click_x, click_y, compile_chyron(), cp_nt_hl_rev, destroy_argv(), display_chyron(), display_error(), em0, em1, em2, Form::f_calculate, Form::f_in_pipe, Form::f_out_spec, Form::f_process, Form::f_provider_cmd, Form::f_query, FA_ACCEPT, FA_CANCEL, FA_CONTINUE, FA_HELP, Form::fcnt, Form::field, form, Init::form, form_display_fields(), form_read_data(), form_write(), Form::in_fp, is_set_chyron_key(), Chyron::l, Form::lines, Perror(), Form::provider_cmd, set_chyron_key(), set_chyron_key_cp(), ssnprintf(), str_to_args(), strnz__cat(), strnz__cpy(), unset_chyron_key(), wait_timeout, waitpid_with_timeout(), Form::win, and xwgetch().

Referenced by form_engine().

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

◆ form_read_data()

int form_read_data ( Form * form)

Read initial data for form fields from a specified input source, such as a file or standard input, and populate the form fields with the data.

Parameters
formA pointer to the Form structure containing form data and state.
Returns
0 on success, or a non-zero value if an error occurs while reading the data or if the specified input source is invalid or empty.

Definition at line 806 of file form_engine.c.

806 {
807 struct stat sb;
808 char in_buf[MAXLEN];
809 char field[MAXLEN];
810
811 if (!form->f_in_pipe) {
812 if (form->f_in_spec && form->in_spec[0] != '\0') {
813 if ((lstat(form->in_spec, &sb) == -1) || (sb.st_size == 0) ||
814 ((form->in_fp = fopen(form->in_spec, "rb")) == nullptr)) {
815 strnz__cat(em0, form->in_spec, MAXLEN - 1);
816 if (sb.st_size == 0)
817 strnz__cpy(em1, "File is empty", MAXLEN - 1);
818 else
819 strnz__cpy(em1, "File does not exist", MAXLEN - 1);
820 strnz__cpy(em2, "Fields will be blank or zero", MAXLEN - 1);
821 cmd_key = display_error(em0, em1, em2, nullptr);
822 if (cmd_key == KEY_F(9))
823 return (1);
824 }
825 if (form->in_fp == nullptr)
826 return (1);
827 } else
828 return (0);
829 }
830 form->fidx = 0;
831 if (form->in_fp != nullptr) {
832 while ((fgets(in_buf, MAXLEN, form->in_fp)) != nullptr) {
833 if (form->fidx < FIELD_MAXCNT)
834 strnz__cpy(field, in_buf, MAXLEN - 1);
835 form_fmt_field(form, field);
836 form->fidx++;
837 }
838 fclose(form->in_fp);
839 }
840 return (0);
841}
int form_fmt_field(Form *, char *)
Format field according to its format type.
Definition fields.c:417

References cmd_key, display_error(), em0, em1, em2, Form::f_in_pipe, Form::f_in_spec, Form::fidx, form_fmt_field(), Form::in_fp, Form::in_spec, strnz__cat(), and strnz__cpy().

Referenced by form_engine(), and form_process().

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

◆ form_write()

int form_write ( Form * form)

Write form field values to a specified output destination, such as a file or standard output, based on the form configuration and user input.

Parameters
formA pointer to the Form structure containing form data and state.
Returns
0 on success, or a non-zero value if an error occurs while writing the data or if the specified output destination is invalid.

Definition at line 1034 of file form_engine.c.

1034 {
1035 int n;
1036 if (form->out_spec[0] == '\0' || strcmp(form->out_spec, "-") == 0 ||
1037 strcmp(form->out_spec, "/dev/stdout") == 0) {
1038 strnz__cpy(form->out_spec, "/dev/stdout", MAXLEN - 1);
1039 close(form->out_fd);
1040 form->out_fd = open(form->out_spec, O_CREAT | O_RDWR | O_TRUNC, 0644);
1041 if (form->out_fd == -1) {
1042 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__, __LINE__ - 1);
1043 strnz__cpy(em1, "open ", MAXLEN - 1);
1044 strnz__cat(em1, form->out_spec, MAXLEN - 1);
1045 strerror_r(errno, em2, MAXLEN);
1046 display_error(em0, em1, em2, nullptr);
1047 return (1);
1048 }
1049 dup2(form->out_fd, STDOUT_FILENO);
1050 form->out_fp = fdopen(STDOUT_FILENO, "w");
1051 form->f_out_spec = true;
1052 form->f_out_pipe = true;
1053 } else {
1054 if ((form->out_fp = fopen(form->out_spec, "w")) == nullptr) {
1055 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__, __LINE__ - 1);
1056 strerror_r(errno, em2, MAXLEN);
1057 display_error(em0, em1, em2, nullptr);
1058 return (1);
1059 }
1060 }
1061 if (form->out_fp == nullptr) {
1062 ssnprintf(em0, MAXLEN - 1, "%s, line: %d", __FILE__, __LINE__ - 1);
1063 strnz__cpy(em1, "fopen ", MAXLEN - 1);
1064 strnz__cat(em1, form->out_spec, MAXLEN - 1);
1065 strerror_r(errno, em2, MAXLEN);
1066 display_error(em0, em1, em2, nullptr);
1067 return (1);
1068 }
1069 for (n = 0; n < form->fcnt; n++)
1070 fprintf(form->out_fp, "%s\n", form->field[n]->accept_s);
1071 if (form->out_fp != nullptr)
1072 fclose(form->out_fp);
1073 return (0);
1074}

References Field::accept_s, display_error(), em0, em1, em2, Form::f_out_pipe, Form::f_out_spec, Form::fcnt, Form::field, Form::out_fd, Form::out_fp, Form::out_spec, ssnprintf(), strnz__cat(), and strnz__cpy().

Referenced by form_engine(), and form_process().

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

◆ init_form()

int init_form ( Init * init,
int argc,
char ** argv,
int begy,
int begx )

Initialize form data structure and parse description file.

Parameters
initA pointer to the Init structure containing form data and state.
argcThe number of command line arguments passed to the form.
argvThe array of command line arguments passed to the form.
begyThe y-coordinate for the top-left corner of the form window.
begxThe x-coordinate for the top-left corner of the form window.
Returns
0 on success, or a non-zero value if an error occurs during

Definition at line 60 of file form_engine.c.

60 {
61 int rc;
62 char tmp_str[MAXLEN];
63 if (init->form != nullptr)
65 init->form = new_form(init, argc, argv, begy, begx);
66 form = init->form;
67 if (!form->f_mapp_spec) {
68 if (form->mapp_spec[0] == '\0') {
69 rc = Perror("Error: No form specification file given");
70 } else {
71 strnz__cpy(tmp_str, "form->mapp_spec: ", MAXLEN - 1);
72 strnz__cat(tmp_str, form->mapp_spec, MAXLEN - 1);
73 strnz__cat(tmp_str, " not found", MAXLEN - 1);
74 rc = Perror(tmp_str);
75 }
77 return rc;
78 }
79 if (begy != 0)
80 form->begy = begy;
81 if (begx != 0)
82 form->begx = begx;
83 if ((form->f_in_spec && (form->in_spec[0] == '\0')) ||
84 (strcmp(form->in_spec, "-") == 0) ||
85 strcmp(form->in_spec, "/dev/stdin") == 0) {
86 strnz__cpy(form->in_spec, "/dev/stdin", MAXLEN - 1);
87 form->f_in_pipe = true;
88 }
89 if (form->title[0] == '\0')
90 strnz__cpy(form->title, form->in_spec, MAXLEN - 1);
91#ifdef DEBUG_IMMEDOK
92 immedok(form->win, true);
93 immedok(form->box, true);
94#endif
95 rc = form_engine(init);
96 destroy_chyron(form->chyron);
97 if (form->win)
98 win_del();
100 return rc;
101}
int begx
int begy
WINDOW * win_del()
Delete the current window and its associated box window.
Definition dwin.c:893
Chyron * destroy_chyron(Chyron *chyron)
Destroy Chyron structure.
Definition dwin.c:1352
int form_engine(Init *)
Form main processing loop.
Form * new_form(Init *, int, char **, int, int)
Create and initialize Form structure.
Definition mem.c:266
Form * destroy_form(Init *init)
Destroy Form structure.
Definition mem.c:289

References Form::begx, Form::begy, Form::chyron, destroy_chyron(), destroy_form(), Form::f_in_pipe, Form::f_in_spec, Form::f_mapp_spec, form, Init::form, form_engine(), Form::in_spec, Form::mapp_spec, new_form(), Perror(), strnz__cat(), strnz__cpy(), Form::title, Form::win, and win_del().

Referenced by main(), and popup_form().

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