Eigener Parser



  • Guten Abend,

    eigentlich bin ich mit meinem 'parser' fertig. Ich wollte aber den parser noch den
    letzten Schliff geben. Es soll auch testen, ob 'required' flags gesetzt sind oder
    nicht.

    Naja, ich weiß auch (so wie ich es gemacht habe), es nicht geht; aber ich bin da
    nicht so einfallsreich.

    Vielleicht könnt ihr mir auch dabei helfen?

    Vorweg: Ich hatte in meinen alten Programmen getopt() bzw. getopt_long() verwendet.
    Nur bin ich kein Fan mehr von "--flag=arg" und leider kann man bei getopt_long()
    auch nicht sowas wie "-sort", also mehr als ein Buchstabe verwenden.

    extern args flag;
    
    void
    my_parser (int argn, char *argv[])
    {
    
     int i = 0;
    
     if (argn <= 1 ) {
      printf("\nMissing flags. Program terminated. Type %s -h for information.", argv[0]);
      printf("\nProgram terminated.\n\n");
      exit(EXIT_FAILURE);
     }
    
     /* parse command line arguments */
     for (i=1; i<argn; i+=2) {
      if (strcmp(argv[i], "-f") == 0) flag.f = argv[i+1];
      else if (strcmp(argv[i], "-sort") == 0) flag.sort = argv[i+1];
      else if (strcmp(argv[i], "-o") == 0) flag.o = argv[i+1];
      else if (strcmp(argv[i], "-h") == 0) info(argv[0], 0);
      else {
       printf("\nUnkown flag. Program terminated. Help information is printed.\n\n");
       info(argv[0], 1);
      }
     }
    
     /* check for required flags --- not works */
     for (i=1; i<argn; i+=2) {
      if (strcmp(argv[i], "-f") != 0 || strcmp(argv[i], "-sort") != 0 || strcmp(argv[i], "-o") != 0) {
       printf("\nRequired flags are missing. Program terminated. Type %s -h for information.", argv[0]);
       printf("\nProgram terminated (here).\n\n");
       exit(EXIT_FAILURE);
      }
     }
    
    }
    
    void info (char *prg_name, int exitvalue) {
     char *PRG = prg_name;
    
     PRG += strlen(prg_name);
     while (*PRG != '/' && PRG >= prg_name)
      PRG--;
     PRG++;
    
     /* info about the program */
     printf("\nThe program has the following structure:\n"
            "  %s [options]\n", PRG);
    
     printf("\n"
            "You can run the program with this options:\n"
            "  -h          prints this information\n");
    
     printf("\n"
            "This options are aviable:\n"
            "  -f          input file [ %s ] (required)\n"
            "  -sort       asc or desc [ %s ] (required)\n"
            "  -o          output file [ %s ] (required)\n\n"
            , args.f, args.sort, args.o);
    
     exit(exitvalue);
    }
    

    Beste Grüße,
    simsa



  • simsa schrieb:

    Naja, ich weiß auch (so wie ich es gemacht habe), es nicht geht; aber ich bin da nicht so einfallsreich.

    Was geht nicht? Was passiert und was soll passieren?



  • Hallo DirkB,

    Es ist so: der erste Teil des Codes (Zeile 16 bis 25) funktioniert so wie ich es
    haben möchte. Der zweite Teil (Zeile 28 bis 34) funktioniert nicht, sprich führt
    immer dazu, dass das Programm beendet wird. Im zweiten Teil will ich nur prüfen,
    ob 'wichtige' flags gesetzt wurden oder nicht.

    Das Problem liegt in der Zeile 29.

    Wie kann ich prüfen, ob flags gesetzt sind oder nicht?

    Viele Grüße,
    simsa



  • Wieviele Kommandozeilenargumente musst du dir angucken, bevor du mit Sicherheit sagen kannst, dass die erforderlichen nicht da sin?

    Antwort: Alle.

    Deine Prüfung kann also keinesfalls innerhalb der Schleife stattfinden, sondern muss dahinter passieren.

    Führe für jedes erforderliche Argument eine Variable ein, die du auf true setzt, wenn du das Argument gefunden hast. Und nach der Schleife prüfst du, ob alle true sind.



  • MFK schrieb:

    Wieviele Kommandozeilenargumente musst du dir angucken, bevor du mit Sicherheit sagen kannst, dass die erforderlichen nicht da sin?

    Man kann aufhören, wenn man die erforderlichen gefunden hat.



  • Hallo Belli,

    Belli schrieb:

    Man kann aufhören, wenn man die erforderlichen gefunden hat.

    Eigentlich soll es nicht aufhören; es gibt's auch den Fall [erforderliche] +
    [optionale].

    Hier ist nun mein parser; es funktioniert ;). Hättet ihr 'bessere' Vorschläge?

    enum boolean {
     FALSE, TRUE
    };
    
    typedef struct {
     const char *f;
     const char *sort;
     const char *o;
    } flags;
    
    enum required_flags {
     rf_f, rf_sort, rf_o, rf_end
    }; 
    
    flags args;
    
    void
    c_parser (int argn, char *argv[])
    {
    
     int i = 0, *rf = (int *) calloc((size_t) rf_end, sizeof(int));
    
     if (argn <= 1 ) {
      printf("\nMissing flags. Type %s -h for information.", argv[0]);
      printf("\nProgram terminated.\n\n");
      exit(EXIT_FAILURE);
     }
    
     /* initialize required flags (with zero)  */
     for (i=0; i<rf_end; i++)
      rf[i] = FALSE;
    
     /* parse command line arguments and set required flags*/
     for (i=1; i<argn; i+=2) {
      if (strcmp(argv[i], "-f") == 0) {
       args.f = argv[i+1];
       rf[rf_f] = TRUE;
      } else if (strcmp(argv[i], "-sort") == 0) {
       args.sort = argv[i+1];
       rf[rf_sort] = TRUE;
      } else if (strcmp(argv[i], "-o") == 0) {
       args.o = argv[i+1];
       rf[rf_o] = TRUE;
      } else if (strcmp(argv[i], "-h") == 0) {
       c_help(argv[0], 0);
      } else {
       printf("\nUnkown flag. Help information is printed.");
       printf("\nProgram terminated.\n\n");
       c_help(argv[0], 1);
      }
     }
    
     /* check for required flags */
     for (i=0; i<rf_end; i++) {
      if (rf[i] != TRUE) {
       printf("\nRequired flags are missing. Type %s -h for information.", argv[0]);
       printf("\nProgram terminated.\n\n");
       exit(EXIT_FAILURE);
      }
     }
    
    }
    

    Beste Grüße,
    simsa


Anmelden zum Antworten