less: stop using data/bss. Code got smaller too.
authorDenis Vlasenko <vda.linux@googlemail.com>
Thu, 31 May 2007 15:55:03 +0000 (15:55 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Thu, 31 May 2007 15:55:03 +0000 (15:55 -0000)
# size busybox_old busybox_unstripped
   text    data     bss     dec     hex filename
 700719    2896   17880  721495   b0257 busybox_old
 700547    2832   17432  720811   affab busybox_unstripped
# size */*/less.o
   text    data     bss     dec     hex filename
   6861      50     344    7255    1c57 busybox.t0/miscutils/less.o
   6657       0       0    6657    1a01 busybox.t1/miscutils/less.o

miscutils/less.c

index 3df1f3785c2d69c50c017b0b4049dfa33df3b65a..d6b71b9f292cd6092aca9ca7fd090e5e1ef26a15 100644 (file)
@@ -72,27 +72,6 @@ enum {
        TILDES = 1,
 };
 
-static unsigned max_displayed_line;
-static unsigned width;
-static const char *empty_line_marker = "~";
-
-static char *filename;
-static char **files;
-static unsigned num_files = 1;
-static unsigned current_file = 1;
-static const char **buffer;
-static const char **flines;
-static int cur_fline; /* signed */
-static unsigned max_fline;
-static unsigned max_lineno; /* this one tracks linewrap */
-
-static ssize_t eof_error = 1; /* eof if 0, error if < 0 */
-static char terminated = 1;
-static size_t readpos;
-static size_t readeof;
-/* last position in last line, taking into account tabs */
-static size_t linepos;
-
 /* Command line options */
 enum {
        FLAG_E = 1,
@@ -104,25 +83,79 @@ enum {
        LESS_STATE_MATCH_BACKWARDS = 1 << 15,
 };
 
-#if ENABLE_FEATURE_LESS_MARKS
-static unsigned mark_lines[15][2];
-static unsigned num_marks;
+#if !ENABLE_FEATURE_LESS_REGEXP
+enum { pattern_valid = 0 };
 #endif
 
+struct globals {
+       int cur_fline; /* signed */
+       int kbd_fd;  /* fd to get input from */
+/* last position in last line, taking into account tabs */
+       size_t linepos;
+       unsigned max_displayed_line;
+       unsigned max_fline;
+       unsigned max_lineno; /* this one tracks linewrap */
+       unsigned width;
+       ssize_t eof_error; /* eof if 0, error if < 0 */
+       size_t readpos;
+       size_t readeof;
+       const char **buffer;
+       const char **flines;
+       const char *empty_line_marker;
+       unsigned num_files;
+       unsigned current_file;
+       char *filename;
+       char **files;
+#if ENABLE_FEATURE_LESS_MARKS
+       unsigned num_marks;
+       unsigned mark_lines[15][2];
+#endif
 #if ENABLE_FEATURE_LESS_REGEXP
-static unsigned *match_lines;
-static int match_pos; /* signed! */
-static unsigned num_matches;
-static regex_t pattern;
-static unsigned pattern_valid;
-#else
-enum { pattern_valid = 0 };
+       unsigned *match_lines;
+       int match_pos; /* signed! */
+       unsigned num_matches;
+       regex_t pattern;
+       smallint pattern_valid;
 #endif
-
-static struct termios term_orig, term_vi;
-
-/* File pointer to get input from */
-static int kbd_fd;
+       smallint terminated;
+       struct termios term_orig, term_less;
+};
+#define G (*ptr_to_globals)
+#define cur_fline           (G.cur_fline         )
+#define kbd_fd              (G.kbd_fd            )
+#define linepos             (G.linepos           )
+#define max_displayed_line  (G.max_displayed_line)
+#define max_fline           (G.max_fline         )
+#define max_lineno          (G.max_lineno        )
+#define width               (G.width             )
+#define eof_error           (G.eof_error         )
+#define readpos             (G.readpos           )
+#define readeof             (G.readeof           )
+#define buffer              (G.buffer            )
+#define flines              (G.flines            )
+#define empty_line_marker   (G.empty_line_marker )
+#define num_files           (G.num_files         )
+#define current_file        (G.current_file      )
+#define filename            (G.filename          )
+#define files               (G.files             )
+#define num_marks           (G.num_marks         )
+#define mark_lines          (G.mark_lines        )
+#define match_lines         (G.match_lines       )
+#define match_pos           (G.match_pos         )
+#define num_matches         (G.num_matches       )
+#define pattern             (G.pattern           )
+#define pattern_valid       (G.pattern_valid     )
+#define terminated          (G.terminated        )
+#define term_orig           (G.term_orig         )
+#define term_less           (G.term_less         )
+#define INIT_G() do { \
+               PTR_TO_GLOBALS = xzalloc(sizeof(G)); \
+               empty_line_marker = "~"; \
+               num_files = 1; \
+               current_file = 1; \
+               eof_error = 1; \
+               terminated = 1; \
+       } while (0)
 
 /* Reset terminal input to normal */
 static void set_tty_cooked(void)
@@ -380,12 +413,12 @@ static void cap_cur_fline(int nlines)
        }
 }
 
-static char controls[] =
+static const char controls[] =
        /* NUL: never encountered; TAB: not converted */
        /**/"\x01\x02\x03\x04\x05\x06\x07\x08"  "\x0a\x0b\x0c\x0d\x0e\x0f"
        "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
        "\x7f\x9b"; /* DEL and infamous Meta-ESC :( */
-static char ctrlconv[] =
+static const char ctrlconv[] =
        /* '\n': it's a former NUL - subst with '@', not 'J' */
        "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x40\x4b\x4c\x4d\x4e\x4f"
        "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f";
@@ -604,7 +637,7 @@ static void getch_nowait(char* input, int sz)
                FD_SET(0, &readfds);
        }
        FD_SET(kbd_fd, &readfds);
-       tcsetattr(kbd_fd, TCSANOW, &term_vi);
+       tcsetattr(kbd_fd, TCSANOW, &term_less);
        select(kbd_fd + 1, &readfds, NULL, NULL, NULL);
 
        input[0] = '\0';
@@ -668,7 +701,7 @@ static char* less_gets(int sz)
 
                /* I be damned if I know why is it needed *repeatedly*,
                 * but it is needed. Is it because of stdio? */
-               tcsetattr(kbd_fd, TCSANOW, &term_vi);
+               tcsetattr(kbd_fd, TCSANOW, &term_less);
 
                read(kbd_fd, &c, 1);
                if (c == 0x0d)
@@ -1244,6 +1277,8 @@ int less_main(int argc, char **argv)
 {
        int keypress;
 
+       INIT_G();
+
        /* TODO: -x: do not interpret backspace, -xx: tab also */
        /* -xxx: newline also */
        /* -w N: assume width N (-xxx -w 32: hex viewer of sorts) */
@@ -1283,16 +1318,16 @@ int less_main(int argc, char **argv)
        tcgetattr(kbd_fd, &term_orig);
        signal(SIGTERM, sig_catcher);
        signal(SIGINT, sig_catcher);
-       term_vi = term_orig;
-       term_vi.c_lflag &= ~(ICANON | ECHO);
-       term_vi.c_iflag &= ~(IXON | ICRNL);
-       /*term_vi.c_oflag &= ~ONLCR;*/
-       term_vi.c_cc[VMIN] = 1;
-       term_vi.c_cc[VTIME] = 0;
+       term_less = term_orig;
+       term_less.c_lflag &= ~(ICANON | ECHO);
+       term_less.c_iflag &= ~(IXON | ICRNL);
+       /*term_less.c_oflag &= ~ONLCR;*/
+       term_less.c_cc[VMIN] = 1;
+       term_less.c_cc[VTIME] = 0;
 
        /* Want to do it just once, but it doesn't work, */
        /* so we are redoing it (see code above). Mystery... */
-       /*tcsetattr(kbd_fd, TCSANOW, &term_vi);*/
+       /*tcsetattr(kbd_fd, TCSANOW, &term_less);*/
 
        reinitialize();
        while (1) {