Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/sort/rec.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1996-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
* Phong Vo <[email protected]> *
19
* Doug McIlroy <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
24
/*
25
* <recfmt.h> test harness
26
*/
27
28
static const char usage[] =
29
"[-?\n@(#)$Id: rec (AT&T Research) 2005-11-01 $\n]"
30
USAGE_LICENSE
31
"[+NAME?rec - <recfmt.h> test harness]"
32
"[+DESCRIPTION?\brec\b is a <recfmt.h> test harness. It converts the "
33
"\aformat\a operand to a format descriptor using \brecstr\b(3) and lists "
34
"the \bfmtrec\b(3) canonical format string on the standard output. If a "
35
"\afile\a operand is specified then a line containing the number of "
36
"records and the sum of all record lengths is printed. If \afile\a is "
37
"\b-\b then the standard input is read.]"
38
"[c:count?COunt the number of records.]"
39
"[l:length?List the length of each record.]"
40
"[r:reserve?List underlying sfreserve() sizes and offsets.]"
41
42
"\n"
43
"\nformat [ file ]\n"
44
"\n"
45
46
"[+SEE ALSO?\brecfmt\b(3)]"
47
;
48
49
#include <ast.h>
50
#include <error.h>
51
#include <ls.h>
52
#include <recfmt.h>
53
54
/*
55
* process argv as in sort(1)
56
*/
57
58
int
59
main(int argc, char** argv)
60
{
61
Recfmt_t f;
62
char* s;
63
char* e;
64
char* b;
65
char* path;
66
ssize_t m;
67
ssize_t z;
68
Sfoff_t o;
69
Sfoff_t r;
70
Sfoff_t t;
71
Sfio_t* sp;
72
struct stat st;
73
74
int count = 0;
75
int length = 0;
76
int reserve = 0;
77
78
NoP(argc);
79
error_info.id = "rec";
80
for (;;)
81
{
82
switch (optget(argv, usage))
83
{
84
case 'c':
85
count = !!opt_info.num;
86
continue;
87
case 'l':
88
length = !!opt_info.num;
89
continue;
90
case 'r':
91
reserve = !!opt_info.num;
92
continue;
93
case '?':
94
error(ERROR_USAGE|4, "%s", opt_info.arg);
95
continue;
96
case ':':
97
error(2, "%s", opt_info.arg);
98
continue;
99
}
100
break;
101
}
102
argv += opt_info.index;
103
if (!*argv || *(argv + 1) && *(argv + 2) || error_info.errors)
104
error(ERROR_USAGE|4, "%s", optusage(NiL));
105
f = recstr(*argv++, &e);
106
if (!(path = *argv))
107
sp = 0;
108
else if (streq(path, "-"))
109
sp = sfstdin;
110
else if (!(sp = sfopen(NiL, path, "r")))
111
error(ERROR_SYSTEM|3, "%s: cannot open", path);
112
sfprintf(sfstdout, "%s", fmtrec(f, 0));
113
if (*e)
114
sfprintf(sfstdout, " [%s]", e);
115
if (sp && RECTYPE(f) == REC_method)
116
{
117
e = "";
118
switch (REC_M_INDEX(f))
119
{
120
case REC_M_data:
121
if (s = sfreserve(sp, SF_UNBOUND, SF_LOCKR))
122
{
123
z = sfvalue(sp);
124
if (fstat(sffileno(sp), &st) || st.st_size < z)
125
st.st_size = 0;
126
f = recfmt(s, z, st.st_size);
127
sfread(sp, s, 0);
128
}
129
break;
130
case REC_M_path:
131
f = ((s = strrchr(path, '%')) && !strchr(++s, '/')) ? recstr(s, &e) : REC_N_TYPE();
132
break;
133
default:
134
f = REC_N_TYPE();
135
break;
136
}
137
sfprintf(sfstdout, " => %s", fmtrec(f, 0));
138
if (*e)
139
sfprintf(sfstdout, " [%s]", e);
140
}
141
sfprintf(sfstdout, "\n");
142
if (sp && (count || length))
143
{
144
r = 0;
145
t = 0;
146
b = s = e = 0;
147
m = SF_UNBOUND;
148
for (;;)
149
{
150
if (s >= e)
151
{
152
if (b)
153
sfread(sp, b, s - b);
154
o = sftell(sp);
155
if (!(b = sfreserve(sp, m, SF_LOCKR)))
156
break;
157
m = SF_UNBOUND;
158
s = b;
159
e = s + sfvalue(sp);
160
if (reserve)
161
sfprintf(sfstdout, "reserve %d at %I*d\n", e - s, sizeof(o), o);
162
}
163
z = reclen(f, s, e - s);
164
if (z > 0)
165
{
166
if (length)
167
sfprintf(sfstdout, "%I*d\n", sizeof(z), z);
168
r++;
169
t += z;
170
if (z <= (e - s))
171
s += z;
172
else
173
{
174
if (b)
175
{
176
sfread(sp, b, e - b);
177
b = 0;
178
}
179
o = sftell(sp);
180
if (reserve)
181
sfprintf(sfstdout, "skip %I*d to complete %I*d at %I*d\n", sizeof(z), z - (e - s), sizeof(z), z, sizeof(o), o);
182
z -= e - s;
183
if (!sfreserve(sp, z, 0))
184
{
185
if (length && (z = sfvalue(sp)))
186
sfprintf(sfstdout, "partial %I*d\n", sizeof(z), z);
187
break;
188
}
189
s = e;
190
}
191
}
192
else if (z < 0)
193
{
194
sfprintf(sfstdout, "recfmt FAILED\n");
195
break;
196
}
197
else
198
{
199
if (reserve)
200
sfprintf(sfstdout, "recfmt 0 with %d remaining in buffer\n", e - s);
201
if (b)
202
{
203
sfread(sp, b, s - b);
204
b = 0;
205
}
206
m = -(e - s + 1);
207
e = s;
208
}
209
}
210
if (count)
211
sfprintf(sfstdout, "%I*d %I*d\n", sizeof(r), r, sizeof(t), t);
212
}
213
return 0;
214
}
215
216