From 83dc519fc2990c235a10631068c5a4fb07304c60 Mon Sep 17 00:00:00 2001 From: Ari Johnson Date: Tue, 20 Feb 2007 22:00:50 +0000 Subject: [PATCH] center() can have multi-character fills and different left and right fills --- game/txt/hlp/cobra_func.hlp | 23 +++++++--- hdrs/externs.h | 1 + src/function.c | 2 +- src/funstr.c | 85 ++++++++++++++++++++++++------------- src/strutil.c | 25 +++++++++++ 5 files changed, 98 insertions(+), 38 deletions(-) diff --git a/game/txt/hlp/cobra_func.hlp b/game/txt/hlp/cobra_func.hlp index 40f8bec..68ca47b 100644 --- a/game/txt/hlp/cobra_func.hlp +++ b/game/txt/hlp/cobra_func.hlp @@ -600,17 +600,26 @@ See also: floor(), bound(), round(), trunc() & CENTER() - center(,[,]) - + center(,[,[,]]) + This function will center within a field characters wide, - using characters for padding on either end of the string for - centering. If is not specified, a space will be used. - + using the string for padding on the left side of the string, + and for padding on the right side. defaults + to the mirror-image of if not specified. defaults to + a space if neither nor are specified. + + If divides into uneven portions, the left side + will be one character shorter than the right side. + Example: > say center(X,5,-) You say, "--X--" - > say center(.NEAT.,15) - You say, " .NEAT. " + > say center(X,5,-=) + You say, "-=X=-" + > say center(.NEAT.,15,-,=) + You say, "----.NEAT.=====" + > say center(hello,16,12345) + You say, "12345hello543215" & CHECKPASS() checkpass(,) diff --git a/hdrs/externs.h b/hdrs/externs.h index c8b535f..d7567e6 100644 --- a/hdrs/externs.h +++ b/hdrs/externs.h @@ -451,6 +451,7 @@ strdup(const char *s) extern ansi_string *parse_ansi_string(const char *src) __attribute_malloc__; + extern void flip_ansi_string(ansi_string *as); extern void free_ansi_string(ansi_string *as); extern void populate_codes(ansi_string *as); extern void depopulate_codes(ansi_string *as); diff --git a/src/function.c b/src/function.c index 3eef453..a8fde26 100644 --- a/src/function.c +++ b/src/function.c @@ -312,7 +312,7 @@ FUNTAB flist[] = { {"CTITLE", fun_ctitle, 2, 2, FN_REG}, {"CWHO", fun_cwho, 1, 1, FN_REG}, #endif /* CHAT_SYSTEM */ - {"CENTER", fun_center, 2, 3, FN_REG}, + {"CENTER", fun_center, 2, 4, FN_REG}, {"CHILDREN", fun_lsearch, 1, 1, FN_REG}, {"CHR", fun_chr, 1, 1, FN_REG}, {"CHECKPASS", fun_checkpass, 2, 2, FN_REG | FN_DIRECTOR}, diff --git a/src/funstr.c b/src/funstr.c index 250c78b..0d25492 100644 --- a/src/funstr.c +++ b/src/funstr.c @@ -606,25 +606,9 @@ FUNCTION(fun_strcat) FUNCTION(fun_flip) { ansi_string *as; - int p, n; - as = parse_ansi_string(args[0]); - populate_codes(as); - - for (p = 0, n = as->len - 1; p < n; p++, n--) { - char *tcode; - char t; - - tcode = as->codes[p]; - t = as->text[p]; - as->codes[p] = as->codes[n]; - as->text[p] = as->text[n]; - as->codes[n] = tcode; - as->text[n] = t; - } - + flip_ansi_string(as); safe_ansi_string(as, 0, as->len, buff, bp); - free_ansi_string(as); } @@ -931,10 +915,11 @@ FUNCTION(fun_rjust) /* ARGSUSED */ FUNCTION(fun_center) { - /* pads a string with leading blanks (or other fill character) */ - - size_t width, len, lsp, rsp; - char sep; + /* pads a string with leading blanks (or other fill string) */ + size_t width, len, lsp, rsp, filllen; + int fillq, fillr, i; + char fillstr[BUFFER_LEN], *fp; + ansi_string *as; if (!is_uinteger(args[1])) { safe_str(T(e_uint), buff, bp); @@ -946,20 +931,60 @@ FUNCTION(fun_center) safe_strl(args[0], arglens[0], buff, bp); return; } - rsp = width - len; - lsp = rsp / 2; - rsp -= lsp; + lsp = rsp = (width - len) / 2; + rsp += (width - len) % 2; if (lsp >= BUFFER_LEN) - lsp = BUFFER_LEN - 1; - if (rsp >= BUFFER_LEN) - rsp = BUFFER_LEN - 1; + lsp = rsp = BUFFER_LEN - 1; - if (!delim_check(buff, bp, nargs, args, 3, &sep)) + if (!args[2] || !*args[2]) { + /* Fast case for default fill with spaces */ + safe_fill(' ', lsp, buff, bp); + safe_strl(args[0], arglens[0], buff, bp); + safe_fill(' ', rsp, buff, bp); return; + } - safe_fill(sep, lsp, buff, bp); + /* args[2] contains the possibly ansi, multi-char fill string */ + filllen = ansi_strlen(args[2]); + as = parse_ansi_string(args[2]); + fillq = lsp / filllen; + fillr = lsp % filllen; + fp = fillstr; + for (i = 0; i < fillq; i++) + safe_ansi_string(as, 0, as->len, fillstr, &fp); + safe_ansi_string(as, 0, fillr, fillstr, &fp); + *fp = '\0'; + free_ansi_string(as); + safe_str(fillstr, buff, bp); safe_strl(args[0], arglens[0], buff, bp); - safe_fill(sep, rsp, buff, bp); + /* If we have args[3], that's the right-side fill string */ + if (nargs > 3) { + if (args[3] && *args[3]) { + filllen = ansi_strlen(args[3]); + as = parse_ansi_string(args[3]); + fillq = rsp / filllen; + fillr = rsp % filllen; + fp = fillstr; + for (i = 0; i < fillq; i++) + safe_ansi_string(as, 0, as->len, fillstr, &fp); + safe_ansi_string(as, 0, fillr, fillstr, &fp); + *fp = '\0'; + free_ansi_string(as); + safe_str(fillstr, buff, bp); + } else { + /* Null args[3], fill right side with spaces */ + safe_fill(' ', rsp, buff, bp); + } + return; + } + /* No args[3], so we flip args[2] */ + as = parse_ansi_string(fillstr); + flip_ansi_string(as); + safe_ansi_string(as, 0, as->len, buff, bp); + /* Is there an extra char left over we need to pad with? */ + if (rsp > lsp) + safe_ansi_string(as, 0, 1, buff, bp); + free_ansi_string(as); } /* ARGSUSED */ diff --git a/src/strutil.c b/src/strutil.c index 2d6e605..4eaa680 100644 --- a/src/strutil.c +++ b/src/strutil.c @@ -1626,6 +1626,31 @@ depopulate_codes(ansi_string *as) } } +/** Reverse an ansi string, preserving its ansification. + * This function destructively modifies the ansi_string passed. + * \param as pointer to an ansi string. + */ +void +flip_ansi_string(ansi_string *as) +{ + int p, n; + + populate_codes(as); + + for (p = 0, n = as->len - 1; p < n; p++, n--) { + char *tcode; + char t; + + tcode = as->codes[p]; + t = as->text[p]; + as->codes[p] = as->codes[n]; + as->text[p] = as->text[n]; + as->codes[n] = tcode; + as->text[n] = t; + } +} + + static int is_ansi_code(const char *s); static int is_start_html_code(const char *s) __attribute__ ((__unused__)); static int is_end_html_code(const char *s); -- 2.30.2