Hallo, der Titel klingt zwar etwas komisch aber ich hab da ein Problem mit 2 verschiedenen getopt_long Versionen. Die eine Version liegt mir als Sourcecode vor und kommt Open/Free/Net BSD. Diese funktioniert bestens, siehe unten. Die andere getopt_long kommt aus der libc vom arm-gcc 7.2.1 (dieser bundled download direkt von ARM). Jedenfalls verhält der sich anders, bis zum aufhängen (FUnktion returned im Debugger nicht mehr). Wirklich debugbar ist es nicht, weil dieses getopt_long nur als vorcompilierte lib vorliegt. Auf einem ARM Projekt soll eine kleines commandinterface ein paar simple Eingaben abhandeln. So zB "ram -r 4", das soll ab Adresse 0 4 bytes lesen und anzeigen. mein Tokenizer läuft 1a und übergibt argc/argv passend. Beim BSD getopt_long funzt alles "ram -r 4" -> Ausgabe "ram -r" -> getopt beschwert sich über ein fehlenden Parameter. Was macht das vorcompilierte getopt long? "ram -r 4" -> nimmt ram als Parameter und beschwert sich, dass ers nicht kennt "ram -r 4" -> beim zweiten mal gehts "ram -r" -> getopt returned nie, also hängt. Hat da wer ne Idee was da rumzickt?
Optionen (-r) nach nicht-Optionen (ram) ist so ne Sache - historisch (und nach POSIX) wird bei der ersten nicht-Option abgebrochen. GNU hat das eingeführt, dass die Argumente umsortiert werden, so dass Optionen auch nach nicht-Optionen vorkommen dürfen. Je nach getopt-Implementation bekommst du mit deinen Argumenten also andere Ergebnisse. Nach nem Fehler-Return weiterzumachen dürfte das Hängen verursachen.
Hatte deinen Beispielcode nicht angeschaut - du scheinst den Restart extra mit "optind=1" zu initialisieren. Ich hab den Eindruck, dass du getopt recursiv benutzt (erste level "ram" erkennen, zweite level die Argumente von "ram" auswerten) - wenn ja: das geht nicht (wegen des globalen States wie z.B. optind). Und sei dir bewusst, dass getopt wirklich den argv umsortiert (von wegen const) ... getopt[_long] ist ne ziemlich historische Funktion - sie ist dafür geschrieben worden, die Argumente von main einmal zu parsen. Bei allen anderen Verwendungen gibt's immer wieder Fallstricke.
Bei dem BSD Code habe ich durchaus was von Umsortierung gelesen, also könnte das ein Ansatz sein. Nun habe ich schon das eine oder andere Linuxkonsolenprogramm programmiert. Den Programmnamen hab ich dabei immer mitbekommennon der Linuxkonsole in argv und argc enthielt ihn von der Anzahl her auch immer. Daher habe ich das in meinem eigenen µC CLI auch so gemacht. Der Commandline tokenizer erkennt das "ram" und ruft dann den passenden Funktionspointer auf (was dann die Funktion im Anhang ist). Wenn laut GNU nun immer umsortiert wird, dann fliegt einem das auch nicht um die Ohren. In den ganzen Beispielen werden argv/argc auch immer direkt an getopt(_long) übergeben ohne den Progammnamen rauszunehmen. Daher bin ich da eher von einem Fehler ausgegangen.
Da man die Grundfunktion von getopt in ein paar Zeilen selber schreiben kann, würde ich mir nicht die Mühe machen eine nicht kooperierende Funktion, die noch dazu außerhalb ihres normalen Anwendungsbereiches verwendet wird, zu debuggen.
> In den ganzen Beispielen werden argv/argc auch immer direkt an > getopt(_long) übergeben ohne den Progammnamen rauszunehmen. GNU getopt sortiert argv[1]..argv[argc-1] beim ersten getopt-Aufruf (optind=1) um, so dass alle Optionen (mit eventuellen Argumenten) vorne stehen, und alle nicht-Options-Argumente hinten. argv[0], der Programmname, wird in Ruhe gelassen. Aus z.B. "./a.out ram -r 4" wird dann "./a.out -r 4 ram".
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.