From: Kevin Day Date: Sun, 21 Jun 2020 23:47:25 +0000 (-0500) Subject: Progress: Featureless Make and IKI. X-Git-Tag: 0.5.0~142 X-Git-Url: https://git.kevux.org/?a=commitdiff_plain;h=f1d4c536213fddd208d4ba49a6893831d3fef6b0;p=fll Progress: Featureless Make and IKI. Continue work progressing Featureless Make 'make' and the newly implemented 'Iki' standard. --- diff --git a/level_0/f_iki/c/iki-common.h b/level_0/f_iki/c/iki-common.h index e3ab6ef..7d970ef 100644 --- a/level_0/f_iki/c/iki-common.h +++ b/level_0/f_iki/c/iki-common.h @@ -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 -#include - -// fll-0 includes -#include -#include -#include +#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 diff --git a/level_0/f_iki/c/iki.c b/level_0/f_iki/c/iki.c index cbd140c..318437d 100644 --- a/level_0/f_iki/c/iki.c +++ b/level_0/f_iki/c/iki.c @@ -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" diff --git a/level_0/f_iki/c/iki.h b/level_0/f_iki/c/iki.h index 5d3629f..945b22b 100644 --- a/level_0/f_iki/c/iki.h +++ b/level_0/f_iki/c/iki.h @@ -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 @@ -57,13 +19,50 @@ // fll-0 includes #include +#include #include #include +#include + +// fll-0 iki includes +#include #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 diff --git a/level_3/fake/data/build/fakefile b/level_3/fake/data/build/fakefile index 6cf82e3..2abaf02 100644 --- a/level_3/fake/data/build/fakefile +++ b/level_3/fake/data/build/fakefile @@ -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). diff --git a/specifications/fss-000D.txt b/specifications/fss-000D.txt index da41436..0cafab7 100644 --- a/specifications/fss-000D.txt +++ b/specifications/fss-000D.txt @@ -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