[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [tyndur-devel] [PATCH] bincat: Positionsangabe moeglich (wird auf 1k-Bloecke gerundet)



On Sun, Aug 09 11:10, Alexander Siol wrote:
> +bincat: Positionsangaben (Start, Länge und Ende)
> *bincat: Umstellung auf getopt
> ---
>  trunk/src/modules/c/shell/cmds/bincat.c |  104 ++++++++++++++++++++++++++++---
>  1 files changed, 96 insertions(+), 8 deletions(-)
> 
> diff --git a/trunk/src/modules/c/shell/cmds/bincat.c b/trunk/src/modules/c/shell/cmds/bincat.c
> index 8c0372e..c8fd907 100644
> --- a/trunk/src/modules/c/shell/cmds/bincat.c
> +++ b/trunk/src/modules/c/shell/cmds/bincat.c
> @@ -1,8 +1,8 @@
>  /*
> - * Copyright (c) 2007 The tyndur Project. All rights reserved.
> + * Copyright (c) 2007-2009 The tyndur Project. All rights reserved.
>   *
>   * This code is derived from software contributed to the tyndur Project
> - * by Antoine Kaufmann.
> + * by Antoine Kaufmann, Alexander Siol
>   *
>   * Redistribution and use in source and binary forms, with or without
>   * modification, are permitted provided that the following conditions
> @@ -38,35 +38,116 @@
>  #include "stdio.h"
>  #include "unistd.h"
>  #include <lost/config.h>
> +#include <getopt.h>
> +#include <errno.h>
>  
>  #define BLOCK_SIZE 1024
>  
>  void bincat_display_usage(void);
>  
> +#define min(a,b) (a < b)?(a):(b);
Weg damit, wird ja, soweit ich sehe nicht benutzt

> +
>  #ifdef CONFIG_SHELL_BUILTIN_ONLY
>      int shell_command_bincat(int argc, char* argv[], const char* args)
>  #else
>      int main(int argc, char* argv[])
>  #endif
>  {
> -    if (argc != 2) {
> +    static const struct option long_options[] =
> +    {
> +        { "start", required_argument,  0, 's' },
> +        { "length", required_argument, 0, 'l' },
> +        { "end", required_argument,    0, 'e' },
> +        { "help", no_argument,         0, 'h' },
> +        { 0, 0, 0, 0 }
> +    };
> +
> +    optind = 0;
> +    uint64_t start = 0;
> +    uint64_t end = 0;
> +    uint64_t length = 0;
> +    char *path = NULL;
> +    int n = 0;
> +    int m = 0;
> +    size_t total_read = 0;
> +
> +
> +    while (optind < argc) {
> +        int result = getopt_long(argc, argv, "s:l:e:h", long_options, NULL);
> +        if (result == -1) {
> +            break;
> +        }
> +        errno = 0;
> +        switch (result) {
> +            case 's':
> +                start = strtoull(optarg, NULL, 0);
> +                if (errno) {
> +                    printf("Ihre Startangabe war ungültig!\n");
> +                    start = 0;
> +                }

Hier vielleicht auch pruefen ob der Kram Block-aligned ist, und ggf.
abbrechen/korrigieren und warnen?

> +                break;
> +            case 'l':
> +                length = strtoull(optarg, NULL, 0);
> +                if (errno) {
> +                    printf("Ihre Längenangabe war ungültig!\n");
> +                    start = 0;
> +                }
> +                break;
> +            case 'e':
> +                end = strtoull(optarg, NULL, 0);
> +                if (errno) {
> +                    printf("Ihre Endangabe war ungültig!\n");
> +                    start = 0;
> +                }
> +                break;
> +            case 'h':
> +                bincat_display_usage();
> +                return EXIT_SUCCESS;
> +            default:
> +                break;
> +        }
> +    }
> +
> +    if (length && end) {
> +        printf("--length und --end schließen sich aus. Verwende --length\n");
> +    } else if (end) {
> +        length = end - start;
> +    }
> +
> +    if (optind == argc) {
>          bincat_display_usage();
> +        return EXIT_SUCCESS;
> +    }
> +
> +    if (optind + 1 == argc) {
> +        path = argv[optind];
> +    } else {
> +        printf("Fehler: bincat kann nur eine Datei auf einmal verarbeiten!\n");
>          return -1;
>      }
>  
> -    char* path = argv[1];
> +    if (path == NULL) {
> +        bincat_display_usage();
> +        return EXIT_SUCCESS;
> +    }
Kann dieser Fall denn überhaupt eintreten? Dann müsste er doch beim if
oben rausfallen?

> +
>      FILE* file = fopen(path, "r");
>  
> +    fseek(file, start, SEEK_SET);
fseek nimmt nur einen 32-Bit Offset. Nimm besser lio_seek, das kann auch
64 bit.

> +    m = start / 8;
> +
>      if (file == NULL) {
>          printf("Konnte '%s' nicht zum lesen oeffnen!\n", path);
>          return -1;
>      } else {
>          char buffer[BLOCK_SIZE];
>          size_t size;
> -        int n, m = 0;
> -        while (feof(file) != EOF) {
> +        while (feof(file) != EOF && (total_read <= length || length == 0)) {
> +
>              size = fread(buffer, 1, BLOCK_SIZE, file);
>  
> +            total_read += size;
> +
>              printf("0x%08x: ", m);
>  
>              for (n=0; n < size; n++) {
> @@ -82,12 +163,19 @@ void bincat_display_usage(void);
>  
>          fclose(file);
>      }
> -    
> +    printf("\n");
>      return EXIT_SUCCESS;
>  }
>  
>  void bincat_display_usage()
>  {
> -    puts("\nAufruf: bincat <Dateiname>");
> +    puts("\nAufruf: bincat [Optionen] <Dateiname>\n");
> +    puts("  -s, --start   Gibt die Startposition an");
> +    puts("  -l, --length  Gibt die Ausgabelänge an");
> +    puts("  -e, --end     Gibt die Endposition an\n");
> +    puts("Falls --length und --end angegeben sind, erhält --length den "
> +        "Vorrang.\n");
> +    puts("Position und Längen können optional via vorangestelltem 0x auch "
> +        "Hexadezimal\n angegeben werden.");
Hier könnte man auch noch darauf hinweisen, dass das ganze nur mit
ganzen Blocks der Grösse BLOCK_SIZE das Erwartete tut.

.>  }
>  
> -- 
> 1.5.6.5
> 
> _______________________________________________
> tyndur-devel mailing list
> tyndur-devel@xxxxxxxxxx
> http://list.tyndur.org/mailman/listinfo/tyndur-devel

-- 
Antoine Kaufmann
<toni@xxxxxxxxxxxxxxxx>

Attachment: pgpNbXXhzN6cV.pgp
Description: PGP signature