Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libcmd/revlib.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1992-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* *
20
***********************************************************************/
21
#pragma prototyped
22
/*
23
* common support for tail and rev
24
*/
25
26
#include <cmd.h>
27
#include <rev.h>
28
29
#define BUFSIZE SF_BUFSIZE
30
#define rounddown(n,size) (((n)-1)&~((size)-1))
31
32
/*
33
* copy the lines starting at offset <start> from in <in> to <out>
34
* in reverse order
35
*/
36
int rev_line(Sfio_t *in, Sfio_t *out, off_t start)
37
{
38
register char *cp, *cpold;
39
register int n, nleft=0;
40
char buff[BUFSIZE];
41
off_t offset;
42
if(sfseek(in,(off_t)0,SEEK_CUR) < 0)
43
{
44
Sfio_t *tmp = sftmp(4*SF_BUFSIZE);
45
if(!tmp)
46
return(-1);
47
if(start>0 && sfmove(in, (Sfio_t*)0, start, -1) != start)
48
return(-1);
49
if(sfmove(in, tmp, SF_UNBOUND, -1) < 0 || !sfeof(in) || sferror(tmp))
50
return(-1);
51
in = tmp;
52
start=0;
53
}
54
if((offset = sfseek(in,(off_t)0,SEEK_END)) <= start)
55
return(0);
56
offset = rounddown(offset,BUFSIZE);
57
while(1)
58
{
59
n = BUFSIZE;
60
if(offset < start)
61
{
62
n -= (start-offset);
63
offset = start;
64
}
65
sfseek(in, offset, SEEK_SET);
66
if((n=sfread(in, buff, n)) <=0)
67
break;
68
cp = buff+n;
69
n = *buff;
70
*buff = '\n';
71
while(1)
72
{
73
cpold = cp;
74
if(nleft==0)
75
cp--;
76
if(cp==buff)
77
{
78
nleft= 1;
79
break;
80
}
81
while(*--cp != '\n');
82
if(cp==buff && n!='\n')
83
{
84
*cp = n;
85
nleft += cpold-cp;
86
break;
87
}
88
else
89
cp++;
90
if(sfwrite(out,cp,cpold-cp) < 0)
91
return(-1);
92
if(nleft)
93
{
94
if(nleft==1)
95
sfputc(out,'\n');
96
else if(sfmove(in,out,nleft,-1) != nleft)
97
return(-1);
98
nleft = 0;
99
}
100
}
101
if(offset <= start)
102
break;
103
offset -= BUFSIZE;
104
}
105
if(nleft)
106
{
107
sfseek(in, start, SEEK_SET);
108
if(sfmove(in,out,nleft,-1) != nleft)
109
return(-1);
110
}
111
return(0);
112
}
113
114