diff options
-rw-r--r-- | el.c | 62 |
1 files changed, 54 insertions, 8 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* Extract Lines | 1 | /* Extract Lines |
2 | Usage: echo -x 10 2 7 100 | el data.txt | 2 | Usage: echo -x 10 2 7 100 | el -x data.txt |
3 | extracts lines 16, 2, 7, 256 from the file data.txt | 3 | extracts lines 16, 2, 7, 256 from the file data.txt |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -25,12 +25,33 @@ static long indexfilled = 1; | |||
25 | 25 | ||
26 | // If set, the stream of linenums specified calls | 26 | // If set, the stream of linenums specified calls |
27 | // the first line number 0... *shiver* | 27 | // the first line number 0... *shiver* |
28 | static int zerobased = 0; | 28 | static int g_zerobased = 0; |
29 | |||
30 | // If set, line numbers are prepended to each line | ||
31 | // (the way grep does it, i.e. ^2342:<line>$) | ||
32 | static int g_echolinenr = 0; | ||
29 | 33 | ||
30 | // This tells us, whether we need to scan for hex | 34 | // This tells us, whether we need to scan for hex |
31 | // line numbers | 35 | // line numbers |
32 | static char *g_scanfmodifier = "%i"; | 36 | static char *g_scanfmodifier = "%i"; |
33 | 37 | ||
38 | // If user specifies some line numbers on command | ||
39 | // line, store pointer here | ||
40 | static char *g_immediatelinenums = (char *)0; | ||
41 | |||
42 | // If input is guaranteed to come from "grep -n" | ||
43 | // we will spare the user from "| cut -f 1 -d :" | ||
44 | static int g_fromgrep = 0; | ||
45 | static int g_fromgrepverbatim = 0; | ||
46 | |||
47 | static int nextchar( void ) { | ||
48 | if( !g_immediatelinenums ) | ||
49 | return getchar(); | ||
50 | if( *g_immediatelinenums ) | ||
51 | return *g_immediatelinenums++; | ||
52 | return EOF; | ||
53 | } | ||
54 | |||
34 | // scans the text file for the requested line | 55 | // scans the text file for the requested line |
35 | // returns NULL, if line exceeds file's end | 56 | // returns NULL, if line exceeds file's end |
36 | // Note: we will not extend the index too early | 57 | // Note: we will not extend the index too early |
@@ -118,10 +139,24 @@ static int acquire_lineno( int c ) { | |||
118 | int inputindex = 0, lineno; | 139 | int inputindex = 0, lineno; |
119 | 140 | ||
120 | while ( (c != EOF) && !isspace(c)) { | 141 | while ( (c != EOF) && !isspace(c)) { |
142 | if( g_fromgrep && c == ':' ) { | ||
143 | if( g_echolinenr ) | ||
144 | putchar( ':' ); | ||
145 | while( ( ( c = nextchar() ) != EOF ) && ( c != '\n' ) ) | ||
146 | if( g_fromgrepverbatim ) | ||
147 | putchar(c); | ||
148 | if( g_fromgrepverbatim ) | ||
149 | putchar( '\t' ); | ||
150 | break; | ||
151 | } | ||
152 | if( g_echolinenr ) | ||
153 | putchar( c ); | ||
121 | if( inputindex < 14 ) | 154 | if( inputindex < 14 ) |
122 | input[inputindex++] = (char)c; | 155 | input[inputindex++] = (char)c; |
123 | c = getchar(); | 156 | c = nextchar(); |
124 | } | 157 | } |
158 | if( !g_fromgrep && g_echolinenr ) | ||
159 | putchar( ':' ); | ||
125 | 160 | ||
126 | if( inputindex == 14 ) | 161 | if( inputindex == 14 ) |
127 | return 0; | 162 | return 0; |
@@ -132,11 +167,11 @@ static int acquire_lineno( int c ) { | |||
132 | if( sscanf( input, g_scanfmodifier, &lineno ) != 1 ) | 167 | if( sscanf( input, g_scanfmodifier, &lineno ) != 1 ) |
133 | return 0; | 168 | return 0; |
134 | 169 | ||
135 | return lineno + zerobased; | 170 | return lineno + g_zerobased; |
136 | } | 171 | } |
137 | 172 | ||
138 | static void usage() { | 173 | static void usage() { |
139 | fputs( "Usage: el [-0xh] filename < filenums\n", stderr); | 174 | fputs( "Usage: el [-0Ggnxh] [-i linenums] filename < linenum_file\n", stderr); |
140 | } | 175 | } |
141 | 176 | ||
142 | int main( int argc, char **argv ) { | 177 | int main( int argc, char **argv ) { |
@@ -144,14 +179,25 @@ int main( int argc, char **argv ) { | |||
144 | MAP textfile = NULL; | 179 | MAP textfile = NULL; |
145 | int c; | 180 | int c; |
146 | 181 | ||
147 | while ((c = getopt(argc, argv, ":0x")) != -1) { | 182 | while ((c = getopt(argc, argv, ":0i:gGnxh")) != -1) { |
148 | switch (c) { | 183 | switch (c) { |
149 | case '0': | 184 | case '0': |
150 | zerobased = 1; | 185 | g_zerobased = 1; |
151 | break; | 186 | break; |
152 | case 'x': | 187 | case 'x': |
153 | g_scanfmodifier = "%x"; | 188 | g_scanfmodifier = "%x"; |
154 | break; | 189 | break; |
190 | case 'i': | ||
191 | g_immediatelinenums = optarg; | ||
192 | break; | ||
193 | case 'n': | ||
194 | g_echolinenr = 1; | ||
195 | break; | ||
196 | case 'G': | ||
197 | g_fromgrepverbatim = 1; | ||
198 | case 'g': | ||
199 | g_fromgrep = 1; | ||
200 | break; | ||
155 | case 'h': | 201 | case 'h': |
156 | case '?': | 202 | case '?': |
157 | default: | 203 | default: |
@@ -178,7 +224,7 @@ int main( int argc, char **argv ) { | |||
178 | // First line starts at begin of file. | 224 | // First line starts at begin of file. |
179 | index[0] = textfile->addr; | 225 | index[0] = textfile->addr; |
180 | 226 | ||
181 | while( (c = getchar()) != EOF ) { | 227 | while( (c = nextchar()) != EOF ) { |
182 | // get linenumber, pass on eof test char | 228 | // get linenumber, pass on eof test char |
183 | long slen, lineno = acquire_lineno(c); | 229 | long slen, lineno = acquire_lineno(c); |
184 | unsigned char *line = scanforline( textfile, lineno, &slen ); | 230 | unsigned char *line = scanforline( textfile, lineno, &slen ); |