Add %A/%a uppercase/lowercase string format specifiers (#2165)

This commit is contained in:
Rangi authored and GitHub committed 2026-09-26 19:30:05 -04:00
1 parent ed02991af9
commit 6e2e2f1db7
5 files changed
+35 -9

No files matched your search

+3 -1
View File
@@ -251,7 +251,9 @@ Valid types are:
.It Ql b Ta Binary Ta 101010
.It Ql o Ta Octal Ta 52
.It Ql f Ta Fixed-point Ta 1234.56789
.It Ql s Ta String Ta string contents
.It Ql s Ta String Ta String contents
.It Ql A Ta Uppercase string Ta UPPERCASED STRING
.It Ql a Ta Lowercase string Ta lowercased string
.El
.Pp
Examples:
+14 -5
View File
@@ -11,7 +11,8 @@
#include <string.h>
#include <string>
#include "util.hpp" // parseNumber
#include "helpers.hpp" // RANGE
#include "util.hpp" // parseNumber, toUpper, toLower
#include "asm/main.hpp" // options
#include "asm/warning.hpp"
@@ -72,6 +73,8 @@ size_t FormatSpec::parseSpec(char const *spec) {
case 'o':
case 'f':
case 's':
case 'A':
case 'a':
++i;
type = c;
break;
@@ -130,11 +133,17 @@ void FormatSpec::appendString(std::string &str, std::string const &value) const
if (hasPrec) {
error("Formatting string with fractional precision");
}
if (useType != 's') {
if (useType != 's' && useType != 'A' && useType != 'a') {
error("Formatting string as type '%c'", useType);
}
std::string useValue = exact ? escapeString(value) : value;
std::string useValue = value;
if (useType == 'A' || useType == 'a') {
std::transform(RANGE(useValue), useValue.begin(), useType == 'A' ? toUpper : toLower);
}
if (exact) {
useValue = escapeString(useValue);
}
size_t valueLen = useValue.length();
size_t totalLen = width > valueLen ? width : valueLen;
size_t padLen = totalLen - valueLen;
@@ -168,8 +177,8 @@ void FormatSpec::appendNumber(std::string &str, uint32_t value) const {
if (useType != 'f' && hasPrec) {
error("Formatting type '%c' with fractional precision", useType);
}
if (useType == 's') {
error("Formatting number as type 's'");
if (useType == 's' || useType == 'A' || useType == 'a') {
error("Formatting number as type '%c'", useType);
}
char signChar = sign; // 0 or ' ' or '+'
+13
View File
@@ -0,0 +1,13 @@
; ASCII
assert STRUPR("camelCase") === "CAMELCASE"
assert STRLWR("camelCase") === "camelcase"
assert STRFMT("%s", "camelCase") === "camelCase"
assert STRFMT("%A", "camelCase") === "CAMELCASE"
assert STRFMT("%a", "camelCase") === "camelcase"
; UTF-8
assert STRUPR("ÇA a été ?") === "ÇA A éTé ?"
assert STRLWR("ÇA a été ?") === "Ça a été ?"
assert STRFMT("%s", "ÇA a été ?") === "ÇA a été ?"
assert STRFMT("%A", "ÇA a été ?") === "ÇA A éTé ?"
assert STRFMT("%a", "ÇA a été ?") === "Ça a été ?"
+3 -2
View File
@@ -2,7 +2,7 @@ def n equ 300
def m equ -42
def f equ -123.0456
def pi equ 3.14159
def s equs "hello"
def s equs "Hello!"
def t equs "\"\\t\" is '\t'"
def u equs "\t\r\0\n"
@@ -10,7 +10,8 @@ def u equs "\t\r\0\n"
println "<{u:m}> <{+3d:m}> <{#016o:m}>"
println "<{f:pi}> <{06.f:f}> <{.10f:f}>"
println "\"{#-20s:t}\", \"{#20s:t}\", \"{20s:t}\""
println "{#s:u}"
println "{s:s} {A:s} {a:s}"
println "{#s:u} {#A:u} {#a:u}"
macro foo
println "\1 <{\1}>"
+2 -1
View File
@@ -2,5 +2,6 @@
<4294967254> <-42> <&000037777777726>
<3.14159> <-00123> <-123.0455932617>
"\"\\t\" is '\t' ", " \"\\t\" is '\t'", " "\t" is ' '"
\t\r\0\n
Hello! HELLO! hello!
\t\r\0\n \t\r\0\n \t\r\0\n
-6d:n <300 >