From f9d581eaa08176e7a3ff93c48ac8d77f0ab6e7f8 Mon Sep 17 00:00:00 2001 From: bones_was_here Date: Thu, 12 Sep 2024 05:37:54 +1000 Subject: [PATCH] con: reduce indenting in Con_CompleteCommandLine, update some comments Signed-off-by: bones_was_here --- cmd.c | 2 +- common.c | 4 +- common.h | 1 - console.c | 253 +++++++++++++++++++++++++++--------------------------- 4 files changed, 128 insertions(+), 132 deletions(-) diff --git a/cmd.c b/cmd.c index cbb3feca..a5482110 100644 --- a/cmd.c +++ b/cmd.c @@ -170,7 +170,7 @@ static cmd_input_t *Cbuf_NodeGet(cmd_buf_t *cbuf, cmd_input_t *existing) Cbuf_LinkString Copies a command string into a buffer node. -The input should not be null-terminated, the output will be. +The input need not be null-terminated, the output will be. ============ */ static void Cbuf_LinkString(cmd_state_t *cmd, llist_t *head, cmd_input_t *existing, const char *text, qbool leavepending, unsigned int cmdsize) diff --git a/common.c b/common.c index 67c2a4fb..76cdc014 100644 --- a/common.c +++ b/common.c @@ -1416,11 +1416,11 @@ size_t dp__strlcpy(char *dst, const char *src, size_t dsize, const char *func, u return dsize - 1; } -/** Catenates a string, like strlcat() but with a better return: the number of bytes copied +/** Catenates a string, like strlcat() but with a better return: the final strlen of dst * excluding the \0 terminator. Truncates and warns on overflow or unterminated source, * whereas strlcat() truncates silently and overreads (possibly segfaulting). * Guarantees \0 termination. - * Inefficient like any strcat(), please use memcpy(), dp_stpecpy() or dp_strlcpy() instead. + * strcat() is inefficient when the offset of \0 in dst is known, prefer dp_stpecpy() then. */ size_t dp__strlcat(char *dst, const char *src, size_t dsize, const char *func, unsigned line) { diff --git a/common.h b/common.h index cde830dc..1875a06f 100644 --- a/common.h +++ b/common.h @@ -299,7 +299,6 @@ size_t COM_StringLengthNoColors(const char *s, size_t size_s, qbool *valid); size_t COM_StringDecolorize(const char *in, size_t size_in, char *out, size_t size_out, qbool escape_carets); - #define dp_strlcpy(dst, src, dsize) dp__strlcpy(dst, src, dsize, __func__, __LINE__) #define dp_strlcat(dst, src, dsize) dp__strlcat(dst, src, dsize, __func__, __LINE__) size_t dp__strlcpy(char *dst, const char *src, size_t dsize, const char *func, unsigned line); diff --git a/console.c b/console.c index 70f8fa20..09c64a67 100644 --- a/console.c +++ b/console.c @@ -2957,165 +2957,162 @@ int Con_CompleteCommandLine(cmd_state_t *cmd, qbool is_console) } return linepos; } - else + else if(patterns) { - if(patterns) + stringlist_t resultbuf, dirbuf; + + // Usage: + // // store completion patterns (space separated) for command foo in con_completion_foo + // set con_completion_foo "foodata/*.foodefault *.foo" + // foo + // + // Note: patterns with slash are always treated as absolute + // patterns; patterns without slash search in the innermost + // directory the user specified. There is no way to "complete into" + // a directory as of now, as directories seem to be unknown to the + // FS subsystem. + // + // Examples: + // set con_completion_playermodel "models/player/*.zym models/player/*.md3 models/player/*.psk models/player/*.dpm" + // set con_completion_playdemo "*.dem" + // set con_completion_play "*.wav *.ogg" + + stringlistinit(&resultbuf); + stringlistinit(&dirbuf); + searchstrlen = Con_UnescapeSpaces(searchstr, s, sizeof(searchstr)); + + while(COM_ParseToken_Simple(&patterns, false, false, true)) { - stringlist_t resultbuf, dirbuf; - - // Usage: - // // store completion patterns (space separated) for command foo in con_completion_foo - // set con_completion_foo "foodata/*.foodefault *.foo" - // foo - // - // Note: patterns with slash are always treated as absolute - // patterns; patterns without slash search in the innermost - // directory the user specified. There is no way to "complete into" - // a directory as of now, as directories seem to be unknown to the - // FS subsystem. - // - // Examples: - // set con_completion_playermodel "models/player/*.zym models/player/*.md3 models/player/*.psk models/player/*.dpm" - // set con_completion_playdemo "*.dem" - // set con_completion_play "*.wav *.ogg" - - stringlistinit(&resultbuf); - stringlistinit(&dirbuf); - searchstrlen = Con_UnescapeSpaces(searchstr, s, sizeof(searchstr)); - - while(COM_ParseToken_Simple(&patterns, false, false, true)) + fssearch_t *search; + if(strchr(com_token, '/')) { - fssearch_t *search; - if(strchr(com_token, '/')) - { - search = FS_Search(com_token, true, true, NULL); - } - else - { - const char *slash = strrchr(searchstr, '/'); - if(slash) - { - dp_ustr2stp(temp, sizeof(temp), searchstr, slash - searchstr + 1); // + 1, because I want to include the slash - dp_strlcat(temp, com_token, sizeof(temp)); - search = FS_Search(temp, true, true, NULL); - } - else - search = FS_Search(com_token, true, true, NULL); - } - if(search) - { - for(i = 0; i < search->numfilenames; ++i) - if(!strncmp(search->filenames[i], searchstr, searchstrlen)) - if(FS_FileType(search->filenames[i]) == FS_FILETYPE_FILE) - stringlistappend(&resultbuf, search->filenames[i]); - FS_FreeSearch(search); - } + search = FS_Search(com_token, true, true, NULL); } - - // In any case, add directory names + else { - fssearch_t *search; const char *slash = strrchr(searchstr, '/'); if(slash) { dp_ustr2stp(temp, sizeof(temp), searchstr, slash - searchstr + 1); // + 1, because I want to include the slash - dp_strlcat(temp, "*", sizeof(temp)); + dp_strlcat(temp, com_token, sizeof(temp)); search = FS_Search(temp, true, true, NULL); } else - search = FS_Search("*", true, true, NULL); - if(search) - { - for(i = 0; i < search->numfilenames; ++i) - if(!strncmp(search->filenames[i], searchstr, searchstrlen)) - if(FS_FileType(search->filenames[i]) == FS_FILETYPE_DIRECTORY) - stringlistappend(&dirbuf, search->filenames[i]); - FS_FreeSearch(search); - } + search = FS_Search(com_token, true, true, NULL); + } + if(search) + { + for(i = 0; i < search->numfilenames; ++i) + if(!strncmp(search->filenames[i], searchstr, searchstrlen)) + if(FS_FileType(search->filenames[i]) == FS_FILETYPE_FILE) + stringlistappend(&resultbuf, search->filenames[i]); + FS_FreeSearch(search); } + } - if(resultbuf.numstrings > 0 || dirbuf.numstrings > 0) + // In any case, add directory names + { + fssearch_t *search; + const char *slash = strrchr(searchstr, '/'); + if(slash) + { + dp_ustr2stp(temp, sizeof(temp), searchstr, slash - searchstr + 1); // + 1, because I want to include the slash + dp_strlcat(temp, "*", sizeof(temp)); + search = FS_Search(temp, true, true, NULL); + } + else + search = FS_Search("*", true, true, NULL); + if(search) { - const char *p, *q; - unsigned int matchchars; - bool appendspace = false; + for(i = 0; i < search->numfilenames; ++i) + if(!strncmp(search->filenames[i], searchstr, searchstrlen)) + if(FS_FileType(search->filenames[i]) == FS_FILETYPE_DIRECTORY) + stringlistappend(&dirbuf, search->filenames[i]); + FS_FreeSearch(search); + } + } + + if(resultbuf.numstrings > 0 || dirbuf.numstrings > 0) + { + const char *p, *q; + unsigned int matchchars; + bool appendspace = false; - if(resultbuf.numstrings == 0 && dirbuf.numstrings == 1) + if(resultbuf.numstrings == 0 && dirbuf.numstrings == 1) + { + dpsnprintf(temp, sizeof(temp), "%s/", dirbuf.strings[0]); + } + else + if(resultbuf.numstrings == 1 && dirbuf.numstrings == 0) + { + dp_strlcpy(temp, resultbuf.strings[0], sizeof(temp)); + // trailing space can't be appended yet as it would get escaped + appendspace = true; + } + else + { + stringlistsort(&resultbuf, true); // dirbuf is already sorted + Con_Printf("\n%i possible filenames\n", resultbuf.numstrings + dirbuf.numstrings); + for(i = 0; i < dirbuf.numstrings; ++i) { - dpsnprintf(temp, sizeof(temp), "%s/", dirbuf.strings[0]); + Con_Printf("^4%s^7/\n", dirbuf.strings[i]); } - else - if(resultbuf.numstrings == 1 && dirbuf.numstrings == 0) + for(i = 0; i < resultbuf.numstrings; ++i) { - dp_strlcpy(temp, resultbuf.strings[0], sizeof(temp)); - // trailing space can't be appended yet as it would get escaped - appendspace = true; + Con_Printf("%s\n", resultbuf.strings[i]); } - else - { - stringlistsort(&resultbuf, true); // dirbuf is already sorted - Con_Printf("\n%i possible filenames\n", resultbuf.numstrings + dirbuf.numstrings); - for(i = 0; i < dirbuf.numstrings; ++i) - { - Con_Printf("^4%s^7/\n", dirbuf.strings[i]); - } - for(i = 0; i < resultbuf.numstrings; ++i) - { - Con_Printf("%s\n", resultbuf.strings[i]); - } - if(resultbuf.numstrings > 0) // matching file - { - p = resultbuf.strings[0]; - q = resultbuf.strings[resultbuf.numstrings - 1]; - if (dirbuf.numstrings > 0) // and matching directory - { - const char *r = dirbuf.strings[0]; - for(; *p && *p == *q && *p == *r; ++p, ++q, ++r); - } - else - for(; *p && *p == *q; ++p, ++q); - matchchars = (unsigned int)(p - resultbuf.strings[0]); - dp_ustr2stp(temp, sizeof(temp), resultbuf.strings[0], matchchars); - } - else // matching directory only + if(resultbuf.numstrings > 0) // matching file + { + p = resultbuf.strings[0]; + q = resultbuf.strings[resultbuf.numstrings - 1]; + if (dirbuf.numstrings > 0) // and matching directory { - p = dirbuf.strings[0]; - q = dirbuf.strings[dirbuf.numstrings - 1]; - for(; *p && *p == *q; ++p, ++q); - matchchars = (unsigned int)(p - dirbuf.strings[0]); - dp_ustr2stp(temp, sizeof(temp), dirbuf.strings[0], matchchars); + const char *r = dirbuf.strings[0]; + for(; *p && *p == *q && *p == *r; ++p, ++q, ++r); } - // now p points to the first non-equal character, or to the end - // of resultbuf.strings[0]. We want to append the characters - // from resultbuf.strings[0] to (not including) p as these are - // the unique prefix + else + for(; *p && *p == *q; ++p, ++q); + matchchars = (unsigned int)(p - resultbuf.strings[0]); + dp_ustr2stp(temp, sizeof(temp), resultbuf.strings[0], matchchars); } - - resultlen = Con_EscapeSpaces(result, temp, sizeof(result)); - if (appendspace && resultlen < sizeof(result) - 1) + else // matching directory only { - result[resultlen++] = ' '; - result[resultlen] = '\0'; + p = dirbuf.strings[0]; + q = dirbuf.strings[dirbuf.numstrings - 1]; + for(; *p && *p == *q; ++p, ++q); + matchchars = (unsigned int)(p - dirbuf.strings[0]); + dp_ustr2stp(temp, sizeof(temp), dirbuf.strings[0], matchchars); } + // now p points to the first non-equal character, or to the end + // of resultbuf.strings[0]. We want to append the characters + // from resultbuf.strings[0] to (not including) p as these are + // the unique prefix + } - // first move the cursor - linepos += (int)resultlen - (int)strlen(s); + resultlen = Con_EscapeSpaces(result, temp, sizeof(result)); + if (appendspace && resultlen < sizeof(result) - 1) + { + result[resultlen++] = ' '; + result[resultlen] = '\0'; + } - // and now do the actual work - *s = 0; - dp_strlcat(line, result, MAX_INPUTLINE); - dp_strlcat(line, s2, MAX_INPUTLINE); //add back chars after cursor + // first move the cursor + linepos += (int)resultlen - (int)strlen(s); - // and fix the cursor - if(linepos > (int) strlen(line)) - linepos = (int) strlen(line); - } - stringlistfreecontents(&resultbuf); - stringlistfreecontents(&dirbuf); + // and now do the actual work + *s = 0; + dp_strlcat(line, result, MAX_INPUTLINE); + dp_strlcat(line, s2, MAX_INPUTLINE); //add back chars after cursor - return linepos; // bail out, when we complete for a command that wants a file name + // and fix the cursor + if(linepos > (int) strlen(line)) + linepos = (int) strlen(line); } + stringlistfreecontents(&resultbuf); + stringlistfreecontents(&dirbuf); + + return linepos; // bail out, when we complete for a command that wants a file name } } -- 2.39.2