]> Kevux Git Server - fll/commitdiff
Progress: Featureless Make and IKI.
authorKevin Day <thekevinday@gmail.com>
Sun, 21 Jun 2020 23:47:25 +0000 (18:47 -0500)
committerKevin Day <thekevinday@gmail.com>
Sun, 21 Jun 2020 23:47:25 +0000 (18:47 -0500)
Continue work progressing Featureless Make 'make' and the newly implemented 'Iki' standard.

level_0/f_iki/c/iki-common.h
level_0/f_iki/c/iki.c
level_0/f_iki/c/iki.h
level_3/fake/data/build/fakefile
specifications/fss-000D.txt

index e3ab6efb48972a60e7057e82019919ece0605e73..7d970ef412c42ca064ff3d8c753be3b01299c11b 100644 (file)
@@ -9,22 +9,24 @@
  *
  * This is auto-included by iki.h and should not need to be explicitly included.
  */
-#ifndef _F_iki_h
-#define _F_iki_h
-
-// libc includes
-#include <stdio.h>
-#include <sys/stat.h>
-
-// fll-0 includes
-#include <level_0/status.h>
-#include <level_0/string.h>
-#include <level_0/type.h>
+#ifndef _F_iki_common_h
+#define _F_iki_common_h
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * IKI-specific syntax.
+ */
+#ifndef _di_f_iki_syntax_
+  #define f_iki_syntax_separator   ':'
+  #define f_iki_syntax_placeholder  0
+  #define f_iki_syntax_quote_double '"'
+  #define f_iki_syntax_quote_single '\''
+  #define f_iki_syntax_slash        '\\'
+#endif //_di_f_iki_syntax_
+
 #ifndef _di_iki_vocabulary_0000_
   #define iki_vocabulary_0000_emphasis "emphasis"
   #define iki_vocabulary_0000_code     "code"
@@ -44,9 +46,11 @@ extern "C" {
 #endif // _di_iki_vocabulary_0000_
 
 #ifndef _di_iki_vocabulary_0001_
-  #define iki_vocabulary_0001_variable "var"
+  #define iki_vocabulary_0001_define    "define"
+  #define iki_vocabulary_0001_parameter "parameter"
 
-  #define iki_vocabulary_0001_variable_length 3
+  #define iki_vocabulary_0001_define_length    6
+  #define iki_vocabulary_0001_parameter_length 9
 #endif // _di_iki_vocabulary_0001_
 
 /**
@@ -155,8 +159,112 @@ extern "C" {
   #define f_macro_iki_contents_adjust(status, content, new_length) f_macro_string_rangess_adjust(status, content, new_length)
 #endif // _di_iki_contents_
 
+/**
+ * Provide a default allocation step.
+ *
+ * For a UTF-8 friendly allocation step, set to at least 4.
+ */
+#ifndef _di_f_iki_default_allocation_step_
+  #define f_iki_default_allocation_step 4
+#endif // _di_f_iki_default_allocation_step_
+
+/**
+ * Reallocate delimits array if necessary for appending a new delimit.
+ *
+ * status:   The return status to use.
+ * delimits: The delimit array to conditionally reallocate.
+ */
+#ifndef _di_f_macro_iki_allocate_delimits_if_necessary_
+  #define f_macro_iki_allocate_delimits_if_necessary(status, delimits) \
+    status = F_none; \
+    if (delimits.used + 1 > delimits.size) { \
+      if (delimits.used + f_iki_default_allocation_step > f_string_length_size) { \
+        if (delimits.used + 1 > f_string_length_size) { \
+          status = F_status_set_error(F_string_too_large); \
+        } \
+        else { \
+          f_macro_string_lengths_resize(status, delimits, delimits.size + 1); \
+        } \
+      } \
+      else { \
+        f_macro_string_lengths_resize(status, delimits, delimits.size + f_iki_default_allocation_step); \
+      } \
+    }
+#endif // _di_f_macro_iki_allocate_delimits_if_necessary_
+
+/**
+ * Reallocate delimits array if necessary for appending a new ranges.
+ *
+ * status: The return status to use.
+ * ranges: The delimit array to conditionally reallocate.
+ */
+#ifndef _di_f_macro_iki_allocate_ranges_if_necessary_
+  #define f_macro_iki_allocate_ranges_if_necessary(status, ranges) \
+    status = F_none; \
+    if (ranges.used + 1 > ranges.size) { \
+      if (ranges.used + f_iki_default_allocation_step > f_string_length_size) { \
+        if (ranges.used + 1 > f_string_length_size) { \
+          status = F_status_set_error(F_string_too_large); \
+        } \
+        else { \
+          f_macro_string_ranges_resize(status, ranges, ranges.size + 1); \
+        } \
+      } \
+      else { \
+        f_macro_string_ranges_resize(status, ranges, ranges.size + f_iki_default_allocation_step); \
+      } \
+    }
+#endif // _di_f_macro_iki_allocate_ranges_if_necessary_
+
+/**
+ * Determine what the max width is based on the buffer and the range.
+ *
+ * buffer:    (A pointer) The buffer to determine width against.
+ * range:     (A pointer) The range within that buffer to determine against.
+ * width_max: The determined width max.
+ */
+#ifndef _di_f_macro_iki_determine_width_max_
+  #define f_macro_iki_determine_width_max(buffer, range, width_max) \
+    width_max = (range->stop - range->start) + 1; \
+    if (width_max > buffer->used - range->start) { \
+      width_max = buffer->used - range->start; \
+    }
+#endif // _di_f_macro_iki_determine_width_max_
+/**
+ * Seek until whitespace is found.
+ *
+ * status: The return status to use.
+ * buffer: (A pointer) The buffer to seek through.
+ * range:  (A pointer) The range within that buffer to seek through.
+ */
+#ifndef _di_f_macro_iki_seek_whitespace_
+  #define f_macro_iki_seek_whitespace(status, buffer, range, width_max) \
+    while (range->start <= range->stop && range->start < buffer->used) { \
+      f_macro_iki_determine_width_max(buffer, range, width_max); \
+      status = f_utf_is_whitespace(buffer->string + range->start, width_max); \
+      if (status == F_true) break; \
+      else if (F_status_is_error(status)) break; \
+      status = f_utf_buffer_increment(*buffer, range, 1); \
+      if (F_status_is_error(status)) break; \
+    }
+#endif // _di_f_macro_iki_seek_whitespace_
+
+/**
+ * Skip past all delimit placeholders.
+ *
+ * status: The return status to use.
+ * buffer: (A pointer) The buffer to skip through.
+ * range:  (A pointer) The range within that buffer to skip through.
+ */
+#ifndef _di_f_macro_iki_skip_past_delimit_placeholders_
+  #define f_macro_iki_skip_past_delimit_placeholders(status, buffer, range) \
+    do { \
+      status = f_utf_buffer_increment(*buffer, range, 1); \
+    } while (F_status_is_fine(status) && buffer->string[range->start] == f_iki_syntax_placeholder);
+#endif // _di_f_macro_iki_skip_past_delimit_placeholders_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
 
-#endif // _F_iki_h
+#endif // _F_iki_common_h
index cbd140ce4fdae2a4fd4abe391f8d84593c4c922c..318437daf2cf8c76623131540523d63fb5cd4c42 100644 (file)
@@ -4,6 +4,486 @@
 extern "C" {
 #endif
 
+#ifndef _di_f_iki_read_
+  f_return_status f_iki_read(f_string_static *buffer, f_string_range *range, f_iki_vocabulary *vocabulary, f_iki_content *content) {
+    #ifndef _di_level_1_parameter_checking_
+      if (buffer == 0) return F_status_set_error(F_parameter);
+      if (range == 0) return F_status_set_error(F_parameter);
+      if (vocabulary == 0) return F_status_set_error(F_parameter);
+      if (content == 0) return F_status_set_error(F_parameter);
+      if (buffer->used == 0) return F_status_set_error(F_parameter);
+      if (range->start > range->stop) return F_status_set_error(F_parameter);
+      if (range->start >= buffer->used) return F_status_set_error(F_parameter);
+    #endif // _di_level_1_parameter_checking_
+
+    f_status status = F_none;
+
+    f_string_length width_max = 0;
+
+    if (width_max > buffer->used - range->start) {
+      width_max = buffer->used - range->start;
+    }
+
+    // skip past all initial non-word, non-dash, and non-plus.
+    while (range->start <= range->stop && range->start < buffer->used) {
+
+      if (buffer->string[range->start] != f_iki_syntax_placeholder) {
+        f_macro_iki_determine_width_max(buffer, range, width_max);
+
+        status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max);
+        if (F_status_is_error(status)) return status;
+
+        if (status == F_true) break;
+      }
+
+      status = f_utf_buffer_increment(*buffer, range, 1);
+      if (F_status_is_error(status)) return status;
+    } // while
+
+    if (range->start > range->stop) {
+      return F_data_not_stop;
+    }
+    else if (range->start >= buffer->used) {
+      return F_data_not_eos;
+    }
+
+    f_string_range found_vocabulary = f_string_range_initialize;
+    f_string_length found_content = 0;
+
+    found_vocabulary.start = range->start;
+
+    f_string_length vocabulary_slash_first = range->start;
+
+    uint8_t quote = 0;
+
+    bool vocabulary_delimited = F_false;
+
+    // delimits must only be applied once a valid object is found.
+    f_string_lengths delimits = f_string_lengths_initialize;
+
+    do {
+      // find the start and end of the vocabulary name.
+      while (range->start <= range->stop && range->start < buffer->used) {
+        if (buffer->string[range->start] == f_iki_syntax_placeholder) {
+          range->start++;
+          continue;
+        }
+
+        if (buffer->string[range->start] == f_iki_syntax_separator) {
+          if (range->start == found_vocabulary.start) {
+            status = f_utf_buffer_increment(*buffer, range, 1);
+            if (F_status_is_error(status)) {
+              f_macro_string_lengths_delete(status, delimits);
+              return status;
+            }
+
+            break;
+          }
+
+          vocabulary_delimited = F_false;
+          found_vocabulary.stop = range->start - 1;
+
+          f_macro_iki_skip_past_delimit_placeholders(status, buffer, range);
+          if (F_status_is_error(status)) {
+            f_macro_string_lengths_delete(status, delimits);
+            return status;
+          }
+
+          // found a valid vocabulary name.
+          if (buffer->string[range->start] == f_iki_syntax_quote_single || buffer->string[range->start] == f_iki_syntax_quote_double) {
+            quote = buffer->string[range->start];
+            break;
+          }
+
+          // this is not a valid vocabulary name so seek until a whitespace to prepare for the next main loop pass.
+          f_macro_iki_seek_whitespace(status, buffer, range, width_max);
+          if (F_status_is_error(status)) {
+            f_macro_string_lengths_delete(status, delimits);
+            return status;
+          }
+
+          break;
+        }
+        else if (buffer->string[range->start] == f_iki_syntax_slash) {
+          bool separator_found = F_false;
+
+          vocabulary_slash_first = range->start;
+
+          // the slash only needs to be delimited if it were to otherwise be a valid vocabulary name.
+          while (range->start <= range->stop && range->start < buffer->used) {
+            if (buffer->string[range->start] == f_iki_syntax_placeholder) {
+              range->start++;
+              continue;
+            }
+
+            if (separator_found) {
+              if (buffer->string[range->start] == f_iki_syntax_quote_single || buffer->string[range->start] == f_iki_syntax_quote_double) {
+                vocabulary_delimited = F_true;
+
+                quote = buffer->string[range->start];
+                range->start++;
+                break;
+              }
+              else {
+                range->start = vocabulary_slash_first;
+
+                // this is not a valid vocabulary name so seek until a whitespace to prepare for the next main loop pass.
+                f_macro_iki_seek_whitespace(status, buffer, range, width_max);
+                if (F_status_is_error(status)) {
+                  f_macro_string_lengths_delete(status, delimits);
+                  return status;
+                }
+
+                break;
+              }
+            }
+            else if (buffer->string[range->start] == f_iki_syntax_separator) {
+              separator_found = F_true;
+            }
+            else {
+              range->start = vocabulary_slash_first;
+
+              // this is not a valid vocabulary name so seek until a whitespace to prepare for the next main loop pass.
+              f_macro_iki_seek_whitespace(status, buffer, range, width_max);
+              if (F_status_is_error(status)) {
+                f_macro_string_lengths_delete(status, delimits);
+                return status;
+              }
+
+              break;
+            }
+
+            status = f_utf_buffer_increment(*buffer, range, 1);
+            if (F_status_is_error(status)) {
+              f_macro_string_lengths_delete(status, delimits);
+              return status;
+            }
+          } // while
+        }
+        else {
+          f_macro_iki_determine_width_max(buffer, range, width_max);
+
+          status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max);
+          if (F_status_is_error(status)) {
+            f_macro_string_lengths_delete(status, delimits);
+            return status;
+          }
+
+          if (status == F_false) {
+            status = f_utf_buffer_increment(*buffer, range, 1);
+            if (F_status_is_error(status)) {
+              f_macro_string_lengths_delete(status, delimits);
+              return status;
+            }
+
+            break;
+          }
+        }
+
+        status = f_utf_buffer_increment(*buffer, range, 1);
+        if (F_status_is_error(status)) {
+          f_macro_string_lengths_delete(status, delimits);
+          return status;
+        }
+      } // while
+
+      // process potentially valid content.
+      if (quote) {
+        found_content = range->start;
+
+        while (range->start <= range->stop && range->start < buffer->used) {
+          if (buffer->string[range->start] == f_iki_syntax_placeholder) {
+            range->start++;
+            continue;
+          }
+
+          if (buffer->string[range->start] == quote) {
+            // this is a valid vocabulary name and content, but if it is delimited, save the delimit and ignore.
+            if (vocabulary_delimited) {
+              f_macro_iki_allocate_delimits_if_necessary(status, delimits);
+              if (F_status_is_error(status)) {
+                f_macro_string_lengths_delete(status, delimits);
+                return status;
+              }
+
+              delimits.array[delimits.used] = vocabulary_slash_first;
+              delimits.used++;
+
+              vocabulary_delimited = F_false;
+              quote = 0;
+
+              range->start++;
+
+              // skip past all initial non-word, non-dash, and non-plus.
+              while (range->start <= range->stop && range->start < buffer->used) {
+                if (buffer->string[range->start] == f_iki_syntax_placeholder) {
+                  range->start++;
+                  continue;
+                }
+
+                f_macro_iki_determine_width_max(buffer, range, width_max);
+
+                status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max);
+                if (F_status_is_error(status)) {
+                  f_macro_string_lengths_delete(status, delimits);
+                  return status;
+                }
+
+                if (status == F_true) break;
+
+                status = f_utf_buffer_increment(*buffer, range, 1);
+                if (F_status_is_error(status)) {
+                  f_macro_string_lengths_delete(status, delimits);
+                  return status;
+                }
+              } // while
+
+              found_vocabulary.start = range->start;
+            }
+            else {
+              f_macro_iki_allocate_ranges_if_necessary(status, (*vocabulary));
+              if (F_status_is_error(status)) {
+                f_macro_string_lengths_delete(status, delimits);
+                return status;
+              }
+
+              f_macro_iki_allocate_ranges_if_necessary(status, (*content));
+              if (F_status_is_error(status)) {
+                f_macro_string_lengths_delete(status, delimits);
+                return status;
+              }
+
+              vocabulary->array[vocabulary->used].start = found_vocabulary.start;
+              vocabulary->array[vocabulary->used].stop = found_vocabulary.stop;
+              vocabulary->used++;
+
+              content->array[content->used].start = found_content;
+              content->array[content->used].stop = range->start - 1;
+              content->used++;
+
+              for (f_array_length i = 0; i < delimits.used; i++) {
+                buffer->string[delimits.array[i]] = f_iki_syntax_placeholder;
+              } // for
+
+              f_macro_string_lengths_delete(status, delimits);
+              if (F_status_is_error(status)) return status;
+
+              range->start++;
+
+              if (range->start > range->stop) {
+                return F_none_stop;
+              }
+
+              if (range->start >= buffer->used) {
+                return F_none_eos;
+              }
+
+              return F_none;
+            }
+          }
+          else if (buffer->string[range->start] == f_iki_syntax_slash) {
+            f_string_length content_slash_first = range->start;
+            f_array_length content_slash_total = 1;
+
+            while (range->start <= range->stop && range->start < buffer->used) {
+              if (buffer->string[range->start] == f_iki_syntax_placeholder) {
+                range->start++;
+                continue;
+              }
+
+              if (buffer->string[range->start] == quote) {
+                f_array_length content_slash_delimits = content_slash_total / 2;
+                f_string_range content_range = f_string_range_initialize;
+                f_array_length i = 0;
+
+                if (content_slash_total % 2) {
+                  content_slash_delimits++;
+                }
+
+                if (delimits.used + content_slash_delimits > delimits.size) {
+                  if (delimits.used + content_slash_delimits > f_string_length_size) {
+                    status = F_status_set_error(F_string_too_large);
+                  }
+                  else {
+                    f_macro_string_lengths_resize(status, delimits, delimits.used + content_slash_delimits);
+                  }
+
+                  if (F_status_is_error(status)) {
+                    f_macro_string_lengths_delete(status, delimits);
+                    return status;
+                  }
+                }
+
+                content_range.start = content_slash_first;
+                content_range.stop = range->stop;
+
+                while (i < content_slash_delimits) {
+                  if (buffer->string[content_range.start] == f_iki_syntax_slash) {
+                    delimits.array[delimits.used] = content_range.start;
+                    delimits.used++;
+
+                    i++;
+                  }
+
+                  status = f_utf_buffer_increment(*buffer, (&content_range), 1);
+                  if (F_status_is_error(status)) {
+                    f_macro_string_lengths_delete(status, delimits);
+                    return status;
+                  }
+                } // while
+
+                // valid content's ending quote is not delimited, save and return.
+                if (content_slash_total % 2 == 0) {
+
+                  // this is a valid vocabulary name and content, but if it is delimited, save the delimit and ignore.
+                  if (vocabulary_delimited) {
+                    f_macro_iki_allocate_delimits_if_necessary(status, delimits);
+                    if (F_status_is_error(status)) {
+                      f_macro_string_lengths_delete(status, delimits);
+                      return status;
+                    }
+
+                    delimits.array[delimits.used] = vocabulary_slash_first;
+                    delimits.used++;
+
+                    vocabulary_delimited = F_false;
+                    quote = 0;
+
+                    range->start++;
+
+                    // skip past all initial non-word, non-dash, and non-plus.
+                    while (range->start <= range->stop && range->start < buffer->used) {
+                      if (buffer->string[range->start] == f_iki_syntax_placeholder) {
+                        range->start++;
+                        continue;
+                      }
+
+                      f_macro_iki_determine_width_max(buffer, range, width_max);
+
+                      status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max);
+                      if (F_status_is_error(status)) {
+                        f_macro_string_lengths_delete(status, delimits);
+                        return status;
+                      }
+
+                      if (status == F_true) break;
+
+                      status = f_utf_buffer_increment(*buffer, range, 1);
+                      if (F_status_is_error(status)) {
+                        f_macro_string_lengths_delete(status, delimits);
+                        return status;
+                      }
+                    } // while
+
+                    found_vocabulary.start = range->start;
+                  }
+                  else {
+                    f_macro_iki_allocate_ranges_if_necessary(status, (*vocabulary));
+                    if (F_status_is_error(status)) {
+                      f_macro_string_lengths_delete(status, delimits);
+                      return status;
+                    }
+
+                    f_macro_iki_allocate_ranges_if_necessary(status, (*content));
+                    if (F_status_is_error(status)) {
+                      f_macro_string_lengths_delete(status, delimits);
+                      return status;
+                    }
+
+                    vocabulary->array[vocabulary->used].start = found_vocabulary.start;
+                    vocabulary->array[vocabulary->used].stop = found_vocabulary.stop;
+                    vocabulary->used++;
+
+                    content->array[content->used].start = found_content;
+                    content->array[content->used].stop = range->start - 1;
+                    content->used++;
+
+                    for (f_array_length i = 0; i < delimits.used; i++) {
+                      buffer->string[delimits.array[i]] = f_iki_syntax_placeholder;
+                    } // for
+
+                    f_macro_string_lengths_delete(status, delimits);
+                    if (F_status_is_error(status)) return status;
+
+                    range->start++;
+
+                    if (range->start > range->stop) {
+                      return F_none_stop;
+                    }
+
+                    if (range->start >= buffer->used) {
+                      return F_none_eos;
+                    }
+
+                    return F_none;
+                  }
+                }
+
+                break;
+              }
+              else if (buffer->string[range->start] != f_iki_syntax_slash) {
+                range->start++;
+                break;
+              }
+
+              content_slash_total++;
+
+              status = f_utf_buffer_increment(*buffer, range, 1);
+              if (F_status_is_error(status)) {
+                f_macro_string_lengths_delete(status, delimits);
+                return status;
+              }
+            } // while
+          }
+
+          status = f_utf_buffer_increment(*buffer, range, 1);
+          if (F_status_is_error(status)) {
+            f_macro_string_lengths_delete(status, delimits);
+            return status;
+          }
+        } // while
+      }
+      else {
+        vocabulary_delimited = F_false;
+
+        // skip past all initial non-word, non-dash, and non-plus.
+        while (range->start <= range->stop && range->start < buffer->used) {
+          if (buffer->string[range->start] == f_iki_syntax_placeholder) {
+            range->start++;
+            continue;
+          }
+
+          f_macro_iki_determine_width_max(buffer, range, width_max);
+
+          status = f_utf_is_word_dash_plus(buffer->string + range->start, width_max);
+          if (F_status_is_error(status)) {
+            f_macro_string_lengths_delete(status, delimits);
+            return status;
+          }
+
+          if (status == F_true) break;
+
+          status = f_utf_buffer_increment(*buffer, range, 1);
+          if (F_status_is_error(status)) {
+            f_macro_string_lengths_delete(status, delimits);
+            return status;
+          }
+        } // while
+
+        found_vocabulary.start = range->start;
+      }
+    } while (range->start <= range->stop && range->start < buffer->used);
+
+    f_macro_string_lengths_delete(status, delimits);
+    if (F_status_is_error(status)) return status;
+
+    if (range->start > range->stop) {
+      return F_data_not_stop;
+    }
+
+    return F_data_not_eos;
+  }
+#endif // _di_f_iki_read_
 
 #ifdef __cplusplus
 } // extern "C"
index 5d3629f006661246a929a4175d351a6c06104a6d..945b22b516552dbf98770d13c8c11dc3e7814039 100644 (file)
@@ -8,45 +8,7 @@
  * 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 define but a few common standards are provided.
- *
- * The example syntax:
- *   - url:"http:// a b c/"
- *   - code:" code goes here"
- *   - quote:"This is a quote"
- *   - var:"some_variable_name"
- *   - emphasis:"This text is important"
- *
- * Which is: (word character, no whitespace, '-', '_', and '+')(colon ':')(quote, either single (') or double ("))(anything goes and closing quotes must be escaped)(closing quote, must match openening quote)
- *
- * Escaping only needs to be done like these three cases:
- * 1) escaping main syntax:
- *   - url\:"http:// a b c/"
- *   - after the first '\:', every '\' is a literal '\'.
- *     - url\\\\\:"http:// a b c/" would be read as: 'url\\\\:"http:// a b c/"'.
- * 2) escaping the quoted part, but only for the closing quote that matches the opening quote:
- *   - quote:"This is a \"quote\""
- *   - There is no way to know the terminating quote so all quotes matching the opening quote inside must be escaped.
- *     - emphasis:"\"This is some Text with a slash before quote: \\\"" would be read as: emphasis, with value: "This is some Text with a slash before quote: \".
- * - Create this as a new FSS format, FSS-Text (FSS-000D).
- *
- * IKI-0000 (Basic) provides the following vocabulary:
- *   - emphasis: Providing emphasis on text, such as bold.
- *   - code: Representing code (formatting preserved or otherwise presented literally).
- *   - quote: Representing quoted text.
- *   - uri: Representing a URI (This is a superset of URL and URN).
- *   - url: Representing a URL.
- *   - urn: Representing a URN.
- *   - var: Representing a variable name.
- *
- * IKI-0001 (Variable) provides the following vocabulary:
- *   - var: Representing a variable name.
- *
- * This is intended to also be used by FSS-Iki_Text (FSS-000D), which focuses on the format and not the context.
- * Wherease, IKI-0000 (Basic) represents the vocabulary and its respective context.
- * Therefore an FSS-000D may have any IKI-???? format within it.
- *
- * A format header such as "# fss-000d iki-0001\n" would represent an IKI format of IKI-0001 (Variable).
+ * The context itself is not explicitly defined but a few common standards are provided.
  */
 #ifndef _F_iki_h
 #define _F_iki_h
 
 // fll-0 includes
 #include <level_0/status.h>
+#include <level_0/memory.h>
 #include <level_0/string.h>
 #include <level_0/type.h>
+#include <level_0/utf.h>
+
+// fll-0 iki includes
+#include <level_0/iki-common.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+/**
+ * Read a single iki Vocabulary and Content.
+ *
+ * This does not verify if the vocabulary name is known.
+ * This only finds a complete vocabulary name and content.
+ *
+ * @param buffer
+ *   The string to process.
+ * @param range
+ *   The start/stop location within the buffer to be processed.
+ *   The start location will be updated as the buffer is being processed.
+ *   The start location will represent where the read stopped on return.
+ *   A start location past the stop location or buffer used means that the entire range was processed.
+ * @param vocabulary
+ *   The vocabulary name list to store the found vocabulary name.
+ * @param content
+ *   The content list to store the content associated with the found vocabulary name.
+ *
+ * @return
+ *   F_none on success and an IKI vocabulary name was found.
+ *   F_none_stop on success and an IKI vocabulary name was found and stop point was reached.
+ *   F_none_eos on success and an IKI vocabulary name was found and end of string was reached.
+ *   F_data_not_eos on success and EOS was reached, but there were no IKI vocabularie names found.
+ *   F_data_not_stop on success and stop point was reached, but there were no IKI vocabularie names found.
+ *   F_memory_reallocation (with error bit) on memory reallocation error.
+ *   F_parameter (with error bit) if a parameter is invalid.
+ *   F_string_too_large (with error bit) if a string length is too large to store in the buffer.
+ */
+#ifndef _di_f_iki_read_
+  extern f_return_status f_iki_read(f_string_static *buffer, f_string_range *range, f_iki_vocabulary *vocabulary, f_iki_content *content);
+#endif // _di_f_iki_read_
+
 #ifdef __cplusplus
 } // extern "C"
 #endif
index 6cf82e306b063839746dc74291fbf2d40a6d5899..2abaf0217094e12b10569aa535da70ad6196c7aa 100644 (file)
@@ -1,10 +1,15 @@
-# fss-0005
+# fss-0005 iki-0001
+# @todo consider creating iki-0002 to support both "parameter" and "define" as opposed to "var" as documented below.
 
 settings:
   load_build yes
 
   define example value
 
+  # from this, adding 'parameter:"verbose"' in main would be replaced with '+v' if and when the +V/++verbose parameter is passed to fake otherwise it is removed.
+  # gcc parameter:"verbose"    would become    gcc +v
+  parameter verbose +v
+
 main:
   print This is a line.
 
@@ -18,13 +23,13 @@ main:
   build    // run the fake build operation ($1 = path to settings file, if missing use default, auto-passes verbosity and other Fake parameters.).
   clean    // run the fake clean operation (auto-passes verbosity and other Fake parameters.).
   compile  // run the gcc compiler (all arguments are passed as arguments, except for reserved parameter words, with $ in front, such as $build_1).
-  create   // create a file or directory ($1 = 'file' or 'directory') ($2 = path to file or directory) ($3 = 'recursive' (optional) for 'directory' only).
-  delete   // delete a file or directory ($1 = 'file' or 'directory') ($2 = path to file or directory) ($3 = 'recursive' (optional) for 'directory' only).
+  create   // create a file or directory ($1 = file or directory) ($2 = path to file or directory) ($3 = recursive (optional) for directory only).
+  delete   // delete a file or directory ($1 = file or directory) ($2 = path to file or directory) ($3 = recursive (optional) for directory only).
   else     // execute next line if immediately previous if condition fails (if exists file_name.txt, if defined environment_name, if equals some string or define another string or define, if succeed for previous run/shell command succeeding, if fail for previous run/shell command failing).
-  fail     // what to do when a command fails, either 'exit', 'warn' or 'ignore'.
+  fail     // what to do when a command fails, either exit, warn or ignore.
   group    // change group on file or directory ($1 = path to file or directory).
   if       // execute next line if condition succeeds (if exists file_name.txt, if defined environment_name, if equals some string or define another string or define, if succeed for previous run/shell command succeeding, if fail for previous run/shell command failing).
-  link     // create a symbolic link ($1 = target) ($2 = point). (@todo also don't allow linking outside project directory).
+  link     // create a symbolic link ($1 = target) ($2 = point). (@todo also dont allow linking outside project directory).
   mode     // change mode of a file or directory ($1 = path to file or directory).
   operate  // enter into a given named operation except for reserved .
   owner    // change owner on file or directory ($1 = path to file or directory).
index da414361204caecabfbc807c395ed7175a6a99f2..0cafab7c2b1a550b8bbd9fdff502d610d63a2cdc 100644 (file)
@@ -16,15 +16,19 @@ Featureless Settings Specification: 000D - Iki Text:
 
   For compatibility with the FSS terminology, the Vocabulary Name is to be considered the Object and the Vocabulary value is to be considered the Content.
 
+  Whitespace (or start of file), must exist before any valid variable name.
+
   Key\:
+    \s = whitespace.
     \o = any printable word character, including "_", "-", "+".
     \c = any printing character, including whitespace, and any delimited quote (used as the opening quote) or a any quote (undelimited) not used as the opening quote.
     \q = either a single quote (') or a double quote (").
     \x = any character.
     * = 0 or more occurrences.
+    ~ = one or more occurrences, or 0 if at start of file.
 
   Structure\:
-    \x*\o:\q\c\q
+    \x*\s~\o:\q\c\q
 
   Example\:
     # fss-000d iki-0000