diff --git a/docs/metadesk_reference.md b/docs/metadesk_reference.md index f7e269f..8b37664 100644 --- a/docs/metadesk_reference.md +++ b/docs/metadesk_reference.md @@ -992,7 +992,7 @@ main: @see(MD_S8Split) @func MD_S8ListJoin: { list: MD_String8List, - separator: MD_String8, + join: *MD_StringJoin, return: MD_String8, }; diff --git a/samples/output_parse/output_parse.c b/samples/output_parse/output_parse.c index 5136b71..906a44f 100644 --- a/samples/output_parse/output_parse.c +++ b/samples/output_parse/output_parse.c @@ -32,7 +32,11 @@ static void PrintNode(MD_Node* node, FILE* file, int indent_count) { Print(file, indent_count+1, "Flags: %s,\n", binary_flags); Print(file, indent_count+1, "Flag Names: ", binary_flags); MD_String8List flags_list = MD_StringListFromNodeFlags(node->flags); - MD_String8 flag_names = MD_S8ListJoin(flags_list, MD_S8CString(", ")); + + MD_StringJoin join = MD_ZERO_STRUCT; + join.mid = MD_S8CString(", "); + + MD_String8 flag_names = MD_S8ListJoin(flags_list, &join); fprintf(file, "%.*s,\n", MD_S8VArg(flag_names)); if(node->string.size > 0) Print(file, indent_count+1, "String: %.*s,\n", MD_S8VArg(node->string)); diff --git a/samples/static_site_generator/static_site_generator.c b/samples/static_site_generator/static_site_generator.c index 6308c17..9545e6e 100644 --- a/samples/static_site_generator/static_site_generator.c +++ b/samples/static_site_generator/static_site_generator.c @@ -35,8 +35,8 @@ int main(int argument_count, char **arguments) //~ NOTE(rjf): Parse command line arguments. MD_CmdLine cmdln = MD_MakeCmdLineFromOptions(MD_StringListFromArgCV(argument_count, arguments)); - MD_String8 site_info_path = MD_S8ListJoin(MD_CmdLineValuesFromString(cmdln, MD_S8Lit("siteinfo")), MD_S8Lit("")); - MD_String8 page_dir_path = MD_S8ListJoin(MD_CmdLineValuesFromString(cmdln, MD_S8Lit("pagedir")), MD_S8Lit("")); + MD_String8 site_info_path = MD_S8ListJoin(MD_CmdLineValuesFromString(cmdln, MD_S8Lit("siteinfo")), 0); + MD_String8 page_dir_path = MD_S8ListJoin(MD_CmdLineValuesFromString(cmdln, MD_S8Lit("pagedir")), 0); if(!MD_CmdLineB32FromString(cmdln, MD_S8Lit("siteinfo")) || !MD_CmdLineB32FromString(cmdln, MD_S8Lit("pagedir"))) { diff --git a/source/md.h b/source/md.h index 03d422d..5bb4fdb 100644 --- a/source/md.h +++ b/source/md.h @@ -313,6 +313,12 @@ struct MD_String8List MD_String8Node *last; }; +typedef struct MD_StringJoin{ + MD_String8 pre; + MD_String8 mid; + MD_String8 post; +} MD_StringJoin; + // NOTE(rjf): @maintenance These three enums must not overlap, and must share a flag space. typedef MD_u32 MD_MatchFlags; typedef MD_u32 MD_StringMatchFlags; @@ -706,9 +712,7 @@ MD_FUNCTION MD_String8 MD_S8(MD_u8 *str, MD_u64 size); #endif #define MD_S8LitComp(s) {(MD_u8 *)(s), sizeof(s)-1} -#if MD_LANG_CPP -// TODO(rjf): @allen this is only supported in C++11 I think, we need a check -// for that in the context cracking +#if MD_CPP_VERSION >= 11 static inline MD_String8 operator "" _md(const char *s, size_t size) { @@ -739,7 +743,7 @@ MD_FUNCTION MD_String8 MD_S8Fmt(char *fmt, ...); MD_FUNCTION void MD_S8ListPush(MD_String8List *list, MD_String8 string); MD_FUNCTION void MD_S8ListConcat(MD_String8List *list, MD_String8List *to_push); MD_FUNCTION MD_String8List MD_S8Split(MD_String8 string, int split_count, MD_String8 *splits); -MD_FUNCTION MD_String8 MD_S8ListJoin(MD_String8List list, MD_String8 separator); +MD_FUNCTION MD_String8 MD_S8ListJoin(MD_String8List list, MD_StringJoin *join); MD_FUNCTION MD_String8 MD_S8Stylize(MD_String8 string, MD_IdentifierStyle word_style, MD_String8 separator); diff --git a/source/md_impl.c b/source/md_impl.c index 8fcdae0..83696c8 100644 --- a/source/md_impl.c +++ b/source/md_impl.c @@ -362,26 +362,41 @@ MD_S8Split(MD_String8 string, int split_count, MD_String8 *splits) } MD_FUNCTION_IMPL MD_String8 -MD_S8ListJoin(MD_String8List list, MD_String8 separator) +MD_S8ListJoin(MD_String8List list, MD_StringJoin *join_ptr) { - if (list.node_count == 0) - { - return MD_S8Lit(""); + // setup join parameters + MD_StringJoin join = MD_ZERO_STRUCT; + if (join_ptr != 0){ + MD_MemoryCopy(&join, join_ptr, sizeof(join)); } - MD_String8 string = MD_ZERO_STRUCT; - string.size = list.total_size + (list.node_count - 1)*separator.size; - string.str = MD_PushArray(MD_u8, string.size); - MD_u64 write_pos = 0; + + // calculate size & allocate + MD_u64 sep_count = 0; + if (list.node_count > 1){ + sep_count = list.node_count - 1; + } + MD_String8 result = MD_ZERO_STRUCT; + result.size = (list.total_size + join.pre.size + + sep_count*join.mid.size + join.post.size); + result.str = MD_PushArray(MD_u8, result.size); + + // fill + MD_u8 *ptr = result.str; + MD_MemoryCopy(ptr, join.pre.str, join.pre.size); + ptr += join.pre.size; for(MD_String8Node *node = list.first; node; node = node->next) { - MD_MemoryCopy(string.str + write_pos, node->string.str, node->string.size); - write_pos += node->string.size; + MD_MemoryCopy(ptr, node->string.str, node->string.size); + ptr += node->string.size; if (node != list.last){ - MD_MemoryCopy(string.str + write_pos, separator.str, separator.size); - write_pos += separator.size; + MD_MemoryCopy(ptr, join.mid.str, join.mid.size); + ptr += join.mid.size; } } - return string; + MD_MemoryCopy(ptr, join.pre.str, join.pre.size); + ptr += join.pre.size; + + return(result); } MD_FUNCTION_IMPL MD_String8 @@ -1852,7 +1867,10 @@ MD_ParseOneNode(MD_String8 string, MD_u64 offset) { MD_S8ListPush(&bytes, MD_S8Fmt("0x%02X", bad_token.raw_string.str[i_byte])); } - MD_String8 byte_string = MD_S8ListJoin(bytes, MD_S8Lit(" ")); + + MD_StringJoin join = MD_ZERO_STRUCT; + join.mid = MD_S8Lit(" "); + MD_String8 byte_string = MD_S8ListJoin(bytes, &join); // NOTE(rjf): @error Bad character MD_Message *error = MD_MakeTokenError(string, bad_token, MD_MessageKind_Error, @@ -2530,7 +2548,7 @@ MD_CmdLineI64FromString(MD_CmdLine cmdln, MD_String8 name) { MD_i64 v = 0; MD_String8List values = MD_CmdLineValuesFromString(cmdln, name); - MD_String8 value_str = MD_S8ListJoin(values, MD_S8Lit("")); + MD_String8 value_str = MD_S8ListJoin(values, 0); v = MD_CStyleIntFromString(value_str); return v; } diff --git a/tests/grammar.c b/tests/grammar.c index 4b1f5e7..0070efa 100644 --- a/tests/grammar.c +++ b/tests/grammar.c @@ -732,7 +732,7 @@ int main(int argument_count, char **arguments) MD_String8List string_list = {0}; // NOTE(mal): Generate a random MD file ExpandProduction(file_production_node, &string_list, test.expected_output, 0, depth_map, max_production_depth, 0); - test.input = MD_S8ListJoin(string_list, MD_S8Lit("")); + test.input = MD_S8ListJoin(string_list, 0); Test *prev = 0; for(Test *cur = first_test; cur; cur = cur->next)