Contents of /tags/mkinitrd-6_5_1/busybox/util-linux/rev.c
Parent Directory | Revision Log
Revision 1519 -
(show annotations)
(download)
Wed Sep 7 17:51:16 2011 UTC (13 years ago) by niro
File MIME type: text/plain
File size: 2336 byte(s)
Wed Sep 7 17:51:16 2011 UTC (13 years ago) by niro
File MIME type: text/plain
File size: 2336 byte(s)
tagged 'mkinitrd-6_5_1'
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 | } |