diff options
author | Marek Polacek <mmpolacek@gmail.com> | 2010-06-22 12:53:35 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-22 12:53:35 +0200 |
commit | fc6f6e933c20e6016d19339ac472f6af3d05d4c3 (patch) | |
tree | 00a93283553b40b34ec39516e4bd45f93bafd40d | |
parent | 6d9c88ad982dbe9cb9d5c375f42a4eb8d4aef39f (diff) | |
download | busybox-w32-fc6f6e933c20e6016d19339ac472f6af3d05d4c3.tar.gz busybox-w32-fc6f6e933c20e6016d19339ac472f6af3d05d4c3.tar.bz2 busybox-w32-fc6f6e933c20e6016d19339ac472f6af3d05d4c3.zip |
rev: new applet
text data bss dec hexfilename
377 0 0 377 179rev.o
Signed-off-by: Marek Polacek <mmpolacek@gmail.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | util-linux/rev.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/util-linux/rev.c b/util-linux/rev.c new file mode 100644 index 000000000..fa3a453ae --- /dev/null +++ b/util-linux/rev.c | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * rev implementation for busybox | ||
3 | * | ||
4 | * Copyright (C) 2010 Marek Polacek <mmpolacek@gmail.com> | ||
5 | * | ||
6 | * Licensed under GPLv2, see file License in this tarball for details. | ||
7 | */ | ||
8 | |||
9 | //applet:IF_REV(APPLET(rev, _BB_DIR_BIN, _BB_SUID_DROP)) | ||
10 | |||
11 | //kbuild:lib-$(CONFIG_REV) += rev.o | ||
12 | |||
13 | //config:config REV | ||
14 | //config: bool "rev" | ||
15 | //config: default y | ||
16 | //config: help | ||
17 | //config: Reverse lines of a file or files. | ||
18 | |||
19 | //usage:#define rev_trivial_usage | ||
20 | //usage: "[FILE]..." | ||
21 | //usage:#define rev_full_usage "\n\n" | ||
22 | //usage: "Reverse lines of FILE" | ||
23 | |||
24 | #include "libbb.h" | ||
25 | #include "unicode.h" | ||
26 | |||
27 | #undef CHAR_T | ||
28 | #if ENABLE_UNICODE_SUPPORT | ||
29 | # define CHAR_T wchar_t | ||
30 | #else | ||
31 | # define CHAR_T char | ||
32 | #endif | ||
33 | |||
34 | /* In-place invert */ | ||
35 | static void strrev(CHAR_T *s, int len) | ||
36 | { | ||
37 | int i; | ||
38 | |||
39 | if (len != 0) { | ||
40 | len--; | ||
41 | if (len != 0 && s[len] == '\n') | ||
42 | len--; | ||
43 | } | ||
44 | |||
45 | for (i = 0; i < len; i++, len--) { | ||
46 | CHAR_T c = s[i]; | ||
47 | s[i] = s[len]; | ||
48 | s[len] = c; | ||
49 | } | ||
50 | } | ||
51 | |||
52 | int rev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
53 | int rev_main(int argc UNUSED_PARAM, char **argv) | ||
54 | { | ||
55 | int retval; | ||
56 | size_t bufsize; | ||
57 | char *buf; | ||
58 | |||
59 | init_unicode(); | ||
60 | |||
61 | getopt32(argv, ""); | ||
62 | argv += optind; | ||
63 | if (!argv[0]) | ||
64 | argv = (char **)&bb_argv_dash; | ||
65 | |||
66 | retval = EXIT_SUCCESS; | ||
67 | bufsize = 256; | ||
68 | buf = xmalloc(bufsize); | ||
69 | do { | ||
70 | size_t pos; | ||
71 | FILE *fp; | ||
72 | |||
73 | fp = fopen_or_warn_stdin(*argv++); | ||
74 | if (!fp) { | ||
75 | retval = EXIT_FAILURE; | ||
76 | continue; | ||
77 | } | ||
78 | |||
79 | pos = 0; | ||
80 | while (1) { | ||
81 | /* Read one line */ | ||
82 | buf[bufsize - 1] = 1; /* not 0 */ | ||
83 | if (!fgets(buf + pos, bufsize - pos, fp)) | ||
84 | break; /* EOF/error */ | ||
85 | if (buf[bufsize - 1] == '\0' /* fgets filled entire buffer */ | ||
86 | && buf[bufsize - 2] != '\n' /* and did not read '\n' */ | ||
87 | && !feof(fp) | ||
88 | ) { | ||
89 | /* Line is too long, extend buffer */ | ||
90 | pos = bufsize - 1; | ||
91 | bufsize += 64 + bufsize / 8; | ||
92 | buf = xrealloc(buf, bufsize); | ||
93 | continue; | ||
94 | } | ||
95 | |||
96 | /* Process and print it */ | ||
97 | #if ENABLE_UNICODE_SUPPORT | ||
98 | { | ||
99 | wchar_t *tmp = xmalloc(bufsize * sizeof(wchar_t)); | ||
100 | /* Convert to wchar_t (might error out!) */ | ||
101 | int len = mbstowcs(tmp, buf, bufsize); | ||
102 | if (len >= 0) { | ||
103 | strrev(tmp, len); | ||
104 | /* Convert back to char */ | ||
105 | wcstombs(buf, tmp, bufsize); | ||
106 | } | ||
107 | free(tmp); | ||
108 | } | ||
109 | #else | ||
110 | strrev(buf, strlen(buf)); | ||
111 | #endif | ||
112 | fputs(buf, stdout); | ||
113 | } | ||
114 | fclose(fp); | ||
115 | } while (*argv); | ||
116 | |||
117 | if (ENABLE_FEATURE_CLEAN_UP) | ||
118 | free(buf); | ||
119 | |||
120 | fflush_stdout_and_exit(retval); | ||
121 | } | ||