aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog5
-rw-r--r--coreutils/ls.c26
-rw-r--r--dmesg.c18
-rw-r--r--editors/sed.c338
-rw-r--r--ls.c26
-rw-r--r--sed.c338
-rw-r--r--util-linux/dmesg.c18
7 files changed, 569 insertions, 200 deletions
diff --git a/Changelog b/Changelog
index 8ba73692d..37570d292 100644
--- a/Changelog
+++ b/Changelog
@@ -17,6 +17,11 @@
17 them so they should now work as expected. 17 them so they should now work as expected.
18 * New app: loadacm contributed by Peter Novodvorsky <petya@logic.ru> 18 * New app: loadacm contributed by Peter Novodvorsky <petya@logic.ru>
19 for loading application character maps for working with Unicode fonts. 19 for loading application character maps for working with Unicode fonts.
20 * sed now supports addresses (numeric or regexp, with negation) and
21 has an append command, thanks to Marco Pantaleoni <panta@prosa.it>
22 * Fixed dmesg. It wasn't parsing its options (-n or -s) properly.
23 * Some cosmetic fixes to ls output formatting to make it behave more
24 like GNU ls.
20 25
21 26
22 -Erik Andersen 27 -Erik Andersen
diff --git a/coreutils/ls.c b/coreutils/ls.c
index 571c962c7..862da4368 100644
--- a/coreutils/ls.c
+++ b/coreutils/ls.c
@@ -193,11 +193,13 @@ static void list_single(const char *name, struct stat *info, const char *fullnam
193 fputs(" ", stdout); 193 fputs(" ", stdout);
194#ifdef BB_FEATURE_LS_USERNAME 194#ifdef BB_FEATURE_LS_USERNAME
195 if (!(opts & DISP_NUMERIC)) { 195 if (!(opts & DISP_NUMERIC)) {
196 scratch[0]='\0'; 196 memset ( scratch, 0, sizeof (scratch));
197 my_getpwuid( scratch, info->st_uid); 197 my_getpwuid( scratch, info->st_uid);
198 scratch[8]='\0'; 198 if (*scratch) {
199 if (*scratch) 199 fputs(scratch, stdout);
200 wr(scratch,8); 200 if ( strlen( scratch) <= 8 )
201 wr(" ", 8-strlen( scratch));
202 }
201 else { 203 else {
202 writenum((long) info->st_uid,(short)8); 204 writenum((long) info->st_uid,(short)8);
203 fputs(" ", stdout); 205 fputs(" ", stdout);
@@ -208,20 +210,21 @@ static void list_single(const char *name, struct stat *info, const char *fullnam
208 writenum((long) info->st_uid,(short)8); 210 writenum((long) info->st_uid,(short)8);
209 fputs(" ", stdout); 211 fputs(" ", stdout);
210 } 212 }
211 tab(16);
212#ifdef BB_FEATURE_LS_USERNAME 213#ifdef BB_FEATURE_LS_USERNAME
213 if (!(opts & DISP_NUMERIC)) { 214 if (!(opts & DISP_NUMERIC)) {
214 scratch[0]='\0'; 215 memset ( scratch, 0, sizeof (scratch));
215 my_getgrgid( scratch, info->st_gid); 216 my_getgrgid( scratch, info->st_gid);
216 scratch[8]='\0'; 217 if (*scratch) {
217 if (*scratch) 218 fputs(scratch, stdout);
218 wr(scratch,8); 219 if ( strlen( scratch) <= 8 )
220 wr(" ", 8-strlen( scratch));
221 }
219 else 222 else
220 writenum((long) info->st_gid,(short)8); 223 writenum((long) info->st_gid,(short)8);
221 } else 224 } else
222#endif 225#endif
223 writenum((long) info->st_gid,(short)8); 226 writenum((long) info->st_gid,(short)8);
224 tab(17); 227 //tab(26);
225 if (S_ISBLK(mode) || S_ISCHR(mode)) { 228 if (S_ISBLK(mode) || S_ISCHR(mode)) {
226 writenum((long)MAJOR(info->st_rdev),(short)3); 229 writenum((long)MAJOR(info->st_rdev),(short)3);
227 fputs(", ", stdout); 230 fputs(", ", stdout);
@@ -230,6 +233,7 @@ static void list_single(const char *name, struct stat *info, const char *fullnam
230 else 233 else
231 writenum((long)info->st_size,(short)8); 234 writenum((long)info->st_size,(short)8);
232 fputs(" ", stdout); 235 fputs(" ", stdout);
236 //tab(32);
233#ifdef BB_FEATURE_LS_TIMESTAMPS 237#ifdef BB_FEATURE_LS_TIMESTAMPS
234 { 238 {
235 time_t cal; 239 time_t cal;
diff --git a/dmesg.c b/dmesg.c
index aa26f5836..e38fd5555 100644
--- a/dmesg.c
+++ b/dmesg.c
@@ -44,10 +44,15 @@ int dmesg_main( int argc, char** argv )
44 int level = 0; 44 int level = 0;
45 int lastc; 45 int lastc;
46 int cmd = 3; 46 int cmd = 3;
47 int stopDoingThat;
48
49 argc--;
50 argv++;
47 51
48 /* Parse any options */ 52 /* Parse any options */
49 while (argc && **argv == '-') { 53 while (argc && **argv == '-') {
50 while (*++(*argv)) 54 stopDoingThat = FALSE;
55 while (stopDoingThat == FALSE && *++(*argv)) {
51 switch (**argv) { 56 switch (**argv) {
52 case 'c': 57 case 'c':
53 cmd = 4; 58 cmd = 4;
@@ -57,19 +62,22 @@ int dmesg_main( int argc, char** argv )
57 if (--argc == 0) 62 if (--argc == 0)
58 goto end; 63 goto end;
59 level = atoi (*(++argv)); 64 level = atoi (*(++argv));
60 --argc; 65 if (--argc > 0)
61 ++argv; 66 ++argv;
67 stopDoingThat = TRUE;
62 break; 68 break;
63 case 's': 69 case 's':
64 if (--argc == 0) 70 if (--argc == 0)
65 goto end; 71 goto end;
66 bufsize = atoi (*(++argv)); 72 bufsize = atoi (*(++argv));
67 --argc; 73 if (--argc > 0)
68 ++argv; 74 ++argv;
75 stopDoingThat = TRUE;
69 break; 76 break;
70 default: 77 default:
71 goto end; 78 goto end;
72 } 79 }
80 }
73 } 81 }
74 82
75 if (argc > 1) { 83 if (argc > 1) {
diff --git a/editors/sed.c b/editors/sed.c
index 4dfc0246c..8e5f695c4 100644
--- a/editors/sed.c
+++ b/editors/sed.c
@@ -5,6 +5,11 @@
5 * Copyright (C) 1999 by Lineo, inc. 5 * Copyright (C) 1999 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> 6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 * 7 *
8 * Modifications for addresses and append command have been
9 * written by Marco Pantaleoni <panta@prosa.it>, <panta@elasticworld.org>
10 * and are:
11 * Copyright (C) 1999 Marco Pantaleoni.
12 *
8 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 15 * the Free Software Foundation; either version 2 of the License, or
@@ -31,48 +36,144 @@
31#include <time.h> 36#include <time.h>
32#include <ctype.h> 37#include <ctype.h>
33 38
34static const char sed_usage[] = 39static const char sed_usage[] =
35"sed [-n] [-e script] [file...]\n\n" 40 "sed [-n] -e script [file...]\n\n"
36"Allowed sed scripts come in the following form:\n" 41 "Allowed sed scripts come in the following form:\n"
37"\t's/regexp/replacement/[gp]'\n" 42 "\t'ADDR [!] COMMAND'\n\n"
38"which attempt to match regexp against the pattern space\n" 43 "\twhere address ADDR can be:\n"
39"and if successful replaces the matched portion with replacement.\n\n" 44 "\t NUMBER Match specified line number\n"
40"Options:\n" 45 "\t $ Match last line\n"
41"-e\tadd the script to the commands to be executed\n" 46 "\t /REGEXP/ Match specified regexp\n"
42"-n\tsuppress automatic printing of pattern space\n\n" 47 "\t (! inverts the meaning of the match)\n\n"
48 "\tand COMMAND can be:\n"
49 "\t s/regexp/replacement/[gp]\n"
50 "\t which attempt to match regexp against the pattern space\n"
51 "\t and if successful replaces the matched portion with replacement.\n\n"
52 "\t aTEXT\n"
53 "\t which appends TEXT after the pattern space\n"
54 "Options:\n"
55 "-e\tadd the script to the commands to be executed\n"
56 "-n\tsuppress automatic printing of pattern space\n\n"
43#if defined BB_REGEXP 57#if defined BB_REGEXP
44"This version of sed matches full regular expresions.\n"; 58 "This version of sed matches full regular expresions.\n";
45#else 59#else
46"This version of sed matches strings (not full regular expresions).\n"; 60 "This version of sed matches strings (not full regular expresions).\n";
47#endif 61#endif
48
49 62
50static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag) 63/* Flags & variables */
64
65typedef enum { f_none, f_replace, f_append } sed_function;
66
67#define NO_LINE -2
68#define LAST_LINE -1
69static int addr_line = NO_LINE;
70static char *addr_pattern = NULL;
71static int negated = 0;
72
73#define SKIPSPACES(p) do { while (isspace(*(p))) (p)++; } while (0)
74
75#define BUFSIZE 1024
76
77static inline int at_last(FILE * fp)
51{ 78{
52 int foundOne=FALSE; 79 int res = 0;
53 char haystack[1024];
54 80
55 while (fgets (haystack, 1023, fp)) { 81 if (feof(fp))
56 foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); 82 return 1;
57 if (foundOne==TRUE && printFlag==TRUE) { 83 else {
58 fprintf(stdout, haystack); 84 char ch;
85 if ((ch = fgetc(fp)) == EOF)
86 res++;
87 ungetc(ch, fp);
88 }
89 return res;
90}
91
92static void do_sed_repl(FILE * fp, char *needle, char *newNeedle,
93 int ignoreCase, int printFlag, int quietFlag)
94{
95 int foundOne = FALSE;
96 char haystack[BUFSIZE];
97 int line = 1, doit;
98
99 while (fgets(haystack, BUFSIZE - 1, fp)) {
100 doit = 0;
101 if (addr_pattern) {
102 doit = !find_match(haystack, addr_pattern, FALSE);
103 } else if (addr_line == NO_LINE)
104 doit = 1;
105 else if (addr_line == LAST_LINE) {
106 if (at_last(fp))
107 doit = 1;
108 } else {
109 if (line == addr_line)
110 doit = 1;
111 }
112 if (negated)
113 doit = 1 - doit;
114 if (doit) {
115 foundOne =
116 replace_match(haystack, needle, newNeedle, ignoreCase);
117
118 if (foundOne == TRUE && printFlag == TRUE) {
119 fprintf(stdout, haystack);
120 }
59 } 121 }
60 if (quietFlag==FALSE) { 122
123 if (quietFlag == FALSE) {
61 fprintf(stdout, haystack); 124 fprintf(stdout, haystack);
62 } 125 }
126
127 line++;
128 }
129}
130
131static void do_sed_append(FILE * fp, char *appendline, int quietFlag)
132{
133 char buffer[BUFSIZE];
134 int line = 1, doit;
135
136 while (fgets(buffer, BUFSIZE - 1, fp)) {
137 doit = 0;
138 if (addr_pattern) {
139 doit = !find_match(buffer, addr_pattern, FALSE);
140 } else if (addr_line == NO_LINE)
141 doit = 1;
142 else if (addr_line == LAST_LINE) {
143 if (at_last(fp))
144 doit = 1;
145 } else {
146 if (line == addr_line)
147 doit = 1;
148 }
149 if (negated)
150 doit = 1 - doit;
151 if (quietFlag == FALSE) {
152 fprintf(stdout, buffer);
153 }
154 if (doit) {
155 fputs(appendline, stdout);
156 fputc('\n', stdout);
157 }
158
159 line++;
63 } 160 }
64} 161}
65 162
66extern int sed_main (int argc, char **argv) 163extern int sed_main(int argc, char **argv)
67{ 164{
68 FILE *fp; 165 FILE *fp;
69 char *needle=NULL, *newNeedle=NULL; 166 char *needle = NULL, *newNeedle = NULL;
70 char *name; 167 char *name;
71 char *cp; 168 char *cp;
72 int ignoreCase=FALSE; 169 int ignoreCase = FALSE;
73 int printFlag=FALSE; 170 int printFlag = FALSE;
74 int quietFlag=FALSE; 171 int quietFlag = FALSE;
75 int stopNow; 172 int stopNow;
173 char *line_s = NULL, saved;
174 char *appendline = NULL;
175 char *pos;
176 sed_function sed_f = f_none;
76 177
77 argc--; 178 argc--;
78 argv++; 179 argv++;
@@ -83,68 +184,119 @@ extern int sed_main (int argc, char **argv)
83 if (**argv == '-') { 184 if (**argv == '-') {
84 argc--; 185 argc--;
85 cp = *argv++; 186 cp = *argv++;
86 stopNow=FALSE; 187 stopNow = FALSE;
87 188
88 while (*++cp && stopNow==FALSE) { 189 while (*++cp && stopNow == FALSE) {
89 switch (*cp) { 190 switch (*cp) {
90 case 'n': 191 case 'n':
91 quietFlag = TRUE; 192 quietFlag = TRUE;
92 break; 193 break;
93 case 'e': 194 case 'e':
94 if (*(cp+1)==0 && --argc < 0) { 195 if (*(cp + 1) == 0 && --argc < 0) {
95 usage( sed_usage); 196 usage(sed_usage);
96 } 197 }
97 if ( *++cp != 's') 198 if (*++cp != 's')
98 cp = *argv++; 199 cp = *argv++;
99 while( *cp ) { 200
100 if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { 201 /* Read address if present */
101 char* pos=needle=cp+2; 202 SKIPSPACES(cp);
102 for(;;) { 203 if (*cp == '$') {
103 pos = strchr(pos, '/'); 204 addr_line = LAST_LINE;
104 if (pos==NULL) { 205 cp++;
105 usage( sed_usage); 206 } else {
106 } 207 if (isdigit(*cp)) { /* LINE ADDRESS */
107 if (*(pos-1) == '\\') { 208 line_s = cp;
108 pos++; 209 while (isdigit(*cp))
109 continue; 210 cp++;
110 } 211 if (cp > line_s) {
111 break; 212 /* numeric line */
213 saved = *cp;
214 *cp = '\0';
215 addr_line = atoi(line_s);
216 *cp = saved;
112 } 217 }
113 *pos=0; 218 } else if (*cp == '/') { /* PATTERN ADDRESS */
114 newNeedle=++pos; 219 pos = addr_pattern = cp + 1;
115 for(;;) { 220 pos = strchr(pos, '/');
116 pos = strchr(pos, '/'); 221 if (!pos)
117 if (pos==NULL) { 222 usage(sed_usage);
118 usage( sed_usage); 223 *pos = '\0';
119 } 224 cp = pos + 1;
120 if (*(pos-1) == '\\') { 225 }
121 pos++; 226 }
122 continue; 227
123 } 228 SKIPSPACES(cp);
124 break; 229 if (*cp == '!') {
230 negated++;
231 cp++;
232 }
233
234 /* Read command */
235
236 SKIPSPACES(cp);
237 switch (*cp) {
238 case 's': /* REPLACE */
239 if (strlen(cp) <= 3 || *(cp + 1) != '/')
240 break;
241 sed_f = f_replace;
242
243 pos = needle = cp + 2;
244
245 for (;;) {
246 pos = strchr(pos, '/');
247 if (pos == NULL) {
248 usage(sed_usage);
249 }
250 if (*(pos - 1) == '\\') {
251 pos++;
252 continue;
125 } 253 }
126 *pos=0; 254 break;
127 if (pos+2 != 0) { 255 }
128 while (*++pos) { 256 *pos = 0;
129 switch (*pos) { 257 newNeedle = ++pos;
130 case 'i': 258 for (;;) {
131 ignoreCase=TRUE; 259 pos = strchr(pos, '/');
132 break; 260 if (pos == NULL) {
133 case 'p': 261 usage(sed_usage);
134 printFlag=TRUE; 262 }
135 break; 263 if (*(pos - 1) == '\\') {
136 case 'g': 264 pos++;
137 break; 265 continue;
138 default: 266 }
139 usage( sed_usage); 267 break;
140 } 268 }
269 *pos = 0;
270 if (pos + 2 != 0) {
271 while (*++pos) {
272 switch (*pos) {
273 case 'i':
274 ignoreCase = TRUE;
275 break;
276 case 'p':
277 printFlag = TRUE;
278 break;
279 case 'g':
280 break;
281 default:
282 usage(sed_usage);
141 } 283 }
142 } 284 }
143 } 285 }
144 cp++; 286 cp = pos;
287 /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
288 break;
289
290 case 'a': /* APPEND */
291 if (strlen(cp) < 2)
292 break;
293 sed_f = f_append;
294 appendline = ++cp;
295 /* fprintf(stderr, "append '%s'\n", appendline); */
296 break;
145 } 297 }
146 //fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); 298
147 stopNow=TRUE; 299 stopNow = TRUE;
148 break; 300 break;
149 301
150 default: 302 default:
@@ -153,30 +305,48 @@ extern int sed_main (int argc, char **argv)
153 } 305 }
154 } 306 }
155 307
156 if (argc==0) { 308 if (argc == 0) {
157 do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag); 309 switch (sed_f) {
310 case f_none:
311 break;
312 case f_replace:
313 do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag,
314 quietFlag);
315 break;
316 case f_append:
317 do_sed_append(stdin, appendline, quietFlag);
318 break;
319 }
158 } else { 320 } else {
159 while (argc-- > 0) { 321 while (argc-- > 0) {
160 name = *argv++; 322 name = *argv++;
161 323
162 fp = fopen (name, "r"); 324 fp = fopen(name, "r");
163 if (fp == NULL) { 325 if (fp == NULL) {
164 perror (name); 326 perror(name);
165 continue; 327 continue;
166 } 328 }
167 329
168 do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag); 330 switch (sed_f) {
331 case f_none:
332 break;
333 case f_replace:
334 do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag,
335 quietFlag);
336 break;
337 case f_append:
338 do_sed_append(fp, appendline, quietFlag);
339 break;
340 }
169 341
170 if (ferror (fp)) 342 if (ferror(fp))
171 perror (name); 343 perror(name);
172 344
173 fclose (fp); 345 fclose(fp);
174 } 346 }
175 } 347 }
176 exit( TRUE); 348 exit(TRUE);
177} 349}
178 350
179 351
180/* END CODE */ 352/* END CODE */
181
182
diff --git a/ls.c b/ls.c
index 571c962c7..862da4368 100644
--- a/ls.c
+++ b/ls.c
@@ -193,11 +193,13 @@ static void list_single(const char *name, struct stat *info, const char *fullnam
193 fputs(" ", stdout); 193 fputs(" ", stdout);
194#ifdef BB_FEATURE_LS_USERNAME 194#ifdef BB_FEATURE_LS_USERNAME
195 if (!(opts & DISP_NUMERIC)) { 195 if (!(opts & DISP_NUMERIC)) {
196 scratch[0]='\0'; 196 memset ( scratch, 0, sizeof (scratch));
197 my_getpwuid( scratch, info->st_uid); 197 my_getpwuid( scratch, info->st_uid);
198 scratch[8]='\0'; 198 if (*scratch) {
199 if (*scratch) 199 fputs(scratch, stdout);
200 wr(scratch,8); 200 if ( strlen( scratch) <= 8 )
201 wr(" ", 8-strlen( scratch));
202 }
201 else { 203 else {
202 writenum((long) info->st_uid,(short)8); 204 writenum((long) info->st_uid,(short)8);
203 fputs(" ", stdout); 205 fputs(" ", stdout);
@@ -208,20 +210,21 @@ static void list_single(const char *name, struct stat *info, const char *fullnam
208 writenum((long) info->st_uid,(short)8); 210 writenum((long) info->st_uid,(short)8);
209 fputs(" ", stdout); 211 fputs(" ", stdout);
210 } 212 }
211 tab(16);
212#ifdef BB_FEATURE_LS_USERNAME 213#ifdef BB_FEATURE_LS_USERNAME
213 if (!(opts & DISP_NUMERIC)) { 214 if (!(opts & DISP_NUMERIC)) {
214 scratch[0]='\0'; 215 memset ( scratch, 0, sizeof (scratch));
215 my_getgrgid( scratch, info->st_gid); 216 my_getgrgid( scratch, info->st_gid);
216 scratch[8]='\0'; 217 if (*scratch) {
217 if (*scratch) 218 fputs(scratch, stdout);
218 wr(scratch,8); 219 if ( strlen( scratch) <= 8 )
220 wr(" ", 8-strlen( scratch));
221 }
219 else 222 else
220 writenum((long) info->st_gid,(short)8); 223 writenum((long) info->st_gid,(short)8);
221 } else 224 } else
222#endif 225#endif
223 writenum((long) info->st_gid,(short)8); 226 writenum((long) info->st_gid,(short)8);
224 tab(17); 227 //tab(26);
225 if (S_ISBLK(mode) || S_ISCHR(mode)) { 228 if (S_ISBLK(mode) || S_ISCHR(mode)) {
226 writenum((long)MAJOR(info->st_rdev),(short)3); 229 writenum((long)MAJOR(info->st_rdev),(short)3);
227 fputs(", ", stdout); 230 fputs(", ", stdout);
@@ -230,6 +233,7 @@ static void list_single(const char *name, struct stat *info, const char *fullnam
230 else 233 else
231 writenum((long)info->st_size,(short)8); 234 writenum((long)info->st_size,(short)8);
232 fputs(" ", stdout); 235 fputs(" ", stdout);
236 //tab(32);
233#ifdef BB_FEATURE_LS_TIMESTAMPS 237#ifdef BB_FEATURE_LS_TIMESTAMPS
234 { 238 {
235 time_t cal; 239 time_t cal;
diff --git a/sed.c b/sed.c
index 4dfc0246c..8e5f695c4 100644
--- a/sed.c
+++ b/sed.c
@@ -5,6 +5,11 @@
5 * Copyright (C) 1999 by Lineo, inc. 5 * Copyright (C) 1999 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org> 6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 * 7 *
8 * Modifications for addresses and append command have been
9 * written by Marco Pantaleoni <panta@prosa.it>, <panta@elasticworld.org>
10 * and are:
11 * Copyright (C) 1999 Marco Pantaleoni.
12 *
8 * This program is free software; you can redistribute it and/or modify 13 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by 14 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or 15 * the Free Software Foundation; either version 2 of the License, or
@@ -31,48 +36,144 @@
31#include <time.h> 36#include <time.h>
32#include <ctype.h> 37#include <ctype.h>
33 38
34static const char sed_usage[] = 39static const char sed_usage[] =
35"sed [-n] [-e script] [file...]\n\n" 40 "sed [-n] -e script [file...]\n\n"
36"Allowed sed scripts come in the following form:\n" 41 "Allowed sed scripts come in the following form:\n"
37"\t's/regexp/replacement/[gp]'\n" 42 "\t'ADDR [!] COMMAND'\n\n"
38"which attempt to match regexp against the pattern space\n" 43 "\twhere address ADDR can be:\n"
39"and if successful replaces the matched portion with replacement.\n\n" 44 "\t NUMBER Match specified line number\n"
40"Options:\n" 45 "\t $ Match last line\n"
41"-e\tadd the script to the commands to be executed\n" 46 "\t /REGEXP/ Match specified regexp\n"
42"-n\tsuppress automatic printing of pattern space\n\n" 47 "\t (! inverts the meaning of the match)\n\n"
48 "\tand COMMAND can be:\n"
49 "\t s/regexp/replacement/[gp]\n"
50 "\t which attempt to match regexp against the pattern space\n"
51 "\t and if successful replaces the matched portion with replacement.\n\n"
52 "\t aTEXT\n"
53 "\t which appends TEXT after the pattern space\n"
54 "Options:\n"
55 "-e\tadd the script to the commands to be executed\n"
56 "-n\tsuppress automatic printing of pattern space\n\n"
43#if defined BB_REGEXP 57#if defined BB_REGEXP
44"This version of sed matches full regular expresions.\n"; 58 "This version of sed matches full regular expresions.\n";
45#else 59#else
46"This version of sed matches strings (not full regular expresions).\n"; 60 "This version of sed matches strings (not full regular expresions).\n";
47#endif 61#endif
48
49 62
50static void do_sed(FILE *fp, char *needle, char *newNeedle, int ignoreCase, int printFlag, int quietFlag) 63/* Flags & variables */
64
65typedef enum { f_none, f_replace, f_append } sed_function;
66
67#define NO_LINE -2
68#define LAST_LINE -1
69static int addr_line = NO_LINE;
70static char *addr_pattern = NULL;
71static int negated = 0;
72
73#define SKIPSPACES(p) do { while (isspace(*(p))) (p)++; } while (0)
74
75#define BUFSIZE 1024
76
77static inline int at_last(FILE * fp)
51{ 78{
52 int foundOne=FALSE; 79 int res = 0;
53 char haystack[1024];
54 80
55 while (fgets (haystack, 1023, fp)) { 81 if (feof(fp))
56 foundOne = replace_match(haystack, needle, newNeedle, ignoreCase); 82 return 1;
57 if (foundOne==TRUE && printFlag==TRUE) { 83 else {
58 fprintf(stdout, haystack); 84 char ch;
85 if ((ch = fgetc(fp)) == EOF)
86 res++;
87 ungetc(ch, fp);
88 }
89 return res;
90}
91
92static void do_sed_repl(FILE * fp, char *needle, char *newNeedle,
93 int ignoreCase, int printFlag, int quietFlag)
94{
95 int foundOne = FALSE;
96 char haystack[BUFSIZE];
97 int line = 1, doit;
98
99 while (fgets(haystack, BUFSIZE - 1, fp)) {
100 doit = 0;
101 if (addr_pattern) {
102 doit = !find_match(haystack, addr_pattern, FALSE);
103 } else if (addr_line == NO_LINE)
104 doit = 1;
105 else if (addr_line == LAST_LINE) {
106 if (at_last(fp))
107 doit = 1;
108 } else {
109 if (line == addr_line)
110 doit = 1;
111 }
112 if (negated)
113 doit = 1 - doit;
114 if (doit) {
115 foundOne =
116 replace_match(haystack, needle, newNeedle, ignoreCase);
117
118 if (foundOne == TRUE && printFlag == TRUE) {
119 fprintf(stdout, haystack);
120 }
59 } 121 }
60 if (quietFlag==FALSE) { 122
123 if (quietFlag == FALSE) {
61 fprintf(stdout, haystack); 124 fprintf(stdout, haystack);
62 } 125 }
126
127 line++;
128 }
129}
130
131static void do_sed_append(FILE * fp, char *appendline, int quietFlag)
132{
133 char buffer[BUFSIZE];
134 int line = 1, doit;
135
136 while (fgets(buffer, BUFSIZE - 1, fp)) {
137 doit = 0;
138 if (addr_pattern) {
139 doit = !find_match(buffer, addr_pattern, FALSE);
140 } else if (addr_line == NO_LINE)
141 doit = 1;
142 else if (addr_line == LAST_LINE) {
143 if (at_last(fp))
144 doit = 1;
145 } else {
146 if (line == addr_line)
147 doit = 1;
148 }
149 if (negated)
150 doit = 1 - doit;
151 if (quietFlag == FALSE) {
152 fprintf(stdout, buffer);
153 }
154 if (doit) {
155 fputs(appendline, stdout);
156 fputc('\n', stdout);
157 }
158
159 line++;
63 } 160 }
64} 161}
65 162
66extern int sed_main (int argc, char **argv) 163extern int sed_main(int argc, char **argv)
67{ 164{
68 FILE *fp; 165 FILE *fp;
69 char *needle=NULL, *newNeedle=NULL; 166 char *needle = NULL, *newNeedle = NULL;
70 char *name; 167 char *name;
71 char *cp; 168 char *cp;
72 int ignoreCase=FALSE; 169 int ignoreCase = FALSE;
73 int printFlag=FALSE; 170 int printFlag = FALSE;
74 int quietFlag=FALSE; 171 int quietFlag = FALSE;
75 int stopNow; 172 int stopNow;
173 char *line_s = NULL, saved;
174 char *appendline = NULL;
175 char *pos;
176 sed_function sed_f = f_none;
76 177
77 argc--; 178 argc--;
78 argv++; 179 argv++;
@@ -83,68 +184,119 @@ extern int sed_main (int argc, char **argv)
83 if (**argv == '-') { 184 if (**argv == '-') {
84 argc--; 185 argc--;
85 cp = *argv++; 186 cp = *argv++;
86 stopNow=FALSE; 187 stopNow = FALSE;
87 188
88 while (*++cp && stopNow==FALSE) { 189 while (*++cp && stopNow == FALSE) {
89 switch (*cp) { 190 switch (*cp) {
90 case 'n': 191 case 'n':
91 quietFlag = TRUE; 192 quietFlag = TRUE;
92 break; 193 break;
93 case 'e': 194 case 'e':
94 if (*(cp+1)==0 && --argc < 0) { 195 if (*(cp + 1) == 0 && --argc < 0) {
95 usage( sed_usage); 196 usage(sed_usage);
96 } 197 }
97 if ( *++cp != 's') 198 if (*++cp != 's')
98 cp = *argv++; 199 cp = *argv++;
99 while( *cp ) { 200
100 if (*cp == 's' && strlen(cp) > 3 && *(cp+1) == '/') { 201 /* Read address if present */
101 char* pos=needle=cp+2; 202 SKIPSPACES(cp);
102 for(;;) { 203 if (*cp == '$') {
103 pos = strchr(pos, '/'); 204 addr_line = LAST_LINE;
104 if (pos==NULL) { 205 cp++;
105 usage( sed_usage); 206 } else {
106 } 207 if (isdigit(*cp)) { /* LINE ADDRESS */
107 if (*(pos-1) == '\\') { 208 line_s = cp;
108 pos++; 209 while (isdigit(*cp))
109 continue; 210 cp++;
110 } 211 if (cp > line_s) {
111 break; 212 /* numeric line */
213 saved = *cp;
214 *cp = '\0';
215 addr_line = atoi(line_s);
216 *cp = saved;
112 } 217 }
113 *pos=0; 218 } else if (*cp == '/') { /* PATTERN ADDRESS */
114 newNeedle=++pos; 219 pos = addr_pattern = cp + 1;
115 for(;;) { 220 pos = strchr(pos, '/');
116 pos = strchr(pos, '/'); 221 if (!pos)
117 if (pos==NULL) { 222 usage(sed_usage);
118 usage( sed_usage); 223 *pos = '\0';
119 } 224 cp = pos + 1;
120 if (*(pos-1) == '\\') { 225 }
121 pos++; 226 }
122 continue; 227
123 } 228 SKIPSPACES(cp);
124 break; 229 if (*cp == '!') {
230 negated++;
231 cp++;
232 }
233
234 /* Read command */
235
236 SKIPSPACES(cp);
237 switch (*cp) {
238 case 's': /* REPLACE */
239 if (strlen(cp) <= 3 || *(cp + 1) != '/')
240 break;
241 sed_f = f_replace;
242
243 pos = needle = cp + 2;
244
245 for (;;) {
246 pos = strchr(pos, '/');
247 if (pos == NULL) {
248 usage(sed_usage);
249 }
250 if (*(pos - 1) == '\\') {
251 pos++;
252 continue;
125 } 253 }
126 *pos=0; 254 break;
127 if (pos+2 != 0) { 255 }
128 while (*++pos) { 256 *pos = 0;
129 switch (*pos) { 257 newNeedle = ++pos;
130 case 'i': 258 for (;;) {
131 ignoreCase=TRUE; 259 pos = strchr(pos, '/');
132 break; 260 if (pos == NULL) {
133 case 'p': 261 usage(sed_usage);
134 printFlag=TRUE; 262 }
135 break; 263 if (*(pos - 1) == '\\') {
136 case 'g': 264 pos++;
137 break; 265 continue;
138 default: 266 }
139 usage( sed_usage); 267 break;
140 } 268 }
269 *pos = 0;
270 if (pos + 2 != 0) {
271 while (*++pos) {
272 switch (*pos) {
273 case 'i':
274 ignoreCase = TRUE;
275 break;
276 case 'p':
277 printFlag = TRUE;
278 break;
279 case 'g':
280 break;
281 default:
282 usage(sed_usage);
141 } 283 }
142 } 284 }
143 } 285 }
144 cp++; 286 cp = pos;
287 /* fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); */
288 break;
289
290 case 'a': /* APPEND */
291 if (strlen(cp) < 2)
292 break;
293 sed_f = f_append;
294 appendline = ++cp;
295 /* fprintf(stderr, "append '%s'\n", appendline); */
296 break;
145 } 297 }
146 //fprintf(stderr, "replace '%s' with '%s'\n", needle, newNeedle); 298
147 stopNow=TRUE; 299 stopNow = TRUE;
148 break; 300 break;
149 301
150 default: 302 default:
@@ -153,30 +305,48 @@ extern int sed_main (int argc, char **argv)
153 } 305 }
154 } 306 }
155 307
156 if (argc==0) { 308 if (argc == 0) {
157 do_sed( stdin, needle, newNeedle, ignoreCase, printFlag, quietFlag); 309 switch (sed_f) {
310 case f_none:
311 break;
312 case f_replace:
313 do_sed_repl(stdin, needle, newNeedle, ignoreCase, printFlag,
314 quietFlag);
315 break;
316 case f_append:
317 do_sed_append(stdin, appendline, quietFlag);
318 break;
319 }
158 } else { 320 } else {
159 while (argc-- > 0) { 321 while (argc-- > 0) {
160 name = *argv++; 322 name = *argv++;
161 323
162 fp = fopen (name, "r"); 324 fp = fopen(name, "r");
163 if (fp == NULL) { 325 if (fp == NULL) {
164 perror (name); 326 perror(name);
165 continue; 327 continue;
166 } 328 }
167 329
168 do_sed( fp, needle, newNeedle, ignoreCase, printFlag, quietFlag); 330 switch (sed_f) {
331 case f_none:
332 break;
333 case f_replace:
334 do_sed_repl(fp, needle, newNeedle, ignoreCase, printFlag,
335 quietFlag);
336 break;
337 case f_append:
338 do_sed_append(fp, appendline, quietFlag);
339 break;
340 }
169 341
170 if (ferror (fp)) 342 if (ferror(fp))
171 perror (name); 343 perror(name);
172 344
173 fclose (fp); 345 fclose(fp);
174 } 346 }
175 } 347 }
176 exit( TRUE); 348 exit(TRUE);
177} 349}
178 350
179 351
180/* END CODE */ 352/* END CODE */
181
182
diff --git a/util-linux/dmesg.c b/util-linux/dmesg.c
index aa26f5836..e38fd5555 100644
--- a/util-linux/dmesg.c
+++ b/util-linux/dmesg.c
@@ -44,10 +44,15 @@ int dmesg_main( int argc, char** argv )
44 int level = 0; 44 int level = 0;
45 int lastc; 45 int lastc;
46 int cmd = 3; 46 int cmd = 3;
47 int stopDoingThat;
48
49 argc--;
50 argv++;
47 51
48 /* Parse any options */ 52 /* Parse any options */
49 while (argc && **argv == '-') { 53 while (argc && **argv == '-') {
50 while (*++(*argv)) 54 stopDoingThat = FALSE;
55 while (stopDoingThat == FALSE && *++(*argv)) {
51 switch (**argv) { 56 switch (**argv) {
52 case 'c': 57 case 'c':
53 cmd = 4; 58 cmd = 4;
@@ -57,19 +62,22 @@ int dmesg_main( int argc, char** argv )
57 if (--argc == 0) 62 if (--argc == 0)
58 goto end; 63 goto end;
59 level = atoi (*(++argv)); 64 level = atoi (*(++argv));
60 --argc; 65 if (--argc > 0)
61 ++argv; 66 ++argv;
67 stopDoingThat = TRUE;
62 break; 68 break;
63 case 's': 69 case 's':
64 if (--argc == 0) 70 if (--argc == 0)
65 goto end; 71 goto end;
66 bufsize = atoi (*(++argv)); 72 bufsize = atoi (*(++argv));
67 --argc; 73 if (--argc > 0)
68 ++argv; 74 ++argv;
75 stopDoingThat = TRUE;
69 break; 76 break;
70 default: 77 default:
71 goto end; 78 goto end;
72 } 79 }
80 }
73 } 81 }
74 82
75 if (argc > 1) { 83 if (argc > 1) {