From 40bba8865b2d5328e5cdd4c0a7044c9eb2de00bd Mon Sep 17 00:00:00 2001 From: leitner Date: Sun, 27 Apr 2003 16:11:47 +0000 Subject: [PATCH] add fmt_human, fmt_humank and fmt_httpdate --- CHANGES | 1 + fmt.h | 6 ++++++ fmt/fmt_httpdate.3 | 17 +++++++++++++++++ fmt/fmt_httpdate.c | 35 +++++++++++++++++++++++++++++++++++ fmt/fmt_human.3 | 22 ++++++++++++++++++++++ fmt/fmt_human.c | 6 ++++-- fmt/fmt_humank.3 | 22 ++++++++++++++++++++++ fmt/fmt_humank.c | 2 +- test/fmt_httpdate.c | 8 ++++++++ test/fmt_human.c | 10 ++++++++++ 10 files changed, 126 insertions(+), 3 deletions(-) create mode 100644 fmt/fmt_httpdate.3 create mode 100644 fmt/fmt_httpdate.c create mode 100644 fmt/fmt_human.3 create mode 100644 fmt/fmt_humank.3 create mode 100644 test/fmt_httpdate.c create mode 100644 test/fmt_human.c diff --git a/CHANGES b/CHANGES index 2375164..cf9365c 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,7 @@ add stralloc versions of textcode API (Kai Ruemmler) add html to textcode ('<' to '<' etc) add fmt_human and fmt_humank (format numbers ala ls -H/-h) + add fmt_httpdate 0.14: avoid bus errors in byte_copy diff --git a/fmt.h b/fmt.h index 9a41c69..e50b3b6 100644 --- a/fmt.h +++ b/fmt.h @@ -1,6 +1,9 @@ #ifndef FMT_H #define FMT_H +/* for time_t: */ +#include + #define FMT_LONG 41 /* enough space to hold -2^127 in decimal, plus \0 */ #define FMT_ULONG 40 /* enough space to hold 2^128 - 1 in decimal, plus \0 */ #define FMT_8LONG 44 /* enough space to hold 2^128 - 1 in octal, plus \0 */ @@ -75,4 +78,7 @@ unsigned int fmt_human(char* dest,unsigned long long l); /* 1 -> "1", 4900 -> "4.8k", 2300000 -> "2.2M" */ unsigned int fmt_humank(char* dest,unsigned long long l); +/* "Sun, 06 Nov 1994 08:49:37 GMT" */ +unsigned int fmt_httpdate(char* dest,time_t t); + #endif diff --git a/fmt/fmt_httpdate.3 b/fmt/fmt_httpdate.3 new file mode 100644 index 0000000..a51a65c --- /dev/null +++ b/fmt/fmt_httpdate.3 @@ -0,0 +1,17 @@ +.TH fmt_httpdate 3 +.SH NAME +fmt_httpdate \- write a date in ASCII as in the HTTP protocol +.SH SYNTAX +.B #include + +unsigned int \fBfmt_httpdate\fP(char *\fIdest\fR,time_t \fIsource\fR); +.SH DESCRIPTION +fmt_httpdate writes a date in ASCII representation as the HTTP protocol defines it: +"Sun, 06 Nov 1994 08:49:37 GMT". + +fmt_httpdate does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_httpdate returns the number +of bytes it would have written. + +The output of fmt_httpdate is 29 until Jan 1st 10000. diff --git a/fmt/fmt_httpdate.c b/fmt/fmt_httpdate.c new file mode 100644 index 0000000..efa7960 --- /dev/null +++ b/fmt/fmt_httpdate.c @@ -0,0 +1,35 @@ +#include "fmt.h" +#include "byte.h" +#include + +static unsigned int fmt_2digits(char* dest,int i) { + dest[0]=(i/10)+'0'; + dest[1]=(i%10)+'0'; + return 2; +} + +unsigned int fmt_httpdate(char* dest,time_t t) { + static const char days[] = "SunMonTueWedThuFriSat"; + static const char months[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; + struct tm* x=gmtime(&t); + int i; + + if (dest==0) return 29; + /* "Sun, 06 Nov 1994 08:49:37 GMT" */ + byte_copy(dest,3,days+3*x->tm_wday); i=3; + i+=fmt_str(dest+i,", "); + i+=fmt_2digits(dest+i,x->tm_mday); + i+=fmt_str(dest+i," "); + byte_copy(dest+i,3,months+3*x->tm_mon); i+=3; + i+=fmt_str(dest+i," "); + i+=fmt_2digits(dest+i,(x->tm_year+1900)/100); + i+=fmt_2digits(dest+i,(x->tm_year+1900)%100); + i+=fmt_str(dest+i," "); + i+=fmt_2digits(dest+i,x->tm_hour); + i+=fmt_str(dest+i,":"); + i+=fmt_2digits(dest+i,x->tm_min); + i+=fmt_str(dest+i,":"); + i+=fmt_2digits(dest+i,x->tm_sec); + i+=fmt_str(dest+i," GMT"); + return i; +} diff --git a/fmt/fmt_human.3 b/fmt/fmt_human.3 new file mode 100644 index 0000000..9934637 --- /dev/null +++ b/fmt/fmt_human.3 @@ -0,0 +1,22 @@ +.TH fmt_human 3 +.SH NAME +fmt_human \- write a human readable ASCII representation of a long integer +.SH SYNTAX +.B #include + +unsigned int \fBfmt_human\fP(char *\fIdest\fR,unsigned long long \fIsource\fR); +.SH DESCRIPTION +fmt_human writes a human readable ASCII representation of \fIsource\fR +to \fIdest\fR and returns the number of bytes written. The result +resembles the file size output of "ls -H"; 1000 becomes "1.0k", 1000000 +becomes "1.0M" and so on for "G" and "T". + +fmt_human does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_human returns the number +of bytes it would have written. + +The output of fmt_human can not exceed 11 (assuming unsigned long long +has 64 bits). +.SH "SEE ALSO" +fmt_humank(3), scan_human(3) diff --git a/fmt/fmt_human.c b/fmt/fmt_human.c index 6c0d085..775b108 100644 --- a/fmt/fmt_human.c +++ b/fmt/fmt_human.c @@ -5,7 +5,9 @@ unsigned int fmt_human(char* dest,unsigned long long l) { int i; if (l<1000) return fmt_ulong(dest,l); if (l>1000000000000ull) { - l=(l+50000000000ull)/100000000000ull; + /* dang! overflow! */ + l/=1000; + l=(l+50000000)/100000000; unit='T'; } else if (l>1000000000) { l=(l+50000000)/100000000; @@ -13,7 +15,7 @@ unsigned int fmt_human(char* dest,unsigned long long l) { } else if (l>1000000) { l=(l+50000)/100000; unit='M'; - } else if (l>1000) { + } else { l=(l+50)/100; unit='k'; } diff --git a/fmt/fmt_humank.3 b/fmt/fmt_humank.3 new file mode 100644 index 0000000..5766ccf --- /dev/null +++ b/fmt/fmt_humank.3 @@ -0,0 +1,22 @@ +.TH fmt_humank 3 +.SH NAME +fmt_humank \- write a human readable ASCII representation of a long integer +.SH SYNTAX +.B #include + +unsigned int \fBfmt_humank\fP(char *\fIdest\fR,unsigned long long \fIsource\fR); +.SH DESCRIPTION +fmt_humank writes a human readable ASCII representation of \fIsource\fR +to \fIdest\fR and returns the number of bytes written. The result +resembles the file size output of "ls -h"; 1024 becomes "1.0k", 1048576 +becomes "1.0M" and so on for "G" and "T". + +fmt_humank does not append \\0. + +If \fIdest\fR equals FMT_LEN (i.e. is zero), fmt_humank returns the number +of bytes it would have written. + +The output of fmt_humank can not exceed 11 (assuming unsigned long long +has 64 bits). +.SH "SEE ALSO" +fmt_human(3), scan_humank(3) diff --git a/fmt/fmt_humank.c b/fmt/fmt_humank.c index 02623d9..70cead8 100644 --- a/fmt/fmt_humank.c +++ b/fmt/fmt_humank.c @@ -13,7 +13,7 @@ unsigned int fmt_humank(char* dest,unsigned long long l) { } else if (l>1024*1024) { l=(l+(1024*1024/20))/(1024*1024/10); unit='M'; - } else if (l>1024) { + } else { l=(l+(1024/20))/(1024/10); unit='k'; } diff --git a/test/fmt_httpdate.c b/test/fmt_httpdate.c new file mode 100644 index 0000000..80ba788 --- /dev/null +++ b/test/fmt_httpdate.c @@ -0,0 +1,8 @@ +#include +#include + +main() { + char buf[100]; + buffer_put(buffer_1,buf,fmt_httpdate(buf,time(0))); + buffer_putnlflush(buffer_1); +} diff --git a/test/fmt_human.c b/test/fmt_human.c new file mode 100644 index 0000000..6bcca8f --- /dev/null +++ b/test/fmt_human.c @@ -0,0 +1,10 @@ +#include +#include + +main() { + char buf[1024]; + buffer_put(buffer_1,buf,fmt_human(buf,1)); buffer_putnlflush(buffer_1); + buffer_put(buffer_1,buf,fmt_human(buf,1400)); buffer_putnlflush(buffer_1); + buffer_put(buffer_1,buf,fmt_human(buf,2300000)); buffer_putnlflush(buffer_1); + buffer_put(buffer_1,buf,fmt_human(buf,(unsigned long long)(-1ll))); buffer_putnlflush(buffer_1); +}