Skip to content

Commit 6a5d01c

Browse files
authored
Merge pull request #33 from ryancdotorg/ryancdotorg/non_str_funcs
remove snprintf/strncat/strlen from fp_ident
2 parents 5602f64 + 1519aa1 commit 6a5d01c

File tree

3 files changed

+85
-10
lines changed

3 files changed

+85
-10
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,5 @@ mtest
3131
stest
3232
rsatest
3333
timing
34+
ident
3435
*.exe

makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ testme: test mtest
8686
timing: $(LIBNAME) demo/timing.o
8787
$(CC) $(CFLAGS) demo/timing.o $(LIBNAME) $(PROF) -o timing
8888

89+
ident: $(LIBNAME)
90+
$(CC) $(CFLAGS) -DSTANDALONE src/misc/fp_ident.c $(LIBNAME) $(PROF) -o ident
91+
8992
profiled:
9093
CC="$(CC)" CROSS_COMPILE="${CROSS_COMPILE} CFLAGS="${CFLAGS} -fprofile-generate" MAKE=${MAKE} ${MAKE} timing
9194
./test

src/misc/fp_ident.c

Lines changed: 81 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,77 @@
66
#define GIT_VERSION TFM_VERSION_S
77
#endif
88

9+
#define dnstrcon_direct(D, N, S) do { dnmemcpy((D), (N), S, sizeof(S)-1); } while(0)
10+
#define dnstrcon(D, N, S) do { if (dnmemcpy((D), (N), S, sizeof(S)-1) == -1) goto err_out; } while(0)
11+
static signed long dnmemcpy(char **d, size_t *n, const char *s, size_t len) {
12+
if (len >= *n) return -1;
13+
memcpy(*d, s, len);
14+
*n -= len;
15+
*d += len;
16+
**d = '\0';
17+
return len;
18+
}
19+
20+
/* log(2)/log(10) ~= 0.30102999... ~= 30103 / 100000
21+
* we need to add one byte because this rounds to zero, and one for sign
22+
* these provide exact answer for integers up to 4720 bytes wide... */
23+
#define U_DIGITS(T) (1 + ((sizeof(T) * 8UL) * 30103UL) / 100000UL)
24+
#define S_DIGITS(T) (2 + ((sizeof(T) * 8UL - 1) * 30103UL) / 100000UL)
25+
26+
#define dnstrul(D, N, V) do { if (dnstrul_impl((D), (N), (V)) == -1) goto err_out; } while(0)
27+
static signed long dnstrul_impl(char **d, size_t *n, unsigned long value) {
28+
char digits[U_DIGITS(unsigned long)+1]; /* fit digits plus null byte */
29+
char *digit = digits + (sizeof(digits) - 1);
30+
size_t len = 0;
31+
*digit = '\0';
32+
do {
33+
*--digit = '0' + (value % 10);
34+
value /= 10;
35+
++len;
36+
if (digit < digits) return -1;
37+
} while (value);
38+
if (len >= *n) return -1;
39+
return dnmemcpy(d, n, digit, len);
40+
}
41+
942
const char *fp_ident(void)
1043
{
11-
static char buf[1024];
44+
static char buf[512];
45+
char *d = buf;
46+
size_t n = sizeof(buf);
1247

13-
memset(buf, 0, sizeof(buf));
14-
snprintf(buf, sizeof(buf)-1,
48+
dnstrcon(&d, &n,
1549
"TomsFastMath " GIT_VERSION "\n"
1650
#if defined(TFM_IDENT_BUILD_DATE)
1751
"Built on " __DATE__ " at " __TIME__ "\n"
1852
#endif
1953
"\n"
2054
"Sizeofs\n"
21-
"\tfp_digit = %lu\n"
22-
"\tfp_word = %lu\n"
55+
"\tfp_digit = "
56+
);
57+
dnstrul(&d, &n, sizeof(fp_digit));
58+
dnstrcon(&d, &n,
59+
"\n"
60+
"\tfp_word = "
61+
);
62+
dnstrul(&d, &n, sizeof(fp_word));
63+
dnstrcon(&d, &n,
64+
"\n\n"
65+
"FP_MAX_SIZE = "
66+
);
67+
dnstrul(&d, &n, FP_MAX_SIZE);
68+
dnstrcon(&d, &n,
2369
"\n"
24-
"FP_MAX_SIZE = %u\n"
70+
"SIZEOF_FP_DIGIT = "
71+
);
72+
dnstrul(&d, &n, SIZEOF_FP_DIGIT);
73+
dnstrcon(&d, &n,
2574
"\n"
75+
"DIGIT_SHIFT = "
76+
);
77+
dnstrul(&d, &n, DIGIT_SHIFT);
78+
dnstrcon(&d, &n,
79+
"\n\n"
2680
"Defines: \n"
2781
#ifdef __i386__
2882
" __i386__ "
@@ -70,20 +124,37 @@ const char *fp_ident(void)
70124
#ifdef TFM_HUGE
71125
" TFM_HUGE "
72126
#endif
73-
"\n", (unsigned long)sizeof(fp_digit), (unsigned long)sizeof(fp_word), FP_MAX_SIZE);
127+
"\n"
128+
);
74129

75130
if (sizeof(fp_digit) == sizeof(fp_word)) {
76-
strncat(buf, "WARNING: sizeof(fp_digit) == sizeof(fp_word), this build is likely to not work properly.\n",
77-
sizeof(buf) - strlen(buf) - 1);
131+
dnstrcon(&d, &n,
132+
"WARNING: sizeof(fp_digit) == sizeof(fp_word),"
133+
" this build is likely to not work properly.\n"
134+
);
78135
}
136+
137+
memset(d, 0, n);
138+
return buf;
139+
err_out:
140+
d = buf;
141+
n = sizeof(buf);
142+
*d = '\0';
143+
144+
dnstrcon_direct(&d, &n,
145+
"ERROR: Buffer too small.\n"
146+
);
147+
79148
return buf;
80149
}
81150

82151
#ifdef STANDALONE
83152

84153
int main(void)
85154
{
86-
printf("%s\n", fp_ident());
155+
const char* ident = fp_ident();
156+
printf("%s\n", ident);
157+
printf("ident len: %lu\n", (unsigned long)strlen(ident));
87158
return 0;
88159
}
89160

0 commit comments

Comments
 (0)