From d46aee4d7010d0cc8d0b8694e939471b5b3cfaab Mon Sep 17 00:00:00 2001 From: Kevin Day Date: Sat, 4 Sep 2021 00:03:18 -0500 Subject: [PATCH] Security: Finish implementing string and convert changes. The observation that some filesystems may have control characters in their names revealed a security issue in the design of this project. There is no provided way to easily handle control characters or invalid UTF-8 sequences. I have long been thinking about writing my own printf()/fprintf() functions but have not been willing to go that far. With the discovery of this security issue, I finally decided to do so. This then allows me to get rid of the rather messy f_color_print() and similar functions. The color support and special FLL types, such as f_static_string_t, are now supported. Due to the size of this change as well as my available time, I have broken up this process over several "Progress" commits. This implementation is not complete. I want to implement floating and double support, but I am not about to spend the research needed to properly handle floating and double digit processing logic. While being similar, there are several differences between the fl_print_format() and fll_print_format() functions with the fprintf() functions. Most notable of these is the the fl_print_format(), does not lock the file stream and fll_print_format() is a wrapper to fl_print_format() that does lock the file stream. The format characters are significantly different, see the function documentation. There are also improvements that need to be made. Most notable is the digit to string conversion in which the algorithm I chose is a simple algorithm. While the performance is acceptable for the time being, the performance can be greatly improved upon. I need to spend time researching in order to improve this. All of the programs (level 3) have been converted to use this and all of the many of the old ways of printing have been entirely removed. I used safe printing where the string needs to be safely printing where I was able to identify such cases. However, given the size of the refactoring, not to mention the work being spread out between days and weeks, I have concerns that I did not get all of the places that should be using safe printing. --- level_0/f_file/c/file-common.h | 4 +- level_0/f_fss/c/fss_nest.h | 2 +- level_0/f_iki/c/iki-common.h | 2 +- level_0/f_print/c/print-common.h | 63 +++--- level_0/f_utf/c/private-utf.c | 22 +- level_0/f_utf/c/utf.c | 4 +- level_1/fl_print/c/print.h | 120 +++++++++- level_1/fl_print/c/private-print.c | 4 +- level_2/fll_fss/c/fss_basic.h | 2 +- level_2/fll_fss/c/fss_basic_list.h | 2 +- level_2/fll_fss/c/fss_embedded_list.h | 2 +- level_2/fll_fss/c/fss_extended.h | 2 +- level_2/fll_fss/c/fss_extended_list.h | 2 +- level_3/byte_dump/c/private-byte_dump.c | 6 +- level_3/controller/c/main.c | 2 +- level_3/controller/c/private-rule.c | 2 +- level_3/fake/c/main.c | 2 +- level_3/fake/documents/fakefile.txt | 2 +- level_3/firewall/c/private-common.h | 1 - .../c/private-fss_embedded_list_read.c | 2 +- level_3/fss_status_code/c/fss_status_code.c | 6 +- level_3/iki_read/c/iki_read.c | 244 +++++++++++---------- level_3/iki_read/c/iki_read.h | 3 + level_3/iki_read/c/private-iki_read.c | 48 ++-- level_3/iki_read/data/build/dependencies | 2 + level_3/iki_read/data/build/settings | 4 +- level_3/status_code/c/status_code.c | 6 +- 27 files changed, 350 insertions(+), 211 deletions(-) diff --git a/level_0/f_file/c/file-common.h b/level_0/f_file/c/file-common.h index f79dd70..cd5040d 100644 --- a/level_0/f_file/c/file-common.h +++ b/level_0/f_file/c/file-common.h @@ -20,8 +20,8 @@ extern "C" { * Provide common file-typ specific data types. */ #ifndef _di_f_file_types_ - #define f_file_default_read_size 8192 // default to 8k read sizes. // @fixme: rename and move into _di_f_file_type_ - #define f_file_default_write_size 8192 // default to 8k write sizes. // @fixme: rename and move into _di_f_file_type_ + #define f_file_default_read_size 8192 // default to 8k read sizes. // @fixme rename and move into _di_f_file_type_ + #define f_file_default_write_size 8192 // default to 8k write sizes. // @fixme rename and move into _di_f_file_type_ #endif // _di_f_file_types_ /** diff --git a/level_0/f_fss/c/fss_nest.h b/level_0/f_fss/c/fss_nest.h index 2bf9969..a2ca95c 100644 --- a/level_0/f_fss/c/fss_nest.h +++ b/level_0/f_fss/c/fss_nest.h @@ -116,7 +116,7 @@ extern "C" { * Each array row represents the nesting depth. * The top-level will not have any parent, so "parent" must be ignored on anything at index 0. * The parent identifier is expected to reference a position in the nesting depth immediately above it. - * @todo: consider instead of using a "parent", have setting set to 0 to represent no data. + * @todo consider instead of using a "parent", have setting set to 0 to represent no data. * * depth: An array of f_fss_items_t, with each index representing the depth. * size: Total amount of allocated space. diff --git a/level_0/f_iki/c/iki-common.h b/level_0/f_iki/c/iki-common.h index c7d864f..1e92e36 100644 --- a/level_0/f_iki/c/iki-common.h +++ b/level_0/f_iki/c/iki-common.h @@ -73,7 +73,7 @@ extern "C" { extern const f_string_t iki_vocabulary_0002_parameter_s; #endif // _di_iki_vocabulary_0002_s_ -// @todo: consider IKI-0003 = vocabulary based on context from HTML5 and accessibility-related? +// @todo consider IKI-0003 = vocabulary based on context from HTML5 and accessibility-related? /** * This holds an array of string ranges that represent the entire vocabulary name, content, and syntax. diff --git a/level_0/f_print/c/print-common.h b/level_0/f_print/c/print-common.h index c537ea0..0573d7b 100644 --- a/level_0/f_print/c/print-common.h +++ b/level_0/f_print/c/print-common.h @@ -120,8 +120,6 @@ extern "C" { /** * Provide basic format flags. * - * @todo be sure to document that the "/", ";", and ":" use pre-defined orders, so "%/;:Q" and "%:/;Q" would be processed in the same (pre-defined) order (which is 1: static/dynamic string, 2: partial range, 3: ignore ats, 4: ignore ins). - * * f_print_format_flag_*: * - align_left: "-", Use left-justification. * - convert: "#", Use alternate form conversion (prefixing 0b/0B, 0o/0O, 0t/0T, 0d/0D, 0x/0X). @@ -154,45 +152,35 @@ extern "C" { #endif // _di_f_print_format_flags_ /** - * Provide base format flags. - * - * f_print_format_base_*: - * - binary: "!", Display number in Binary notation. - * - octal: "@", Display number in Octal notation. - * - decimal: "^", Display number in Octal notation. - * - duodecimal: "&", Display number in Duodecimal notation. - * - hexidecimal: "_", Display number in Hexidecimal notation. - * - * @see fprintf() - */ - -/** * Provide type format flags. * - * The uppercase "I", "L", "LL", "UL", "ULL" designates setting the uppercase flag. + * @todo float and double support will likely be something like: "%d", "%dl", and "%dll" for float, double, and long double, respectively. + * @todo there may be support in the future for min/max type sizes, such that "%n" = min, "%m" = max, and "%niii" = min int8_t. * * f_print_format_type_*: - * - character: "c", type is a 1-byte unsigned character. - * - character_safe: "C", type is a 1-byte unsigned character, where control characters and other problems are handled. - * - color_after: "]", type is f_color_set_t such that the f_color_set_t.after is used. - * - color_before: "[", type is f_color_set_t such that the f_color_set_t.begin is used. - * - signed_8: "iii", "III", type is a int8_t. - * - signed_16: "ii", "II", type is a int16_t. - * - signed_32: "i", "I", type is a int32_t. - * - signed_64: "il", "IL", type is a signed int64_t. - * - signed_128: "ill", "ILL", type is a f_int_128_t. - * - number: "in", "IN", type is an f_number_signed_t. - * - size: "z", "Z", type is a size_t. - * - string_safe: "S", type is a NULL terminated string, where control characters and other problems are handled. - * - string_static: "q", type is an f_string_static_t or f_string_dynamic_t and NULLs are ignored (not printed). - * - string_static_raw: "r", type is an f_string_static_t or f_string_dynamic_t and NULLs (and all other control characters) are printed. - * - string_static_safe: "Q", type is an f_string_static_t or f_string_dynamic_t and NULLs are printed, where control characters and other problems are handled. - * - unsigned_8: "uii", "UII", type is an uint8_t. - * - unsigned_16: "ui", "UI", type is an uint16_t. - * - unsigned_32: "u", "U", type is an uint32_t. - * - unsigned_64: "ul", "UL", type is an uint64_t. - * - unsigned_128: "ull", "ULL", type is an f_uint_128_t. - * - unsigned_number: "un", "UN", type is an f_number_unsigned_t (which by default is what f_array_length_t is a type of). + * - character: "c", Type is a 1-byte unsigned character. + * - character_safe: "C", Type is a 1-byte unsigned character, where control characters and invalid UTF-8 are replaced. + * - color_after: "]", Type is a f_color_set_t such that the f_color_set_t.after is used. + * - color_before: "[", Type is a f_color_set_t such that the f_color_set_t.begin is used. + * - signed_8: "iii", "III", Type is a int8_t digit. + * - signed_16: "ii", "II", Type is a int16_t digit. + * - signed_32: "i", "I", Type is a int32_t digit. + * - signed_64: "il", "IL", Type is a signed int64_t digit. + * - signed_128: "ill", "ILL", Type is a f_int_128_t digit. + * - number: "in", "IN", Type is a f_number_signed_t digit. + * - size: "z", "Z", Type is a size_t digit. + * - string: "s", Type is a NULL terminated string, where the string is printed as-is. + * - string_safe: "S", Type is a NULL terminated string, where control characters and other problems are handled. + * - string_static: "q", Type is a f_string_static_t or f_string_dynamic_t and NULLs are ignored (not printed). + * - string_static_raw: "r", Type is a f_string_static_t or f_string_dynamic_t and NULLs (and all other control characters) are printed. + * - string_static_safe: "Q", Type is a f_string_static_t or f_string_dynamic_t and NULLs are printed, where control characters and other problems are handled. + * - string_static_safe_raw: "R", Type is a f_string_static_t or f_string_dynamic_t and NULLs are printed, where control characters and other problems are handled. + * - unsigned_8: "uii", "UII", Type is a uint8_t digit. + * - unsigned_16: "ui", "UI", Type is a uint16_t digit. + * - unsigned_32: "u", "U", Type is a uint32_t digit. + * - unsigned_64: "ul", "UL", Type is a uint64_t digit. + * - unsigned_128: "ull", "ULL", Type is a f_uint_128_t digit. + * - unsigned_number: "un", "UN", Type is a f_number_unsigned_t digit (which by default is what f_array_length_t is a type of). * * @see fprintf() */ @@ -214,6 +202,7 @@ extern "C" { f_print_format_type_string_static, f_print_format_type_string_static_raw, f_print_format_type_string_static_safe, + f_print_format_type_string_static_safe_raw, // @todo not yet implemented. f_print_format_type_unsigned_8, f_print_format_type_unsigned_16, f_print_format_type_unsigned_32, diff --git a/level_0/f_utf/c/private-utf.c b/level_0/f_utf/c/private-utf.c index c2635d3..82ce4c2 100644 --- a/level_0/f_utf/c/private-utf.c +++ b/level_0/f_utf/c/private-utf.c @@ -1171,8 +1171,8 @@ extern "C" { return F_true; } - // @todo: add letter UTF-8 numbers. - // @todo: add other UTF-8 numbers. + // @todo add letter UTF-8 numbers. + // @todo add other UTF-8 numbers. if (width == 3) { @@ -1944,7 +1944,7 @@ extern "C" { // reduce the number of checks by grouping checks by first byte. //const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); - // @todo: handle all Unicode "symbol". + // @todo handle all Unicode "symbol". return F_false; } @@ -1956,14 +1956,14 @@ extern "C" { // reduce the number of checks by grouping checks by first byte. //const uint8_t byte_first = macro_f_utf_character_t_to_char_1(character); - // @todo: Basic Multilingual Plane - // @todo: handle all unassigned UTF-8 spaces. - // @todo: Supplementary Multilingual Plane. - // @todo: Supplementary Ideographic Plane. - // @todo: Tertiary Ideographic Plane - // @todo: Planes 4–13 - // @todo: Supplementary Special-purpose Plane - // @todo: Supplement­ary Private Use Area planes + // @todo Basic Multilingual Plane + // @todo handle all unassigned UTF-8 spaces. + // @todo Supplementary Multilingual Plane. + // @todo Supplementary Ideographic Plane. + // @todo Tertiary Ideographic Plane + // @todo Planes 4–13 + // @todo Supplementary Special-purpose Plane + // @todo Supplement­ary Private Use Area planes return F_false; } diff --git a/level_0/f_utf/c/utf.c b/level_0/f_utf/c/utf.c index d9c6ef2..870657e 100644 --- a/level_0/f_utf/c/utf.c +++ b/level_0/f_utf/c/utf.c @@ -669,7 +669,7 @@ extern "C" { if (macro_f_utf_character_t_width_is(utf_character)) { - // @todo: endianess is compile time so a function is not needed, replace with macros. + // @todo endianess is compile time so a function is not needed, replace with macros. if (f_utf_is_big_endian()) { memcpy(*character, &utf_character, macro_f_utf_character_t_width_is(utf_character)); } @@ -698,7 +698,7 @@ extern "C" { } else { - // @todo: endianess is compile time so a function is not needed, replace with macros. + // @todo endianess is compile time so a function is not needed, replace with macros. if (f_utf_is_big_endian()) { memcpy(*character, &utf_character, 1); } diff --git a/level_1/fl_print/c/print.h b/level_1/fl_print/c/print.h index c96c8d3..6114179 100644 --- a/level_1/fl_print/c/print.h +++ b/level_1/fl_print/c/print.h @@ -9,7 +9,7 @@ * * Functions provided here are UTF-8 aware. * - * @fixme: the except_in and except_at only apply to 1-byte characters, so what happens if a single except byte is only a part of a single multibyte character? + * @fixme the except_in and except_at only apply to 1-byte characters, so what happens if a single except byte is only a part of a single multibyte character? */ #ifndef _FL_print_h #define _FL_print_h @@ -136,10 +136,125 @@ extern "C" { /** * A formatted print function similar to (but not the same as) the c-library fprintf() function. * - * @todo add the complex documentation. + * This function attempts to operate as closely to how fprintf() operates, however, there are notable differences. + * + * This formatted print provides replacement variables for specific types of the FLL project, such f_string_static_t. + * There is support for safe printing where certain control characters or invalid UTF-8 sequences are not directly printed. + * There is support for color context printing. + * There is support for more digit base forms than those provided by fprintf() such as base-2 (binary) or base-12 (duodecimal). + * + * The reserved formatting character is only the '%' character, which may be escaped by a second '%' character. + * This '%' character designates the start of a format flag sequence which must be ended by another '%' or a format character. + * A '%' at the end of the string is considered invalid. + * + * Each formatting flags is followed by basic flag or base flag and end on a type flag. + * The basic, base, and type format flags are represented by a discrete set of reserved characters. + * + * Each basic format flags may be specified in any order but must be specified before the type flag. + * The order in which basic format flags are processed in regards parameters is a present order irrespective to the order specified. + * The basic format flags "/", ";", and ":" are examples of this. + * + * For these basic format flags ("/", ";", and ":"), the order is always processed as: + * 1) static/dynamic string. + * 2) partial range. + * 3) ignore at. + * 4) ignore in. + * + * Uppercase base format flags designates to print the base designation in uppercase and lowercase base format flags designate to print the base designation in lowercase. + * There are 5 support base format flags: + * - binary: 0b/0B, representing base-2 units. + * - octal: 0o/0O, representing base-8 units (note that this is a letter O, and not a zero). + * - decimal: 0t/0T, representing base-10 units (this is the default when no base is specified, in which case the 0t/0T is not printed). + * - duodecimal: 0d/0D, representing base-12 units. + * - hexidecimal: 0x/0X, representing base-16 units. + * + * When printing digits, using lowercase designates to print alphabetic digits in lowercase and using uppercase designates to print alphabetic digits in uppercase. + * + * To keep the design simple, this does not support index position variable replacement like fprintf() does (such as '%1$', '%2$', etc..). + * + * Basic Format Flags: + * - "-": Use left-justification. + * - "#": Use alternate form conversion (prefixing 0b/0B, 0o/0O, 0t/0T, 0d/0D, 0x/0X). + * - ";": Ignore characters in the given positions from a f_array_length_t (only applies to static/dynamic string arguments but not character arguments). + * - ":": Ignore characters in the given ranges from a f_string_range_t (only applies to static/dynamic string arguments but not character arguments). + * - "/", Print only the given range of a string, specified by f_string_range_t (only applies to static/dynamic string arguments but not character arguments). + * - "+", Always show the signs (+ or -). + * - " ", Add a space where a sign would be if the sign is not displayed (this is the space character). + * - "=", Trim leading and trailing whitespaces (only applies to static/dynamic string arguments but not character arguments). + * - "0" to "9", The width to use, however if a leading 0 is used, then a 0 is printed in each leading digit as needed. + * + * Base Format Flags: + * - "!": Display digits in Binary notation. + * - "@": Display digits in Octal notation. + * - "^": Display digits in Decimal notation. + * - "&": Display digits in Duodecimal notation. + * - "_": Display digits in Hexidecimal notation. + * + * Type Format Flags: + * - "c": Type is a 1-byte unsigned character. + * - "C": Type is a 1-byte unsigned character, where control characters and invalid UTF-8 are replaced. + * - "[": Type is a f_color_set_t such that the f_color_set_t.begin is used. + * - "]": Type is a f_color_set_t such that the f_color_set_t.after is used. + * - "iii" "III": Type is a int8_t digit. + * - "ii", "II": Type is a int16_t digit. + * - "i", "I": Type is a int32_t digit. + * - "il", "IL": Type is a signed int64_t digit. + * - "ill", "ILL": Type is a f_int_128_t digit. + * - "in", "IN": Type is a f_number_signed_t digit. + * - "z", "Z": Type is a size_t digit. + * - "s": Type is a NULL terminated string, where the string is printed as-is. + * - "S": Type is a NULL terminated string, where control characters and invalid UTF-8 are replaced. + * - "q": Type is a f_string_static_t or f_string_dynamic_t and NULLs are ignored (not printed). + * - "Q": Type is a f_string_static_t or f_string_dynamic_t and NULLs are ignored (not printed), where control characters and invalid UTF-8 are replaced. + * - "r": Type is a f_string_static_t or f_string_dynamic_t and NULLs (and all other control characters) are printed. + * - "R": Type is a f_string_static_t or f_string_dynamic_t and NULLs are printed, but control characters and invalid UTF-8 are replaced. @todo not yet implemented. + * - "uii", "UII": Type is a uint8_t digit. + * - "ui", "UI": Type is a uint16_t digit. + * - "u", "U": Type is a uint32_t digit. + * - "ul", "UL": Type is a uint64_t digit. + * - "ull", "ULL": Type is a f_uint_128_t digit. + * - "un", "UN": Type is a f_number_unsigned_t digit (which by default is what f_array_length_t is a type of). + * + * The following are control characters and their replacements for "safe" printing (unknown is used for invalid UTF-8 sequences): + * - "␆": Acknowledge. + * - "␕": Negative Acknowledge. + * - "␈": Backspace. + * - "␇": Bell. + * - "␘": Cancel. + * - "␍": Carriage Return. + * - "␐": Data Link Escape. + * - "␡": Delete. + * - "␑": Device Control 1. + * - "␒": Device Control 2. + * - "␓": Device Control 3. + * - "␔": Device Control 4. + * - "␙": End of Medium. + * - "␃": End of Text. + * - "␄": End of Transmission. + * - "␗": End of Transmission Block. + * - "␅": Enquiry. + * - "␛": Escape. + * - "␌": Form Feed. + * - "␊": Line Feed. + * - "␀": Null. + * - "␜": Separator File. + * - "␝": Separator Group. + * - "␞": Separator Record. + * - "␟": Separator Unit. + * - "␏": Shift In. + * - "␎": Shift Out. + * - "␁": Start Of Header. + * - "␂": Start Of Text. + * - "␚": Substitute. + * - "␖": Synchronous Idle. + * - "␉": Tab. + * - "␋": Vertical Tab. + * - "�": Unknown. * * This print function does not use locking, be sure something like flockfile() and funlockfile() are appropriately called. * + * @todo float/double support is not yet implemented, but is intended to eventually be supported. + * * @param string * The formatted string to process and output. * This is a NULL terminated string. @@ -152,6 +267,7 @@ extern "C" { * The number of 1-byte characters processed from the string. * Any error will will result in the current count at the time of the error to be returned. * + * @see fprintf() * @see fputc_unlocked() * @see va_start() * @see va_end() diff --git a/level_1/fl_print/c/private-print.c b/level_1/fl_print/c/private-print.c index c06232b..a77e69d 100644 --- a/level_1/fl_print/c/private-print.c +++ b/level_1/fl_print/c/private-print.c @@ -70,7 +70,7 @@ extern "C" { continue; } else if (*string == f_string_ascii_asterisk_s[0]) { - // @fixme: what should I do here? review the fprintf() docs. + // @fixme what should I do here? review the fprintf() docs. continue; } else if (*string == f_string_ascii_plus_s[0]) { @@ -1699,7 +1699,7 @@ extern "C" { return F_status_set_error(F_utf_not); } - // @todo: change logic to use single fwrite() based on byte width rather than multiple fputc... + // @todo change logic to use single fwrite() based on byte width rather than multiple fputc... if (!fputc_unlocked(string[i], output)) { return F_status_set_error(F_output); } diff --git a/level_2/fll_fss/c/fss_basic.h b/level_2/fll_fss/c/fss_basic.h index 00e728f..f51f26c 100644 --- a/level_2/fll_fss/c/fss_basic.h +++ b/level_2/fll_fss/c/fss_basic.h @@ -63,7 +63,7 @@ extern "C" { * F_none on success. * F_none_eos on success after reaching the end of the buffer. * F_none_stop on success after reaching stopping point. - * F_data_not_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing). + * F_data_not_eol if there is no data to write and EOL was reached (@todo review related code and detemine what this is doing). * F_data_not_eos no data to write due start location being greater than or equal to buffer size. * F_data_not_stop no data to write due start location being greater than stop location. * diff --git a/level_2/fll_fss/c/fss_basic_list.h b/level_2/fll_fss/c/fss_basic_list.h index 9f32715..1924aaa 100644 --- a/level_2/fll_fss/c/fss_basic_list.h +++ b/level_2/fll_fss/c/fss_basic_list.h @@ -62,7 +62,7 @@ extern "C" { * F_none on success. * F_none_eos on success after reaching the end of the buffer. * F_none_stop on success after reaching stopping point. - * F_data_not_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing). + * F_data_not_eol if there is no data to write and EOL was reached (@todo review related code and detemine what this is doing). * F_data_not_eos no data to write due start location being greater than or equal to buffer size. * F_data_not_stop no data to write due start location being greater than stop location. * diff --git a/level_2/fll_fss/c/fss_embedded_list.h b/level_2/fll_fss/c/fss_embedded_list.h index 22b66a2..0a933ae 100644 --- a/level_2/fll_fss/c/fss_embedded_list.h +++ b/level_2/fll_fss/c/fss_embedded_list.h @@ -59,7 +59,7 @@ extern "C" { * F_none on success (both valid object and valid content found with start location is at end of content). * F_none_eos on success after reaching the end of the buffer (both valid object and valid content found with start location is at end of buffer). * F_none_stop on success after reaching stopping point (both valid object and valid content found with start location is at stop point). - * F_data_not_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing). + * F_data_not_eol if there is no data to write and EOL was reached (@todo review related code and detemine what this is doing). * F_data_not_eos no data to write due start location being greater than or equal to buffer size. * F_data_not_stop no data to write due start location being greater than stop location. * FL_fss_found_object_content_not on success and object was found but no content was found (start location is at end of object). diff --git a/level_2/fll_fss/c/fss_extended.h b/level_2/fll_fss/c/fss_extended.h index 7c21574..c84e996 100644 --- a/level_2/fll_fss/c/fss_extended.h +++ b/level_2/fll_fss/c/fss_extended.h @@ -66,7 +66,7 @@ extern "C" { * F_none_eos on success after reaching the end of the buffer. * F_data_not_stop no data to write due start location being greater than stop location. * F_data_not_eos no data to write due start location being greater than or equal to buffer size. - * F_data_not_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing). + * F_data_not_eol if there is no data to write and EOL was reached (@todo review related code and detemine what this is doing). * * F_complete_not_utf (with error bit) is returned on failure to read/process a UTF-8 character due to the character being potentially incomplete. * F_interrupt (with error bit) if stopping due to an interrupt. diff --git a/level_2/fll_fss/c/fss_extended_list.h b/level_2/fll_fss/c/fss_extended_list.h index bd7f5fe..f576d49 100644 --- a/level_2/fll_fss/c/fss_extended_list.h +++ b/level_2/fll_fss/c/fss_extended_list.h @@ -63,7 +63,7 @@ extern "C" { * F_none on success (both valid object and valid content found with start location is at end of content). * F_none_eos on success after reaching the end of the buffer (both valid object and valid content found with start location is at end of buffer). * F_none_stop on success after reaching stopping point (both valid object and valid content found with start location is at stop point). - * F_data_not_eol if there is no data to write and EOL was reached (@todo: review related code and detemine what this is doing). + * F_data_not_eol if there is no data to write and EOL was reached (@todo review related code and detemine what this is doing). * F_data_not_eos no data to write due start location being greater than or equal to buffer size. * F_data_not_stop no data to write due start location being greater than stop location. * FL_fss_found_object_content_not on success and object was found but no content was found (start location is at end of object). diff --git a/level_3/byte_dump/c/private-byte_dump.c b/level_3/byte_dump/c/private-byte_dump.c index 7824a06..87bd3d8 100644 --- a/level_3/byte_dump/c/private-byte_dump.c +++ b/level_3/byte_dump/c/private-byte_dump.c @@ -271,7 +271,7 @@ extern "C" { } if (ferror(file.stream)) { - // @todo: determine what the error is and display it. + // @todo determine what the error is and display it. flockfile(main.error.to.stream); fl_print_format("%[%Sread() failed for '%]", main.error.to.stream, main.context.set.error, main.error.prefix, main.context.set.error); @@ -379,7 +379,7 @@ extern "C" { } if (cell->column < main.width) { - // @fixme: when unicode is enabled but invalid, the mode and its respective length now matters. This needs to be included in the width calculations. + // @fixme when unicode is enabled but invalid, the mode and its respective length now matters. This needs to be included in the width calculations. if (main.parameters[byte_dump_parameter_unicode].result == f_console_result_found && !invalid[character_current]) { if (byte_current == 1) { uint32_t unicode = 0; @@ -795,7 +795,7 @@ extern "C" { } } - // @todo: implement a function in f_utf, such as f_utf_is_combining(), for detecting these combining characters. + // @todo implement a function in f_utf, such as f_utf_is_combining(), for detecting these combining characters. // print a space for combining characters to combine into, thereby allowing it to be safely and readably displayed. if (width_utf == 2 && characters.string[i] >= 0xdea60000 && characters.string[i] <= 0xdeb00000) { diff --git a/level_3/controller/c/main.c b/level_3/controller/c/main.c index 1f00632..d39db7e 100644 --- a/level_3/controller/c/main.c +++ b/level_3/controller/c/main.c @@ -28,7 +28,7 @@ int main(const int argc, const f_string_t *argv) { f_signal_close(&data.signal); } - // @fixme: bad design in POSIX where there is no get umask without setting it. + // @fixme bad design in POSIX where there is no get umask without setting it. data.umask = umask(0); // restore umask. diff --git a/level_3/controller/c/private-rule.c b/level_3/controller/c/private-rule.c index fb428cf..169566a 100644 --- a/level_3/controller/c/private-rule.c +++ b/level_3/controller/c/private-rule.c @@ -3054,7 +3054,7 @@ extern "C" { rule->status[i] = F_known_not; } // for - // @todo: timeouts may be passed from entry, consider to or not to initialize in a more consistent manner. + // @todo timeouts may be passed from entry, consider to or not to initialize in a more consistent manner. //rule->timeout_kill = 2; //rule->timeout_start = 2; //rule->timeout_stop = 2; diff --git a/level_3/fake/c/main.c b/level_3/fake/c/main.c index 098bf6a..147a85e 100644 --- a/level_3/fake/c/main.c +++ b/level_3/fake/c/main.c @@ -39,7 +39,7 @@ int main(const int argc, const f_string_t *argv) { } } - // @fixme: bad design in POSIX where there is no get umask without setting it. + // @fixme bad design in POSIX where there is no get umask without setting it. data.umask = umask(0); // restore umask. diff --git a/level_3/fake/documents/fakefile.txt b/level_3/fake/documents/fakefile.txt index 14ab6dd..e58c6fb 100644 --- a/level_3/fake/documents/fakefile.txt +++ b/level_3/fake/documents/fakefile.txt @@ -297,7 +297,7 @@ Fakefile Documentation: - shell\: Manually execute a remote program or script using a specific path to the program or script. This does not require the program to exist in PATH, but the path to the program or script must be relative to the project path. - @todo: consider relaxing this restriction on the relativeness of the path, possibly adding a configurable setting to allow enabling/disabling this restriction. + @todo consider relaxing this restriction on the relativeness of the path, possibly adding a configurable setting to allow enabling/disabling this restriction. The first Content represents the program or script name. All Content after the first are passed to the program or script when running. diff --git a/level_3/firewall/c/private-common.h b/level_3/firewall/c/private-common.h index 73ebb1e..7f2437c 100644 --- a/level_3/firewall/c/private-common.h +++ b/level_3/firewall/c/private-common.h @@ -85,7 +85,6 @@ typedef struct { (structure.array[index].stop - structure.array[index].start) + 1 // TODO: temporarily added, convert this to a function below. -// TODO: also report: f_color_print(main.error.to.stream, main.context.set.error, "CRITICAL ERROR: Unable to allocate memory.%c", f_string_eol_s[0]); #define macro_firewall_append_argument_to_arguments(status, arguments, argument) \ if (arguments.used == arguments.size) { \ macro_f_string_dynamics_t_resize(status, arguments, arguments.used + firewall_default_allocation_step); \ diff --git a/level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.c b/level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.c index 0aa8e05..efa1cac 100644 --- a/level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.c +++ b/level_3/fss_embedded_list_read/c/private-fss_embedded_list_read.c @@ -242,7 +242,7 @@ extern "C" { status = fll_fss_embedded_list_read(main->buffer, state, &input, &main->nest, objects_delimits, contents_delimits, comments); if (F_status_is_error(status)) { - // @todo: detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. + // @todo detect and replace fll_error_file_type_file with fll_error_file_type_pipe as appropriate. fll_error_file_print(main->error, F_status_set_fine(status), "fll_fss_embedded_list_read", F_true, filename, "process", fll_error_file_type_file); } else if (status == F_data_not_stop || status == F_data_not_eos) { diff --git a/level_3/fss_status_code/c/fss_status_code.c b/level_3/fss_status_code/c/fss_status_code.c index e76bd63..7f588f2 100644 --- a/level_3/fss_status_code/c/fss_status_code.c +++ b/level_3/fss_status_code/c/fss_status_code.c @@ -174,7 +174,7 @@ extern "C" { if (main->parameters[fss_status_code_parameter_is_error].result == f_console_result_found || main->parameters[fss_status_code_parameter_is_warning].result == f_console_result_found || main->parameters[fss_status_code_parameter_is_fine].result == f_console_result_found) { if (main->process_pipe) { - // @todo: call fss_status_code_process_check() here for all main from pipe that is space separated. + // @todo call fss_status_code_process_check() here for all main from pipe that is space separated. } if (main->remaining.used > 0) { @@ -194,7 +194,7 @@ extern "C" { } else if (main->parameters[fss_status_code_parameter_number].result == f_console_result_found) { if (main->process_pipe) { - // @todo: call fss_status_code_process_number() here for all main from pipe that is space separated. + // @todo call fss_status_code_process_number() here for all main from pipe that is space separated. } if (main->remaining.used > 0) { @@ -214,7 +214,7 @@ extern "C" { } else { if (main->process_pipe) { - // @todo: call fss_status_code_process_normal() here for all main from pipe that is space separated. + // @todo call fss_status_code_process_normal() here for all main from pipe that is space separated. } if (main->remaining.used > 0) { diff --git a/level_3/iki_read/c/iki_read.c b/level_3/iki_read/c/iki_read.c index ff1891f..30dc929 100644 --- a/level_3/iki_read/c/iki_read.c +++ b/level_3/iki_read/c/iki_read.c @@ -9,6 +9,8 @@ extern "C" { #ifndef _di_iki_read_print_help_ f_status_t iki_read_print_help(const f_file_t output, const f_color_context_t context) { + flockfile(output.stream); + fll_program_print_help_header(output, context, iki_read_name_long, iki_read_version); fll_program_print_help_option(output, context, f_console_standard_short_help_s, f_console_standard_long_help_s, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print this help message."); @@ -21,69 +23,43 @@ extern "C" { fll_program_print_help_option(output, context, f_console_standard_short_debug_s, f_console_standard_long_debug_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Enable debugging, inceasing verbosity beyond normal output."); fll_program_print_help_option(output, context, f_console_standard_short_version_s, f_console_standard_long_version_s, f_console_symbol_short_disable_s, f_console_symbol_long_disable_s, " Print only the version number."); - fprintf(output.stream, "%c", f_string_eol_s[0]); + f_print_character(f_string_eol_s[0], output.stream); fll_program_print_help_option(output, context, iki_read_short_at, iki_read_long_at, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select variable at this numeric index."); - fll_program_print_help_option(output, context, iki_read_short_line, iki_read_long_line, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the variables at the given line."); + fll_program_print_help_option(output, context, iki_read_short_line, iki_read_long_line, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print only the variables at the given line within the file."); fll_program_print_help_option(output, context, iki_read_short_name, iki_read_long_name, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Select variables with this name."); - fll_program_print_help_option(output, context, iki_read_short_whole, iki_read_long_whole, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print all of the main instead of just the variable main."); + fll_program_print_help_option(output, context, iki_read_short_whole, iki_read_long_whole, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print all of the data instead of just the IKI variable data."); - fprintf(output.stream, "%c", f_string_eol_s[0]); + f_print_character(f_string_eol_s[0], output.stream); fll_program_print_help_option(output, context, iki_read_short_content, iki_read_long_content, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the variable content (default)."); fll_program_print_help_option(output, context, iki_read_short_literal, iki_read_long_literal, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Print the entire variable (aka: object, content, and syntax)."); fll_program_print_help_option(output, context, iki_read_short_object, iki_read_long_object, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the variable name (aka: object)."); fll_program_print_help_option(output, context, iki_read_short_total, iki_read_long_total, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, " Print the total number of variables."); - fprintf(output.stream, "%c", f_string_eol_s[0]); + f_print_character(f_string_eol_s[0], output.stream); fll_program_print_help_option(output, context, iki_read_short_substitute, iki_read_long_substitute, f_console_symbol_short_enable_s, f_console_symbol_long_enable_s, "Substitute the entire variable for the given name and content value with the given string."); fll_program_print_help_usage(output, context, iki_read_name, "filename(s)"); - f_color_print(output.stream, context.set.important, " Notes:"); - - fprintf(output.stream, "%c", f_string_eol_s[0]); - - fprintf(output.stream, " This program will find and print variables, vocabularies, or content following the IKI standard, without focusing on any particular vocabulary specification.%c", f_string_eol_s[0]); - - fprintf(output.stream, "%c", f_string_eol_s[0]); - - fprintf(output.stream, " The "); - f_color_print(output.stream, context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_substitute); - fprintf(output.stream, " option, requires 3 additional parameters: "); - - f_color_print(output.stream, context.set.notable, "<"); - fprintf(output.stream, "%s", iki_read_substitution_vocabulary); - f_color_print(output.stream, context.set.notable, ">"); - fprintf(output.stream, "%s", f_string_space_s); - f_color_print(output.stream, context.set.notable, "<"); - fprintf(output.stream, "%s", iki_read_substitution_replace); - f_color_print(output.stream, context.set.notable, ">"); - fprintf(output.stream, "%s", f_string_space_s); - f_color_print(output.stream, context.set.notable, "<"); - fprintf(output.stream, "%s", iki_read_substitution_with); - f_color_print(output.stream, context.set.notable, ">"); - fprintf(output.stream, ".%c", f_string_eol_s[0]); - - f_color_print(output.stream, context.set.notable, " %s", iki_read_substitution_vocabulary); - fprintf(output.stream, ": The name of the vocabulary whose content is to be substituted.%c", f_string_eol_s[0]); - - f_color_print(output.stream, context.set.notable, " %s", iki_read_substitution_replace); - fprintf(output.stream, ": The content matching this exact string will be substituted.%c", f_string_eol_s[0]); - - f_color_print(output.stream, context.set.notable, " %s", iki_read_substitution_with); - fprintf(output.stream, ": The new string to use as the substitute.%c", f_string_eol_s[0]); + fl_print_format(" %[Notes:%]%c", output.stream, context.set.important, context.set.important, f_string_eol_s[0]); + fl_print_format(" This program will find and print variables, vocabularies, or content following the IKI standard, without focusing on any particular vocabulary specification.%c%c", output.stream, f_string_eol_s[0], f_string_eol_s[0]); - fprintf(output.stream, "%c", f_string_eol_s[0]); + fl_print_format(" This %[%s%s%] option, requires 3 additional parameters:", output.stream, context.set.notable, f_console_symbol_long_enable_s, iki_read_long_substitute, context.set.notable); + fl_print_format(" %[<%]%s%[>%]", output.stream, context.set.notable, context.set.notable, iki_read_substitution_vocabulary, context.set.notable, context.set.notable); + fl_print_format(" %[<%]%s%[>%]", output.stream, context.set.notable, context.set.notable, iki_read_substitution_replace, context.set.notable, context.set.notable); + fl_print_format(" %[<%]%s%[>%].%c", output.stream, context.set.notable, context.set.notable, iki_read_substitution_with, context.set.notable, context.set.notable, f_string_eol_s[0]); - fprintf(output.stream, " The vocabulary and replacement are case-sensitive and must exactly match.%c", f_string_eol_s[0]); + fl_print_format(" %[%s%]: The name of the vocabulary whose content is to be substituted.%c", output.stream, context.set.notable, iki_read_substitution_vocabulary, context.set.notable, f_string_eol_s[0]); + fl_print_format(" %[%s%]: The content matching this exact string will be substituted.%c", output.stream, context.set.notable, iki_read_substitution_replace, context.set.notable, f_string_eol_s[0]); + fl_print_format(" %[%s%]: The new string to use as the substitute.%c%c", output.stream, context.set.notable, iki_read_substitution_with, context.set.notable, f_string_eol_s[0], f_string_eol_s[0]); - fprintf(output.stream, "%c", f_string_eol_s[0]); + fl_print_format(" The vocabulary and replacement are case-sensitive and must exactly match.%c%c", output.stream, f_string_eol_s[0], f_string_eol_s[0]); - fprintf(output.stream, " The default behavior is to only display content portion of the IKI variable.%c", f_string_eol_s[0]); + fl_print_format(" The default behavior is to only display content portion of the IKI variable.%c%c", output.stream, f_string_eol_s[0], f_string_eol_s[0]); - fprintf(output.stream, "%c", f_string_eol_s[0]); + funlockfile(output.stream); return F_none; } @@ -105,9 +81,12 @@ extern "C" { if (main->context.set.error.before) { main->error.context = main->context.set.error; main->error.notable = main->context.set.notable; + + main->warning.context = main->context.set.warning; + main->warning.notable = main->context.set.notable; } else { - f_color_set_t *sets[] = { &main->error.context, &main->error.notable, 0 }; + f_color_set_t *sets[] = { &main->error.context, &main->error.notable, &main->warning.context, &main->warning.notable, 0 }; fll_program_parameter_process_empty(&main->context, sets); } @@ -116,7 +95,7 @@ extern "C" { fll_error_print(main->error, F_status_set_fine(status), "fll_program_parameter_process", F_true); if (main->error.verbosity == f_console_verbosity_verbose) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); + fll_print_character(f_string_eol_s[0], main->error.to.stream); } iki_read_main_delete(main); @@ -141,15 +120,19 @@ extern "C" { if (choice == iki_read_parameter_verbosity_quiet) { main->error.verbosity = f_console_verbosity_quiet; + main->warning.verbosity = f_console_verbosity_quiet; } else if (choice == iki_read_parameter_verbosity_normal) { main->error.verbosity = f_console_verbosity_normal; + main->warning.verbosity = f_console_verbosity_normal; } else if (choice == iki_read_parameter_verbosity_verbose) { main->error.verbosity = f_console_verbosity_verbose; + main->warning.verbosity = f_console_verbosity_verbose; } else if (choice == iki_read_parameter_verbosity_debug) { main->error.verbosity = f_console_verbosity_debug; + main->warning.verbosity = f_console_verbosity_debug; } } @@ -173,10 +156,13 @@ extern "C" { if (main->remaining.used > 0 || main->process_pipe) { if (main->parameters[iki_read_parameter_at].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sThe parameter '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_at); - f_color_print(main->error.to.stream, main->context.set.error, "' requires a positive number.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_at, main->error.notable); + fl_print_format("%[' requires a positive number.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -199,12 +185,15 @@ extern "C" { if (main->parameters[iki_read_parameter_total].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_at); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '"); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_total); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter."); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sCannot specify the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_at, main->error.notable); + fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_total, main->error.notable); + fl_print_format("%[' parameter.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -213,10 +202,13 @@ extern "C" { if (main->parameters[iki_read_parameter_line].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sThe parameter '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_line); - f_color_print(main->error.to.stream, main->context.set.error, "' requires a positive number.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_line, main->error.notable); + fl_print_format("%[' requires a positive number.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -240,10 +232,13 @@ extern "C" { if (main->parameters[iki_read_parameter_name].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sThe parameter '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_name); - f_color_print(main->error.to.stream, main->context.set.error, "' requires a string.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_name, main->error.notable); + fl_print_format("%[' requires a string.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -252,10 +247,13 @@ extern "C" { if (main->parameters[iki_read_parameter_substitute].result != f_console_result_none) { if (main->parameters[iki_read_parameter_substitute].result == f_console_result_found || main->parameters[iki_read_parameter_substitute].values.used % 3 != 0) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sThe parameter '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_substitute); - f_color_print(main->error.to.stream, main->context.set.error, "' requires 3 strings.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sThe parameter '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_substitute, main->error.notable); + fl_print_format("%[' requires 3 strings.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -263,12 +261,15 @@ extern "C" { if (main->parameters[iki_read_parameter_total].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_substitute); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '"); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_total); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sCannot specify the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_substitute, main->error.notable); + fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_total, main->error.notable); + fl_print_format("%[' parameter.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -278,12 +279,15 @@ extern "C" { if (main->parameters[iki_read_parameter_literal].result == f_console_result_found) { if (main->parameters[iki_read_parameter_object].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_literal); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '"); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_object); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sCannot specify the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_literal, main->error.notable); + fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_object, main->error.notable); + fl_print_format("%[' parameter.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -291,12 +295,15 @@ extern "C" { if (main->parameters[iki_read_parameter_content].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_literal); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '"); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_content); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sCannot specify the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_literal, main->error.notable); + fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_content, main->error.notable); + fl_print_format("%[' parameter.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -304,12 +311,15 @@ extern "C" { if (main->parameters[iki_read_parameter_total].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_literal); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '"); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_total); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sCannot specify the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_literal, main->error.notable); + fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_total, main->error.notable); + fl_print_format("%[' parameter.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -320,12 +330,15 @@ extern "C" { else if (main->parameters[iki_read_parameter_object].result == f_console_result_found) { if (main->parameters[iki_read_parameter_content].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_object); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '"); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_content); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sCannot specify the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_object, main->error.notable); + fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_content, main->error.notable); + fl_print_format("%[' parameter.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -333,12 +346,15 @@ extern "C" { if (main->parameters[iki_read_parameter_total].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_object); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '"); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_total); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sCannot specify the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_object, main->error.notable); + fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_total, main->error.notable); + fl_print_format("%[' parameter.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -357,12 +373,15 @@ extern "C" { if (main->parameters[iki_read_parameter_whole].result == f_console_result_found) { if (main->parameters[iki_read_parameter_total].result == f_console_result_found) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%sCannot specify the '", fll_error_print_error); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_whole); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter with the '"); - f_color_print(main->error.to.stream, main->context.set.notable, "%s%s", f_console_symbol_long_enable_s, iki_read_long_total); - f_color_print(main->error.to.stream, main->context.set.error, "' parameter.%c", f_string_eol_s[0]); + flockfile(main->error.to.stream); + + fl_print_format("%c%[%sCannot specify the '%]", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_whole, main->error.notable); + fl_print_format("%[' parameter with the '%]", main->error.to.stream, main->error.context, main->error.context); + fl_print_format("%[%s%s%]", main->error.to.stream, main->error.notable, f_console_symbol_long_enable_s, iki_read_long_total, main->error.notable); + fl_print_format("%[' parameter.%]%c", main->error.to.stream, main->error.context, main->error.context, f_string_eol_s[0]); + + funlockfile(main->error.to.stream); } status = F_status_set_error(F_parameter); @@ -371,7 +390,7 @@ extern "C" { if (F_status_is_error(status)) { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); + fll_print_character(f_string_eol_s[0], main->error.to.stream); } iki_read_main_delete(main); @@ -446,8 +465,7 @@ extern "C" { } else { if (main->error.verbosity != f_console_verbosity_quiet) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); - f_color_print(main->error.to.stream, main->context.set.error, "%syou failed to specify one or more files.%c", fll_error_print_error, f_string_eol_s[0]); + fll_print_format("%c%[%sYou failed to specify one or more files.%]%c", main->error.to.stream, f_string_eol_s[0], main->error.context, main->error.prefix, main->error.context, f_string_eol_s[0]); } status = F_status_set_error(F_parameter); @@ -456,7 +474,7 @@ extern "C" { // ensure a newline is always put at the end of the program execution, unless in quiet mode. if (main->error.verbosity != f_console_verbosity_quiet) { if (F_status_is_error(status) || !main->mode) { - fprintf(main->error.to.stream, "%c", f_string_eol_s[0]); + fll_print_character(f_string_eol_s[0], main->error.to.stream); } } diff --git a/level_3/iki_read/c/iki_read.h b/level_3/iki_read/c/iki_read.h index b97e408..ba65148 100644 --- a/level_3/iki_read/c/iki_read.h +++ b/level_3/iki_read/c/iki_read.h @@ -46,6 +46,7 @@ // fll-2 includes #include #include +#include #include #ifdef __cplusplus @@ -199,6 +200,7 @@ extern "C" { f_file_t output; fll_error_print_t error; + fll_error_print_t warning; uint8_t mode; @@ -219,6 +221,7 @@ extern "C" { F_false, \ macro_f_file_t_initialize2(f_type_output, f_type_descriptor_output, f_file_flag_write_only), \ fll_error_print_t_initialize, \ + macro_fll_error_print_t_initialize_warning(), \ 0, \ 0, \ 0, \ diff --git a/level_3/iki_read/c/private-iki_read.c b/level_3/iki_read/c/private-iki_read.c index bf65cd1..c7284d9 100644 --- a/level_3/iki_read/c/private-iki_read.c +++ b/level_3/iki_read/c/private-iki_read.c @@ -170,6 +170,8 @@ extern "C" { buffer_range->stop = name.used - 1; + flockfile(main->output.stream); + for (j = 0; j < vocabulary->used; ++j) { status = fl_string_dynamic_partial_compare(name, main->buffer, *buffer_range, vocabulary->array[j]); @@ -181,12 +183,14 @@ extern "C" { iki_read_substitutions_print(*main, *variable, *content, *ranges, substitutionss[j], j, content_only); } else { - f_print_dynamic_partial(main->output.stream, main->buffer, ranges->array[j]); + f_print_dynamic_partial(main->buffer, ranges->array[j], main->output.stream); } - printf("%c", f_string_eol_s[0]); + f_print_character(f_string_eol_s[0], main->output.stream); } } // for + + funlockfile(main->output.stream); } // for macro_f_string_dynamic_t_delete_simple(name); @@ -198,18 +202,22 @@ extern "C" { f_array_length_t i = 0; f_array_length_t j = 0; + flockfile(main->output.stream); + for (; i < ranges->used; ++i) { if (substitutionss[i].used) { iki_read_substitutions_print(*main, *variable, *content, *ranges, substitutionss[i], i, content_only); } else { - f_print_dynamic_partial(main->output.stream, main->buffer, ranges->array[i]); + f_print_dynamic_partial(main->buffer, ranges->array[i], main->output.stream); } - printf("%c", f_string_eol_s[0]); + f_print_character(f_string_eol_s[0], main->output.stream); } // for + funlockfile(main->output.stream); + status = F_none; } else { @@ -243,7 +251,7 @@ extern "C" { } if (!variable->used) { - f_print_dynamic_partial(main->output.stream, main->buffer, buffer_range); + fll_print_dynamic_partial(main->buffer, buffer_range, main->output.stream); return F_none; } @@ -333,13 +341,15 @@ extern "C" { range = buffer_range; name_range.start = 0; + flockfile(main->output.stream); + while (i <= range.stop && j < variable->used) { if (i < variable->array[j].start) { range.start = i; range.stop = variable->array[j].start - 1; - f_print_dynamic_partial(main->output.stream, main->buffer, range); + f_print_dynamic_partial(main->buffer, range, main->output.stream); range.start = variable->array[j].stop + 1; range.stop = buffer_range.stop; @@ -366,7 +376,7 @@ extern "C" { iki_read_substitutions_print(*main, *variable, *content, *variable, substitutionss[j], j, F_false); } else { - f_print_dynamic_partial(main->output.stream, main->buffer, variable->array[j]); + f_print_dynamic_partial(main->buffer, variable->array[j], main->output.stream); } } else { @@ -374,7 +384,7 @@ extern "C" { iki_read_substitutions_print(*main, *variable, *content, *ranges, substitutionss[j], j, content_only); } else { - f_print_dynamic_partial(main->output.stream, main->buffer, ranges->array[j]); + f_print_dynamic_partial(main->buffer, ranges->array[j], main->output.stream); } } } @@ -383,7 +393,7 @@ extern "C" { iki_read_substitutions_print(*main, *variable, *content, *ranges, substitutionss[j], j, content_only); } else { - f_print_dynamic_partial(main->output.stream, main->buffer, ranges->array[j]); + f_print_dynamic_partial(main->buffer, ranges->array[j], main->output.stream); } } @@ -393,8 +403,10 @@ extern "C" { if (i <= buffer_range.stop) { range.start = i; - f_print_dynamic_partial(main->output.stream, main->buffer, range); + f_print_dynamic_partial(main->buffer, range, main->output.stream); } + + funlockfile(main->output.stream); } for (f_array_length_t i = 0; i < variable->used; ++i) { @@ -416,13 +428,13 @@ extern "C" { if (status == F_true) { if (range.start > main->buffer.used) { - printf("0\n"); + fll_print_format("0%c", main->output.stream, f_string_eol_s[0]); return F_none; } } else if (status == F_data_not) { - printf("0\n"); + fll_print_format("0%c", main->output.stream, f_string_eol_s[0]); return F_none; } @@ -480,7 +492,7 @@ extern "C" { total = variable->used; } - printf("%llu\n", total); + fll_print_format("%ul%c", main->output.stream, total, f_string_eol_s[0]); return F_none; } @@ -557,24 +569,24 @@ extern "C" { if (status == F_equal_to) { if (content_only) { - f_print_dynamic(main.output.stream, substitutions.array[i].with); + f_print_dynamic(substitutions.array[i].with, main.output.stream); } else { range.start = variable.array[index].start; range.stop = content.array[index].start - 1; - f_print_dynamic_partial(main.output.stream, main.buffer, range); + f_print_dynamic_partial(main.buffer, range, main.output.stream); - f_print_dynamic(main.output.stream, substitutions.array[i].with); + f_print_dynamic(substitutions.array[i].with, main.output.stream); range.start = content.array[index].stop + 1; range.stop = variable.array[index].stop; - f_print_dynamic_partial(main.output.stream, main.buffer, range); + f_print_dynamic_partial(main.buffer, range, main.output.stream); } } else { - f_print_dynamic_partial(main.output.stream, main.buffer, ranges.array[index]); + f_print_dynamic_partial(main.buffer, ranges.array[index], main.output.stream); } } #endif // _di_iki_read_substitutions_print_ diff --git a/level_3/iki_read/data/build/dependencies b/level_3/iki_read/data/build/dependencies index f8af2dc..285a995 100644 --- a/level_3/iki_read/data/build/dependencies +++ b/level_3/iki_read/data/build/dependencies @@ -15,7 +15,9 @@ f_print fl_console fl_conversion fl_iki +fl_print fl_signal fl_string fll_error +fll_print fll_program diff --git a/level_3/iki_read/data/build/settings b/level_3/iki_read/data/build/settings index 9f248b0..dc3d889 100644 --- a/level_3/iki_read/data/build/settings +++ b/level_3/iki_read/data/build/settings @@ -20,7 +20,7 @@ build_compiler gcc build_indexer ar build_language c build_libraries -lc -build_libraries-individual -lfll_error -lfll_program -lfl_console -lfl_conversion -lfl_iki -lfl_signal -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf +build_libraries-individual -lfll_error -lfll_print -lfll_program -lfl_console -lfl_conversion -lfl_iki -lfl_print -lfl_signal -lfl_string -lf_color -lf_console -lf_conversion -lf_file -lf_iki -lf_memory -lf_path -lf_pipe -lf_print -lf_signal -lf_string -lf_type_array -lf_utf build_libraries-level -lfll_2 -lfll_1 -lfll_0 build_libraries-monolithic -lfll build_sources_library iki_read.c private-common.c private-iki_read.c @@ -51,7 +51,7 @@ defines_all defines_static defines_shared -flags_all -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-logical-op-parentheses -Wno-parentheses +flags_all -O2 -z now -g -fdiagnostics-color=always -Wno-logical-not-parentheses -Wno-logical-op-parentheses -Wno-parentheses flags_shared flags_static flags_library -fPIC diff --git a/level_3/status_code/c/status_code.c b/level_3/status_code/c/status_code.c index 97652ae..47c7643 100644 --- a/level_3/status_code/c/status_code.c +++ b/level_3/status_code/c/status_code.c @@ -174,7 +174,7 @@ extern "C" { if (main->parameters[status_code_parameter_is_error].result == f_console_result_found || main->parameters[status_code_parameter_is_warning].result == f_console_result_found || main->parameters[status_code_parameter_is_fine].result == f_console_result_found) { if (main->process_pipe) { - // @todo: call status_code_process_check() here for all main from pipe that is space separated. + // @todo call status_code_process_check() here for all main from pipe that is space separated. } if (main->remaining.used > 0) { @@ -194,7 +194,7 @@ extern "C" { } else if (main->parameters[status_code_parameter_number].result == f_console_result_found) { if (main->process_pipe) { - // @todo: call status_code_process_number() here for all main from pipe that is space separated. + // @todo call status_code_process_number() here for all main from pipe that is space separated. } if (main->remaining.used > 0) { @@ -214,7 +214,7 @@ extern "C" { } else { if (main->process_pipe) { - // @todo: call status_code_process_normal() here for all main from pipe that is space separated. + // @todo call status_code_process_normal() here for all main from pipe that is space separated. } if (main->remaining.used > 0) { -- 1.8.3.1