summaryrefslogtreecommitdiffstats
path: root/stream.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2015-07-28 20:00:26 -0700
committerKaz Kylheku <kaz@kylheku.com>2015-07-28 20:00:26 -0700
commit4f61ef03a2f9559d93ce43d5a5a5db86cbf33cd5 (patch)
tree36f3936c6d68cdb80406d5df7c93c6578124a1c5 /stream.c
parent0928a2c836681e9f0a91feda3fdae127bfca6b76 (diff)
downloadtxr-4f61ef03a2f9559d93ce43d5a5a5db86cbf33cd5.tar.gz
txr-4f61ef03a2f9559d93ce43d5a5a5db86cbf33cd5.tar.bz2
txr-4f61ef03a2f9559d93ce43d5a5a5db86cbf33cd5.zip
Centered fields in format.
* stream.c (enum align): New enum. (vformat_align_pre, vformat_align_post): New static functions. (vformat_num, vformat_str): Argument left renamed to align, and changed to enum align. vformat_align_pre and vformat_align_post are called to generate the correct padding for left, center and right alignment. (vformat): Two-valued local variable left turned into three-valued align. The ^ prefix on the width field is recognized. * txr.1: Documented ^ width prefix.
Diffstat (limited to 'stream.c')
-rw-r--r--stream.c94
1 files changed, 69 insertions, 25 deletions
diff --git a/stream.c b/stream.c
index 30c77ee3..e84025d5 100644
--- a/stream.c
+++ b/stream.c
@@ -1825,8 +1825,54 @@ static void detect_format_string(void)
}
}
+enum align { al_left, al_center, al_right };
+
+static val vformat_align_pre(val stream, enum align align, int slack)
+{
+ int i;
+
+ switch (align) {
+ case al_right:
+ for (i = 0; i < slack; i++)
+ if (!put_char(chr(' '), stream))
+ return nil;
+ break;
+ case al_left:
+ break;
+ case al_center:
+ for (i = 0; i < slack/2; i++)
+ if (!put_char(chr(' '), stream))
+ return nil;
+ break;
+ }
+
+ return t;
+}
+
+static val vformat_align_post(val stream, enum align align, int slack)
+{
+ int i;
+
+ switch (align) {
+ case al_right:
+ break;
+ case al_left:
+ for (i = 0; i < slack; i++)
+ if (!put_char(chr(' '), stream))
+ return nil;
+ break;
+ case al_center:
+ for (i = 0; i < (slack+1)/2; i++)
+ if (!put_char(chr(' '), stream))
+ return nil;
+ break;
+ }
+
+ return t;
+}
+
static val vformat_num(val stream, const char *str,
- int width, int left, int zeropad,
+ int width, enum align align, int zeropad,
int precision, int sign)
{
int sign_char = (str[0] == '-' || str[0] == '+') ? str[0] : 0;
@@ -1836,10 +1882,8 @@ static val vformat_num(val stream, const char *str,
int slack = (total_len < width) ? width - total_len : 0;
int i;
- if (!left)
- for (i = 0; i < slack; i++)
- if (!put_char(chr(' '), stream))
- return nil;
+ if (!vformat_align_pre(stream, align, slack))
+ return nil;
if (!zeropad)
for (i = 0; i < padlen; i++)
@@ -1862,15 +1906,10 @@ static val vformat_num(val stream, const char *str,
if (!put_char(chr(*str++), stream))
return nil;
- if (left)
- for (i = 0; i < slack; i++)
- if (!put_char(chr(' '), stream))
- return nil;
-
- return t;
+ return vformat_align_post(stream, align, slack);
}
-static val vformat_str(val stream, val str, int width, int left,
+static val vformat_str(val stream, val str, int width, enum align align,
int precision)
{
const wchar_t *cstr = c_str(str);
@@ -1881,7 +1920,10 @@ static val vformat_str(val stream, val str, int width, int left,
prot1(&str);
- if (!left)
+ if (!vformat_align_pre(stream, align, slack))
+ goto nilout;
+
+ if (!al_left)
for (i = 0; i < slack; i++)
if (!put_char(chr(' '), stream))
goto nilout;
@@ -1890,10 +1932,8 @@ static val vformat_str(val stream, val str, int width, int left,
if (!put_char(chr(cstr[i]), stream))
goto nilout;
- if (left)
- for (i = 0; i < slack; i++)
- if (!put_char(chr(' '), stream))
- goto nilout;
+ if (!vformat_align_post(stream, align, slack))
+ goto nilout;
rel1(&str);
return t;
@@ -1917,7 +1957,8 @@ val vformat(val stream, val fmtstr, va_list vl)
vf_init, vf_width, vf_digits, vf_star, vf_precision, vf_spec
} state = vf_init, saved_state = vf_init;
int width = 0, precision = 0, precision_p = 0, digits = 0;
- int left = 0, sign = 0, zeropad = 0;
+ enum align align = al_right;
+ int sign = 0, zeropad = 0;
cnum value;
for (;;) {
@@ -1933,7 +1974,7 @@ val vformat(val stream, val fmtstr, va_list vl)
case '~':
state = vf_width;
width = 0;
- left = 0;
+ align = al_right;
zeropad = 0;
precision = 0;
precision_p = 0;
@@ -1951,7 +1992,10 @@ val vformat(val stream, val fmtstr, va_list vl)
state = vf_init;
continue;
case '<':
- left = 1;
+ align = al_left;
+ continue;
+ case '^':
+ align = al_center;
continue;
case ',':
state = vf_precision;
@@ -2010,7 +2054,7 @@ val vformat(val stream, val fmtstr, va_list vl)
case vf_width:
if (width < 0) {
width = -digits;
- left = 1;
+ align = al_left;
} else {
width = digits;
}
@@ -2134,7 +2178,7 @@ val vformat(val stream, val fmtstr, va_list vl)
}
if (!isdigit(num_buf[0]) && !isdigit(num_buf[1])) {
if (!vformat_str(stream, lit("#<bad-float>"),
- width, left, 0))
+ width, align, 0))
goto nilout;
continue;
}
@@ -2195,7 +2239,7 @@ val vformat(val stream, val fmtstr, va_list vl)
if (!isdigit(num_buf[0]) && !isdigit(num_buf[1])) {
if (!vformat_str(stream, lit("#<bad-float>"),
- width, left, 0))
+ width, align, 0))
goto nilout;
continue;
}
@@ -2206,7 +2250,7 @@ val vformat(val stream, val fmtstr, va_list vl)
if (width != 0 || precision_p) {
val str = format(nil, ch == 'a' ? lit("~a") : lit("~s"),
obj, nao);
- if (!vformat_str(stream, str, width, left, precision))
+ if (!vformat_str(stream, str, width, align, precision))
goto nilout;
continue;
}
@@ -2228,7 +2272,7 @@ val vformat(val stream, val fmtstr, va_list vl)
chr(ch), nao);
output_num:
{
- val res = vformat_num(stream, pnum, width, left,
+ val res = vformat_num(stream, pnum, width, align,
zeropad, precision, sign);
if (pnum != num_buf)
free(pnum);