Take strings into account when printing widths
diff --git a/include/num.h b/include/num.h
index 58442e8..684bc28 100644
--- a/include/num.h
+++ b/include/num.h
@@ -97,9 +97,9 @@
// ** Exclude start. **
BcStatus bc_num_parse(BcNum *n, const char *val, BcNum *base, size_t base_t);
-BcStatus bc_num_print(BcNum *n, BcNum *base, size_t base_t, bool newline);
+BcStatus bc_num_print(BcNum *n, BcNum *base, size_t base_t, bool newline, size_t *nchars);
BcStatus bc_num_fprint(BcNum *n, BcNum *base, size_t base_t,
- bool newline, FILE *f);
+ bool newline, size_t *nchars, FILE *f);
// ** Exclude end. **
extern const char bc_num_hex_digits[];
diff --git a/include/program.h b/include/program.h
index 82af4ba..40bc097 100644
--- a/include/program.h
+++ b/include/program.h
@@ -77,6 +77,8 @@
char *num_buf;
size_t buf_size;
+ size_t nchars;
+
} BcProgram;
#define BC_PROGRAM_CHECK_STACK(p) ((p)->stack.len > 1)
diff --git a/src/bc/num.c b/src/bc/num.c
index d1be48e..0ea605e 100644
--- a/src/bc/num.c
+++ b/src/bc/num.c
@@ -1310,49 +1310,45 @@
return BC_STATUS_SUCCESS;
}
-static BcStatus bc_num_printDecimal(BcNum *n, FILE *f) {
+static BcStatus bc_num_printDecimal(BcNum *n, size_t *nchars, FILE *f) {
BcStatus status;
size_t i;
- size_t nchars;
bool radix;
- nchars = 0;
-
if (n->neg) {
if (fputc('-', f) == EOF) return BC_STATUS_IO_ERR;
- ++nchars;
+ ++(*nchars);
}
status = BC_STATUS_SUCCESS;
for (i = n->len - 1; !status && i >= n->rdx && i < n->len; --i)
- status = bc_num_printHex(n->num[i], 1, false, &nchars, f);
+ status = bc_num_printHex(n->num[i], 1, false, nchars, f);
if (status || !n->rdx) return status;
for (radix = true; !status && i < n->len; --i, radix = false)
- status = bc_num_printHex(n->num[i], 1, radix, &nchars, f);
+ status = bc_num_printHex(n->num[i], 1, radix, nchars, f);
return status;
}
-static BcStatus bc_num_printBase(BcNum *n, BcNum *base, size_t base_t, FILE* f) {
-
+static BcStatus bc_num_printBase(BcNum *n, BcNum *base, size_t base_t,
+ size_t *nchars, FILE* f)
+{
BcStatus status;
BcVec stack;
BcNum intp;
BcNum fracp;
BcNum digit;
BcNum frac_len;
- size_t nchars;
size_t width;
BcNumDigitFunc print;
unsigned long dig;
size_t i;
bool neg, radix;
- nchars = 0;
neg = n->neg;
n->neg = false;
@@ -1423,7 +1419,7 @@
ptr = bc_vec_item_rev(&stack, i);
- status = print(*ptr, width, false, &nchars, f);
+ status = print(*ptr, width, false, nchars, f);
if (status) goto frac_len_err;
}
@@ -1454,7 +1450,7 @@
if (status) goto err;
- status = print(dig, width, radix, &nchars, f);
+ status = print(dig, width, radix, nchars, f);
if (status) goto err;
@@ -1585,7 +1581,7 @@
}
BcStatus bc_num_fprint(BcNum *n, BcNum *base, size_t base_t,
- bool newline, FILE *f)
+ bool newline, size_t *nchars, FILE *f)
{
BcStatus status;
@@ -1594,24 +1590,34 @@
if (base_t < BC_NUM_MIN_BASE || base_t > BC_BASE_MAX_DEF)
return BC_STATUS_EXEC_INVALID_OBASE;
+ if (*nchars >= BC_NUM_PRINT_WIDTH) {
+ if (fputc('\\', f) == EOF) return BC_STATUS_IO_ERR;
+ if (fputc('\n', f) == EOF) return BC_STATUS_IO_ERR;
+ *nchars = 0;
+ }
+
if (!n->len) {
if (fputc('0', f) == EOF) return BC_STATUS_IO_ERR;
+ ++(*nchars);
status = BC_STATUS_SUCCESS;
}
- else if (base_t == 10) status = bc_num_printDecimal(n, f);
- else status = bc_num_printBase(n, base, base_t, f);
+ else if (base_t == 10) status = bc_num_printDecimal(n, nchars, f);
+ else status = bc_num_printBase(n, base, base_t, nchars, f);
if (status) return status;
if (newline) {
if (fputc('\n', f) == EOF) return BC_STATUS_IO_ERR;
+ *nchars = 0;
}
return status;
}
-BcStatus bc_num_print(BcNum *n, BcNum *base, size_t base_t, bool newline) {
- return bc_num_fprint(n, base, base_t, newline, stdout);
+BcStatus bc_num_print(BcNum *n, BcNum *base, size_t base_t,
+ bool newline, size_t *nchars)
+{
+ return bc_num_fprint(n, base, base_t, newline, nchars, stdout);
}
BcStatus bc_num_long(BcNum *n, long *result) {
diff --git a/src/bc/program.c b/src/bc/program.c
index 6278eee..231e928 100644
--- a/src/bc/program.c
+++ b/src/bc/program.c
@@ -555,7 +555,7 @@
return status;
}
-static BcStatus bc_program_printString(const char *str) {
+static BcStatus bc_program_printString(const char *str, size_t *nchars) {
char c;
char c2;
@@ -566,7 +566,7 @@
len = strlen(str);
- for (i = 0; i < len; ++i) {
+ for (i = 0; i < len; ++i, ++(*nchars)) {
c = str[i];
@@ -608,6 +608,7 @@
case 'n':
{
err = fputc('\n', stdout);
+ *nchars = SIZE_MAX;
break;
}
@@ -1297,6 +1298,8 @@
name = NULL;
+ p->nchars = 0;
+
#ifdef _POSIX_BC_BASE_MAX
p->base_max = _POSIX_BC_BASE_MAX;
#elif defined(_BC_BASE_MAX)
@@ -1675,7 +1678,6 @@
BcStatus status;
uint8_t *code;
size_t idx;
- int pchars;
BcResult result;
BcFunc *func;
BcInstPtr *ip;
@@ -1845,7 +1847,7 @@
if (status) return status;
status = bc_num_print(num, &p->obase, p->obase_t,
- inst == BC_INST_PRINT);
+ inst == BC_INST_PRINT, &p->nchars);
if (status) return status;
@@ -1861,6 +1863,8 @@
case BC_INST_STR:
{
const char **string;
+ const char *s;
+ size_t len;
idx = bc_program_index(code, &ip->idx);
@@ -1870,9 +1874,15 @@
if (!string) return BC_STATUS_EXEC_INVALID_STRING;
- pchars = fprintf(stdout, "%s", *string);
- status = pchars > 0 ? BC_STATUS_SUCCESS :
- BC_STATUS_EXEC_PRINT_ERR;
+ s = *string;
+ len = strlen(s);
+
+ for (idx = 0; idx < len; ++idx) {
+ char c = s[idx];
+ if (fputc(c, stdout) == EOF) return BC_STATUS_IO_ERR;
+ if (c == '\n') p->nchars = SIZE_MAX;
+ ++p->nchars;
+ }
break;
}
@@ -1889,7 +1899,7 @@
if (!string) return BC_STATUS_EXEC_INVALID_STRING;
- status = bc_program_printString(*string);
+ status = bc_program_printString(*string, &p->nchars);
break;
}