00001
00023
00024
00025
00026
00027 #include "GSP.h"
00028 #include "GSP_File.h"
00029 #ifdef WX
00030 #include "wx/wxchar.h"
00031 #else
00032 #include <string.h>
00033 #endif
00034
00035
00036
00037 int GspCurrentLineNr;
00038 int GspErrorLineNr;
00039 int GspErrorPos;
00040 mutString GspErrorLine;
00041 int GspError;
00042
00043
00044 int PossibleErrorLineNr;
00045 int PossibleErrorPos;
00046 mutString PossibleErrorLine;
00047
00048 #ifdef WX
00049 mutString Sep = mutEmptyString;
00050 inline size_t SepPos()
00051 {
00052 size_t a = (Sep.Len());
00053 return a;
00054 }
00055
00056 #define SepPos SepPos()
00057 #else
00058 char Sep[GSP_MAX_SEP];
00059 int SepPos;
00060 #endif
00061
00062
00063 char ParaMode;
00064 char Komma;
00065 int NumberLength;
00066 #ifdef WX
00067 mutString Brackets = mutEmptyString;
00068 #define BracketDeep \
00069 (Brackets.Len())
00070 #else
00071 int BracketDeep;
00072 char Brackets[200];
00073 #endif
00074 char LastTag;
00075
00076
00077 static int octave;
00078
00079 static mutString accedentials ;
00080
00081 static frac duration;
00082
00083 #define NEW_LINE mutT("\n")
00084 mutChar SepChars[] = mutT(" \t\r\n");
00085
00086 mutChar DelimitChars[] = mutT("{}[]()");
00087
00088 #define uchar unsigned char
00089
00090
00091
00092
00093 #ifdef WX
00094 inline void AddStr(mutString & Target, int Pos, const mutString& Source)
00095 {
00096 DEBUGLOG2(other,_T("%s + %s"), Target.c_str(), Source.c_str());
00097 Target += Source;
00098 DEBUGLOG2(other,_T("=%s"), Target.c_str());
00099 }
00100
00101 inline int CharIn(mutChar c, const mutChar * s)
00102
00103 {
00104 DEBUGLOG2(other,_T("'%c' is in '%s' at position %d, returning %d"),
00105 c, s, mutStrChr(s, c), mutStrChr(s, c) != NULL);
00106 return mutStrChr(s, c) != NULL;
00107 }
00108
00109 inline int IsLetter(mutChar c)
00110
00111 {
00112 return ((mutT('a') <= c) && (c <= mutT('z'))) ||
00113 ((mutT('A') <= c) && (c <= mutT('Z'))) ||
00114 ( c == mutT('_') );
00115 }
00116
00117
00118
00119
00120
00121
00122
00123 #else
00124 void AddStr(char *Target, int &Pos, char *Source)
00125 {
00126 for (int i = 0; Source[i]; i++) {
00127 Target[Pos++] = Source[i];
00128 }
00129
00130 Target[Pos] = 0;
00131 }
00132
00133 int CharIn(mutChar c, const mutString s)
00134 {
00135 return mutStrChr(s, c) != 0;
00136 }
00137
00138 int IsLetter(mutChar c)
00139
00140 {
00141 return ((mutT('a') <= c) && (c <= mutT('z'))) ||
00142 ((mutT('A') <= c) && (c <= mutT('Z'))) ||
00143 ( c == mutT('_') );
00144 }
00145
00146 int IsNumber(mutChar c)
00147 {
00148 return (mutT('0') <= c) && (c <= mutT('9'));
00149 }
00150
00151 #endif
00152
00153
00154
00155
00156 int DoError(int nr, int pos = -1)
00157 {
00158 if ( GspError ) return GspError;
00159
00160 GspError = nr;
00161
00162 GspErrorLineNr = GspCurrentLineNr;
00163
00164 if ( pos == -1 )
00165 GspErrorPos = CurrentPos;
00166 else
00167 GspErrorPos = pos;
00168
00169 GspErrorLine = CurrentLine;
00170
00171 return nr;
00172 }
00173
00174
00175 int CheckError(int nr)
00176 {
00177 if ( !nr ) return 0;
00178
00179 if ( GspError ) return GspError;
00180
00181 GspError = nr;
00182
00183 GspErrorLineNr = PossibleErrorLineNr;
00184
00185 GspErrorPos = PossibleErrorPos;
00186
00187 GspErrorLine = PossibleErrorLine;
00188
00189 return nr;
00190 }
00191
00192
00193 void SavePos()
00194 {
00195 PossibleErrorLineNr = GspCurrentLineNr;
00196 PossibleErrorPos = CurrentPos;
00197 mutCopyIntoString(PossibleErrorLine, CurrentLine);
00198 }
00199
00200
00201
00202
00203 #define CHAR0 CurrentLine[CurrentPos]
00204 #define CHAR1 CurrentLine[CurrentPos+1]
00205 inline wxString & takesep()
00206 {
00207 Sep += CurrentLine[CurrentPos++];
00208 DEBUGLOG2(other,_T("New Sep: %s"), Sep.c_str());
00209 return Sep;
00210 }
00211
00212 #define TAKESEP takesep()
00213
00214
00215
00216 int GetSep()
00217 {
00218 #ifdef WX
00219 Sep = mutEmptyString;
00220 #else
00221 SepPos = 0;
00222 #endif
00223 Komma = 0;
00224 int RemDeep = 0;
00225 int RemLine = 0;
00226
00227 while ( !Eof && !GspError ) {
00228 #ifdef WX
00229 DEBUGLOG2(other,_T("%d >= %d? Sep.Len=%d"),CurrentPos,CurrentLine.Len(),Sep.Len());
00230 DEBUGLOG2(other,_T("%s"),CurrentLine.c_str());
00231
00232 if (CurrentPos >= CurrentLine.Len())
00233 #else
00234 mutChar c = CHAR0;
00235
00236 if ( !c )
00237 #endif
00238 {
00239
00240 if ( ReadNewLine() )
00241 {
00242 DoError(32);
00243 #ifdef WX
00244 Sep = Sep.Left(1);
00245 DEBUGLOG2(other,_T("Returning 1 at with (%d) '%s'"),
00246 SepPos, Sep.c_str());
00247 return SepPos;
00248 #else
00249 return ( SepPos = 1 );
00250 #endif
00251 }
00252
00253 RemLine = 0;
00254
00255 if ( GspCurrentLineNr != 1 )
00256 AddStr(Sep, SepPos, NEW_LINE);
00257
00258 continue;
00259 }
00260
00261 #ifdef WX
00262 mutChar c = CHAR0;
00263
00264 #endif
00265
00266 if ( c == mutT('(') && CHAR1 == mutT('*') )
00267 {
00268 TAKESEP;
00269 TAKESEP;
00270 RemDeep++;
00271 continue;
00272 }
00273
00274 if ( RemDeep )
00275 {
00276
00277 if ( c == mutT('*') && CHAR1 == mutT(')') )
00278 {
00279 TAKESEP;
00280 TAKESEP;
00281 RemDeep--;
00282 } else
00283 TAKESEP;
00284
00285 continue;
00286 }
00287
00288 if ( RemLine ) {
00289 TAKESEP;
00290 continue;
00291 }
00292
00293 if ( c == mutT('%') )
00294 {
00295 RemLine = 1;
00296 continue;
00297 }
00298
00299 if ( CharIn(c, SepChars) )
00300 {
00301 TAKESEP;
00302 continue;
00303 }
00304
00305 if ( c == mutT(',') && ParaMode )
00306 {
00307 TAKESEP;
00308 Komma = 1;
00309 continue;
00310 }
00311
00312 break;
00313 }
00314
00315 DEBUGLOG2(other,_T("Returning with (%d) '%s'"),SepPos,Sep.c_str());
00316
00317 #ifndef WX
00318 Sep[SepPos] = 0;
00319 #endif
00320 return SepPos;
00321 }
00322
00323
00324
00325
00326 bool minus;
00327
00328
00329 long ReadLong(int SignAllowed)
00330 {
00331 long a = 0;
00332 NumberLength = 0;
00333 minus = false;
00334
00335 if ( SignAllowed ) {
00336 DEBUGLOG2(other,_T("Sign char %c?"), CHAR0);
00337
00338 if ( CHAR0 == mutT('+') ) CurrentPos++;
00339 else if ( CHAR0 == mutT('-') ) {
00340 CurrentPos++;
00341 minus = true;
00342 }
00343 }
00344
00345 GetSep();
00346
00347 while ( mutIsdigit(CHAR0) && !SepPos ) {
00348 DEBUGLOG2(other,_T("Number char %c? (a=%d)"), CHAR0, a);
00349 a = a*10 + (CurrentLine[CurrentPos++]-mutT('0'));
00350 NumberLength++;
00351 GetSep();
00352 }
00353
00354 if ( minus ) return -a;
00355
00356 return a;
00357 }
00358
00359
00360 int ReadParaNumber()
00361 {
00362 long a = ReadLong(1);
00363
00364 if ( SepPos || CHAR0 != mutT('.') )
00365 return CheckError(TagParaInt(a));
00366
00367
00368 CurrentPos++;
00369
00370 GetSep();
00371
00372 mutChar minus1 = minus;
00373
00374 double r = (double)a;
00375
00376 if ( SepPos )
00377 return CheckError(TagParaReal(r));
00378
00379 float b = (double) ReadLong(0);
00380
00381 for (int i = 1; i <= NumberLength; i++)
00382 b = b / 10;
00383
00384 if ( minus1 ) b = -b;
00385
00386 return CheckError(TagParaReal(r+b));
00387 }
00388
00389
00390 int ReadParaStr()
00391 {
00392 #ifdef WX
00393 mutString s = mutT("");
00394 #else
00395 mutChar s[GSP_MAX_LINE] = "";
00396 #endif
00397 int i = 0;
00398 CurrentPos++;
00399
00400 while ( (CHAR0 != mutT('"') || CHAR1 == mutT('"')) && !Eof ) {
00401 if ( !CHAR0 )
00402 {
00403 ReadNewLine();
00404 AddStr(s, i, NEW_LINE);
00405 continue;
00406 }
00407 if ( CHAR0 == mutT('"') ) CurrentPos++;
00408
00409 #ifdef WX
00410 s += CurrentLine[CurrentPos++];
00411
00412 #else
00413 s[i++] = CurrentLine[CurrentPos++];
00414
00415 #endif
00416 }
00417
00418 if ( CHAR0 == mutT('"') ) CurrentPos++;
00419
00420 #ifndef WX
00421 s[i] = 0;
00422
00423 #endif
00424 GetSep();
00425
00426 return CheckError(TagParaStr(s));
00427 }
00428
00429
00430 int ReadTag()
00431 {
00432 mutString Name = mutT("");
00433 mutChar i = 0;
00434 LastTag = 2;
00435 CurrentPos++;
00436 GetSep();
00437 #ifdef WX
00438 i = CurrentPos;
00439 #endif
00440
00441 while ( IsLetter(CHAR0) && !SepPos ) {
00442 #ifdef WX
00443 CurrentPos++;
00444 #else
00445 Name[i++] = CurrentLine[CurrentPos++];
00446 #endif
00447 GetSep();
00448 }
00449
00450 #ifdef WX
00451 Name = CurrentLine (i,CurrentPos-i);
00452
00453 #else
00454 Name[i] = 0;
00455
00456 #endif
00457 if ( !GspError ) CheckError(Tag(Name));
00458
00459 if ( CHAR0 == mutT('<') ) {
00460 CurrentPos++;
00461 GetSep();
00462
00463 if ( !GspError ) CheckError(BeginParameter());
00464
00465 ParaMode = 1;
00466 }
00467
00468 if ( CHAR0 == mutT('>') ) {
00469 CurrentPos++;
00470 GetSep();
00471
00472 if ( !GspError ) CheckError(EndParameter());
00473
00474 ParaMode = 0;
00475 }
00476
00477 return GspError;
00478 }
00479
00480
00481 int ReadNote()
00482 {
00483 mutChar i = 0;
00484 #ifdef WX
00485 mutString Name = wxEmptyString;
00486 accedentials = wxEmptyString;
00487 #else
00488 mutChar Name[GSP_MAX_LINE] = mutT("");
00489 accedentials[0] = 0;
00490 #endif
00491
00492 GetSep();
00493
00494 #ifdef WX
00495
00496 for (i = CurrentPos; IsLetter(CHAR0) && !SepPos; CurrentPos++)
00497 GetSep();
00498
00499 Name = CurrentLine(i,CurrentPos-i);
00500
00501 GetSep();
00502
00503 #else
00504 while ( IsLetter(CHAR0) && !SepPos ) {
00505 Name[i++] = CurrentLine[CurrentPos++];
00506 GetSep();
00507 mutString Name = mutT("");
00508
00509 }
00510
00511 Name[i] = 0;
00512
00513 #endif
00514
00515 DEBUGLOG2(other,_T("SepPos: %d"),SepPos);
00516
00517 if ( SepPos )
00518 return CheckError(Note(Name, accedentials, octave, duration));
00519
00520 i = 0;
00521
00522 while ( CharIn(CHAR0, mutT("#&")) && !SepPos ) {
00523 #ifdef WX
00524 accedentials += CurrentLine[CurrentPos++];
00525 #else
00526 accedentials[i++] = CurrentLine[CurrentPos++];
00527 #endif
00528 GetSep();
00529 }
00530
00531 #ifndef WX
00532 accedentials[i] = 0;
00533
00534 #endif
00535
00536 DEBUGLOG2(other,_T("SepPos: %d"),SepPos);
00537
00538 if ( SepPos )
00539 return CheckError(Note(Name, accedentials, octave, duration));
00540
00541 int cp = CurrentPos;
00542
00543 int oct = ReadLong(1);
00544
00545 if ( cp != CurrentPos ) octave = oct;
00546
00547 if ( SepPos || !CharIn(CHAR0, mutT("/*.")) )
00548 return CheckError(Note(Name, accedentials, octave, duration));
00549
00550 int DurOk = 0;
00551
00552 duration = frac(1,1);
00553
00554 if ( CHAR0 == mutT('*') ) {
00555 DurOk = 1;
00556 CurrentPos++;
00557 duration = frac(ReadLong(0));
00558
00559 if ( !duration )
00560 return DoError(21);
00561 }
00562
00563 if ( SepPos || !CharIn(CHAR0, mutT("/.")) )
00564 return CheckError(Note(Name, accedentials, octave, duration));
00565
00566 if ( CHAR0 == mutT('/') ) {
00567 DurOk = 1;
00568 CurrentPos++;
00569 duration /= ReadLong(0);
00570
00571 if ( !duration )
00572 return DoError(22);
00573 }
00574
00575 if ( SepPos )
00576 return CheckError(Note(Name, accedentials, octave, duration));
00577
00578 if ( CHAR0 == mutT('.') && !DurOk )
00579 return DoError(23);
00580
00581 frac add = duration;
00582
00583 while ( CHAR0 == mutT('.') && !SepPos ) {
00584 add *= frac(1,2);
00585
00586 duration += add;
00587
00588 CurrentPos++;
00589
00590 GetSep();
00591 }
00592
00593 return CheckError(Note(Name, accedentials, octave, duration));
00594 }
00595
00596
00597
00598
00599
00600 int DoParse()
00601 {
00602 ParaMode = 0;
00603
00604 while ( !Eof ) {
00605 mutChar c = CHAR0;
00606 SavePos();
00607 Komma = 0;
00608
00609 if ( ParaMode ) {
00610 if ( mutIsdigit(c) || ( c == mutT('+')) || ( c == mutT('-')) )
00611 {
00612
00613 if ( ReadParaNumber() ) return GspError;
00614 } else if ( c == mutT('"') )
00615 {
00616
00617 if ( ReadParaStr() ) return GspError;
00618 } else
00619 {
00620 return DoError(10);
00621 }
00622
00623 if ( CHAR0 == mutT('>') )
00624 {
00625 CurrentPos++;
00626 GetSep();
00627
00628 if ( CheckError(EndParameter()) ) return GspError;
00629
00630 ParaMode = 0;
00631
00632 continue;
00633 }
00634 if ( !Komma )
00635 {
00636 return DoError(11);
00637 }
00638 } else
00639 {
00640 if ( LastTag ) LastTag --;
00641
00642 if ( CharIn(c, DelimitChars) ) {
00643 mutChar i = 0;
00644
00645 while ( DelimitChars[i] != c ) i++;
00646
00647 if ( i & 1 )
00648 {
00649
00650 if ( !BracketDeep )
00651 return DoError(1);
00652
00653 #ifdef WX
00654 DEBUGLOGBASE (other,_T(""),
00655 _T("brackets: %s, i= %d, last = %d"),
00656 Brackets.c_str(),
00657 i,
00658 Brackets[Brackets.Len()-1]);
00659
00660 if ( Brackets[Brackets.Len()-1] != i-1 )
00661 return DoError(2 + (int) Brackets[BracketDeep-1]/2);
00662
00663 Brackets = Brackets.Left(Brackets.Len()-1);
00664
00665 #else
00666 if ( Brackets[--BracketDeep] != i-1 )
00667 return DoError(2 + Brackets[BracketDeep]/2);
00668
00669 #endif
00670 } else
00671 #ifdef WX
00672 Brackets += i;
00673
00674 #else
00675 Brackets[BracketDeep++] = i;
00676
00677 #endif
00678 #ifdef GMN_STRICT
00679 if ( !LastTag && c == mutT('(') ) return DoError(41);
00680
00681 #endif
00682 CurrentPos++;
00683
00684 GetSep();
00685
00686 switch ( c ) {
00687 case mutT('{'): if ( CheckError(BeginSegment()) ) return GspError;
00688
00689 break;
00690
00691 case mutT('}'): if ( CheckError(EndSegment()) ) return GspError;
00692
00693 break;
00694
00695 case mutT('['): if ( CheckError(BeginSequenz()) ) return GspError;
00696
00697 break;
00698
00699 case mutT(']'): if ( CheckError(EndSequenz()) ) return GspError;
00700
00701 break;
00702
00703 case mutT('('): if ( CheckError(BeginRange()) ) return GspError;
00704
00705 break;
00706
00707 case mutT(')'): if ( CheckError(EndRange()) ) return GspError;
00708
00709 break;
00710 }
00711
00712
00713
00714 continue;
00715 }
00716
00717 if ( c == mutT('\\') ) {
00718 if ( ReadTag() ) return GspError;
00719
00720
00721
00722 continue;
00723 }
00724
00725 if ( c == mutT('|') ) {
00726 CurrentPos++;
00727 GetSep();
00728 #ifdef NO_SHORT_BAR
00729
00730 if ( CheckError(Tag(mutT("bar"))) ) return GspError;
00731
00732 #else
00733 if ( CheckError(Tag(mutT("|"))) ) return GspError;
00734
00735 #endif
00736
00737
00738 continue;
00739 }
00740
00741 if ( c == mutT(',') ) {
00742 if ( Brackets[BracketDeep-1] != 0 )
00743 return DoError(24);
00744
00745 CurrentPos++;
00746
00747 GetSep();
00748
00749 if ( CheckError(Comma()) ) return GspError;
00750
00751 continue;
00752 }
00753
00754 if ( IsLetter(c) ) {
00755 if ( ReadNote() ) return GspError;
00756
00757 if ( Komma )
00758 if ( CheckError(NextSequenz()) ) return GspError;
00759
00760 continue;
00761 }
00762
00763
00764 return DoError(20);
00765 }
00766 }
00767
00768 return 0;
00769 }
00770
00771
00772
00773
00774 int GspParse(const mutString &FileName)
00775 {
00776 GspCurrentLineNr = 0;
00777 CurrentPos = 0;
00778 CurrentLine = _T("");
00779
00780 GspErrorLineNr = 0;
00781 GspErrorPos = 0;
00782 GspErrorLine = mutEmptyString;
00783 GspError = 0;
00784
00785 Eof = 0;
00786 #ifdef WX
00787 Brackets = mutEmptyString;
00788 #else
00789 BracketDeep = 0;
00790 #endif
00791 LastTag = 0;
00792
00793 octave = 1;
00794 duration = frac(1,4);
00795
00796 if ( OpenFile(FileName) )
00797 return DoError(30);
00798
00799 GetSep();
00800
00801 if ( CheckError(StartSep()) )
00802 return GspError;
00803
00804 #ifdef GMN_STRICT
00805 if ( !Eof && CHAR0 != '[' && CHAR0 != '{' )
00806 DoError(40);
00807
00808 #endif
00809 if ( !GspError) DoParse();
00810
00811 if ( CloseFile() )
00812 return DoError(31);
00813
00814 return GspError;
00815 };
00816