source: branches/3.2/mindi-busybox/util-linux/rev.c @ 3232

Last change on this file since 3232 was 3232, checked in by bruno, 5 years ago
  • Update mindi-busybox to 1.21.1
  • Property svn:eol-style set to native
File size: 2.3 KB
Line 
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 source tree.
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 */
35static 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
52int rev_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
53int 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}
Note: See TracBrowser for help on using the repository browser.