From cb7c5c51ca22fdb7eab50b76550b2e6005965b2f Mon Sep 17 00:00:00 2001 From: Erich Eckner Date: Mon, 19 Dec 2016 18:08:17 +0100 Subject: wieder was gemacht --- analyzer.lpi | 6 +- analyzer.lpr | 252 +++++++++++++++++++++++++++++++++++++++++++-------------- analyzer.lps | 152 ++++++++++++++++++++++++++++++---- valuesunit.pas | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 570 insertions(+), 76 deletions(-) create mode 100644 valuesunit.pas diff --git a/analyzer.lpi b/analyzer.lpi index f5eae51..4961aad 100644 --- a/analyzer.lpi +++ b/analyzer.lpi @@ -29,11 +29,15 @@ - + + + + + diff --git a/analyzer.lpr b/analyzer.lpr index 348518c..5b6d150 100644 --- a/analyzer.lpr +++ b/analyzer.lpr @@ -6,22 +6,33 @@ uses {$IFDEF UNIX}{$IFDEF UseCThreads} cthreads, {$ENDIF}{$ENDIF} - classes, sysUtils, custApp - { you can add units after this }; + classes, sysUtils, custApp, valuesunit, lowlevelunit, dateutils; type - tOption = (oHelp, oInput); + tOption = (oHelp, oAcceleration, oPosition, oOutput); + + tOptionMeta = record + long: string; + short: char; + value: byte; // bit 0: kann Wert haben; bit 1: muss Wert haben + end; + + tOptionContent = record + typ: tOption; + hasValue: boolean; + value: string; + end; { TAnalyzer } tAnalyzer = class(tCustomApplication) protected - options: array of tOption; - oValues: array of string; + options: array of tOptionContent; + oCnt: array[tOption] of longint; procedure doRun; override; procedure parseOptions; - procedure illegalOption(i: longint); + function optionArgument(o: tOption; i: longint): string; public constructor create(theOwner: tComponent); override; destructor destroy; override; @@ -29,46 +40,70 @@ type end; const - shortOptions: array[tOption] of char = - ('h','i'); - longOptions: array[tOption] of string = ( - 'help', - 'input' - ); - optionValue: array[tOption] of byte = ( // bit 0: kann Wert haben; bit 1: muss Wert haben - 0, - 3 + optionsMeta: array[tOption] of tOptionMeta = ( + (long: 'help'; short: 'h'; value: $00), + (long: 'acceleration'; short: 'a'; value: $03), + (long: 'position'; short: 'p'; value: $03), + (long: 'output'; short: 'o'; value: $03) ); { TAnalyzer } procedure tAnalyzer.doRun; var - errorMsg: string; + i: longint; + values: array of array[boolean] of tValues; begin - // quick check parameters - errorMsg:=checkOptions('hi:', 'help input:'); - if errorMsg<>'' then begin - showException(Exception.Create(ErrorMsg)); + if oCnt[oHelp]>0 then begin + writeHelp; + terminate; + exit; + end; + + if oCnt[oAcceleration]=0 then begin + writeln('error: required option ''-a'' not given'); + writeHelp; halt(1); end; - // parse parameters - if hasOption('h', 'help') then begin + if oCnt[oAcceleration]<>oCnt[oPosition] then begin + writeln('error: option ''-p'' not given equally often as option ''-a'''); writeHelp; - terminate; - exit; + halt(1); end; - if not hasOption('i','input') then begin - writeln('error: required option ''-i'' not given'); + if oCnt[oOutput]<>1 then begin + writeln('error: required option ''-o'' not given exactly once'); writeHelp; halt(1); end; + for i:=0 to oCnt[oAcceleration]-1 do begin + if not fileexists(optionArgument(oAcceleration,i)) then begin + writeln('Acceleration file '''+optionArgument(oAcceleration,i)+''' does not exist'); + halt(1); + end; + if not fileexists(optionArgument(oPosition,i)) then begin + writeln('Position file '''+optionArgument(oPosition,i)+''' does not exist'); + halt(1); + end; + end; + { add your program here } + setlength(values,oCnt[oAcceleration]); + for i:=0 to length(values)-1 do begin + values[i,false]:=tValues.create; + values[i,false].readFromFile(optionArgument(oAcceleration,i)); + values[i,true]:=tValues.create; + values[i,true].readFromFile(values[i,false].timeInterval,optionArgument(oPosition,i)); + values[i,false].intersect(values[i,true]); + end; - writeln(''''+getOptionValue('i','input')+''''); + for i:=0 to length(values)-1 do begin + values[i,false].free; + values[i,true].free; + end; + setlength(values,0); // stop program loop terminate; @@ -76,50 +111,144 @@ end; procedure tAnalyzer.parseOptions; var - i: longint; - s,t: string; - o: tOption; - v,gefunden: boolean; + i,j,incre,jncre: longint; + s: string; + oTypen: array of byte; // 0 = argument; 1 = short option(s); 2 = long option + o: tOption; begin + for o:=low(tOption) to high(tOption) do + oCnt[o]:=0; + + setlength(oTypen,paramcount); + for i:=0 to length(oTypen)-1 do + if copy(paramstr(i+1),1,2)='--' then + oTypen[i]:=2 + else if copy(paramstr(i+1),1,1)='-' then + oTypen[i]:=1 + else + oTypen[i]:=0; + setlength(options,0); - setlength(oValues,0); - i:=1; - while i<=paramcount do begin - s:=paramstr(i); - if copy(s,1,1)<>'-' then - illegalOption(i); - delete(s,1,1); - gefunden:=false; - if copy(s,1,1)='-' then begin // long option - delete(s,1,1); - if pos('=',s)>0 then begin - t:=copy(s,pos('=',s)+1,length(s)); - s:=copy(s,1,pos('=',s)-1); - v:=true; - end - else begin - t:=''; - v:=false; + i:=0; + while is[j]) then begin + writeln('Illegal option at position '+inttostr(i+1)+', character '+inttostr(j)+': '''+s[j]+''''); + writeHelp; + halt(1); + end; + + if odd(optionsMeta[options[length(options)-1].typ].value) // may have value + and (((i'') and (longOptions[o]=s) and ((not v) or odd(optionValue[o])) then begin - gefunden:=true; - break; + 2: begin + delete(s,1,2); + + setlength(options,length(options)+1); + + if pos('=',s)>0 then begin + options[length(options)-1].value:=copy(s,pos('=',s)+1,length(s)); + s:=copy(s,1,pos('=',s)-1); + options[length(options)-1].hasValue:=true; + end + else begin + options[length(options)-1].value:=''; + options[length(options)-1].hasValue:=false; + end; + options[length(options)-1].typ:=low(optionsMeta); + while options[length(options)-1].typ'') and (optionsMeta[options[length(options)-1].typ].long=s) then + break; + inc(options[length(options)-1].typ); + end; + if (optionsMeta[options[length(options)-1].typ].long='') or (optionsMeta[options[length(options)-1].typ].long<>s) then begin + writeln('Illegal option at position '+inttostr(i+1)+': '''+s+''''); + writeHelp; + halt(1); end; - end; - if not gefunden then - illegalOption(i); + if (not options[length(options)-1].hasValue) // no value yet + and odd(optionsMeta[options[length(options)-1].typ].value) // may have value + and (i - + - - - - + + + @@ -19,26 +18,151 @@ - + + + + + + + + + + + + + + + + + + + + + + + - + - - + + - - + + - + - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/valuesunit.pas b/valuesunit.pas new file mode 100644 index 0000000..97d960f --- /dev/null +++ b/valuesunit.pas @@ -0,0 +1,236 @@ +unit valuesunit; + +{$mode objfpc}{$H+} + +interface + +uses + Classes, SysUtils, lowlevelunit; + +type + tWert = record + time: int64; // unix timestamp * 1000 + vec: array['x'..'z'] of extended; + end; + + tValues = class + private + werte: array of tWert; + public + constructor create; + destructor destroy; override; + procedure readFromFile(dat: string); overload; + procedure readFromFile(ti: tExtPoint; dat: string); overload; + procedure readFromFile(minT,maxT: extended; dat: string); overload; + function count: int64; + function timeInterval: tExtPoint; + procedure intersect(v: tValues); + end; + +function interpolate(w1,w2: tWert; x: extended): tWert; inline; +function isoStrToDateTime(s: string): extended; inline; +function timeToInt64(s: string): int64; + +implementation + +uses + math, dateutils; + +constructor tValues.create; +begin + inherited create; + setlength(werte,0); +end; + +destructor tValues.destroy; +begin + setlength(werte,0); + inherited destroy; +end; + +procedure tValues.readFromFile(dat: string); +begin + readFromFile(-infinity,infinity,dat); +end; + +procedure tValues.readFromFile(ti: tExtPoint; dat: string); +begin + readFromFile(ti['x'],ti['y'],dat); +end; + +procedure tValues.readFromFile(minT,maxT: extended; dat: string); +var + f: textfile; + s: string; + i,delta,cnt: int64; + ws: tWert; + c: char; + isXml: boolean; +begin + setlength(werte,0); + fillchar(ws,sizeOf(tWert),0); + cnt:=0; + assignFile(f,dat); + reset(f); + isXml:=false; + s:=''; + while (s<>'') or not eof(f) do begin + if s='' then + readln(f,s); + if s='' then + continue; + + if (not isXml) and (not (s[1] in ['0'..'9'])) then begin + if copy(s,1,6)='1 then + raise exception.create('Syntax error in '''+dat+''' (lon) - no valid gpx file.'#10'Hickup: '''+copy(s,1,40)+' ...'''); + delete(s,1,pos('"',s)); + ws.vec['x']:=strtofloat(erstesArgument(s,'"')); + if pos('>',s)<>1 then + raise exception.create('Syntax error in '''+dat+''' (lat) - no valid gpx file.'#10'Hickup: '''+copy(s,1,40)+' ...'''); + delete(s,1,pos('>',s)); + delete(s,1,pos('>',s)); + ws.vec['z']:=strtofloat(erstesArgument(s,'<')); + if pos('/ele>