Forum: Mikrocontroller und Digitale Elektronik getopt_long und Versionsdifferenzen


von Mw E. (Firma: fritzler-avr.de) (fritzler)


Angehängte Dateien:

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?

von foobar (Gast)


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.

von foobar (Gast)


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.

von Mw E. (Firma: fritzler-avr.de) (fritzler)


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.

von Hannes J. (pnuebergang)


Lesenswert?

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.

von foobar (Gast)


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

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
Noch kein Account? Hier anmelden.