Scrap readrune(), introducing fgetrune()

Interface as proposed by cls, but internally rewritten after a few
considerations.
The code is much shorter and to the point, aligning itself with other
standard functions. It should also be much faster, which is not bad.
master
FRIGN 2015-02-11 20:13:43 +01:00
parent 4888bae455
commit a5ae899a48
10 changed files with 45 additions and 57 deletions

View File

@ -23,7 +23,7 @@ LIBUTFSRC =\
libutf/runetype.c\
libutf/utf.c\
libutf/chartorunearr.c\
libutf/readrune.c\
libutf/fgetrune.c\
libutf/writerune.c\
libutf/isalnumrune.c\
libutf/isalpharune.c\

View File

@ -39,7 +39,7 @@ expand(const char *file, FILE *fp)
size_t bol = 1, col = 0, i;
Rune r;
while (readrune(file, fp, &r)) {
while (efgetrune(&r, fp, file)) {
switch (r) {
case '\t':
if (tablistlen == 1)

34
libutf/fgetrune.c Normal file
View File

@ -0,0 +1,34 @@
/* See LICENSE file for copyright and license details. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../utf.h"
int
fgetrune(Rune *p, FILE *fp)
{
char buf[UTFmax];
int i;
for (i = 0; i < UTFmax && (buf[i] = fgetc(fp)) != EOF && ++i ;)
if (charntorune(p, buf, i) > 0)
break;
if (ferror(fp))
return -1;
return i;
}
int
efgetrune(Rune *p, FILE *fp, const char *file)
{
int ret;
if ((ret = fgetrune(p, fp)) < 0) {
fprintf(stderr, "fgetrune %s: %s\n", file, strerror(errno));
exit(1);
}
return ret;
}

View File

@ -1,47 +0,0 @@
/* See LICENSE file for copyright and license details. */
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../utf.h"
int
readrune(const char *file, FILE *fp, Rune *r)
{
char buf[UTFmax];
int c, i;
if ((c = fgetc(fp)) == EOF) {
if (ferror(fp)) {
fprintf(stderr, "%s: read error: %s\n",
file, strerror(errno));
exit(1);
}
return 0;
}
if (c < Runeself) {
*r = (Rune)c;
return 1;
}
buf[0] = c;
for (i = 1; i < UTFmax; ) {
if ((c = fgetc(fp)) == EOF) {
if (ferror(fp)) {
fprintf(stderr, "%s: read error: %s\n",
file, strerror(errno));
exit(1);
}
*r = Runeerror;
return i;
}
buf[i++] = c;
if (fullrune(buf, i)) {
chartorune(r, buf);
break;
}
}
return i;
}

View File

@ -23,7 +23,7 @@ sequential(struct fdescr *dsc, int fdescrlen, Rune *delim, size_t delimlen)
d = 0;
last = 0;
while (readrune(dsc[i].name, dsc[i].fp, &c)) {
while (efgetrune(&c, dsc[i].fp, dsc[i].name)) {
if (last == '\n') {
if (delim[d] != '\0')
writerune("<stdout>", stdout, &delim[d]);
@ -54,7 +54,7 @@ nextline:
d = delim[i % delimlen];
c = 0;
for (; readrune(dsc[i].name, dsc[i].fp, &c) ;) {
for (; efgetrune(&c, dsc[i].fp, dsc[i].name) ;) {
for (m = last + 1; m < i; m++)
writerune("<stdout>", stdout, &(delim[m % delimlen]));
last = i;

4
tail.c
View File

@ -29,7 +29,7 @@ dropinit(FILE *fp, const char *str)
if (len > 0 && buf[len - 1] == '\n')
i++;
} else {
while (i < num && (len = readrune(str, fp, &r)))
while (i < num && (len = efgetrune(&r, fp, str)))
i++;
}
free(buf);
@ -52,7 +52,7 @@ taketail(FILE *fp, const char *str)
} else {
r = ecalloc(num, sizeof *r);
for (i = j = 0; readrune(str, fp, &r[i]); )
for (i = j = 0; efgetrune(&r[i], fp, str); )
i = j = (i + 1) % num;
}
if (ferror(fp))

2
tr.c
View File

@ -204,7 +204,7 @@ main(int argc, char *argv[])
if (set2check && cflag && !dflag)
eprintf("set2 can't be imaged to from a complement.\n");
read:
if (!readrune("<stdin>", stdin, &r))
if (!efgetrune(&r, stdin, "<stdin>"))
return 0;
off1 = off2 = 0;
for (i = 0; i < set1ranges; i++) {

View File

@ -73,7 +73,7 @@ unexpand(const char *file, FILE *fp)
size_t last = 0, col = 0, i;
int bol = 1;
while (readrune(file, fp, &r)) {
while (efgetrune(&r, fp, file)) {
switch (r) {
case ' ':
if (!bol && !aflag)

3
utf.h
View File

@ -59,6 +59,7 @@ int isxdigitrune(Rune);
Rune tolowerrune(Rune);
Rune toupperrune(Rune);
int readrune(const char *, FILE *, Rune *);
int fgetrune(Rune *, FILE *);
int efgetrune(Rune *, FILE *, const char *);
void writerune(const char *, FILE *, Rune *);
int chartorunearr(const char*, Rune **);

2
wc.c
View File

@ -34,7 +34,7 @@ wc(FILE *fp, const char *str)
Rune c;
size_t nc = 0, nl = 0, nw = 0;
while ((rlen = readrune(str, fp, &c))) {
while ((rlen = efgetrune(&c, fp, str))) {
nc += (cmode == 'c') ? rlen :
(c != Runeerror) ? 1 : 0;
if (c == '\n')