build_language c
build_libraries -lc
build_libraries-level
-build_sources_library account.c console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c memory.c path.c private-path.c pipe.c print.c serialize.c private-serialize.c signal.c socket.c utf.c private-utf.c
+build_sources_library account.c console.c conversion.c directory.c private-directory.c environment.c private-environment.c file.c private-file.c fss.c iki.c private-iki.c memory.c path.c private-path.c pipe.c print.c serialize.c private-serialize.c signal.c socket.c utf.c private-utf.c
build_sources_program
build_sources_headers account.h color.h console.h conversion.h directory.h directory_type.h environment.h file.h fss.h fss-common.h fss-named.h fss-nest.h fss-quoted.h fss-set.h iki.h iki-common.h memory.h memory-structure.h path.h pipe.h print.h serialize.h signal.h socket.h status.h status_array.h string.h string_common.h string_dynamic.h string_map.h string_quantity.h string_range.h type.h type_array.h utf.h utf-common.h
build_sources_script
build_language c
build_libraries -lc
build_libraries-level -lfll_1 -lfll_0
-build_sources_library execute.c private-execute.c file.c private-file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c path.c program.c status.c
+build_sources_library execute.c private-execute.c file.c private-file.c fss.c private-fss.c fss_basic.c fss_basic_list.c fss_extended.c fss_extended_list.c fss_status.c iki.c private-iki.c path.c program.c status.c
build_sources_program
-build_sources_headers execute.h file.h fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_status.h path.h program.h status.h
+build_sources_headers execute.h file.h fss.h fss_basic.h fss_basic_list.h fss_extended.h fss_extended_list.h fss_status.h iki.h path.h program.h status.h
build_sources_script
build_sources_setting
build_script yes
build_language c
build_libraries -lc
build_libraries-monolithic
-build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/path.c level_2/program.c level_2/status.c
+build_sources_library level_0/account.c level_0/console.c level_0/conversion.c level_0/directory.c level_0/private-directory.c level_0/environment.c level_0/private-environment.c level_0/file.c level_0/private-file.c level_0/fss.c level_0/iki.c level_0/private-iki.c level_0/memory.c level_0/path.c level_0/private-path.c level_0/pipe.c level_0/print.c level_0/serialize.c level_0/private-serialize.c level_0/signal.c level_0/socket.c level_0/utf.c level_0/private-utf.c level_1/color.c level_1/console.c level_1/conversion.c level_1/directory.c level_1/private-directory.c level_1/environment.c level_1/private-fss.c level_1/fss_basic.c level_1/fss_basic_list.c level_1/fss_extended.c level_1/fss_extended_list.c level_1/iki.c level_1/print.c level_1/status.c level_1/string.c level_1/private-string.c level_1/utf.c level_1/private-utf.c level_1/utf_file.c level_1/private-utf_file.c level_2/execute.c level_2/private-execute.c level_2/file.c level_2/private-file.c level_2/fss.c level_2/private-fss.c level_2/fss_basic.c level_2/fss_basic_list.c level_2/fss_extended.c level_2/fss_extended_list.c level_2/fss_status.c level_2/iki.c level_2/private-iki.c level_2/path.c level_2/program.c level_2/status.c
build_sources_program
-build_sources_headers level_0/account.h level_0/color.h level_0/console.h level_0/conversion.h level_0/directory.h level_0/directory_type.h level_0/environment.h level_0/file.h level_0/fss.h level_0/fss-common.h level_0/fss-named.h level_0/fss-nest.h level_0/fss-quoted.h level_0/fss-set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory-structure.h level_0/path.h level_0/pipe.h level_0/print.h level_0/serialize.h level_0/signal.h level_0/socket.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string_common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/path.h level_2/program.h level_2/status.h
+build_sources_headers level_0/account.h level_0/color.h level_0/console.h level_0/conversion.h level_0/directory.h level_0/directory_type.h level_0/environment.h level_0/file.h level_0/fss.h level_0/fss-common.h level_0/fss-named.h level_0/fss-nest.h level_0/fss-quoted.h level_0/fss-set.h level_0/iki.h level_0/iki-common.h level_0/memory.h level_0/memory-structure.h level_0/path.h level_0/pipe.h level_0/print.h level_0/serialize.h level_0/signal.h level_0/socket.h level_0/status.h level_0/status_array.h level_0/string.h level_0/string_common.h level_0/string_dynamic.h level_0/string_map.h level_0/string_quantity.h level_0/string_range.h level_0/type.h level_0/type_array.h level_0/utf.h level_0/utf-common.h level_1/color.h level_1/console.h level_1/conversion.h level_1/directory.h level_1/environment.h level_1/fss.h level_1/fss_basic.h level_1/fss_basic_list.h level_1/fss_extended.h level_1/fss_extended_list.h level_1/fss_macro.h level_1/fss_status.h level_1/iki.h level_1/print.h level_1/status.h level_1/string.h level_1/utf.h level_1/utf_file.h level_2/execute.h level_2/file.h level_2/fss.h level_2/fss_basic.h level_2/fss_basic_list.h level_2/fss_extended.h level_2/fss_extended_list.h level_2/fss_status.h level_2/iki.h level_2/path.h level_2/program.h level_2/status.h
build_sources_script
build_sources_setting
build_script yes
bash build/scripts/package.sh build -i
if [[ $? -eq 0 ]] ; then
- for i in f_type f_status f_memory f_string f_utf f_account f_color f_console f_conversion f_directory f_environment f_file f_fss f_iki f_path f_pipe f_print f_serialize f_signal f_socket fl_color fl_console fl_conversion fl_directory fl_environment fl_fss fl_iki fl_print fl_status fl_string fl_utf fl_utf_file fll_execute fll_file fll_fss fll_path fll_program fll_status ; do
+ for i in f_type f_status f_memory f_string f_utf f_account f_color f_console f_conversion f_directory f_environment f_file f_fss f_iki f_path f_pipe f_print f_serialize f_signal f_socket fl_color fl_console fl_conversion fl_directory fl_environment fl_fss fl_iki fl_print fl_status fl_string fl_utf fl_utf_file fll_execute fll_file fll_fss fll_iki fll_path fll_program fll_status ; do
echo && echo "Processing $i." &&
cd package/individual/$i-$2/ &&
#include "iki.h"
+#include "private-iki.h"
#ifdef __cplusplus
extern "C" {
#endif
+#ifndef _di_f_iki_content_is_
+ f_return_status f_iki_content_is(const f_string_static_t content, const uint8_t quote) {
+ #ifndef _di_level_0_parameter_checking_
+ if (content.used > content.size) return F_status_set_error(F_parameter);
+ if (quote != f_iki_syntax_quote_single && quote != f_iki_syntax_quote_double) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ const f_string_range_t range = f_macro_string_range_t_initialize(content.used);
+
+ return private_f_iki_content_partial_is(content, range, quote);
+ }
+#endif // _di_f_iki_content_is_
+
+#ifndef _di_f_iki_content_partial_is_
+ f_return_status f_iki_content_partial_is(const f_string_static_t content, const f_string_range_t range, const uint8_t quote) {
+ #ifndef _di_level_0_parameter_checking_
+ if (content.used > content.size) return F_status_set_error(F_parameter);
+ if (range.start > range.stop) return F_status_set_error(F_parameter);
+ if (range.start >= content.used) return F_status_set_error(F_parameter);
+ if (quote != f_iki_syntax_quote_single && quote != f_iki_syntax_quote_double) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_f_iki_content_partial_is(content, range, quote);
+ }
+#endif // _di_f_iki_content_partial_is_
+
+#ifndef _di_f_iki_object_is_
+ f_return_status f_iki_object_is(const f_string_static_t object) {
+ #ifndef _di_level_0_parameter_checking_
+ if (object.used > object.size) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ const f_string_range_t range = f_macro_string_range_t_initialize(object.used);
+
+ return private_f_iki_object_partial_is(object, range);
+ }
+#endif // _di_f_iki_object_is_
+
+#ifndef _di_f_iki_object_partial_is_
+ f_return_status f_iki_object_partial_is(const f_string_static_t object, const f_string_range_t range) {
+ #ifndef _di_level_0_parameter_checking_
+ if (object.used > object.size) return F_status_set_error(F_parameter);
+ if (range.start > range.stop) return F_status_set_error(F_parameter);
+ if (range.start >= object.used) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_f_iki_object_partial_is(object, range);
+ }
+#endif // _di_f_iki_object_partial_is_
+
#ifndef _di_f_iki_read_
f_return_status f_iki_read(f_string_static_t *buffer, f_string_range_t *range, f_iki_variable_t *variable, f_iki_vocabulary_t *vocabulary, f_iki_content_t *content) {
#ifndef _di_level_0_parameter_checking_
return F_data_not_eos;
}
- f_string_range_t found_vocabulary = f_string_range_initialize;
+ f_string_range_t found_vocabulary = f_string_range_t_initialize;
f_string_length_t found_content = 0;
found_vocabulary.start = range->start;
if (buffer->string[range->start] == quote) {
f_array_length_t content_slash_delimits = content_slash_total / 2;
- f_string_range_t content_range = f_string_range_initialize;
+ f_string_range_t content_range = f_string_range_t_initialize;
f_array_length_t i = 0;
if (content_slash_total % 2) {
#endif
/**
+ * Determine if an content is a valid IKI content name.
+ *
+ * @param content
+ * The string to validate as an content name.
+ * @param quote
+ * The quote character in use.
+ * This must be either a single (') or double (") quote.
+ *
+ * @return
+ * F_true on success and string is a valid content name.
+ * F_false on success and string is not a valid content name.
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_iki_content_is_
+ extern f_return_status f_iki_content_is(const f_string_static_t content, const uint8_t quote);
+#endif // _di_f_iki_content_is_
+
+/**
+ * Determine if an content, found within the given range, is a valid IKI content name.
+ *
+ * @param content
+ * The string to validate as an content name.
+ * @param range
+ * The range within the buffer that represents the content name.
+ * @param quote
+ * The quote character in use.
+ * This must be either a single (') or double (") quote.
+ *
+ * @return
+ * F_true on success and string is a valid content name.
+ * F_false on success and string is not a valid content name.
+ * F_parameter (with error bit) if a parameter is invalid.
+ */
+#ifndef _di_f_iki_content_partial_is_
+ extern f_return_status f_iki_content_partial_is(const f_string_static_t content, const f_string_range_t range, const uint8_t quote);
+#endif // _di_f_iki_content_partial_is_
+
+/**
+ * Determine if an object is a valid IKI object name.
+ *
+ * @param object
+ * The string to validate as an object name.
+ *
+ * @return
+ * F_true on success and string is a valid object name.
+ * F_false on success and string is not a valid object name.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors from (with error bit): f_utf_is_word().
+ */
+#ifndef _di_f_iki_object_is_
+ extern f_return_status f_iki_object_is(const f_string_static_t object);
+#endif // _di_f_iki_object_is_
+
+/**
+ * Determine if an object, found within the buffer, is a valid IKI object name.
+ *
+ * @param object
+ * The string to validate as an object name.
+ * @param range
+ * The range within the buffer that represents the object name.
+ *
+ * @return
+ * F_true on success and string is a valid object name.
+ * F_false on success and string is not a valid object name.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors from (with error bit): f_utf_is_word().
+ */
+#ifndef _di_f_iki_object_partial_is_
+ extern f_return_status f_iki_object_partial_is(const f_string_static_t object, const f_string_range_t range);
+#endif // _di_f_iki_object_partial_is_
+
+/**
* Read a single iki Vocabulary and Content.
*
* This does not verify if the vocabulary name is known.
--- /dev/null
+#include "iki.h"
+#include "private-iki.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_f_iki_content_is_) || !defined(_di_f_iki_content_partial_is_)
+ f_return_status private_f_iki_content_partial_is(const f_string_static_t buffer, const f_string_range_t range, const uint8_t quote) {
+ f_string_length_t delimits = 0;
+
+ for (f_string_length_t i = 0; i < buffer.used; i++) {
+
+ if (buffer.string[i] == quote) {
+ if (delimits && delimits % 2) {
+ delimits = 0;
+ continue;
+ }
+
+ return F_false;
+ }
+ else if (buffer.string[i] == f_iki_syntax_slash) {
+ delimits++;
+ }
+ else {
+ delimits = 0;
+ }
+ } // for
+
+ return F_true;
+ }
+#endif // !defined(_di_f_iki_content_is_) || !defined(_di_f_iki_content_partial_is_)
+
+#if !defined(_di_f_iki_object_is_) || !defined(_di_f_iki_object_partial_is_)
+ f_return_status private_f_iki_object_partial_is(const f_string_static_t buffer, const f_string_range_t range) {
+ f_status_t status = F_none;
+
+ for (f_string_length_t i = 0; i < buffer.used; i++) {
+
+ status = f_utf_is_word(buffer.string + i, buffer.used - i, F_false);
+ if (F_status_is_error(status)) return status;
+
+ if (status == F_false) return F_false;
+ } // for
+
+ return F_true;
+ }
+#endif // !defined(_di_f_iki_object_is_) || !defined(_di_f_iki_object_partial_is_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 0
+ *
+ * Project: IKI
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * These are provided for internal reduction in redundant code.
+ * These should not be exposed/used outside of this project.
+ */
+#ifndef _PRIVATE_F_iki_h
+#define _PRIVATE_F_iki_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Private implementation of f_iki_content_partial_is().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param buffer
+ * The string to validate as an content name.
+ * @param range
+ * The range within the buffer that represents the content name.
+ * @param quote
+ * The quote character in use.
+ * This must be either a single (') or double (") quote.
+ *
+ * @return
+ * F_true on success and string is a valid content name.
+ * F_false on success and string is not a valid content name.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see f_iki_content_is()
+ * @see f_iki_content_partial_is()
+ */
+#if !defined(_di_f_iki_content_is_) || !defined(_di_f_iki_content_partial_is_)
+ extern f_return_status private_f_iki_content_partial_is(const f_string_static_t buffer, const f_string_range_t range, const uint8_t quote) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_iki_content_is_) || !defined(_di_f_iki_content_partial_is_)
+
+/**
+ * Private implementation of f_iki_object_partial_is().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param buffer
+ * The string to validate as an object name.
+ * @param range
+ * The range within the buffer that represents the object name.
+ *
+ * @return
+ * F_true on success and string is a valid object name.
+ * F_false on success and string is not a valid object name.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * @see f_iki_object_is()
+ * @see f_iki_object_partial_is()
+ */
+#if !defined(_di_f_iki_object_is_) || !defined(_di_f_iki_object_partial_is_)
+ extern f_return_status private_f_iki_object_partial_is(const f_string_static_t buffer, const f_string_range_t range) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_f_iki_object_is_) || !defined(_di_f_iki_object_partial_is_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_F_iki_h
build_language c
build_libraries -lc
build_libraries-individual -lf_utf -lf_memory
-build_sources_library iki.c
+build_sources_library iki.c private-iki.c
build_sources_program
build_sources_headers iki.h iki-common.h
build_sources_script
--- /dev/null
+#include "iki.h"
+#include "private-iki.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_fll_iki_content_escape_
+ f_return_status fll_iki_content_escape(const f_string_static_t content, const uint8_t quote, f_string_dynamic_t *escaped) {
+ #ifndef _di_level_0_parameter_checking_
+ if (content.used > content.size) return F_status_set_error(F_parameter);
+ if (quote != f_iki_syntax_quote_single && quote != f_iki_syntax_quote_double) return F_status_set_error(F_parameter);
+ if (escaped->used > escaped->size) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ const f_string_range_t range = f_macro_string_range_t_initialize(content.used);
+
+ return private_fll_iki_content_partial_escape(content, range, quote, escaped);
+ }
+#endif // _di_fll_iki_content_escape_
+
+#ifndef _di_fll_iki_content_partial_escape_
+ f_return_status fll_iki_content_partial_escape(const f_string_static_t content, const f_string_range_t range, const uint8_t quote, f_string_dynamic_t *escaped) {
+ #ifndef _di_level_0_parameter_checking_
+ if (content.used > content.size) return F_status_set_error(F_parameter);
+ if (range.start > range.stop) return F_status_set_error(F_parameter);
+ if (range.start >= content.used) return F_status_set_error(F_parameter);
+ if (quote != f_iki_syntax_quote_single && quote != f_iki_syntax_quote_double) return F_status_set_error(F_parameter);
+ if (escaped->used > escaped->size) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_fll_iki_content_partial_escape(content, range, quote, escaped);
+ }
+#endif // _di_fll_iki_content_partial_escape_
+
+#ifndef _di_fll_iki_content_escape_un_
+ f_return_status fll_iki_content_escape_un(const f_string_static_t content, const uint8_t quote, f_string_dynamic_t *unescaped) {
+ #ifndef _di_level_0_parameter_checking_
+ if (content.used > content.size) return F_status_set_error(F_parameter);
+ if (quote != f_iki_syntax_quote_single && quote != f_iki_syntax_quote_double) return F_status_set_error(F_parameter);
+ if (unescaped->used > unescaped->size) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ const f_string_range_t range = f_macro_string_range_t_initialize(content.used);
+
+ return private_fll_iki_content_partial_escape_un(content, range, quote, unescaped);
+ }
+#endif // _di_fll_iki_content_escape_un_
+
+#ifndef _di_fll_iki_content_partial_escape_un_
+ f_return_status fll_iki_content_partial_escape_un(const f_string_static_t content, const f_string_range_t range, const uint8_t quote, f_string_dynamic_t *unescaped) {
+ #ifndef _di_level_0_parameter_checking_
+ if (content.used > content.size) return F_status_set_error(F_parameter);
+ if (range.start > range.stop) return F_status_set_error(F_parameter);
+ if (range.start >= content.used) return F_status_set_error(F_parameter);
+ if (quote != f_iki_syntax_quote_single && quote != f_iki_syntax_quote_double) return F_status_set_error(F_parameter);
+ if (unescaped->used > unescaped->size) return F_status_set_error(F_parameter);
+ #endif // _di_level_0_parameter_checking_
+
+ return private_fll_iki_content_partial_escape_un(content, range, quote, unescaped);
+ }
+#endif // _di_fll_iki_content_partial_escape_un_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 2
+ *
+ * Project: IKI
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * Provides a Wiki-Like syntax meant to be much simpler.
+ *
+ * This simpler Wiki-Like syntax, called Iki, focuses just on simply adding context.
+ * The context itself is not explicitly defined but a few common standards are provided.
+ */
+#ifndef _FLL_iki_h
+#define _FLL_iki_h
+
+// libc includes
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+// fll-0 includes
+#include <level_0/type.h>
+#include <level_0/status.h>
+#include <level_0/memory.h>
+#include <level_0/string.h>
+#include <level_0/utf.h>
+#include <level_0/iki.h>
+
+// fll-1 includes
+#include <level_1/iki.h>
+#include <level_1/string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Escape a string to allow it to be used in its entirety as an IKI content.
+ *
+ * This does not copy NULL characters.
+ *
+ * @param content
+ * The string to escape.
+ * @param quote
+ * The quote character in use.
+ * This must be either a single (') or double (") quote.
+ * @param escaped
+ * The content whose data is escaped.
+ * The escaped string data is appended to this, so set the escaped.used = 0 if "replace" behavior is desired.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors from (with error bit): f_macro_string_dynamic_t_resize().
+ * Errors from (with error bit): fl_string_dynamic_size_increase().
+ */
+#ifndef _di_fll_iki_content_escape_
+ extern f_return_status fll_iki_content_escape(const f_string_static_t content, const uint8_t quote, f_string_dynamic_t *escaped);
+#endif // _di_fll_iki_content_escape_
+
+/**
+ * Escape a string, found within the given range, to allow it to be used in its entirety as an IKI content.
+ *
+ * This does not copy NULL characters.
+ *
+ * @param content
+ * The string to escape.
+ * @param range
+ * The range within the buffer that represents the content.
+ * @param quote
+ * The quote character in use.
+ * This must be either a single (') or double (") quote.
+ * @param escaped
+ * The content whose data is escaped.
+ * The escaped string data is appended to this, so set the escaped.used = 0 if "replace" behavior is desired.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors from (with error bit): f_macro_string_dynamic_t_resize().
+ * Errors from (with error bit): fl_string_dynamic_size_increase().
+ */
+#ifndef _di_fll_iki_content_partial_escape_
+ extern f_return_status fll_iki_content_partial_escape(const f_string_static_t content, const f_string_range_t range, const uint8_t quote, f_string_dynamic_t *escaped);
+#endif // _di_fll_iki_content_partial_escape_
+
+/**
+ * Unescape a string from IKI content to allow it to be used normally.
+ *
+ * This does not copy NULL characters.
+ *
+ * @param content
+ * The string to escape.
+ * @param quote
+ * The quote character in use.
+ * This must be either a single (') or double (") quote.
+ * @param unescaped
+ * The content whose data is unescaped.
+ * The unescaped string data is appended to this, so set the unescaped.used = 0 if "replace" behavior is desired.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_syntax (with error bit) if the given string is invalid, such as having an undelimited quote.
+ *
+ * Errors from (with error bit): f_macro_string_dynamic_t_resize().
+ * Errors from (with error bit): fl_string_dynamic_size_increase().
+ */
+#ifndef _di_fll_iki_content_escape_un_
+ extern f_return_status fll_iki_content_escape_un(const f_string_static_t content, const uint8_t quote, f_string_dynamic_t *unescaped);
+#endif // _di_fll_iki_content_escape_un_
+
+/**
+ * Unescape a string, found within the given range, from IKI content to allow it to be used normally.
+ *
+ * This does not copy NULL characters.
+ *
+ * @param content
+ * The string to escape.
+ * @param range
+ * The range within the buffer that represents the content.
+ * @param quote
+ * The quote character in use.
+ * This must be either a single (') or double (") quote.
+ * @param unescaped
+ * The content whose data is unescaped.
+ * The unescaped string data is appended to this, so set the unescaped.used = 0 if "replace" behavior is desired.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_syntax (with error bit) if the given string is invalid, such as having an undelimited quote.
+ *
+ * Errors from (with error bit): f_macro_string_dynamic_t_resize().
+ * Errors from (with error bit): fl_string_dynamic_size_increase().
+ */
+#ifndef _di_fll_iki_content_partial_escape_un_
+ extern f_return_status fll_iki_content_partial_escape_un(const f_string_static_t content, const f_string_range_t range, const uint8_t quote, f_string_dynamic_t *unescaped);
+#endif // _di_fll_iki_content_partial_escape_un_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _FLL_iki_h
--- /dev/null
+#include "iki.h"
+#include "private-iki.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(_di_fll_iki_content_escape_) || !defined(_di_fll_iki_content_partial_escape_)
+ f_return_status private_fll_iki_content_partial_escape(const f_string_static_t content, const f_string_range_t range, const uint8_t quote, f_string_dynamic_t *escaped) {
+ f_status_t status = F_none;
+
+ // ensure escaped is at least the same size as content.
+ if (content.used > escaped->size) {
+ f_macro_string_dynamic_t_resize(status, (*escaped), content.used);
+ if (F_status_is_error(status)) return status;
+ }
+
+ f_string_length_t i = 0;
+ f_string_length_t j = 0;
+ f_string_length_t delimits = 0;
+
+ for (; i < content.used; i++) {
+
+ if (content.string[i] == quote) {
+ if (escaped->used + delimits + 2 > escaped->size) {
+ status = fl_string_dynamic_size_increase(delimits, escaped);
+ if (F_status_is_error(status)) return status;
+ }
+
+ for (j = 0; j < delimits; j++) {
+ escaped->string[escaped->used++] = f_iki_syntax_slash;
+ } // for
+
+ escaped->string[escaped->used++] = f_iki_syntax_slash;
+ escaped->string[escaped->used++] = quote;
+
+ delimits = 0;
+ }
+ else if (content.string[i]) {
+ if (escaped->used + 1 > escaped->size) {
+ status = fl_string_dynamic_size_increase(f_memory_default_allocation_step, escaped);
+ if (F_status_is_error(status)) return status;
+ }
+
+ if (content.string[i] == f_iki_syntax_slash) {
+ delimits++;
+ }
+ else {
+ delimits = 0;
+ }
+
+ escaped->string[escaped->used++] = content.string[i];
+ }
+ } // for
+
+ // delimits found at the end must be escaped to prevent escaping the end quote.
+ if (delimits) {
+ if (escaped->used + delimits > escaped->size) {
+ status = fl_string_dynamic_size_increase(delimits, escaped);
+ if (F_status_is_error(status)) return status;
+ }
+
+ for (j = 0; j < delimits; j++) {
+ escaped->string[escaped->used++] = f_iki_syntax_slash;
+ } // for
+ }
+
+ return F_none;
+ }
+#endif // !defined(_di_fll_iki_content_escape_) || !defined(_di_fll_iki_content_partial_escape_)
+
+#if !defined(_di_fll_iki_content_escape_un_) || !defined(_di_fll_iki_content_partial_escape_un_)
+ f_return_status private_fll_iki_content_partial_escape_un(const f_string_static_t content, const f_string_range_t range, const uint8_t quote, f_string_dynamic_t *unescaped) {
+ f_status_t status = F_none;
+
+ // ensure escaped is at least the same size as content.
+ if (content.used > unescaped->size) {
+ f_macro_string_dynamic_t_resize(status, (*unescaped), content.used);
+ if (F_status_is_error(status)) return status;
+ }
+
+ f_string_length_t i = 0;
+ f_string_length_t j = 0;
+ f_string_length_t delimits = 0;
+
+ const f_string_length_t used = unescaped->used;
+
+ for (; i < content.used; i++) {
+
+ if (content.string[i] == quote) {
+
+ // reset the used array on failure.
+ unescaped->used = used;
+
+ return F_status_set_error(F_syntax);
+ }
+ else if (content.string[i] == f_iki_syntax_slash) {
+ delimits = 1;
+
+ if (i + 1 < content.used) {
+ for (j = i + 1; j < content.used; j++) {
+
+ if (content.string[j] == quote) {
+ if (delimits % 2 == 0) {
+
+ // reset the used array on failure.
+ unescaped->used = used;
+
+ return F_status_set_error(F_syntax);
+ }
+
+ i = j;
+ delimits /= 2;
+
+ if (unescaped->used + delimits + 1 > unescaped->size) {
+ status = fl_string_dynamic_size_increase(delimits + 1, unescaped);
+ if (F_status_is_error(status)) return status;
+ }
+
+ for (j = 0; j < delimits; j++) {
+ unescaped->string[unescaped->used++] = f_iki_syntax_slash;
+ } // for
+
+ delimits = 0;
+ unescaped->string[unescaped->used++] = quote;
+ break;
+ }
+ else if (content.string[j] == f_iki_syntax_slash) {
+ delimits++;
+ }
+ else if (content.string[j]) {
+ if (unescaped->used + (j - i) + 1 > unescaped->size) {
+ status = fl_string_dynamic_size_increase((j - i) + 1, unescaped);
+ if (F_status_is_error(status)) return status;
+ }
+
+ for (; i <= j; i++) {
+ unescaped->string[unescaped->used++] = content.string[i];
+ } // for
+
+ delimits = 0;
+ i--;
+ break;
+ }
+ } // for
+ }
+
+ // at this point if delimits > 0, then this should be the end of the string.
+ if (delimits) {
+
+ // delimits at the end must be even to prevent escaping the closing quote.
+ if (delimits % 2) {
+
+ // reset the used array on failure.
+ unescaped->used = used;
+
+ return F_status_set_error(F_syntax);
+ }
+
+ delimits /= 2;
+
+ if (unescaped->used + delimits > unescaped->size) {
+ status = fl_string_dynamic_size_increase(delimits, unescaped);
+ if (F_status_is_error(status)) return status;
+ }
+
+ for (j = 0; j < delimits; j++) {
+ unescaped->string[unescaped->used++] = f_iki_syntax_slash;
+ } // for
+
+ break;
+ }
+ }
+ else if (content.string[i]) {
+ if (unescaped->used + 1 > unescaped->size) {
+ status = fl_string_dynamic_size_increase(f_memory_default_allocation_step, unescaped);
+ if (F_status_is_error(status)) return status;
+ }
+
+ unescaped->string[unescaped->used++] = content.string[i];
+ }
+ } // for
+
+ return F_none;
+ }
+#endif // !defined(_di_fll_iki_content_escape_un_) || !defined(_di_fll_iki_content_partial_escape_un_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 2
+ *
+ * Project: IKI
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * These are provided for internal reduction in redundant code.
+ * These should not be exposed/used outside of this project.
+ */
+#ifndef _PRIVATE_FLL_iki_h
+#define _PRIVATE_FLL_iki_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Private implementation of fll_iki_content_escape().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param content
+ * The string to escape.
+ * @param range
+ * The range within the buffer that represents the content.
+ * @param quote
+ * The quote character in use.
+ * This must be either a single (') or double (") quote.
+ * @param escaped
+ * The content whose data is escaped.
+ * The escaped string data is appended to this, so set the escaped.used = 0 if "replace" behavior is desired.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ *
+ * Errors from (with error bit): f_macro_string_dynamic_t_resize().
+ * Errors from (with error bit): fl_string_dynamic_size_increase().
+ */
+#if !defined(_di_fll_iki_content_escape_) || !defined(_di_fll_iki_content_partial_escape_)
+ extern f_return_status private_fll_iki_content_partial_escape(const f_string_static_t content, const f_string_range_t range, const uint8_t quote, f_string_dynamic_t *escaped) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fll_iki_content_escape_) || !defined(_di_fll_iki_content_partial_escape_)
+
+/**
+ * Private implementation of fll_iki_content_escape_un().
+ *
+ * Intended to be shared to each of the different implementation variations.
+ *
+ * @param content
+ * The string to escape.
+ * @param range
+ * The range within the buffer that represents the content.
+ * @param quote
+ * The quote character in use.
+ * This must be either a single (') or double (") quote.
+ * @param unescaped
+ * The content whose data is unescaped.
+ * The unescaped string data is appended to this, so set the unescaped.used = 0 if "replace" behavior is desired.
+ *
+ * @return
+ * F_none on success.
+ * F_parameter (with error bit) if a parameter is invalid.
+ * F_syntax (with error bit) if the given string is invalid, such as having an undelimited quote.
+ *
+ * Errors from (with error bit): f_macro_string_dynamic_t_resize().
+ * Errors from (with error bit): fl_string_dynamic_size_increase().
+ */
+#if !defined(_di_fll_iki_content_escape_un_) || !defined(_di_fll_iki_content_partial_escape_un_)
+ extern f_return_status private_fll_iki_content_partial_escape_un(const f_string_static_t content, const f_string_range_t range, const uint8_t quote, f_string_dynamic_t *unescaped) f_gcc_attribute_visibility_internal;
+#endif // !defined(_di_fll_iki_content_escape_un_) || !defined(_di_fll_iki_content_partial_escape_un_)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_FLL_iki_h
--- /dev/null
+# fss-0000
+
--- /dev/null
+# fss-0000
+
+f_type
+f_status
+f_memory
+f_string
+f_utf
+f_iki
+fl_iki
+fl_string
--- /dev/null
+# fss-0001
+
+project_name fll_iki
+
+version_major 0
+version_minor 5
+version_micro 1
+version_target major
+
+environment
+
+process_pre
+process_post
+
+modes individual
+modes_default individual
+
+build_compiler gcc
+build_indexer ar
+build_language c
+build_libraries -lc
+build_libraries-individual -lfl_iki -lfl_string -lf_iki -lf_utf -lf_memory
+build_sources_library iki.c private-iki.c
+build_sources_program
+build_sources_headers iki.h
+build_sources_script
+build_sources_setting
+build_script yes
+build_shared yes
+build_static yes
+
+path_headers level_2
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+path_sources
+path_standard yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines_all
+defines_static
+defines_shared
+
+flags_all -z now -g
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE
--- /dev/null
+#include "iki_write.h"
+#include "private-iki_write.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_write_print_help_
+ f_return_status iki_write_print_help(const fl_color_context_t context) {
+ fll_program_print_help_header(context, iki_write_name_long, iki_write_version);
+
+ fll_program_print_help_option(context, f_console_standard_short_help, f_console_standard_long_help, f_console_symbol_short_enable, f_console_symbol_long_enable, " Print this help message.");
+ fll_program_print_help_option(context, f_console_standard_short_dark, f_console_standard_long_dark, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on dark backgrounds.");
+ fll_program_print_help_option(context, f_console_standard_short_light, f_console_standard_long_light, f_console_symbol_short_disable, f_console_symbol_long_disable, " Output using colors that show up better on light backgrounds.");
+ fll_program_print_help_option(context, f_console_standard_short_no_color, f_console_standard_long_no_color, f_console_symbol_short_disable, f_console_symbol_long_disable, "Do not output in color.");
+ fll_program_print_help_option(context, f_console_standard_short_quiet, f_console_standard_long_quiet, f_console_symbol_short_disable, f_console_symbol_long_disable, " Decrease verbosity beyond normal output.");
+ fll_program_print_help_option(context, f_console_standard_short_verbose, f_console_standard_long_verbose, f_console_symbol_short_disable, f_console_symbol_long_disable, " Increase verbosity beyond normal output.");
+ fll_program_print_help_option(context, f_console_standard_short_version, f_console_standard_long_version, f_console_symbol_short_disable, f_console_symbol_long_disable, " Print only the version number.");
+
+ printf("%c", f_string_eol[0]);
+
+ fll_program_print_help_option(context, iki_write_short_file, iki_write_long_file, f_console_symbol_short_enable, f_console_symbol_long_enable, " Specify a file to send output to.");
+ fll_program_print_help_option(context, iki_write_short_content, iki_write_long_content, f_console_symbol_short_enable, f_console_symbol_long_enable, "The content to write.");
+ fll_program_print_help_option(context, iki_write_short_double, iki_write_long_double, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use double quotes (default).");
+ fll_program_print_help_option(context, iki_write_short_object, iki_write_long_object, f_console_symbol_short_enable, f_console_symbol_long_enable, " The object to write.");
+ fll_program_print_help_option(context, iki_write_short_single, iki_write_long_single, f_console_symbol_short_enable, f_console_symbol_long_enable, " Use single quotes.");
+
+ fll_program_print_help_usage(context, iki_write_name, "filename(s)");
+
+ fl_color_print(f_type_output, context.important, context.reset, " Notes:");
+
+ printf("%c", f_string_eol[0], f_string_eol[0]);
+
+ printf(" This program will accept object and content strings to generate an IKI string, such as: ");
+ fl_color_print(f_type_output, context.notable, context.reset, "object:\"content\"");
+ printf(".%c", f_string_eol[0]);
+
+ printf(" Each object must have a content (and each content must have an object).%c", f_string_eol[0]);
+
+ printf("%c", f_string_eol[0]);
+
+ printf(" When piping data to this program, a single end of line (\\n) must be used to separate each object from each content.%c", f_string_eol[0]);
+ printf(" Furthermore, each object must be followed by a content.%c", f_string_eol[0]);
+
+ printf("%c", f_string_eol[0]);
+
+ return F_none;
+ }
+#endif // _di_iki_write_print_help_
+
+#ifndef _di_iki_write_main_
+ f_return_status iki_write_main(const f_console_arguments_t arguments, iki_write_data_t *data) {
+ f_status_t status = F_none;
+
+ {
+ f_console_parameter_id_t ids[3] = { iki_write_parameter_no_color, iki_write_parameter_light, iki_write_parameter_dark };
+ const f_console_parameters_t parameters = { data->parameters, iki_write_total_parameters };
+ const f_console_parameter_ids_t choices = { ids, 3 };
+
+ status = fll_program_parameter_process(arguments, parameters, choices, F_true, &data->remaining, &data->context);
+ if (F_status_is_error(status)) {
+ iki_write_print_error(data->context, data->verbosity, F_status_set_fine(status), "fll_program_parameter_process", F_true);
+
+ if (data->verbosity == iki_write_verbosity_verbose) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+
+ iki_write_delete_data(data);
+ return F_status_set_error(status);
+ }
+
+ status = F_none;
+ }
+
+ if (data->parameters[iki_write_parameter_help].result == f_console_result_found) {
+ iki_write_print_help(data->context);
+
+ iki_write_delete_data(data);
+ return status;
+ }
+ else if (data->parameters[iki_write_parameter_version].result == f_console_result_found) {
+ fll_program_print_version(iki_write_version);
+
+ iki_write_delete_data(data);
+ return status;
+ }
+
+ if (data->parameters[iki_write_parameter_verbose].result == f_console_result_found) {
+ if (data->parameters[iki_write_parameter_quiet].result == f_console_result_found) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: Cannot specify the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, f_console_standard_long_verbose);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' parameter with the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, f_console_standard_long_quiet);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameter.");
+
+ status = F_status_set_error(F_parameter);
+ }
+
+ data->verbosity = iki_write_verbosity_verbose;
+ }
+ else if (data->parameters[iki_write_parameter_quiet].result == f_console_result_found) {
+ data->verbosity = iki_write_verbosity_quiet;
+ }
+ else {
+ data->verbosity = iki_write_verbosity_normal;
+ }
+
+ if (!data->process_pipe) {
+ if (data->parameters[iki_write_parameter_object].result != f_console_result_additional && data->parameters[iki_write_parameter_content].result != f_console_result_additional) {
+ if (data->verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: No data provided, either pipe the data or use the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_write_long_object);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' and the '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_write_long_content);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' parameters.");
+ }
+
+ status = F_status_set_error(F_parameter);
+ }
+ }
+
+ if (F_status_is_fine(status)) {
+ if (data->parameters[iki_write_parameter_object].additional.used != data->parameters[iki_write_parameter_content].additional.used) {
+ if (data->verbosity != iki_write_verbosity_quiet) {
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "ERROR: The parameters '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_write_long_content);
+ fl_color_print(f_type_error, data->context.error, data->context.reset, "' and '");
+ fl_color_print(f_type_error, data->context.notable, data->context.reset, "%s%s", f_console_symbol_long_enable, iki_write_long_object);
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "' must be specified the same number of times.");
+ }
+
+ status = F_status_set_error(F_parameter);
+ }
+ }
+
+ uint8_t quote = f_iki_syntax_quote_double;
+
+ if (F_status_is_fine(status)) {
+ if (data->parameters[iki_write_parameter_double].result == f_console_result_found) {
+ if (data->parameters[iki_write_parameter_single].result == f_console_result_found) {
+ if (data->parameters[iki_write_parameter_double].location < data->parameters[iki_write_parameter_single].location) {
+ quote = f_iki_syntax_quote_single;
+ }
+ }
+ }
+ else if (data->parameters[iki_write_parameter_single].result == f_console_result_found) {
+ quote = f_iki_syntax_quote_single;
+ }
+ }
+
+ if (F_status_is_fine(status)) {
+ f_string_dynamic_t escaped = f_string_dynamic_t_initialize;
+
+ if (data->process_pipe) {
+ f_file_t file = f_file_t_initialize;
+
+ file.id = f_type_descriptor_input;
+ file.size_read = 1;
+
+ f_string_dynamic_t buffer = f_string_dynamic_t_initialize;
+ f_string_dynamic_t object = f_string_dynamic_t_initialize;
+ f_string_dynamic_t content = f_string_dynamic_t_initialize;
+
+ bool object_ended = F_false;
+
+ f_string_length_t previous = 0;
+ f_string_range_t range = f_string_range_t_initialize;
+
+ range.start = 0;
+
+ for (f_status_t status_pipe = F_none; ; ) {
+
+ if (status_pipe != F_none_eof) {
+ status_pipe = f_file_read(file, &buffer);
+
+ if (F_status_is_error(status_pipe)) {
+ iki_write_print_error_file(data->context, data->verbosity, F_status_set_fine(status_pipe), "f_file_read_to", "-", "read", 2, F_true);
+
+ status = F_status_set_error(F_pipe);
+ break;
+ }
+
+ if (!buffer.used) {
+ if (data->verbosity != iki_write_verbosity_quiet) {
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "ERROR: The pipe has no content.");
+ }
+
+ status = F_status_set_error(F_parameter);
+ break;
+ }
+
+ range.stop = buffer.used - 1;
+ }
+
+ previous = range.start;
+ status = fl_string_dynamic_seek_line(buffer.string, &range);
+
+ if (F_status_is_error(status)) {
+ iki_write_print_error(data->context, data->verbosity, F_status_set_fine(status), "fl_string_dynamic_seek_line", F_true);
+ break;
+ }
+
+ if (status == F_data_not_stop) {
+ status = F_status_set_error(F_parameter);
+ iki_write_print_error(data->context, data->verbosity, F_parameter, "fl_string_dynamic_seek_line", F_true);
+ break;
+ }
+
+ if (object_ended && previous == range.start) {
+ if (data->verbosity != iki_write_verbosity_quiet) {
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "ERROR: The pipe has incorrectly placed newlines.");
+ }
+
+ status = F_status_set_error(F_parameter);
+ break;
+ }
+
+ range.stop = range.start - 1;
+ range.start = previous;
+
+ if (object_ended) {
+ content.used = 0;
+
+ if (buffer.used) {
+ status = fl_string_dynamic_partial_append_nulless(buffer, range, &content);
+
+ if (F_status_is_error(status)) {
+ iki_write_print_error(data->context, data->verbosity, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+ break;
+ }
+ }
+
+ status = iki_write_process(*data, object, content, quote, f_type_output, &escaped);
+ if (F_status_is_error(status)) break;
+
+ fprintf(f_type_output, "%c", f_string_eol[0]);
+
+ object_ended = F_false;
+ }
+ else {
+ object.used = 0;
+
+ status = fl_string_dynamic_partial_append_nulless(buffer, range, &object);
+
+ if (F_status_is_error(status)) {
+ iki_write_print_error(data->context, data->verbosity, F_status_set_fine(status), "fl_string_dynamic_partial_append_nulless", F_true);
+ break;
+ }
+
+ object_ended = F_true;
+ }
+
+ // restore the range, positioned after the newline.
+ range.start = range.stop + 2;
+ range.stop = buffer.used - 1;
+
+ // only clear the buffer and reset the start when the entire buffer has been processed.
+ if (range.start > range.stop) {
+ range.start = 0;
+ buffer.used = 0;
+ }
+
+ if (status_pipe == F_none_eof && !buffer.used && !object_ended) break;
+ } // for
+
+ if (F_status_is_fine(status) && object_ended) {
+ if (data->verbosity != iki_write_verbosity_quiet) {
+ fl_color_print_line(f_type_error, data->context.error, data->context.reset, "ERROR: The pipe has an object without content.");
+ }
+
+ status = F_status_set_error(F_parameter);
+ }
+
+ f_macro_string_dynamic_t_delete_simple(buffer);
+ f_macro_string_dynamic_t_delete_simple(object);
+ f_macro_string_dynamic_t_delete_simple(content);
+ }
+
+ if (F_status_is_fine(status)) {
+ f_string_static_t object = f_string_static_t_initialize;
+ f_string_static_t content = f_string_static_t_initialize;
+
+ for (f_array_length_t i = 0; i < data->parameters[iki_write_parameter_object].additional.used; i++) {
+
+ object.string = arguments.argv[data->parameters[iki_write_parameter_object].additional.array[i]];
+ object.used = strnlen(object.string, f_console_length_size);
+ object.size = object.used;
+
+ content.string = arguments.argv[data->parameters[iki_write_parameter_content].additional.array[i]];
+ content.used = strnlen(content.string, f_console_length_size);
+ content.size = content.used;
+
+ status = iki_write_process(*data, object, content, quote, f_type_output, &escaped);
+ if (F_status_is_error(status)) break;
+
+ fprintf(f_type_output, "%c", f_string_eol[0]);
+ } // for
+
+ // ensure there is always a newline at the end, unless in quiet mode.
+ if (F_status_is_fine(status) && data->verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_output, "%c", f_string_eol[0]);
+ }
+ }
+
+ f_macro_string_dynamic_t_delete_simple(escaped);
+ }
+
+ // ensure a newline is always put at the end of the program execution, unless in quiet mode.
+ if (data->verbosity != iki_write_verbosity_quiet) {
+ if (F_status_is_error(status)) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ }
+ }
+
+ iki_write_delete_data(data);
+ return status;
+ }
+#endif // _di_iki_write_main_
+
+#ifndef _di_iki_write_delete_data_
+ f_return_status iki_write_delete_data(iki_write_data_t *data) {
+ f_status_t status = F_none;
+ f_string_length_t i = 0;
+
+ while (i < iki_write_total_parameters) {
+ f_macro_string_lengths_t_delete_simple(data->parameters[i].locations);
+ f_macro_string_lengths_t_delete_simple(data->parameters[i].additional);
+ i++;
+ } // while
+
+ f_macro_string_lengths_t_delete_simple(data->remaining);
+ f_macro_string_dynamic_t_delete_simple(data->buffer);
+ fl_macro_color_context_t_delete_simple(data->context);
+
+ return F_none;
+ }
+#endif // _di_iki_write_delete_data_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: IKI
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ *
+ * This is the IKI Write program.
+ *
+ * This program utilizes the Featureless Linux Library.
+ * This program processes files or other input in fss format and stores the results in the iki_write_data_t.
+ *
+ * This processes in accordance to the IKI specification.
+ */
+#ifndef _iki_write_h
+
+// libc includes
+#include <dirent.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+// fll-0 includes
+#include <level_0/type.h>
+#include <level_0/status.h>
+#include <level_0/memory.h>
+#include <level_0/string.h>
+#include <level_0/utf.h>
+#include <level_0/console.h>
+#include <level_0/conversion.h>
+#include <level_0/file.h>
+#include <level_0/iki.h>
+#include <level_0/pipe.h>
+#include <level_0/print.h>
+
+// fll-1 includes
+#include <level_1/color.h>
+#include <level_1/console.h>
+#include <level_1/conversion.h>
+#include <level_1/iki.h>
+#include <level_1/print.h>
+#include <level_1/string.h>
+
+// fll-2 includes
+#include <level_2/file.h>
+#include <level_2/iki.h>
+#include <level_2/program.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_write_version_
+ #define iki_write_major_version "0"
+ #define iki_write_minor_version "5"
+ #define iki_write_micro_version "1"
+ #define iki_write_version iki_write_major_version "." iki_write_minor_version "." iki_write_micro_version
+#endif // _di_iki_write_version_
+
+#ifndef _di_iki_write_name_
+ #define iki_write_name "iki_write"
+ #define iki_write_name_long "IKI Write"
+#endif // _di_iki_write_name_
+
+#ifndef _di_iki_write_defines_
+ enum {
+ iki_write_verbosity_quiet = 1,
+ iki_write_verbosity_normal,
+ iki_write_verbosity_verbose,
+ iki_write_verbosity_debug,
+ };
+
+ #define iki_write_short_file "f"
+ #define iki_write_short_content "c"
+ #define iki_write_short_double "d"
+ #define iki_write_short_object "o"
+ #define iki_write_short_single "s"
+
+ #define iki_write_long_file "file"
+ #define iki_write_long_content "content"
+ #define iki_write_long_double "double"
+ #define iki_write_long_object "object"
+ #define iki_write_long_single "single"
+
+ enum {
+ iki_write_parameter_help,
+ iki_write_parameter_light,
+ iki_write_parameter_dark,
+ iki_write_parameter_no_color,
+ iki_write_parameter_quiet,
+ iki_write_parameter_verbose,
+ iki_write_parameter_version,
+
+ iki_write_parameter_file,
+ iki_write_parameter_content,
+ iki_write_parameter_double,
+ iki_write_parameter_object,
+ iki_write_parameter_single,
+ };
+
+ #define iki_write_console_parameter_t_initialize \
+ { \
+ f_console_parameter_t_initialize(f_console_standard_short_help, f_console_standard_long_help, 0, 0, f_console_type_normal), \
+ f_console_parameter_t_initialize(f_console_standard_short_light, f_console_standard_long_light, 0, 0, f_console_type_inverse), \
+ f_console_parameter_t_initialize(f_console_standard_short_dark, f_console_standard_long_dark, 0, 0, f_console_type_inverse), \
+ f_console_parameter_t_initialize(f_console_standard_short_no_color, f_console_standard_long_no_color, 0, 0, f_console_type_inverse), \
+ f_console_parameter_t_initialize(f_console_standard_short_quiet, f_console_standard_long_quiet, 0, 0, f_console_type_inverse), \
+ f_console_parameter_t_initialize(f_console_standard_short_verbose, f_console_standard_long_verbose, 0, 0, f_console_type_inverse), \
+ f_console_parameter_t_initialize(f_console_standard_short_version, f_console_standard_long_version, 0, 0, f_console_type_inverse), \
+ f_console_parameter_t_initialize(iki_write_short_file, iki_write_long_file, 0, 1, f_console_type_normal), \
+ f_console_parameter_t_initialize(iki_write_short_content, iki_write_long_content, 0, 1, f_console_type_normal), \
+ f_console_parameter_t_initialize(iki_write_short_double, iki_write_long_double, 0, 0, f_console_type_normal), \
+ f_console_parameter_t_initialize(iki_write_short_object, iki_write_long_object, 0, 1, f_console_type_normal), \
+ f_console_parameter_t_initialize(iki_write_short_single, iki_write_long_single, 0, 0, f_console_type_normal), \
+ }
+
+ #define iki_write_total_parameters 12
+#endif // _di_iki_write_defines_
+
+#ifndef _di_iki_write_data_t_
+ typedef struct {
+ f_console_parameter_t parameters[iki_write_total_parameters];
+
+ f_string_lengths_t remaining;
+ bool process_pipe;
+
+ uint8_t verbosity;
+
+ f_string_dynamic_t buffer;
+
+ fl_color_context_t context;
+ } iki_write_data_t;
+
+ #define iki_write_data_t_initialize \
+ { \
+ iki_write_console_parameter_t_initialize, \
+ f_string_lengths_t_initialize, \
+ F_false, \
+ 0, \
+ f_string_dynamic_t_initialize, \
+ fl_color_context_t_initialize, \
+ }
+#endif // _di_iki_write_data_t_
+
+/**
+ * Print help to standard output.
+ *
+ * @param context
+ * The color context settings.
+ *
+ * @return
+ * F_none on success.
+ */
+#ifndef _di_iki_write_print_help_
+ extern f_return_status iki_write_print_help(const fl_color_context_t context);
+#endif // _di_iki_write_print_help_
+
+/**
+ * Execute main program.
+ *
+ * Be sure to call iki_write_delete_data() after executing this.
+ *
+ * @param arguments
+ * The parameters passed to the process.
+ * @param data
+ * The program data.
+ *
+ * @return
+ * F_none on success.
+ *
+ * Status codes (with error bit) are returned on any problem.
+ *
+ * @see iki_write_delete_data()
+ */
+#ifndef _di_iki_write_main_
+ extern f_return_status iki_write_main(const f_console_arguments_t arguments, iki_write_data_t *data);
+#endif // _di_iki_write_main_
+
+/**
+ * Deallocate data.
+ *
+ * Be sure to call this after executing iki_write_main().
+ *
+ * @param data
+ * The program data.
+ *
+ * @return
+ * F_none on success.
+ *
+ * Status codes (with error bit) are returned on any problem.
+ *
+ * @see iki_write_main()
+ */
+#ifndef _di_iki_write_delete_data_
+ extern f_return_status iki_write_delete_data(iki_write_data_t *data);
+#endif // _di_iki_write_delete_data_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _iki_write_h
--- /dev/null
+#include "iki_write.h"
+
+int main(const unsigned long argc, const f_string_t *argv) {
+ const f_console_arguments_t arguments = { argc, argv };
+ iki_write_data_t data = iki_write_data_t_initialize;
+
+ if (f_pipe_input_exists()) {
+ data.process_pipe = F_true;
+ }
+
+ f_status_t status = iki_write_main(arguments, &data);
+
+ if (F_status_is_error(status)) {
+ return 1;
+ }
+
+ return 0;
+}
--- /dev/null
+#include "iki_write.h"
+#include "private-iki_write.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef _di_iki_write_print_error_
+ f_return_status iki_write_print_error(const fl_color_context_t context, const uint8_t verbosity, const f_status_t status, const f_string_t function, const bool fallback) {
+
+ if (status == F_parameter) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid parameter when calling function ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print_line(f_type_error, context.error, context.reset, "().");
+ }
+
+ return F_none;
+ }
+
+ if (status == F_memory_allocation || status == F_memory_reallocation) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Unable to allocate memory in function ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print_line(f_type_error, context.error, context.reset, "().");
+ }
+
+ return F_none;
+ }
+
+ if (status == F_buffer_too_large) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Maximum buffer limit reached while processing ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print_line(f_type_error, context.error, context.reset, "().");
+ }
+
+ return F_none;
+ }
+
+ if (status == F_string_too_large) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Maximum string limit reached while processing ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print_line(f_type_error, context.error, context.reset, "().");
+ }
+
+ return F_none;
+ }
+
+ if (fallback && verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "UNKNOWN ERROR: (");
+ fl_color_print(f_type_error, context.notable, context.reset, "%llu", status);
+ fl_color_print(f_type_error, context.error, context.reset, ") in function ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print_line(f_type_error, context.error, context.reset, "().");
+ }
+
+ return F_unknown;
+ }
+#endif // _di_iki_write_print_error_
+
+#ifndef _di_iki_write_print_error_file_
+ bool iki_write_print_error_file(const fl_color_context_t context, const uint8_t verbosity, const f_status_t status, const f_string_t function, const f_string_t name, const f_string_t operation, const uint8_t type, const bool fallback) {
+ f_string_t type_name = "file";
+
+ if (type == 1) {
+ type_name = "directory";
+ }
+ else if (type == 2) {
+ type_name = "pipe";
+ }
+
+ if (status == F_file_found_not) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to find %s '", type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_file_closed) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fl_color_print(f_type_error, context.error, context.reset, "INTERNAL ERROR: The %s '", type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "' is no longer open.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_file_seek) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: A seek error occurred while accessing the file '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_file_read) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: A read error occurred while accessing the file '");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_file_found) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: The %s '", type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "' already exists.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_parameter) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "INTERNAL ERROR: Invalid parameter when calling ");
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", function);
+ fl_color_print(f_type_error, context.error, context.reset, "() for the %s '", type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_name) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid %s name '", type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_memory_out) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "CRITICAL ERROR: Unable to allocate memory, while trying to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_number_overflow) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Overflow while trying to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_directory) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Invalid directory while trying to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_access_denied) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Access denied while trying to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_loop) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Loop while trying to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_prohibited) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Prohibited by system while trying to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+
+ if (!type) {
+ if (status == F_directory_found_not) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "' due to an invalid directory in the path.");
+ }
+
+ return F_false;
+ }
+ }
+ else if (type == 1) {
+ if (status == F_directory_found_not) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "' due to an invalid directory in the path.");
+ }
+
+ return F_false;
+ }
+
+ if (status == F_failure) {
+ if (verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "ERROR: Failed to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_false;
+ }
+ }
+
+ if (iki_write_print_error(context, verbosity, status, function, F_false) == F_unknown && fallback && verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, context.error, context.reset, "UNKNOWN ERROR: (");
+ fl_color_print(f_type_error, context.notable, context.reset, "%llu", status);
+ fl_color_print(f_type_error, context.error, context.reset, ") occurred while trying to %s %s '", operation, type_name);
+ fl_color_print(f_type_error, context.notable, context.reset, "%s", name);
+ fl_color_print_line(f_type_error, context.error, context.reset, "'.");
+ }
+
+ return F_true;
+ }
+#endif // _di_iki_write_print_error_file_
+
+#ifndef _di_iki_write_process_
+ f_return_status iki_write_process(const iki_write_data_t data, const f_string_static_t object, const f_string_static_t content, const uint8_t quote, FILE *output, f_string_dynamic_t *escaped) {
+
+ if (!object.used) {
+ if (data.verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: The object is missing, it must not have a length of ");
+ fl_color_print(f_type_error, data.context.notable, data.context.reset, "0");
+ fl_color_print_line(f_type_error, data.context.error, data.context.reset, ".");
+ }
+
+ return F_status_set_error(F_failure);
+ }
+
+ f_status_t status = f_iki_object_is(object);
+
+ if (status == F_false) {
+ if (data.verbosity != iki_write_verbosity_quiet) {
+ fprintf(f_type_error, "%c", f_string_eol[0]);
+ fl_color_print(f_type_error, data.context.error, data.context.reset, "ERROR: The object '");
+
+ fl_color_print_code(f_type_error, data.context.notable);
+ f_print_string_dynamic(f_type_error, object);
+ fl_color_print_code(f_type_error, data.context.reset);
+
+ fl_color_print_line(f_type_error, data.context.error, data.context.reset, "' is not a valid IKI object.");
+ }
+
+ return F_status_set_error(F_failure);
+ }
+ else if (F_status_is_error(status)) {
+ iki_write_print_error(data.context, data.verbosity, F_status_set_fine(status), "f_iki_object_is", F_true);
+
+ return F_status_set_error(F_failure);
+ }
+
+ escaped->used = 0;
+
+ status = fll_iki_content_escape(content, quote, escaped);
+
+ if (F_status_is_error(status)) {
+ iki_write_print_error(data.context, data.verbosity, F_status_set_fine(status), "fll_iki_content_escape", F_true);
+
+ f_macro_string_dynamic_t_delete_simple((*escaped));
+ return F_status_set_error(F_failure);
+ }
+
+ f_print_string_dynamic(output, object);
+ fprintf(output, "%c%c", f_iki_syntax_separator, quote);
+ f_print_string_dynamic(output, *escaped);
+ fprintf(output, "%c", quote);
+
+ return F_none;
+ }
+#endif // _di_iki_write_process_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
--- /dev/null
+/**
+ * FLL - Level 3
+ *
+ * Project: FSS
+ * API Version: 0.5
+ * Licenses: lgplv2.1
+ */
+#ifndef _PRIVATE_iki_write_h
+#define _PRIVATE_iki_write_h
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Print generic error messages.
+ *
+ * @param context
+ * The color context.
+ * @param verbosity
+ * The verbosity level, which determines if and what should be printed.
+ * @param status
+ * The status code representing an error.
+ * @param function
+ * The name of the function where the error happened.
+ * @param fallback
+ * Set to F_true to print the fallback error message for unknown errors.
+ *
+ * @return
+ * F_none is returned on successful print of known errors.
+ * F_unknown is returned if the status code has no print message.
+ */
+#ifndef _di_iki_write_print_error_
+ extern f_return_status iki_write_print_error(const fl_color_context_t context, const uint8_t verbosity, const f_status_t status, const f_string_t function, const bool fallback) f_gcc_attribute_visibility_internal;
+#endif // _di_iki_write_print_error_
+
+/**
+ * Print file/directory error messages.
+ *
+ * @param context
+ * The color context.
+ * @param verbosity
+ * The verbosity level, which determines if and what should be printed.
+ * @param status
+ * The error status code to report on.
+ * @param function
+ * The function call that returned the error.
+ * @param name
+ * The name of the file or directory.
+ * @param operation
+ * The operation that fails, such as 'create' or 'access'.
+ * @param type
+ * Set to 0 for "file", 1 for "directory", and 2 for "pipe".
+ * @param fallback
+ * Set to F_true to print the fallback error message for unknown errors.
+ *
+ * @return
+ * F_true is returned if the status code has no print message.
+ * F_false is returned on successful print of known errors.
+ */
+#ifndef _di_iki_write_print_error_file_
+ extern bool iki_write_print_error_file(const fl_color_context_t context, const uint8_t verbosity, const f_status_t status, const f_string_t function, const f_string_t name, const f_string_t operation, const uint8_t type, const bool fallback) f_gcc_attribute_visibility_internal;
+#endif // _di_iki_write_print_error_file_
+
+/**
+ * Process a given object and content, printing the IKI if valid or an error if invalid.
+ *
+ * @param data
+ * The program data.
+ * @param object
+ * The object to validate and print.
+ * @param content
+ * The content to escape and print.
+ * @param quote
+ * The quote character to use.
+ * This is either f_iki_syntax_quote_single or f_iki_syntax_quote_double.
+ * @param output
+ * The output file (or stdout) to print to.
+ * @param escaped
+ * A string buffer used as a string cache to save the string into while escaping.
+ *
+ * @return
+ * F_none on success.
+ * F_failure (with error bit) for any othe failure.
+ */
+#ifndef _di_iki_write_process_
+ extern f_return_status iki_write_process(const iki_write_data_t data, const f_string_static_t object, const f_string_static_t content, const uint8_t quote, FILE *output, f_string_dynamic_t *escaped) f_gcc_attribute_visibility_internal;
+#endif // _di_iki_write_process_
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif // _PRIVATE_iki_write_h
--- /dev/null
+# fss-0000
+
--- /dev/null
+# fss-0000
+
+f_type
+f_status
+f_memory
+f_string
+f_utf
+f_color
+f_console
+f_conversion
+f_file
+f_iki
+f_pipe
+f_print
+fl_color
+fl_console
+fl_conversion
+fl_iki
+fl_string
+fl_utf
+fll_file
+fll_iki
+fll_program
--- /dev/null
+# fss-0001
+
+project_name iki_write
+
+version_major 0
+version_minor 5
+version_micro 1
+version_target major
+
+environment
+
+process_pre
+process_post
+
+modes individual level monolithic
+modes_default individual
+
+build_compiler gcc
+build_indexer ar
+build_language c
+build_libraries -lc
+build_libraries-individual -lfll_program -lfll_iki -lfll_file -lfl_directory -lf_path -lf_directory -lfl_utf -lfl_string -lfl_iki -lfl_conversion -lfl_console -lfl_color -lf_print -lf_pipe -lf_iki -lf_file -lf_conversion -lf_console -lf_utf -lf_memory
+build_libraries-level -lfll_2 -lfll_1 -lfll_0
+build_libraries-monolithic -lfll
+build_sources_library iki_write.c private-iki_write.c
+build_sources_program main.c
+build_sources_headers iki_write.h
+build_sources_script
+build_sources_setting
+build_script yes
+build_shared yes
+build_static yes
+
+path_headers level_3
+path_library_script script
+path_library_shared shared
+path_library_static static
+path_program_script script
+path_program_shared shared
+path_program_static static
+path_sources
+path_standard yes
+
+search_exclusive yes
+search_shared yes
+search_static yes
+
+defines_all
+defines_static
+defines_shared
+
+flags_all -z now -g -fdiagnostics-color=always
+flags_shared
+flags_static
+flags_library -fPIC
+flags_program -fPIE