getopt_long und Versionsdifferenzen

(Firma: fritzler-avr.de) #5952698
Lesenswert?

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?
Angehängte Dateien:
Gast #5952816
Lesenswert?

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.
Gast #5952831
Lesenswert?

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.
(Firma: fritzler-avr.de) #5952837
Lesenswert?

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.
Gast #5952849
Lesenswert?

> 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".

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren