diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-26 13:32:30 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-03-26 13:32:30 +0000 |
commit | 08ec67bc62242503f77d9503fdbf820c9c12d856 (patch) | |
tree | 101a86c0fe86a07f786670ceca36bfcbdc2794ed | |
parent | cc2965fd236a85e5cac4fffa1c34057997780385 (diff) | |
download | busybox-w32-08ec67bc62242503f77d9503fdbf820c9c12d856.tar.gz busybox-w32-08ec67bc62242503f77d9503fdbf820c9c12d856.tar.bz2 busybox-w32-08ec67bc62242503f77d9503fdbf820c9c12d856.zip |
patch: add support for -R. ~ +110 byte. By Pascal Bellard <pascal.bellard AT ads-lu.com>
fbsplash: new applet by Michele Sanges <michele.sanges AT otomelara.it
function old new delta
fbsplash_main - 1525 +1525
fb_drawfullrectangle - 118 +118
static.param_value - 100 +100
packed_usage 23776 23872 +96
applet_names 1843 1852 +9
applet_main 1120 1124 +4
read_line_input 3156 3158 +2
applet_nameofs 560 562 +2
applet_install_loc 140 141 +1
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 6/0 up/down: 1857/0) Total: 1857 bytes
text data bss dec hex filename
799233 641 7380 807254 c5156 busybox_old
801202 641 7380 809223 c5907 busybox_unstripped
-rw-r--r-- | editors/patch.c | 52 | ||||
-rw-r--r-- | include/applets.h | 1 | ||||
-rw-r--r-- | include/usage.h | 14 | ||||
-rw-r--r-- | libbb/lineedit.c | 14 | ||||
-rw-r--r-- | miscutils/Config.in | 33 | ||||
-rw-r--r-- | miscutils/Kbuild | 1 | ||||
-rwxr-xr-x | testsuite/patch.tests | 20 |
7 files changed, 103 insertions, 32 deletions
diff --git a/editors/patch.c b/editors/patch.c index 2a2b130b9..6f42b835c 100644 --- a/editors/patch.c +++ b/editors/patch.c | |||
@@ -21,7 +21,7 @@ | |||
21 | 21 | ||
22 | #include "libbb.h" | 22 | #include "libbb.h" |
23 | 23 | ||
24 | static unsigned copy_lines(FILE *src_stream, FILE *dest_stream, unsigned lines_count) | 24 | static unsigned copy_lines(FILE *src_stream, FILE *dst_stream, unsigned lines_count) |
25 | { | 25 | { |
26 | while (src_stream && lines_count) { | 26 | while (src_stream && lines_count) { |
27 | char *line; | 27 | char *line; |
@@ -29,7 +29,7 @@ static unsigned copy_lines(FILE *src_stream, FILE *dest_stream, unsigned lines_c | |||
29 | if (line == NULL) { | 29 | if (line == NULL) { |
30 | break; | 30 | break; |
31 | } | 31 | } |
32 | if (fputs(line, dest_stream) == EOF) { | 32 | if (fputs(line, dst_stream) == EOF) { |
33 | bb_perror_msg_and_die("error writing to new file"); | 33 | bb_perror_msg_and_die("error writing to new file"); |
34 | } | 34 | } |
35 | free(line); | 35 | free(line); |
@@ -73,12 +73,14 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
73 | FILE *patch_file; | 73 | FILE *patch_file; |
74 | int patch_level; | 74 | int patch_level; |
75 | int ret = 0; | 75 | int ret = 0; |
76 | char plus = '+'; | ||
76 | 77 | ||
77 | xfunc_error_retval = 2; | 78 | xfunc_error_retval = 2; |
78 | { | 79 | { |
79 | const char *p = "-1"; | 80 | const char *p = "-1"; |
80 | const char *i = "-"; /* compat */ | 81 | const char *i = "-"; /* compat */ |
81 | getopt32(argv, "p:i:", &p, &i); | 82 | if (getopt32(argv, "p:i:R", &p, &i) & 4) |
83 | plus = '-'; | ||
82 | patch_level = xatoi(p); /* can be negative! */ | 84 | patch_level = xatoi(p); /* can be negative! */ |
83 | patch_file = xfopen_stdin(i); | 85 | patch_file = xfopen_stdin(i); |
84 | } | 86 | } |
@@ -91,8 +93,8 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
91 | char *new_filename; | 93 | char *new_filename; |
92 | char *backup_filename; | 94 | char *backup_filename; |
93 | unsigned src_cur_line = 1; | 95 | unsigned src_cur_line = 1; |
94 | unsigned dest_cur_line = 0; | 96 | unsigned dst_cur_line = 0; |
95 | unsigned dest_beg_line; | 97 | unsigned dst_beg_line; |
96 | unsigned bad_hunk_count = 0; | 98 | unsigned bad_hunk_count = 0; |
97 | unsigned hunk_count = 0; | 99 | unsigned hunk_count = 0; |
98 | smallint copy_trailing_lines_flag = 0; | 100 | smallint copy_trailing_lines_flag = 0; |
@@ -143,15 +145,26 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
143 | unsigned src_beg_line; | 145 | unsigned src_beg_line; |
144 | unsigned hunk_offset_start; | 146 | unsigned hunk_offset_start; |
145 | unsigned src_last_line = 1; | 147 | unsigned src_last_line = 1; |
148 | unsigned dst_last_line = 1; | ||
146 | 149 | ||
147 | if ((sscanf(patch_line, "@@ -%d,%d +%d", &src_beg_line, &src_last_line, &dest_beg_line) != 3) | 150 | if ((sscanf(patch_line, "@@ -%d,%d +%d,%d", &src_beg_line, &src_last_line, &dst_beg_line, &dst_last_line) < 3) |
148 | && (sscanf(patch_line, "@@ -%d +%d", &src_beg_line, &dest_beg_line) != 2) | 151 | && (sscanf(patch_line, "@@ -%d +%d,%d", &src_beg_line, &dst_beg_line, &dst_last_line) < 2) |
149 | ) { /* No more hunks for this file */ | 152 | ) { |
153 | /* No more hunks for this file */ | ||
150 | break; | 154 | break; |
151 | } | 155 | } |
156 | if (plus != '+') { | ||
157 | /* reverse patch */ | ||
158 | unsigned tmp = src_last_line; | ||
159 | src_last_line = dst_last_line; | ||
160 | dst_last_line = tmp; | ||
161 | tmp = src_beg_line; | ||
162 | src_beg_line = dst_beg_line; | ||
163 | dst_beg_line = tmp; | ||
164 | } | ||
152 | hunk_count++; | 165 | hunk_count++; |
153 | 166 | ||
154 | if (src_beg_line && dest_beg_line) { | 167 | if (src_beg_line && dst_beg_line) { |
155 | /* Copy unmodified lines upto start of hunk */ | 168 | /* Copy unmodified lines upto start of hunk */ |
156 | /* src_beg_line will be 0 if it's a new file */ | 169 | /* src_beg_line will be 0 if it's a new file */ |
157 | count = src_beg_line - src_cur_line; | 170 | count = src_beg_line - src_cur_line; |
@@ -159,14 +172,15 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
159 | bb_error_msg_and_die("bad src file"); | 172 | bb_error_msg_and_die("bad src file"); |
160 | } | 173 | } |
161 | src_cur_line += count; | 174 | src_cur_line += count; |
162 | dest_cur_line += count; | 175 | dst_cur_line += count; |
163 | copy_trailing_lines_flag = 1; | 176 | copy_trailing_lines_flag = 1; |
164 | } | 177 | } |
165 | src_last_line += hunk_offset_start = src_cur_line; | 178 | src_last_line += hunk_offset_start = src_cur_line; |
179 | dst_last_line += dst_cur_line; | ||
166 | 180 | ||
167 | while (1) { | 181 | while (1) { |
168 | free(patch_line); | 182 | free(patch_line); |
169 | patch_line = xmalloc_fgets(patch_file); | 183 | patch_line = xmalloc_fgets(patch_file); |
170 | if (patch_line == NULL) | 184 | if (patch_line == NULL) |
171 | break; /* EOF */ | 185 | break; /* EOF */ |
172 | if ((*patch_line != '-') && (*patch_line != '+') | 186 | if ((*patch_line != '-') && (*patch_line != '+') |
@@ -174,7 +188,7 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
174 | ) { | 188 | ) { |
175 | break; /* End of hunk */ | 189 | break; /* End of hunk */ |
176 | } | 190 | } |
177 | if (*patch_line != '+') { /* '-', ' ' or '\n' */ | 191 | if (*patch_line != plus) { /* '-' or ' ' */ |
178 | char *src_line = NULL; | 192 | char *src_line = NULL; |
179 | if (src_cur_line == src_last_line) | 193 | if (src_cur_line == src_last_line) |
180 | break; | 194 | break; |
@@ -184,7 +198,8 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
184 | int diff = strcmp(src_line, patch_line + 1); | 198 | int diff = strcmp(src_line, patch_line + 1); |
185 | src_cur_line++; | 199 | src_cur_line++; |
186 | free(src_line); | 200 | free(src_line); |
187 | if (diff) src_line = NULL; | 201 | if (diff) |
202 | src_line = NULL; | ||
188 | } | 203 | } |
189 | } | 204 | } |
190 | if (!src_line) { | 205 | if (!src_line) { |
@@ -192,12 +207,14 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
192 | bad_hunk_count++; | 207 | bad_hunk_count++; |
193 | break; | 208 | break; |
194 | } | 209 | } |
195 | if (*patch_line == '-') { | 210 | if (*patch_line != ' ') { /* '-' */ |
196 | continue; | 211 | continue; |
197 | } | 212 | } |
198 | } | 213 | } |
214 | if (dst_cur_line == dst_last_line) | ||
215 | break; | ||
199 | fputs(patch_line + 1, dst_stream); | 216 | fputs(patch_line + 1, dst_stream); |
200 | dest_cur_line++; | 217 | dst_cur_line++; |
201 | } /* end of while loop handling one hunk */ | 218 | } /* end of while loop handling one hunk */ |
202 | } /* end of while loop handling one file */ | 219 | } /* end of while loop handling one file */ |
203 | 220 | ||
@@ -217,7 +234,7 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
217 | if (backup_filename) { | 234 | if (backup_filename) { |
218 | unlink(backup_filename); | 235 | unlink(backup_filename); |
219 | } | 236 | } |
220 | if ((dest_cur_line == 0) || (dest_beg_line == 0)) { | 237 | if ((dst_cur_line == 0) || (dst_beg_line == 0)) { |
221 | /* The new patched file is empty, remove it */ | 238 | /* The new patched file is empty, remove it */ |
222 | xunlink(new_filename); | 239 | xunlink(new_filename); |
223 | // /* old_filename and new_filename may be the same file */ | 240 | // /* old_filename and new_filename may be the same file */ |
@@ -228,8 +245,7 @@ int patch_main(int argc ATTRIBUTE_UNUSED, char **argv) | |||
228 | //free(old_filename); | 245 | //free(old_filename); |
229 | free(new_filename); | 246 | free(new_filename); |
230 | } /* end of "while there are patch lines" */ | 247 | } /* end of "while there are patch lines" */ |
231 | quit: | 248 | quit: |
232 | |||
233 | /* 0 = SUCCESS | 249 | /* 0 = SUCCESS |
234 | * 1 = Some hunks failed | 250 | * 1 = Some hunks failed |
235 | * 2 = More serious problems (exited earlier) | 251 | * 2 = More serious problems (exited earlier) |
diff --git a/include/applets.h b/include/applets.h index 13c464887..1917f2afa 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -149,6 +149,7 @@ USE_EXPR(APPLET(expr, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | |||
149 | USE_FAKEIDENTD(APPLET(fakeidentd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | 149 | USE_FAKEIDENTD(APPLET(fakeidentd, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) |
150 | USE_FALSE(APPLET_NOFORK(false, false, _BB_DIR_BIN, _BB_SUID_NEVER, false)) | 150 | USE_FALSE(APPLET_NOFORK(false, false, _BB_DIR_BIN, _BB_SUID_NEVER, false)) |
151 | USE_FBSET(APPLET(fbset, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | 151 | USE_FBSET(APPLET(fbset, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) |
152 | USE_FBSPLASH(APPLET(fbsplash, _BB_DIR_BIN, _BB_SUID_NEVER)) | ||
152 | USE_FDFLUSH(APPLET_ODDNAME(fdflush, freeramdisk, _BB_DIR_BIN, _BB_SUID_NEVER, fdflush)) | 153 | USE_FDFLUSH(APPLET_ODDNAME(fdflush, freeramdisk, _BB_DIR_BIN, _BB_SUID_NEVER, fdflush)) |
153 | USE_FDFORMAT(APPLET(fdformat, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 154 | USE_FDFORMAT(APPLET(fdformat, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
154 | USE_FDISK(APPLET(fdisk, _BB_DIR_SBIN, _BB_SUID_NEVER)) | 155 | USE_FDISK(APPLET(fdisk, _BB_DIR_SBIN, _BB_SUID_NEVER)) |
diff --git a/include/usage.h b/include/usage.h index 71c958260..11f235c89 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -120,6 +120,17 @@ | |||
120 | "$ basename /foo/bar.txt .txt\n" \ | 120 | "$ basename /foo/bar.txt .txt\n" \ |
121 | "bar" | 121 | "bar" |
122 | 122 | ||
123 | #define fbsplash_trivial_usage \ | ||
124 | "[-c] [-d DEV] [-s IMGFILE] [-i INIFILE] [-f CMD]" | ||
125 | #define fbsplash_full_usage \ | ||
126 | "Options:\n" \ | ||
127 | "\n -c Hide cursor" \ | ||
128 | "\n -d Framebuffer device (default /dev/fb0)" \ | ||
129 | "\n -s Splash image" \ | ||
130 | "\n -i Config file" \ | ||
131 | "\n -f Control pipe (else exit after drawing image)" \ | ||
132 | "\n commands: 'NN' (% for progressbar) or 'exit'" \ | ||
133 | |||
123 | #define brctl_trivial_usage \ | 134 | #define brctl_trivial_usage \ |
124 | "COMMAND [BRIDGE [INTERFACE]]" | 135 | "COMMAND [BRIDGE [INTERFACE]]" |
125 | #define brctl_full_usage \ | 136 | #define brctl_full_usage \ |
@@ -2838,10 +2849,11 @@ | |||
2838 | ) | 2849 | ) |
2839 | 2850 | ||
2840 | #define patch_trivial_usage \ | 2851 | #define patch_trivial_usage \ |
2841 | "[-p NUM] [-i DIFF]" | 2852 | "[-p NUM] [-i DIFF] [-R]" |
2842 | #define patch_full_usage \ | 2853 | #define patch_full_usage \ |
2843 | " -p NUM Strip NUM leading components from file names" \ | 2854 | " -p NUM Strip NUM leading components from file names" \ |
2844 | "\n -i DIFF Read DIFF instead of stdin" \ | 2855 | "\n -i DIFF Read DIFF instead of stdin" \ |
2856 | "\n -R Reverse patch" \ | ||
2845 | 2857 | ||
2846 | #define patch_example_usage \ | 2858 | #define patch_example_usage \ |
2847 | "$ patch -p1 < example.diff\n" \ | 2859 | "$ patch -p1 < example.diff\n" \ |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index b25386bc0..5d65665d3 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -958,14 +958,16 @@ static void load_history(const char *fromfile) | |||
958 | FILE *fp; | 958 | FILE *fp; |
959 | int hi; | 959 | int hi; |
960 | 960 | ||
961 | /* cleanup old */ | 961 | /* NB: do not trash old history if file can't be opened */ |
962 | for (hi = state->cnt_history; hi > 0;) { | ||
963 | hi--; | ||
964 | free(state->history[hi]); | ||
965 | } | ||
966 | 962 | ||
967 | fp = fopen(fromfile, "r"); | 963 | fp = fopen(fromfile, "r"); |
968 | if (fp) { | 964 | if (fp) { |
965 | /* clean up old history */ | ||
966 | for (hi = state->cnt_history; hi > 0;) { | ||
967 | hi--; | ||
968 | free(state->history[hi]); | ||
969 | } | ||
970 | |||
969 | for (hi = 0; hi < MAX_HISTORY;) { | 971 | for (hi = 0; hi < MAX_HISTORY;) { |
970 | char *hl = xmalloc_getline(fp); | 972 | char *hl = xmalloc_getline(fp); |
971 | int l; | 973 | int l; |
@@ -982,8 +984,8 @@ static void load_history(const char *fromfile) | |||
982 | state->history[hi++] = hl; | 984 | state->history[hi++] = hl; |
983 | } | 985 | } |
984 | fclose(fp); | 986 | fclose(fp); |
987 | state->cur_history = state->cnt_history = hi; | ||
985 | } | 988 | } |
986 | state->cur_history = state->cnt_history = hi; | ||
987 | } | 989 | } |
988 | 990 | ||
989 | /* state->flags is already checked to be nonzero */ | 991 | /* state->flags is already checked to be nonzero */ |
diff --git a/miscutils/Config.in b/miscutils/Config.in index e149e41c9..04c9a0c54 100644 --- a/miscutils/Config.in +++ b/miscutils/Config.in | |||
@@ -194,12 +194,33 @@ config EJECT | |||
194 | Used to eject cdroms. (defaults to /dev/cdrom) | 194 | Used to eject cdroms. (defaults to /dev/cdrom) |
195 | 195 | ||
196 | config FEATURE_EJECT_SCSI | 196 | config FEATURE_EJECT_SCSI |
197 | bool "SCSI support" | 197 | bool "SCSI support" |
198 | default n | 198 | default n |
199 | depends on EJECT | 199 | depends on EJECT |
200 | help | 200 | help |
201 | Add the -s option to eject, this allows to eject SCSI-Devices and | 201 | Add the -s option to eject, this allows to eject SCSI-Devices and |
202 | usb-storage devices. | 202 | usb-storage devices. |
203 | |||
204 | config FBSPLASH | ||
205 | bool "fbsplash" | ||
206 | default n | ||
207 | help | ||
208 | Shows splash image and progress bar on framebuffer device. | ||
209 | Can be used during boot phase of an embedded device. ~2kb. | ||
210 | Usage: | ||
211 | - use kernel option 'vga=xxx' or otherwise enable fb device. | ||
212 | - put somewhere the fbsplash.ini file and image in .ppm format. | ||
213 | - $ setsid fbsplash [params] & | ||
214 | -c: hide cursor | ||
215 | -d /dev/fbN: framebuffer device (if not /dev/fb0) | ||
216 | -s path_of_image_file | ||
217 | -i path_of_ini_file | ||
218 | -f path_of_fifo (can be "-" for stdin) | ||
219 | - if you want to run applet only in presence of kernel parameter: | ||
220 | grep -q "fbsplash=on" </proc/cmdline && setsid fbsplash [params] & | ||
221 | - commands for fifo: | ||
222 | "NN" (ASCII decimal number) - percentage to show on progress bar | ||
223 | "exit" (or just close fifo) - well you guessed it | ||
203 | 224 | ||
204 | config LAST | 225 | config LAST |
205 | bool "last" | 226 | bool "last" |
diff --git a/miscutils/Kbuild b/miscutils/Kbuild index 51187c556..513c03882 100644 --- a/miscutils/Kbuild +++ b/miscutils/Kbuild | |||
@@ -14,6 +14,7 @@ lib-$(CONFIG_CRONTAB) += crontab.o | |||
14 | lib-$(CONFIG_DC) += dc.o | 14 | lib-$(CONFIG_DC) += dc.o |
15 | lib-$(CONFIG_DEVFSD) += devfsd.o | 15 | lib-$(CONFIG_DEVFSD) += devfsd.o |
16 | lib-$(CONFIG_EJECT) += eject.o | 16 | lib-$(CONFIG_EJECT) += eject.o |
17 | lib-$(CONFIG_FBSPLASH) += fbsplash.o | ||
17 | lib-$(CONFIG_HDPARM) += hdparm.o | 18 | lib-$(CONFIG_HDPARM) += hdparm.o |
18 | lib-$(CONFIG_LAST) += last.o | 19 | lib-$(CONFIG_LAST) += last.o |
19 | lib-$(CONFIG_LESS) += less.o | 20 | lib-$(CONFIG_LESS) += less.o |
diff --git a/testsuite/patch.tests b/testsuite/patch.tests index 8a957d3f7..cfe69b76a 100755 --- a/testsuite/patch.tests +++ b/testsuite/patch.tests | |||
@@ -26,7 +26,7 @@ zxc | |||
26 | " \ | 26 | " \ |
27 | 27 | ||
28 | testing "patch with nonexistent old_file" \ | 28 | testing "patch with nonexistent old_file" \ |
29 | "strace -o zzz patch; echo $?; cat input" \ | 29 | "patch; echo $?; cat input" \ |
30 | "\ | 30 | "\ |
31 | patching file input | 31 | patching file input |
32 | 0 | 32 | 0 |
@@ -44,4 +44,22 @@ zxc | |||
44 | zxc | 44 | zxc |
45 | " \ | 45 | " \ |
46 | 46 | ||
47 | testing "patch -R with nonexistent old_file" \ | ||
48 | "patch -R; echo $?; cat input" \ | ||
49 | "\ | ||
50 | patching file input | ||
51 | 0 | ||
52 | qwe | ||
53 | zxc | ||
54 | " \ | ||
55 | "qwe\nasd\nzxc\n" \ | ||
56 | "\ | ||
57 | --- input.doesnt_exist Jan 01 01:01:01 2000 | ||
58 | +++ input Jan 01 01:01:01 2000 | ||
59 | @@ -1,2 +1,3 @@ | ||
60 | qwe | ||
61 | +asd | ||
62 | zxc | ||
63 | " \ | ||
64 | |||
47 | exit $FAILCOUNT | 65 | exit $FAILCOUNT |