この記事は「tac と rev でやれ」 Advent Calender 2049 の記事です。
毎度の事ですが、呼び出し元 (main()
) から読んで下さい。そうすればわかります。
/*
* tacrev.c - tac と rev でやれ
*
* gcc tacrev.c -lbenly_typestring -o tacrev
*
*/
#include <benly/typestring.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
static
int read_file(FILE* fp, size_t* lines, STRING*** dest)
{
size_t th_lines = 256;
STRING** s = NULL;
if ((s = (STRING**)
malloc(sizeof(STRING*) * (th_lines + 1))) == NULL) {
perror("malloc"); goto ERR;
}
*lines = 0;
string_errno = 0;
while (fgetline(fp, &s[*lines]) != EOF) {
if (string_errno < 0)
goto ERR;
if (*lines == (th_lines - 1)) {
th_lines += th_lines;
if ((s = (STRING**)
realloc(s, sizeof(STRING*) * th_lines)) == NULL) {
perror("realloc"); goto ERR;
}
}
(*lines)++;
}
*dest = s;
return 0;
ERR:
th_lines = 0;
if (s != NULL) {
while (th_lines < *lines) {
if (s[th_lines] != NULL) {
s[th_lines]->release(s[th_lines]);
}
th_lines++;
}
free(s);
}
return -1;
}
static
void do_tacrev(STRING** s, size_t lines)
{
while (lines > 0) {
lines--;
s[lines]->chomp(&s[lines]);
s[lines]->reverse(&s[lines]);
fputline(stdout, s[lines]);
s[lines]->release(s[lines]);
putchar('\n');
}
free(s);
return;
}
static
int source_pipe(void)
{
size_t lines = 0;
STRING** s = NULL;
if (read_file(stdin, &lines, &s) < 0)
return -1;
else
do_tacrev(s, lines);
return 0;
}
static
int source_argument(char* path)
{
FILE* fp = NULL;
size_t lines = 0;
STRING** s = NULL;
if ((fp = fopen(path, "r")) == NULL) {
fprintf(stdout, "tacrev: %s: %s\n",
path, strerror(errno));
return -1;
}
if (read_file(fp, &lines, &s) < 0) {
fclose(fp);
return -2;
}
fclose(fp);
do_tacrev(s, lines);
return 0;
}
int main(int argc, char* argv[])
{
if (argc > 1) {
while (argc > 1) {
argc--;
if (source_argument(argv[argc]) < 0)
return 1;
}
} else {
if (source_pipe() < 0)
return 2;
}
return 0;
}
% gcc tacrev.c -lbenly_typestring -o tacrev
% < tacrev.c | ./tacrev
}
;0 nruter
;)s(eerf
}
;)'n\'(rahctup
;)]senil[s(esaeler>-]senil[s
;)]senil[s ,tuodts(eniltupf
;)]senil[s&(esrever>-]senil[s
;)]senil[s&(pmohc>-]senil[s
;--senil
{ )0 > senil( elihw
;1 nruter
)0 < )s& ,senil& ,nidts(elif_daer( fi
;LLUN = s **GNIRTS
;0 = senil t_ezis
{
)][vgra *rahc ,cgra tni(niam tni
}
;1- nruter
}
;)s(eerf
}
;++senil_ht
}
;)]senil_ht[s(esaeler>-]senil_ht[s
{ )LLUN =! ]senil_ht[s( fi
{ )senil* < senil_ht( elihw
{ )LLUN =! s( fi
;0 = senil_ht
:RRE
;0 nruter
;s = tsed*
}
;++)senil*(
}
}
;RRE otog ;)"collaer"(rorrep
{ )LLUN == ))senil_ht * )*GNIRTS(foezis ,s(collaer
)**GNIRTS( = s(( fi
;senil_ht =+ senil_ht
{ ))1 - senil_ht( == senil*( fi
;RRE otog
)0 < onrre_gnirts( fi
{ )FOE =! )]senil*[s& ,pf(eniltegf( elihw
;0 = senil*
}
;RRE otog ;)"collam"(rorrep
{ )LLUN == )))1 + senil_ht( * )*GNIRTS(foezis(collam
)**GNIRTS( = s(( fi
;LLUN = s **GNIRTS
;652 = senil_ht t_ezis
{
)tsed ***GNIRTS ,senil *t_ezis ,pf *ELIF(elif_daer tni
citats
>h.bildts< edulcni#
>h.oidts< edulcni#
>h.gnirtsepyt/ylneb< edulcni#
/*
*
vercat o- gnirtsepyt_ylnebl- c.vercat ccg *
*
れやで ver と cat - c.vercat *
*/
;LLUN ってやけに楽しそうね。
% time sh -c "cat /usr/share/yasuna/yasuna-quotes | tac | rev" > /dev/null
sh -c "cat /usr/share/yasuna/yasuna-quotes | tac | rev" > /dev/null 0.01s user 0.01s system 42% cpu 0.038 total
% time sh -c "cat /usr/share/yasuna/yasuna-quotes | tacrev" > /dev/null
sh -c "cat /usr/share/yasuna/yasuna-quotes | tacrev" > /dev/null 0.03s user 0.01s system 103% cpu 0.036 total
速度もそんなに遅くない。もっと遅いかと思っていた。