add fmt_human, fmt_humank and fmt_httpdate

master
leitner 22 years ago
parent a3b08eb5e5
commit 40bba8865b

@ -12,6 +12,7 @@
add stralloc versions of textcode API (Kai Ruemmler) add stralloc versions of textcode API (Kai Ruemmler)
add html to textcode ('<' to '&lt;' etc) add html to textcode ('<' to '&lt;' etc)
add fmt_human and fmt_humank (format numbers ala ls -H/-h) add fmt_human and fmt_humank (format numbers ala ls -H/-h)
add fmt_httpdate
0.14: 0.14:
avoid bus errors in byte_copy avoid bus errors in byte_copy

@ -1,6 +1,9 @@
#ifndef FMT_H #ifndef FMT_H
#define FMT_H #define FMT_H
/* for time_t: */
#include <sys/types.h>
#define FMT_LONG 41 /* enough space to hold -2^127 in decimal, plus \0 */ #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_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 */ #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" */ /* 1 -> "1", 4900 -> "4.8k", 2300000 -> "2.2M" */
unsigned int fmt_humank(char* dest,unsigned long long l); 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 #endif

@ -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 <fmt.h>
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.

@ -0,0 +1,35 @@
#include "fmt.h"
#include "byte.h"
#include <time.h>
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;
}

@ -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 <fmt.h>
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)

@ -5,7 +5,9 @@ unsigned int fmt_human(char* dest,unsigned long long l) {
int i; int i;
if (l<1000) return fmt_ulong(dest,l); if (l<1000) return fmt_ulong(dest,l);
if (l>1000000000000ull) { if (l>1000000000000ull) {
l=(l+50000000000ull)/100000000000ull; /* dang! overflow! */
l/=1000;
l=(l+50000000)/100000000;
unit='T'; unit='T';
} else if (l>1000000000) { } else if (l>1000000000) {
l=(l+50000000)/100000000; l=(l+50000000)/100000000;
@ -13,7 +15,7 @@ unsigned int fmt_human(char* dest,unsigned long long l) {
} else if (l>1000000) { } else if (l>1000000) {
l=(l+50000)/100000; l=(l+50000)/100000;
unit='M'; unit='M';
} else if (l>1000) { } else {
l=(l+50)/100; l=(l+50)/100;
unit='k'; unit='k';
} }

@ -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 <fmt.h>
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)

@ -13,7 +13,7 @@ unsigned int fmt_humank(char* dest,unsigned long long l) {
} else if (l>1024*1024) { } else if (l>1024*1024) {
l=(l+(1024*1024/20))/(1024*1024/10); l=(l+(1024*1024/20))/(1024*1024/10);
unit='M'; unit='M';
} else if (l>1024) { } else {
l=(l+(1024/20))/(1024/10); l=(l+(1024/20))/(1024/10);
unit='k'; unit='k';
} }

@ -0,0 +1,8 @@
#include <time.h>
#include <buffer.h>
main() {
char buf[100];
buffer_put(buffer_1,buf,fmt_httpdate(buf,time(0)));
buffer_putnlflush(buffer_1);
}

@ -0,0 +1,10 @@
#include <fmt.h>
#include <buffer.h>
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);
}
Loading…
Cancel
Save