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.
This commit is contained in:
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')