Changeset d553f81 in mainline


Ignore:
Timestamp:
2011-03-24T18:31:01Z (13 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
fb2ceeb
Parents:
8f29507f
git-author:
Martin Sucha <> (2011-03-24 18:31:01)
git-committer:
Jakub Jermar <jakub@…> (2011-03-24 18:31:01)
Message:

Support for —more and —hex for 'cat'.
(Thanks to Martin Sucha).

Location:
uspace/app/bdsh/cmds/modules/cat
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/bdsh/cmds/modules/cat/cat.c

    r8f29507f rd553f81  
    11/* Copyright (c) 2008, Tim Post <tinkertim@gmail.com>
     2 * Copyright (c) 2011, Martin Sucha
    23 * All rights reserved.
    34 *
     
    3536#include <str.h>
    3637#include <fcntl.h>
     38#include <io/console.h>
     39#include <io/color.h>
     40#include <io/style.h>
     41#include <errno.h>
     42#include <vfs/vfs.h>
     43#include <assert.h>
    3744
    3845#include "config.h"
     
    4855
    4956static const char *cat_oops = "That option is not yet supported\n";
     57static const char *hexchars = "0123456789abcdef";
     58
     59static bool paging_enabled = false;
     60static size_t chars_remaining = 0;
     61static size_t lines_remaining = 0;
     62static sysarg_t console_cols = 0;
     63static sysarg_t console_rows = 0;
    5064
    5165static struct option const long_options[] = {
     
    5670        { "buffer", required_argument, 0, 'b' },
    5771        { "more", no_argument, 0, 'm' },
     72        { "hex", no_argument, 0, 'x' },
    5873        { 0, 0, 0, 0 }
    5974};
     
    7590                "  -b, --buffer ##  Set the read buffer size to ##\n"
    7691                "  -m, --more       Pause after each screen full\n"
     92                "  -x, --hex        Print bytes as hex values\n"
    7793                "Currently, %s is under development, some options don't work.\n",
    7894                cmdname, cmdname);
     
    8298}
    8399
    84 static unsigned int cat_file(const char *fname, size_t blen)
     100static void waitprompt()
     101{
     102        console_set_pos(fphone(stdout), 0, console_rows-1);
     103        console_set_color(fphone(stdout), COLOR_BLUE, COLOR_WHITE, 0);
     104        printf("Press any key to continue");
     105        fflush(stdout);
     106        console_set_style(fphone(stdout), STYLE_NORMAL);
     107}
     108
     109static void waitkey()
     110{
     111        console_event_t ev;
     112       
     113        while (true) {
     114                if (!console_get_event(fphone(stdin), &ev)) {
     115                        return;
     116                }
     117                if (ev.type == KEY_PRESS) {
     118                        return;
     119                }
     120        }
     121        assert(false);
     122}
     123
     124static void newpage()
     125{
     126        console_clear(fphone(stdout));
     127        chars_remaining = console_cols;
     128        lines_remaining = console_rows-1;
     129}
     130
     131static void paged_char(wchar_t c)
     132{
     133        putchar(c);
     134        if (paging_enabled) {
     135                chars_remaining--;
     136                if (c == '\n' || chars_remaining == 0) {
     137                        chars_remaining = console_cols;
     138                        lines_remaining--;
     139                }
     140                if (lines_remaining == 0) {
     141                        fflush(stdout);
     142                        waitprompt();
     143                        waitkey();
     144                        newpage();
     145                }
     146        }
     147}
     148
     149static unsigned int cat_file(const char *fname, size_t blen, bool hex)
    85150{
    86151        int fd, bytes = 0, count = 0, reads = 0;
    87152        off64_t total = 0;
    88153        char *buff = NULL;
     154        int i;
     155        size_t offset = 0;
    89156
    90157        fd = open(fname, O_RDONLY);
     
    109176                        count += bytes;
    110177                        buff[bytes] = '\0';
    111                         printf("%s", buff);
     178                        offset = 0;
     179                        for (i = 0; i < bytes; i++) {
     180                                if (hex) {
     181                                        paged_char(hexchars[((uint8_t)buff[i])/16]);
     182                                        paged_char(hexchars[((uint8_t)buff[i])%16]);
     183                                }
     184                                else {
     185                                        wchar_t c = str_decode(buff, &offset, bytes);
     186                                        if (c == 0) {
     187                                                // reached end of string
     188                                                break;
     189                                        }
     190                                        paged_char(c);
     191                                }
     192                               
     193                        }
    112194                        reads++;
    113195                }
     
    131213        unsigned int argc, i, ret = 0, buffer = 0;
    132214        int c, opt_ind;
     215        bool hex = false;
     216        bool more = false;
     217        sysarg_t rows, cols;
     218        int rc;
     219       
     220        // reset global state
     221        // TODO: move to structure?
     222        paging_enabled = false;
     223        chars_remaining = 0;
     224        lines_remaining = 0;
     225        console_cols = 0;
     226        console_rows = 0;
    133227
    134228        argc = cli_count_args(argv);
    135229
    136230        for (c = 0, optind = 0, opt_ind = 0; c != -1;) {
    137                 c = getopt_long(argc, argv, "hvmH:t:b:", long_options, &opt_ind);
     231                c = getopt_long(argc, argv, "xhvmH:t:b:", long_options, &opt_ind);
    138232                switch (c) {
    139233                case 'h':
     
    153247                        break;
    154248                case 'm':
    155                         printf("%s", cat_oops);
    156                         return CMD_FAILURE;
     249                        more = true;
     250                        break;
     251                case 'x':
     252                        hex = true;
     253                        break;
    157254                }
    158255        }
     
    168265        if (buffer <= 0)
    169266                buffer = CAT_DEFAULT_BUFLEN;
     267       
     268        if (more) {
     269                rc = console_get_size(fphone(stdout), &cols, &rows);
     270                if (rc != EOK) {
     271                        printf("%s - cannot get console size\n", cmdname);
     272                        return CMD_FAILURE;
     273                }
     274                console_cols = cols;
     275                console_rows = rows;
     276                paging_enabled = true;
     277                newpage();
     278        }
    170279
    171280        for (i = optind; argv[i] != NULL; i++)
    172                 ret += cat_file(argv[i], buffer);
     281                ret += cat_file(argv[i], buffer, hex);
    173282
    174283        if (ret)
  • uspace/app/bdsh/cmds/modules/cat/cat.h

    r8f29507f rd553f81  
    44/* Prototypes for the cat command, excluding entry points */
    55
    6 static unsigned int cat_file(const char *, size_t);
     6static unsigned int cat_file(const char *, size_t, bool);
    77
    88#endif /* CAT_H */
Note: See TracChangeset for help on using the changeset viewer.