OSDN Git Service

[Refactor] vstrnfmt の整形
authorHabu <habu1010+github@gmail.com>
Tue, 27 Dec 2022 13:43:10 +0000 (22:43 +0900)
committerHabu <habu1010+github@gmail.com>
Wed, 28 Dec 2022 11:10:19 +0000 (20:10 +0900)
- 変数の宣言と代入を同時に行う
- 書式シーケンスを格納する aux を char 型配列から std::string に変更
- 自明なコメントを削除

src/term/z-form.cpp

index 2c7e89b..e5998e5 100644 (file)
@@ -13,6 +13,7 @@
 #include "term/z-form.h"
 #include "term/z-util.h"
 #include "term/z-virt.h"
+#include <span>
 #include <vector>
 
 /*
  */
 uint vstrnfmt(char *buf, uint max, concptr fmt, va_list vp)
 {
-    concptr s;
-
-    /* The argument is "long" */
-    bool do_long;
-
-    /* The argument is "long long" */
-    bool do_long_long;
-
-    /* The argument needs "processing" */
-    bool do_xtra;
-
-    /* Bytes used in buffer */
-    uint n;
-
-    /* Bytes used in format sequence */
-    uint q;
-
-    /* Format sequence */
-    char aux[128];
-
-    /* Resulting string */
-    char tmp[1024];
-
-    /* Mega-Hack -- treat "illegal" length as "infinite" */
-    if (!max) {
-        max = 32767;
-    }
-
-    /* Mega-Hack -- treat "no format" as "empty string" */
-    if (!fmt) {
-        fmt = "";
+    /* treat "no format" or "illegal" length as "empty string" */
+    if (!fmt || (max == 0)) {
+        buf[0] = '\0';
+        return 0;
     }
 
-    /* Begin the buffer */
-    n = 0;
-
-    /* Begin the format string */
-    s = fmt;
-
-    /* Scan the format string */
-    while (true) {
-        /* All done */
-        if (!*s) {
-            break;
-        }
+    /* Output length to buffer */
+    auto n = 0U;
 
+    for (auto s = fmt; *s != '\0';) {
         /* Normal character */
         if (*s != '%') {
-            /* Check total length */
             if (n == max - 1) {
                 break;
             }
 
-            /* Save the character */
             buf[n++] = *s++;
             continue;
         }
 
-        /* Skip the "percent" */
         s++;
 
         /* Pre-process "%%" */
         if (*s == '%') {
-            /* Check total length */
             if (n == max - 1) {
                 break;
             }
 
-            /* Save the percent */
             buf[n++] = '%';
-
-            /* Skip the "%" */
             s++;
             continue;
         }
 
         /* Pre-process "%n" */
         if (*s == 'n') {
-            int *arg;
-
-            /* Access the next argument */
-            arg = va_arg(vp, int *);
-
             /* Save the current length */
+            auto *arg = va_arg(vp, int *);
             (*arg) = n;
 
-            /* Skip the "n" */
             s++;
             continue;
         }
 
-        /* Begin the "aux" string */
-        q = 0;
+        auto do_long = false;
+        auto do_long_long = false;
+        auto do_capitalize = false;
 
-        /* Save the "percent" */
-        aux[q++] = '%';
+        /* Format sequence */
+        std::string aux;
+        aux.reserve(128);
+        aux.push_back('%');
 
-        /* Assume no "long" argument */
-        do_long = false;
-
-        /* Assume no "long long" argument */
-        do_long_long = false;
-
-        /* Assume no "xtra" processing */
-        do_xtra = false;
-
-        /* Build the "aux" string */
+        /* Build the format sequence string */
         while (true) {
             /* Error -- format sequence is not terminated */
-            if (!*s) {
-                /* Terminate the buffer */
+            if (*s == '\0') {
                 buf[0] = '\0';
-
-                /* Return "error" */
                 return 0;
             }
 
             /* Error -- format sequence may be too long */
-            if (q > 100) {
-                /* Terminate the buffer */
+            if (aux.length() > 100) {
                 buf[0] = '\0';
-
-                /* Return "error" */
                 return 0;
             }
 
-            /* Handle "alphabetic" chars */
             if (isalpha(*s)) {
-                /* Hack -- handle "long" request */
+                /* handle "long" request */
                 if (*s == 'l') {
-                    /* Save the character */
-                    aux[q++] = *s++;
-
-                    /* Note the "long" flag */
+                    aux.push_back(*s++);
                     do_long = true;
                 }
 
-                /* Mega-Hack -- handle "extra-long" request */
+                /* handle "extra-long" request */
                 else if (*s == 'L') {
-                    /* Save the character */
-                    aux[q++] = 'l';
-                    aux[q++] = 'l';
-                    s++;
-
-                    /* Note the "long long" flag */
+                    aux.append("ll");
                     do_long_long = true;
+                    s++;
                 }
 
                 /* Handle normal end of format sequence */
                 else {
-                    /* Save the character */
-                    aux[q++] = *s++;
-
-                    /* Stop processing the format sequence */
+                    aux.push_back(*s++);
                     break;
                 }
-            }
-
-            /* Handle "non-alphabetic" chars */
-            else {
-                /* Hack -- Handle 'star' (for "variable length" argument) */
+            } else {
+                /* Handle 'star' (for "variable length" argument) */
                 if (*s == '*') {
-                    int arg;
-
-                    /* Access the next argument */
-                    arg = va_arg(vp, int);
-
-                    /* Hack -- append the "length" */
-                    snprintf(aux + q, sizeof(aux) - q, "%d", arg);
-
-                    /* Hack -- accept the "length" */
-                    while (aux[q]) {
-                        q++;
-                    }
-
-                    /* Skip the "*" */
+                    auto arg = va_arg(vp, int);
+                    aux.append(std::to_string(arg));
                     s++;
                 }
 
-                /* Mega-Hack -- Handle 'caret' (for "uppercase" request) */
+                /* Handle 'caret' (for "uppercase" request) */
                 else if (*s == '^') {
-                    /* Note the "xtra" flag */
-                    do_xtra = true;
-
-                    /* Skip the "^" */
+                    do_capitalize = true;
                     s++;
                 }
 
                 /* Collect "normal" characters (digits, "-", "+", ".", etc) */
                 else {
-                    /* Save the character */
-                    aux[q++] = *s++;
+                    aux.push_back(*s++);
                 }
             }
         }
 
-        /* Terminate "aux" */
-        aux[q] = '\0';
-
-        /* Clear "tmp" */
-        tmp[0] = '\0';
+        /* Resulting string */
+        char tmp[1024]{};
 
         /* Process the "format" char */
-        switch (aux[q - 1]) {
+        switch (aux.back()) {
         /* Simple Character -- standard format */
         case 'c': {
-            int arg;
-
-            /* Access next argument */
-            arg = va_arg(vp, int);
-
-            /* Format the argument */
+            auto arg = va_arg(vp, int);
             snprintf(tmp, sizeof(tmp), "%c", arg);
-
             break;
         }
 
@@ -405,31 +307,15 @@ uint vstrnfmt(char *buf, uint max, concptr fmt, va_list vp)
         case 'd':
         case 'i': {
             if (do_long) {
-                long arg;
-
-                /* Access next argument */
-                arg = va_arg(vp, long);
-
-                /* Format the argument */
-                snprintf(tmp, sizeof(tmp), aux, arg);
+                auto arg = va_arg(vp, long);
+                snprintf(tmp, sizeof(tmp), aux.data(), arg);
             } else if (do_long_long) {
-                long long arg;
-
-                /* Access next argument */
-                arg = va_arg(vp, long long);
-
-                /* Format the argument */
-                snprintf(tmp, sizeof(tmp), aux, arg);
+                auto arg = va_arg(vp, long long);
+                snprintf(tmp, sizeof(tmp), aux.data(), arg);
             } else {
-                int arg;
-
-                /* Access next argument */
-                arg = va_arg(vp, int);
-
-                /* Format the argument */
-                snprintf(tmp, sizeof(tmp), aux, arg);
+                auto arg = va_arg(vp, int);
+                snprintf(tmp, sizeof(tmp), aux.data(), arg);
             }
-
             break;
         }
 
@@ -439,27 +325,15 @@ uint vstrnfmt(char *buf, uint max, concptr fmt, va_list vp)
         case 'x':
         case 'X': {
             if (do_long) {
-                ulong arg;
-
-                /* Access next argument */
-                arg = va_arg(vp, ulong);
-
-                snprintf(tmp, sizeof(tmp), aux, arg);
+                auto arg = va_arg(vp, unsigned long);
+                snprintf(tmp, sizeof(tmp), aux.data(), arg);
             } else if (do_long_long) {
-                unsigned long long arg;
-
-                /* Access next argument */
-                arg = va_arg(vp, unsigned long long);
-
-                snprintf(tmp, sizeof(tmp), aux, arg);
+                auto arg = va_arg(vp, unsigned long long);
+                snprintf(tmp, sizeof(tmp), aux.data(), arg);
             } else {
-                uint arg;
-
-                /* Access next argument */
-                arg = va_arg(vp, uint);
-                snprintf(tmp, sizeof(tmp), aux, arg);
+                auto arg = va_arg(vp, unsigned int);
+                snprintf(tmp, sizeof(tmp), aux.data(), arg);
             }
-
             break;
         }
 
@@ -470,98 +344,64 @@ uint vstrnfmt(char *buf, uint max, concptr fmt, va_list vp)
         case 'E':
         case 'g':
         case 'G': {
-            double arg;
-
-            /* Access next argument */
-            arg = va_arg(vp, double);
-
-            /* Format the argument */
-            snprintf(tmp, sizeof(tmp), aux, arg);
-
+            auto arg = va_arg(vp, double);
+            snprintf(tmp, sizeof(tmp), aux.data(), arg);
             break;
         }
 
         /* Pointer -- implementation varies */
         case 'p': {
-            vptr arg;
-
-            /* Access next argument */
-            arg = va_arg(vp, vptr);
-
-            /* Format the argument */
-            snprintf(tmp, sizeof(tmp), aux, arg);
-
+            auto arg = va_arg(vp, void *);
+            snprintf(tmp, sizeof(tmp), aux.data(), arg);
             break;
         }
 
         /* String */
         case 's': {
-            concptr arg;
-            char arg2[1024];
-
-            /* Access next argument */
-            arg = va_arg(vp, concptr);
-
-            /* Hack -- convert nullptr to EMPTY */
-            if (!arg) {
+            auto arg = va_arg(vp, const char *);
+            if (arg == nullptr) {
                 arg = "";
             }
-
-            /* Prevent buffer overflows */
-            strncpy(arg2, arg, 1024);
-            arg2[1023] = '\0';
-
-            /* Format the argument */
-            snprintf(tmp, sizeof(tmp), aux, arg);
-
+            snprintf(tmp, sizeof(tmp), aux.data(), arg);
             break;
         }
 
         default: {
             /* Error -- illegal format char */
             buf[0] = '\0';
-
-            /* Return "error" */
             return 0;
         }
         }
 
+        std::span<char> formatted_str(std::begin(tmp), strlen(tmp));
 #ifdef JP
-        for (q = 0; tmp[q]; q++) {
-            if (iskanji(tmp[q])) {
-                do_xtra = false;
+        for (auto ch : formatted_str) {
+            if (iskanji(ch)) {
+                do_capitalize = false;
                 break;
             }
         }
 #endif
-        /* Mega-Hack -- handle "capitilization" */
-        if (do_xtra) {
-            /* Now append "tmp" to "buf" */
-            for (q = 0; tmp[q]; q++) {
-                /* Notice first non-space */
-                if (!iswspace(tmp[q])) {
-                    /* Capitalize if possible */
-                    if (islower(tmp[q])) {
-                        tmp[q] = (char)toupper(tmp[q]);
+        if (do_capitalize) {
+            for (auto &ch : formatted_str) {
+                if (!iswspace(ch)) {
+                    if (islower(ch)) {
+                        ch = static_cast<char>(toupper(ch));
                     }
-
                     break;
                 }
             }
         }
 
-        /* Now append "tmp" to "buf" */
-        for (q = 0; tmp[q]; q++) {
-            /* Check total length */
+        /* Now append formatted_str to "buf" */
+        for (auto it = formatted_str.begin(), it_end = formatted_str.end(); it != it_end;) {
             if (n == max - 1) {
                 break;
             }
-
-            /* Save the character */
 #ifdef JP
-            if (iskanji(tmp[q])) {
-                if (tmp[q + 1]) {
-                    buf[n++] = tmp[q++];
+            if (iskanji(*it)) {
+                if ((n < max - 2) && ((it + 1) != it_end)) {
+                    buf[n++] = *it++;
                 } else {
                     // 最後の文字が2バイト文字の前半で終わる場合は空白で置き換えて終了する
                     buf[n++] = ' ';
@@ -569,14 +409,11 @@ uint vstrnfmt(char *buf, uint max, concptr fmt, va_list vp)
                 }
             }
 #endif
-            buf[n++] = tmp[q];
+            buf[n++] = *it++;
         }
     }
 
-    /* Terminate buffer */
     buf[n] = '\0';
-
-    /* Return length */
     return n;
 }