This addresses some of the `--total` processing.
It looks like I had not completed a lot of that code.
Much of that is added back.
I also noticed that I need to keep tabs on the `--select` parameter.
I will need tests for this and I may have missed some logic cases.
My first objective is to just get the 0.6.x runtime tests to work in 0.7.x.
(Or, I need to fix the 0.6.x tests to be correct.)
The expected next steps:
- Review and address what is left for IKI Read that is incorrect.
- For anything identified in the 0.6.x runtime tests that is invalid shall be fixed in 0.6.x.
- Update the EKI Read with all of the changes from IKI Read.
- Make a copy of the IKI Read runtime tests and see how EKI Read passes or fails.
- Address unexpected failures.
- Fix the tests for expected failures, which would be relating to having multiple Vocabularies/Objects.
- Write all of the new runtime tests for EKI Read.
- Make sure everything all passes.
- I probably need to update the help and describe the order of operations for some parameters.
extern "C" {
#endif
-#ifndef _di_iki_read_eki_process_buffer_line_
- void iki_read_eki_process_buffer_line(iki_read_main_t * const main, const f_number_unsigned_t index) {
+#ifndef _di_iki_read_iki_process_buffer_at_
+ void iki_read_eki_process_buffer_at(iki_read_main_t * const main, const f_number_unsigned_t index) {
if (!main || F_status_is_error(main->setting.state.status)) return;
main->setting.state.status = main->cache.expand.used ? F_okay : F_data_not;
}
-#endif // _di_iki_read_eki_process_buffer_line_
+#endif // _di_iki_read_iki_process_buffer_at_
#ifndef _di_iki_read_eki_process_buffer_ranges_
void iki_read_eki_process_buffer_ranges(iki_read_main_t * const main, f_range_t * const range_buffer) {
if ((main->setting.flag & iki_read_main_flag_at_d) && (main->setting.flag & iki_read_main_flag_line_d)) {
if ((main->setting.flag & iki_read_main_flag_object_d) && main->setting.line) {
if (main->setting.flag & iki_read_main_flag_total_d) {
- fll_print_format("0%r", main->program.output.to, f_string_eol_s);
+ iki_read_print_data_total(&main->program.output, 0);
}
main->setting.state.status = F_data_not;
++matches;
}
- if (main->setting.flag & iki_read_main_flag_line_d) { // @todo handle --at.
- iki_read_eki_process_buffer_line(main, i);
-
- // Ensure that a newline is always at the end.
- if (main->setting.state.status == F_okay) {
- main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
- }
+ if (main->setting.flag & (iki_read_main_flag_at_d | iki_read_main_flag_line_d)) {
+ iki_read_eki_process_buffer_at(main, i);
+ iki_read_process_buffer_at_newline(main);
}
}
else if (main->setting.flag & iki_read_main_flag_line_d) {
- iki_read_eki_process_buffer_line(main, i);
-
- // Ensure that a newline is always at the end.
- if (main->setting.state.status == F_okay) {
- main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
- }
+ iki_read_eki_process_buffer_at(main, i);
+ iki_read_process_buffer_at_newline(main);
}
else {
f_file_stream_lock(main->program.output.to);
if (main->setting.flag & iki_read_main_flag_line_d) {
if (main->setting.flag & iki_read_main_flag_total_d) {
- iki_read_print_data_line_total(&main->program.output);
+ iki_read_print_data_total_expand(&main->program.output);
}
else {
iki_read_print_data_line(&main->program.output);
}
}
- else if ((main->setting.flag & iki_read_main_flag_total_d)) {
- iki_read_print_data_total(
- &main->program.output,
- (main->setting.flag & iki_read_main_flag_line_d)
- ? main->setting.at < matches ? 1 : 0
- : matches
- );
+ else if (main->setting.flag & iki_read_main_flag_total_d) {
+ if (main->setting.flag & iki_read_main_flag_at_d) {
+ iki_read_print_data_total_expand(&main->program.output);
+ }
+ else {
+ iki_read_print_data_total(&main->program.output, matches);
+ }
- main->setting.state.status = F_okay;
+ main->setting.state.status = matched ? F_okay : F_data_not;
return;
}
if (main->setting.flag & iki_read_main_flag_at_d) {
if (main->setting.at < data->variable.used) {
if (main->setting.flag & iki_read_main_flag_line_d) {
- iki_read_eki_process_buffer_line(main, main->setting.at);
-
- // Ensure that a newline is always at the end.
- if (main->setting.state.status == F_okay) {
- main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
- }
+ iki_read_eki_process_buffer_at(main, main->setting.at);
+ iki_read_process_buffer_at_newline(main);
if (main->setting.flag & iki_read_main_flag_total_d) {
- iki_read_print_data_line_total(&main->program.output);
+ iki_read_print_data_total_expand(&main->program.output);
}
else {
iki_read_print_data_line(&main->program.output);
}
}
+ else if (main->setting.flag & iki_read_main_flag_total_d) {
+ if (main->setting.flag & iki_read_main_flag_object_d) {
+ iki_read_print_data_total(&main->program.output, ((main->setting.flag & iki_read_main_flag_select_d) && main->setting.select) ? 0 : 1);
+ }
+ else {
+ iki_read_eki_process_buffer_at(main, main->setting.at);
+ iki_read_process_buffer_at_newline(main);
+
+ iki_read_print_data_total_expand(&main->program.output);
+ }
+ }
else {
f_file_stream_lock(main->program.output.to);
}
}
else {
+ if (main->setting.flag & iki_read_main_flag_total_d) {
+ iki_read_print_data_total(&main->program.output, 0);
+ }
+
main->setting.state.status = F_data_not;
}
}
if (iki_read_signal_check(main)) return;
- iki_read_eki_process_buffer_line(main, i);
-
- // Ensure that a newline is always at the end.
- if (main->setting.state.status == F_okay) {
- main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
- }
+ iki_read_eki_process_buffer_at(main, i);
+ iki_read_process_buffer_at_newline(main);
} // for
if (main->setting.flag & iki_read_main_flag_total_d) {
- iki_read_print_data_line_total(&main->program.output);
+ iki_read_print_data_total_expand(&main->program.output);
}
else {
iki_read_print_data_line(&main->program.output);
}
}
+ else if (main->setting.flag & iki_read_main_flag_total_d) {
+ if (main->setting.flag & iki_read_main_flag_object_d) {
+ iki_read_print_data_total(&main->program.output, ((main->setting.flag & iki_read_main_flag_select_d) && main->setting.select) ? 0 : data->variable.used);
+ }
+ else {
+ for (i = 0; F_status_is_error_not(main->setting.state.status) && i < data->variable.used; ++i) {
+
+ if (iki_read_signal_check(main)) return;
+
+ iki_read_eki_process_buffer_at(main, i);
+ iki_read_process_buffer_at_newline(main);
+ } // for
+
+ iki_read_print_data_total_expand(&main->program.output);
+ }
+ }
else {
f_file_stream_lock(main->program.output.to);
#endif
/**
- * Print the given range at the given index for EKI read, for when printing a single Line in Content and Literal modes.
+ * Process the given range at the given index for EKI read.
*
- * This expects the caller to have the output locked appropriately.
+ * This expands all of the appropriate Variables so that post-expansion calculations may be performed.
+ * This is particularly useful for preparing to print a single Line in Content and Literal modes.
*
- * This detects and prints any applicable substitution matching the vocabulary at the given index.
- * If there is no substitution, then this prints the given range at the given index.
+ * @param main
+ * The main program data.
*
- * @param print
- * The output structure to print to.
+ * Must not be NULL.
*
* The setting.map_wrapss is expected to be defined as a valid pointer to an array.
* The setting.map_replacess is expected to be defined as a valid pointer to an array.
*
- * This does not alter print.custom.setting.state.status.
+ * This alters setting.state.status:
+ * F_okay on success.
+ * F_data_not on success, but nothing done.
+ *
+ * F_interrupt (with error bit) on (exit) signal received.
+ *
+ * Errors (with error bit) from: f_string_dynamic_append_nulless().
+ * Errors (with error bit) from: f_string_dynamic_partial_append_nulless().
+ *
+ * Errors (with error bit) from: iki_read_process_wrap_append().
+ * Errors (with error bit) from: iki_read_process_wrap_prepend().
* @param index
* The index used to identify the desired range in variable, content, and ranges.
*
- * @see f_print_dynamic()
- * @see f_print_dynamic_partial()
+ * @see f_string_dynamic_append_nulless()
+ * @see f_string_dynamic_partial_append_nulless()
*
* @see iki_read_identify_substitution()
- * @see iki_read_print_data_wrap_append()
- * @see iki_read_print_data_wrap_prepend()
+ * @see iki_read_process_wrap_append()
+ * @see iki_read_process_wrap_prepend()
*/
-#ifndef _di_iki_read_eki_process_buffer_line_
- extern void iki_read_eki_process_buffer_line(iki_read_main_t * const main, const f_number_unsigned_t index);
-#endif // _di_iki_read_eki_process_buffer_line_
+#ifndef _di_iki_read_eki_process_buffer_at_
+ extern void iki_read_eki_process_buffer_at(iki_read_main_t * const main, const f_number_unsigned_t index);
+#endif // _di_iki_read_eki_process_buffer_at_
/**
* Process a given buffer, printing the given range for EKI read.
extern "C" {
#endif
-#ifndef _di_iki_read_iki_process_buffer_line_
- void iki_read_iki_process_buffer_line(iki_read_main_t * const main, const f_number_unsigned_t index) {
+#ifndef _di_iki_read_iki_process_buffer_at_
+ void iki_read_iki_process_buffer_at(iki_read_main_t * const main, const f_number_unsigned_t index) {
if (!main || F_status_is_error(main->setting.state.status)) return;
main->setting.state.status = main->cache.expand.used == original ? F_data_not : F_okay;
}
-#endif // _di_iki_read_iki_process_buffer_line_
+#endif // _di_iki_read_iki_process_buffer_at_
#ifndef _di_iki_read_iki_process_buffer_ranges_
void iki_read_iki_process_buffer_ranges(iki_read_main_t * const main, f_range_t * const range_buffer) {
if ((main->setting.flag & iki_read_main_flag_at_d) && (main->setting.flag & iki_read_main_flag_line_d)) {
if ((main->setting.flag & iki_read_main_flag_object_d) && main->setting.line) {
if (main->setting.flag & iki_read_main_flag_total_d) {
- fll_print_format("0%r", main->program.output.to, f_string_eol_s);
+ iki_read_print_data_total(&main->program.output, 0);
}
main->setting.state.status = F_data_not;
++matches;
}
- if (main->setting.flag & iki_read_main_flag_line_d) { // @todo handle --at.
- iki_read_iki_process_buffer_line(main, i);
-
- // Ensure that a newline is always at the end.
- if (main->setting.state.status == F_okay) {
- main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
- }
+ if (main->setting.flag & (iki_read_main_flag_at_d | iki_read_main_flag_line_d)) {
+ iki_read_iki_process_buffer_at(main, i);
+ iki_read_process_buffer_at_newline(main);
}
}
else if (main->setting.flag & iki_read_main_flag_line_d) {
- iki_read_iki_process_buffer_line(main, i);
-
- // Ensure that a newline is always at the end.
- if (main->setting.state.status == F_okay) {
- main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
- }
+ iki_read_iki_process_buffer_at(main, i);
+ iki_read_process_buffer_at_newline(main);
}
else {
f_file_stream_lock(main->program.output.to);
if (main->setting.flag & iki_read_main_flag_line_d) {
if (main->setting.flag & iki_read_main_flag_total_d) {
- iki_read_print_data_line_total(&main->program.output);
+ iki_read_print_data_total_expand(&main->program.output);
}
else {
iki_read_print_data_line(&main->program.output);
}
}
else if (main->setting.flag & iki_read_main_flag_total_d) {
- if (main->setting.flag & iki_read_main_flag_line_d) {
- for (i = 0; F_status_is_error_not(main->setting.state.status) && i < data->variable.used; ++i) {
-
- if (iki_read_signal_check(main)) return;
-
- iki_read_iki_process_buffer_line(main, i);
-
- // Ensure that a newline is always at the end.
- if (main->setting.state.status == F_okay) {
- main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
- }
- } // for
+ if (main->setting.flag & iki_read_main_flag_at_d) {
+ iki_read_print_data_total_expand(&main->program.output);
}
else {
iki_read_print_data_total(&main->program.output, matches);
if (main->setting.flag & iki_read_main_flag_at_d) {
if (main->setting.at < data->variable.used) {
if (main->setting.flag & iki_read_main_flag_line_d) {
- iki_read_iki_process_buffer_line(main, main->setting.at);
-
- // Ensure that a newline is always at the end.
- if (main->setting.state.status == F_okay) {
- main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
- }
+ iki_read_iki_process_buffer_at(main, main->setting.at);
+ iki_read_process_buffer_at_newline(main);
if (main->setting.flag & iki_read_main_flag_total_d) {
- iki_read_print_data_line_total(&main->program.output);
+ iki_read_print_data_total_expand(&main->program.output);
}
else {
iki_read_print_data_line(&main->program.output);
}
}
+ else if (main->setting.flag & iki_read_main_flag_total_d) {
+ if (main->setting.flag & iki_read_main_flag_object_d) {
+ iki_read_print_data_total(&main->program.output, ((main->setting.flag & iki_read_main_flag_select_d) && main->setting.select) ? 0 : 1);
+ }
+ else {
+ iki_read_iki_process_buffer_at(main, main->setting.at);
+ iki_read_process_buffer_at_newline(main);
+
+ iki_read_print_data_total_expand(&main->program.output);
+ }
+ }
else {
f_file_stream_lock(main->program.output.to);
}
}
else {
+ if (main->setting.flag & iki_read_main_flag_total_d) {
+ iki_read_print_data_total(&main->program.output, 0);
+ }
+
main->setting.state.status = F_data_not;
}
}
if (iki_read_signal_check(main)) return;
- iki_read_iki_process_buffer_line(main, i);
-
- // Ensure that a newline is always at the end.
- if (main->setting.state.status == F_okay) {
- main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
- }
+ iki_read_iki_process_buffer_at(main, i);
+ iki_read_process_buffer_at_newline(main);
} // for
if (main->setting.flag & iki_read_main_flag_total_d) {
- iki_read_print_data_line_total(&main->program.output);
+ iki_read_print_data_total_expand(&main->program.output);
}
else {
iki_read_print_data_line(&main->program.output);
}
}
+ else if (main->setting.flag & iki_read_main_flag_total_d) {
+ if (main->setting.flag & iki_read_main_flag_object_d) {
+ iki_read_print_data_total(&main->program.output, ((main->setting.flag & iki_read_main_flag_select_d) && main->setting.select) ? 0 : data->variable.used);
+ }
+ else {
+ for (i = 0; F_status_is_error_not(main->setting.state.status) && i < data->variable.used; ++i) {
+
+ if (iki_read_signal_check(main)) return;
+
+ iki_read_iki_process_buffer_at(main, i);
+ iki_read_process_buffer_at_newline(main);
+ } // for
+
+ iki_read_print_data_total_expand(&main->program.output);
+ }
+ }
else {
f_file_stream_lock(main->program.output.to);
#endif
/**
- * Process and print the given range at the given index for IKI read, for when printing a single Line in Content and Literal modes.
+ * Process the given range at the given index for IKI read.
*
- * This expects the caller to have the output locked appropriately.????
- *
- * This detects and prints any applicable substitution matching the vocabulary at the given index.
- * If there is no substitution, then this prints the given range at the given index.
+ * This expands all of the appropriate Variables so that post-expansion calculations may be performed.
+ * This is particularly useful for preparing to print a single Line in Content and Literal modes.
*
* @param main
* The main program data.
* @see iki_read_process_wrap_append()
* @see iki_read_process_wrap_prepend()
*/
-#ifndef _di_iki_read_iki_process_buffer_line_
- extern void iki_read_iki_process_buffer_line(iki_read_main_t * const main, const f_number_unsigned_t index);
-#endif // _di_iki_read_iki_process_buffer_line_
+#ifndef _di_iki_read_iki_process_buffer_at_
+ extern void iki_read_iki_process_buffer_at(iki_read_main_t * const main, const f_number_unsigned_t index);
+#endif // _di_iki_read_iki_process_buffer_at_
/**
* Process a given buffer, printing the given range for IKI read.
}
#endif // _di_iki_read_print_data_line_
-#ifndef _di_iki_read_print_data_line_total_
- void iki_read_print_data_line_total(fl_print_t * const print) {
+#ifndef _di_iki_read_print_data_line_total_expand_
+ void iki_read_print_data_total_expand(fl_print_t * const print) {
if (!print || !print->custom) return;
} // for
}
- iki_read_print_data_total(print, main->setting.line < total ? 1 : 0);
+ iki_read_print_data_total(
+ print,
+ (main->setting.flag & iki_read_main_flag_line_d)
+ ? main->setting.line < total ? 1 : 0
+ : total
+ );
- main->setting.state.status = main->setting.line < total ? F_okay : F_data_not;
+ main->setting.state.status = (main->setting.flag & iki_read_main_flag_line_d)
+ ? main->setting.line < total ? F_okay : F_data_not
+ : total ? F_okay : F_data_not;
}
-#endif // _di_iki_read_print_data_line_total_
+#endif // _di_iki_read_print_data_line_total_expand_
#ifndef _di_iki_read_print_data_total_
void iki_read_print_data_total(fl_print_t * const print, const f_number_unsigned_t total) {
#endif // _di_iki_read_print_data_line_
/**
- * Print the total from the data in the expand cache at the line.
- *
- * This requires that the expand cache is properly populated.
- * The expand cache may be empty.
- *
- * @param print
- * The output structure to print to.
- *
- * This does not alter print.custom.setting.state.status.
- */
-#ifndef _di_iki_read_print_data_line_total_
- extern void iki_read_print_data_line_total(fl_print_t * const print);
-#endif // _di_iki_read_print_data_line_total_
-
-/**
* Print the number that represents the total.
*
* @param print
#endif // _di_iki_read_print_data_total_
/**
+ * Count and print the total from the data in the expand cache at the line.
+ *
+ * This requires that the expand cache is properly populated.
+ * The expand cache may be empty.
+ *
+ * This only checks if the flag iki_read_main_flag_line_d is set.
+ * Otherwise, the total lines from the expand cache is counted as-is.
+ *
+ * @param print
+ * The output structure to print to.
+ *
+ * This does not alter print.custom.setting.state.status.
+ */
+#ifndef _di_iki_read_print_data_line_total_expand_
+ extern void iki_read_print_data_total_expand(fl_print_t * const print);
+#endif // _di_iki_read_print_data_line_total_expand_
+
+/**
* Print the append part of the wrap at the given index, if valid.
*
* This expects the caller to have the output locked appropriately.
}
#endif // _di_iki_read_process_buffer_
+#ifndef _di_iki_read_process_buffer_at_newline_
+ void iki_read_process_buffer_at_newline(iki_read_main_t * const main) {
+
+ if (!main || main->setting.state.status != F_okay) return;
+
+ main->setting.state.status = f_string_dynamic_append(f_string_eol_s, &main->cache.expand);
+ }
+#endif // _di_iki_read_process_buffer_at_newline_
+
#ifndef _di_iki_read_process_line_
void iki_read_process_line(iki_read_main_t * const main, f_range_t * const range) {
#endif // _di_iki_read_process_buffer_
/**
+ * Append a new line at the end of the expand cache if the state status is F_okay.
+ *
+ * This is intended to be called immediately after iki_read_iki_process_buffer_at() and iki_read_eki_process_buffer_at() to handle the state status.
+ *
+ * @param main
+ * The main program data.
+ *
+ * Must not be NULL.
+ *
+ * This alters setting.state.status:
+ * Success from: f_string_dynamic_append()
+ *
+ * Errors (with error bit) from: f_string_dynamic_append().
+ *
+ * @see f_string_dynamic_append()
+ */
+#ifndef _di_iki_read_process_buffer_at_newline_
+ extern void iki_read_process_buffer_at_newline(iki_read_main_t * const main);
+#endif // _di_iki_read_process_buffer_at_newline_
+
+/**
* Determine the range based on the --line parameter.
*
* If the --line parameter is not specified in the console arguments, then range is untouched.