Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswerten?

Für allgemeine Fragen zur Programmierung, welche nicht! direkt mit Lazarus zu tun haben.
Antworten
alfware17
Beiträge: 134
Registriert: Di 14. Dez 2010, 23:27

Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswerten?

Beitrag von alfware17 »

Hallo!
Ich habe ein Sortierprogramm, welches die EIngabe über Datei oder über Standardeingabe akzeptiert.
Aufrufe wären dann etwa:
SORT /Idatei1 /odatei2
bzw.
SORT < datei1 > datei2
Es können, müssen aber nicht, weitere Parameter angegeben werden.
Nun mein Problem: Ich möchte gerne beim Aufruf ohne alles, also
SORT
einen kurzen Hilfebildschirm sehen (die längere Hilfe gibt es auch bei /?)
Also habe ich das über PARAMCOUNT=0 gesteuert.
Dummerweise nur liefert mir das beim
SORT < datei1 > datei2
auch die Kurzhilfe und nicht die eigentlich erwünschte Programmausführung.
Meine Lösung war dann ein zusätzlicher Parameter /Y den ich im Programm nicht kenne und auswerte, aber
SORT /Y < datei1 > datei2
tut es eben. Nur ist das nicht sehr elegant und ich muß dafür massig Scripte ändern, was auch fehleranfällig ist.
Kann man nicht die Zeichen nach dem SORT (in diesem Fall also "< datei1 > datei2") irgendwie auswerten? Leer oder nicht leer
würde ja schon helfen. PARAMSTR(0) ist hier irgendwie nicht passend.
Ich könnte auch die Eingabe nach dem ersten Satz anhalten und fragen, ob der Satz leer oder nicht leer war - aber das wäre ein
Eingriff in die Logik und da das ganz ziemlich komplex ist, will ich das auch gar nicht. Zumal dann fliegt er bei Eingaben,
deren erster Satz tatsächlich leer ist, wo aber weitere folgen, auf die Nase... Zwischenzählen ist auch keine Lösung - da die
Eingabe meistens direkt verarbeitet wird (es gibt auch Zweige, wo die Anzahl der Zwischenpuffer noch unbekannt ist und
wo tatsächlich gazählt wird, aber es soll ja allgemeingültig sein).
Hat jemand eine Idee?
Source kann ich zur Verfügung stellen, wobei ich glaube, daß es in dieser allgemeinen Frage keine Rolle spielt.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von af0815 »

Ein leeres Konsolenprojekt erstellen und sich den Source ansehen, vielleicht beantwortet das die Fragen.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

alfware17
Beiträge: 134
Registriert: Di 14. Dez 2010, 23:27

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von alfware17 »

af0815 hat geschrieben:Ein leeres Konsolenprojekt erstellen und sich den Source ansehen, vielleicht beantwortet das die Fragen.


Nein, tut es leider nicht.

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von Michl »

Habe vorhin mal ein Konsolenprog. geschrieben. Man kann doch alle Parameter aufrufen und auswerten.

Ich verstehe die Frage nicht ganz. Eine Überprüfung, ob es sich bei ParamStr(1) um einen Parameter handelt oder nicht, könnte man doch ganz einfach überprüfen. Nämlich, ob das erste Zeichen einen Parameter darstellt oder nicht. Also

Code: Alles auswählen

 
if paramStr(1)[1]='/' then .... //Parameter!
else ....
 

Oder was meinst Du sonst?

Michl

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von af0815 »

Eigentlich fällt mir dazu nur folgendes ein. Prüfe ob überhaupt was zum Sortieren da ist. Daher ohne Input gibts den Hilfescreen. Dabei ist es ja egal ob das ganze von der Konsole oder über eine Pipe kommt.
Mein Tip von weiter oben ist deshalb gekommen, weil viele gar nicht schauen oder wissen, was für Basisgerüste von Lazarus angelegt werden. Gleich mit komfortabelen Auwertung der Kommandozeilenoptionen.

In dem Beispiel würde ich im DoRun sofort den Input prüfen und wenn der leer ist, ebenfalls das WriteHelp aufrufen. Das dürfte dem entsprechen was du wolltest.

Code: Alles auswählen

program project1;
 
{$mode objfpc}{$H+}
 
uses
  {$IFDEF UNIX}{$IFDEF UseCThreads}
  cthreads,
  {$ENDIF}{$ENDIF}
  Classes, SysUtils, CustApp
  { you can add units after this };
 
type
 
  { TMyApplication }
 
  TMyApplication = class(TCustomApplication)
  protected
    procedure DoRun; override;
  public
    constructor Create(TheOwner: TComponent); override;
    destructor Destroy; override;
    procedure WriteHelp; virtual;
  end;
 
{ TMyApplication }
 
procedure TMyApplication.DoRun;
var
  ErrorMsg: String;
begin
  // quick check parameters
  ErrorMsg:=CheckOptions('h','help');
  if ErrorMsg<>'' then begin
    ShowException(Exception.Create(ErrorMsg));
    Terminate;
    Exit;
  end;
 
  // parse parameters
  if HasOption('h','help') then begin
    WriteHelp;
    Terminate;
    Exit;
  end;
 
  { add your program here }
 
  // stop program loop
  Terminate;
end;
 
constructor TMyApplication.Create(TheOwner: TComponent);
begin
  inherited Create(TheOwner);
  StopOnException:=True;
end;
 
destructor TMyApplication.Destroy;
begin
  inherited Destroy;
end;
 
procedure TMyApplication.WriteHelp;
begin
  { add your help code here }
  writeln('Usage: ',ExeName,' -h');
end;
 
var
  Application: TMyApplication;
begin
  Application:=TMyApplication.Create(nil);
  Application.Title:='My Application';
  Application.Run;
  Application.Free;
end.
 
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

alfware17
Beiträge: 134
Registriert: Di 14. Dez 2010, 23:27

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von alfware17 »

An die letzten beiden Beitragenden:
vielen Dank, aber das ist beides nicht das Problem.
1.Die Parameter kann ich schon auswerten, sehr gut sogar.
2.Sobald ich die StdIn angefaßt habe (EOF fragen, Readln), habe ich verloren. Da wartet das Programm auf eine Eingabe und kann dann erst mit ^Z (EOF simuliert) beendet werden. Das soll es nun gerade nicht sein.
Unterschieden werden sollen die Fälle
QSORT
(man ruft es nur mal so auf und soll die Kurzinfo bekommen)
QSORT < eingabe > ausgabe
(er soll mit den Standardwerten sortieren)
In beiden Fällen also ohne Parameter. Mit Parametern läuft ja alles prima. Ich hänge Euch mal die Quelle an. Version 5.22 ist die aktuelle. Dummerweise verhindert hier die Abfrage auf PARAMCOUNT=0
eben den 2.Aufruf. Gelöst habe ich das eben mit einem künstlichen Parameter (z.B. /Y) im aufrufenden Script.
Version 5.23 ist ein Testballon, nicht gut durchdacht - die Abfrage, ob keine Sätze gelesen wurden. Man hätte auch schon vorher auf EOF fragen können, aber es beißt sich generell, die Abfrage auf EOF
bzw die Parameter, einer von beiden Aufrufen geht immer fehl.

Ich gebe zu, das Problem ist nur ein marginales - den ersten Aufruf (man will nur mal so wissen, was das ist) zu ermöglichen. Dafür jetzt groß die Logik zu verändern oder die Pipelines ganz zu verbieten
(man kann die Eingabe auch über /I angeben), finde ich nicht angemessen. Wäre nur schön, wenn das Programm feststellen könnte, da steht noch was in der Eingabezeile von < also zack umgeleitet, keine
Kurzinfo.
Zuletzt geändert von alfware17 am Di 19. Feb 2013, 11:36, insgesamt 1-mal geändert.

Michl
Beiträge: 2505
Registriert: Di 19. Jun 2012, 12:54

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von Michl »

Ist vielleicht nicht ganz sauber aber so sollte es doch gehen:

Dein Code:

Code: Alles auswählen

 
      p:=PARAMSTR(i); VAL(COPY(p,3,255),j,k); tname:=COPY(p,3,255);
      IF p[1] IN ['/','-'] THEN
        CASE upcase(p[2]) OF
         '?','H': BEGIN
                 HILFE(0);
                 WriteLN(' Weiter mit Taste'); ch:=Taste0; WriteLN;
 
 ......
 
       end   //Case ende
      else   //Standard-Verhalten auslösen -> versuche <eingabe> zu sortieren und speicher ausgabe
 


... irgendwie steh ich auf dem Schlauch, wo das Problem ist :?

Michl

Code: Alles auswählen

type
  TLiveSelection = (lsMoney, lsChilds, lsTime);
  TLive = Array[0..1] of TLiveSelection; 

mschnell
Beiträge: 3444
Registriert: Mo 11. Sep 2006, 10:24
OS, Lazarus, FPC: svn (Window32, Linux x64, Linux ARM (QNAP) (cross+nativ)
CPU-Target: X32 / X64 / ARMv5
Wohnort: Krefeld

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von mschnell »

Wenn ich mich recht erinnere kommt PARAMSTR nicht als UTF-8 rein, weil es keine Lazarus (LCL) Funktion ist, sondern aus der fpc Library stammt. Es könnte also so ähnlich gehen.

-Michael

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von af0815 »

Das Problem ist, das die Pipe oder Umleitung von BS vor dem Programm transparent (quasi versteckt) gehalten wird. Darum wird meiner Meinung nach die Auswertung der Kommandozeile problematisch werden. Ich glaube das ist der Pudels Kern.

Stimmt es, das ein

Code: Alles auswählen

cat Datei1.txt | sort > Datei2.txt 
auch funktionieren soll. Oder stehe ich jetzt noch immer auf der Leitung.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

alfware17
Beiträge: 134
Registriert: Di 14. Dez 2010, 23:27

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von alfware17 »

af0815 hat geschrieben:Das Problem ist, das die Pipe oder Umleitung von BS vor dem Programm transparent (quasi versteckt) gehalten wird. Darum wird meiner Meinung nach die Auswertung der Kommandozeile problematisch werden. Ich glaube das ist der Pudels Kern.

Stimmt es, das ein

Code: Alles auswählen

cat Datei1.txt | sort > Datei2.txt 
auch funktionieren soll. Oder stehe ich jetzt noch immer auf der Leitung.



Ja, das soll es... Und auch dieser Aufruf würde nur als

cat Datei1.txt | QSORT -y > Datei2.txt

funktionieren, da ohne den Parameter erstmal die Kurzhilfe kommt...

Wie schon vermutet, wäre der andere Beitrag (feststellen, ob Stdin umgeleitet wird), hier die Lösung gewesen. Nur leider ist das wie so vieles aus dem guten alten TP im Free Pascal
jetzt "entfunden"... Ja, richtig, Herr Marcov wird mir gleich antworten, daß TP als Standard nur zu sich selbst komatibel war...

Und, nebenbei, es tut mir leid, daß Du das anfangs duch meine sprachliche Wahl falsch verstanden hattest, aber jetzt denke ich mal, ist es klar: ich meinte mit Aufrufzeile
alles, also nicht nur die Parameter, sondern alles was da steht, ggf. eben mit Pipes und so weiter.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6209
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Kann 1 Konsolenanwendung ihre eigene Aufrufzeile auswert

Beitrag von af0815 »

Eigentlich sollte es BOF und EOF zugleich sein, dann weis ich normalerweise das eine Datei/Pipe leer ist. Denn diese Konstellation ist nur für eine leere Datei gültig.

Interessant wär eine Minimalversion, wo man das verhalten besser testen kann. Ich muß mal meinen Lazarus wieder flott bekommen, nach den aktuellen Cross-Compiling Versuchen ist der gerade nicht lauffähig :-)
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Antworten