From 09587ee41eecc3677b3361a24fa0c0ac12587162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Wed, 2 Dec 2015 14:52:50 +0100 Subject: [PATCH] working command matching, tbd trailing space and args --- main.c | 13 +++- main.elf | Bin 9720 -> 10832 bytes scpi_parser.c | 167 ++++++++++++++++++++++++++++++++++++++------------ scpi_parser.h | 2 +- 4 files changed, 140 insertions(+), 42 deletions(-) diff --git a/main.c b/main.c index 83e895a..4a5e0d2 100644 --- a/main.c +++ b/main.c @@ -1,4 +1,5 @@ #include +#include #include #include "scpi_parser.h" @@ -15,7 +16,7 @@ const SCPI_command_t scpi_cmd_lang[4] = { .callback = cmd_aIDNq_cb }, { - .level_cnt = 2, .levels = {"APPLy", "SINe"}, + .level_cnt = 3, .levels = {"APPLy", "SINe"}, .param_cnt = 3, .params = {SCPI_DT_INT, SCPI_DT_FLOAT, SCPI_DT_FLOAT}, .callback = cmd_APPL_SIN_cb }, @@ -57,9 +58,15 @@ void cmd_FREQ_cb(const SCPI_argval_t *args) -int main(int argc, const char**argv) +int main() { - const char *inp = argv[1]; + //const char *inp = "*IDN?\n"; + const char *inp = "FREQ 123\n"; + + for(int i=0;i||RR5%4Z~xLJbw z`_4T_magS&+L<1Y?svZ5_c-5q-gD0NX>Y?mtHr`(va&y5#7!5d95SAaO|9juz;>}> zrm{7xk`)56=0 zQpOYxkR8Q(UC6I5Z{xV6nuw!6<6Pl#g2`@H*v$$%NvA|$lFIr~-RQSk_+4#P!4a<# zVSD*=p7OQ;*7&PvJLN}RhQg>zK zvHmUnyLN8b`KUV*a&PDHlO9#^$%8H2wQLUs9F@HSKk7@8f4eiFtgHLSq1FHDshzms zc>T)sOP`Rf{2}|bQzJ z$$p7F(7l8-_K83eE8BRE`Z&9vrv+XFoa|*vX5nH8a?xxSPW>j+Tox|J6qnuC#tHe) zObz6Vv+(SAwBeh@+F5&GnZmRe5>b2dc_?ec?-XC-ZdiK95s1?3pTpDnkcu4fT_l{D zP9v>vBA%);GsXG+#8VY!5}dCko}OgE0x}y z55bR7{?HR~m%>ie+EIQumjq^DYE24F*Z z^n^=`pPCz2ov7lad+GG(Pp{<&_LJaj9>Fst2kl>kl!C@3qp-p~X(5W=*FTrz(^ZZ?egj~rW@rv_2H5YPigN1kw z3~s_x<@qCnYmnc{^ScMjk=LVTcy5Z4=AM`rg;i2v!*iu4)`D?>IoD|Eh_5U_&iQ6S z`!nZQOL}DV`u%Mz6&W9)e*5#g>GY)i1E<0#a;g=sSU)*jG8n+Kgcqj_KI6RNO%Ko2 zM9YTf9*gcAo-2tiNjZ|W2sX7b`4N$|q!OPPzYMp$-;x3D`?U1Eax_IzFXi!;#O%pU zG-ky3L%c`Pgw#@xpry_rkB%utcEHFMC4c*6I-NQ>K1E^Q_$`IKPP+Dw)7p^i$BFrBN53(kuy#JMHSURkM#mO|z?fGABwj#5|XY`ETJkwPIYs8#eg@FJ#m@vDwR};l9H9=Va*llo$)T9Mk6Xbh#C=uF_`0D#AioZ?v8lphECmW8?3`~ z;Pewir{>ydT+9ueF2lIITjQN`{veU+2ciyE;CbY9Ir`|X^GeIy@Y~AnDUu%HrKAqS zg~}Zr;f_@9=tz#Et-JtoG?3-!hH$jZa8xp1vJoq-231&cu50laO@GkIBuHp_bb)LFdtm!KYixE$%}Asi9Lh+Xgq_IdJ+L zs8ugk2Ji_jtjH z9hm(e5*vS?eAFQpv=A1f4_UP6Et){7Y7%R4dnw{FkTs*^AC1uw_ufObu0pS4xA$In zgf~{^<)NU9lNgoWkDOyGC(3A)^Ky5+Ej#pQM%`b743k0hGC3JK^%0A%hS^KmX0eBj zaqtQ^TN%lgAzYv=b!x(!W~mPJMS4LKo^44|Tb$D@dBqDBfuB>GJcTJZJZnL-h!QHv zm=6W?xcyeC!fL$f6X$u`{1oqA<9+Y>mgk$Ec-qtAX>K^T{*^)nFZ**_h#szwe^wv= zMZ-pV^A>AYzqBQ9e}-Z7!pBi%+XvFVA%3GF{@Gr5NU!)%8@^`IcBf)DXoK`@tLHgS ztLLakzcxC*pSXj46Zbd2g`)PzBunN1m4R|H1v%V8#IU~71_=h;lu1kD#uIc3}SM@qPBZ&TBuCdD7>?ezuQ zl|CFGlxQfV^n`+)Zc;Ghv0$LTFW`>`+7*A7FRW}>@86(w2c@06B#&MQKC*R;njCtH z7t-zPQT)B_o0T44B&tLLoxOozRCz*KA2Grb{(>PT67zS-a+E4RdEJP}a^vppjzqeH zor*8q86!^-9{YU!3;YBFCvffzY(#+w9?4Q^dyLMubjF*$gI6VJ<0t7ftpfW#O{ZPx z4;{1`v>&t)^iM(iKwkqL1+`<^(X`zIdL8r}=p5*Oe4b8Mpfg9Xr0xPO!z%xWpl^ZF ze&P~dRTn`o;60oGy@*ZCG^h(pMHR*sB|7g?vJ5maOTWufSyog$YAJFNz8b$##Jq_V zM9Qzv*gD8bfA%+sopc?peU6I#&e9XbLu}6jk8OHn-CBZ4XD@zkw81I@JPy~3*1DyI z%_tZw$=mVU@D=hikSkvyzXbWJMda%sdk4RA$e#txlU(z0QT<|}=GZk{bikp89lJb^ zYLBC;)}cTT`n8T?J`SIQpK163S&-fk>*uJTQURgyBx#x88w*sPTPpZVI382tV-8f_ zlT~sQ=YK&T5OjKZ8_!WcQIhgc@1;Y;w^>y@=kE}zYz8my4u-4-FP0tF#EeAuK$I#B z!d40@iI|q`C*uA>w#BGWkn^ud@N^$UDIv<2_+`P%xMg{`gyBi@*h=#Hj0k<~4>@lU zdb5Hb5OM+kzY}>MX)fqR(XX!v`l_H~f=&qfzMy9NC+q5Jlq%frZB%yP+Nv5WQRHNA z)OQRt8a8N`%;7F95bk5{U?>`Jdur>qM17rt>kP)+$70>MXY6igZsNLpkuK(LKN*BS zgGR%KR7#*^3pvOlBBG=awW$x}^H=fZzKb{?6APcqoqCVyhbm<*oUvEI~ zYKN`l3=7>C4*O0T7Bc^BKh)se*W2w!(IGg*!_7-EJRXZgn44bFc(a+?DIag69gS68 zAhKacu{tkqV~^*>3o`R3+nEgq`Jue}g-p(`T>T=JZ(Q0iTjhAp)nCHoyvW5%GV>=F zFJ*Ea$;Hc9U!L)0V@osN8FKXl4XZC*Bbt+q$yIk= zLhDZf`*nIAF>NT+l{vP+UiqTaNC6{<{e1JUF_vJ#BV8-_@pf~U%{9gpl z_bk9{G^K%uidAro@x2IWxxg!ys06b!{K?qE0)Mnr7tWVYxu0BJ;+DW6oh8hv61WSy z3iJG0%k>woKUItPc^vpM=EVM8;Pm-~l01vw0`9_m zZ(P;Jarw9-^ryx8FV99_2z_(=7h+ygx%6Fz5MYhHb<2{S|a3#zpq=zB}60;2G@rVn$Z9w zUJnN%fvAov0~4!19|$0{yN~ED>A*l`G7v(Wz7fbsKc6l$8ZNldqU&GuJ|IX zs@b1+>GNaet)ykBLvsxfY~D_edmP@bNiU z6=P*SVAE%5$RZ)V3pY=wmtKDe)oSk!>aj?mormGW9pQJf%Aoe47G)SKIP-V<$0yGBv^l8TYpTxZWgYLme)lBIxX#Hqeca>S%V^-P9j)w&e7N5szuI z{~uU7-_jC}<;h4^RZxS-^R2-dx-w7nVf^S!DedJxU;ZD60$FyF>#fALA(L${&ja+H zp|s8*nWx!)FC@6)2+8u>tSS&Xe{;g`FDPd>*vvUyu#EOObmo@!Lsk_W!#RT!cG)2O ze-NmhX#YV;o{ztYJeJ0cy*!7=`!jj2CmTxSBRkQ)kV*$Fkw@9E+OpYy#(3Q z-HW;X&I6;kC_YN^Jk=;V+Pw1@u%V1+9KURPdG6{HihUVPBjXahq_hvuwwLeiX<`4i z4A^8RSoR~6y*$TV5*JJIK1J%AUO`Z$o|5II% zih`QUA2Zp@^JDcg!{Cy1EbL9q!4kk}jEe5goHOPBotgE`{6E7MyUC2b+;>mYfep#5 zZ|1K0W*R=mP*wWaO_VRoy|Nm`@oFmEcDa)7R=RYCKE?=I56DzsdqVY>V zDU-dt*ZYaE*9o50%imle+>eC0Pj#NDt#lh70n`yZcz()$1a literal 9720 zcmcIq4Qy1`mA*6Mfx(!WF@&uf(&RM-#bw1n5`usv<&Etz{OvRZ^koY?8csP zXWmfT62_@XaNv|)TrwIXj?&6+67axb|baBuGFT{CY9(a?b;X!{mag# zl-cjxchCGh4d9r=nA#qdp?U~ zD1;^%WJj?Iza#-87NVf8;utDA*QA`-WY?hV8k9c6c@-E#ZXdOco;#G^JDfTwqICkI zMZQZ=<^sF}zcS;5=j$wme4Q>4h9@nyV90il!A`bM$v+Bk8nzDf_w3ldbs)ZFpg)-% z-ZH#%$Ce%21DRCdJ{dphQ4{y>?~*P#9~vmC`!+n(mn4sTuV=CDg`fXA^5a*&_t43u zhAW@{+t=D%zj837_JurccAR8h;!38lGhZ`G`^TcZi{^nGr+j{-oI} zGG=-pkrakOVk2Wl)21;P?I+HW!BkRl46(Ppt*P0#FK}Pr0rKorf0P6ID-FNw?ft7r zzDEVHP#=*P&nLwep0yT#B^YGS#b3r(LrjVq%J|eTT(mMij~S9Rmhp>2AN=sdWl#7y z_rI;tMEIE*)4dRr%r`t2$f{Hd5Bw8U3Y)%T5y~fsDY`FE)V%?w z&yu_={Pb1n;QS329E5Y%!si$EgdMZtpWHCl7rm`!Z@#T6J ztb5k|7Fdqo$(qjjv4Dgp_K2)|=|$KTo&AOk3iI8Iqp%?yJ>U=Lj^)p3SOOMay-_Gk zy?LQRu$ctURT1nWLAr{dodi!*2(;X>%i&!1V)(fb9^Dhph4N<)LGN6gl;1^9`A*N| zX3sqZQbxP56AmP1#WUyrHoA;T@0|NvUP5QxKPEWqo+A*RbDx)N;{2AdsczYlIrm`6 zvQMh`PP<LoIZy7);v+h?3Q{Ip;Etj7RUG|+0U7idT zo^!8*cMM+dMBeQ?u>xaoaUEX1GwvG@^gc6_{Y%ub5iU;5WVP{Q1uj*P7UJvw$L-nzsOjjaW~RpPtk+sKAc!8fUbiTvuX+znz1#PbIny}9+z z0`r}j3BTey-Bp;J%CC!vrPR40O7w;6g~FV>8zY6L;nEXuD~74MRbx@SYo&8-tjl*c zRG7%`HtQzx51Lyi^0nrcrIibxBb!YmLr+Z=d+L;Q>S3o1Q%mcomMG#iCb_Q7x)*lS zXiy^yvAzdg%FO-9Of8~CN2~@aEOh0(EQrcZc%6mu8lR!O_PW@IG{WEgEs%ceX1( z@dItwJV_79v9@#&E_CVWkaVO=M~5mLZIu;}qtP-)mz1M=%TaBqW@{K8#K>vHRC^oq zU>@@TaBiXbkA=cy=*n#9eK8xlDi;498HVB2-JvT-Yo(*bvy#>IK1}Arj(Oi{AqQXA zRp~=9me7{VXwwop=AB~4{NckwVf@(T$k;u2j~@Rtl%N>8oO=sZ{|j=Ayl8Fa_TG(&&BP>251DxXhxy@U9EKukOO?qMG4*aV9+RM&lQ) zB%tpXYSrkR9jB2=T{#u}Lh$imt`O`BcD6si>EGQN7RTqe5IoqH`=BlNv-Z!@O63Wk z|C4KB?tf9sGgnOQ-gkICZO>h5&wbDW4~5&_4NqKfgm*1vFQHz~7rTRpgWbU=gT{ra z()#;5d|#wLXwav|fp6rkO3kf=WWTwsWj}vpKSK9b;+OHAq2df4IM6;KQGpcfPbl=J z0ADt00cJ+U_xm5J`RnXxizbf@+|uVw{QXe*bF_AZ9?K?@F^=)3fhhq3tCrzkDu1ya zO|w!+m~8xR+3XTojG9=b>NmFzkBl}25A6|~TP4^OuN5NH(eY@97E28dMw4-E2>U3_ zOr^AeRPsoGBC_P!WMX(I5i=8UE!G!JYxiu5-J|s<*)C99MK1*(#=lDQV#=afF7)qI^dc=6$-TTX#|`EdiR-#gq-yIpdTS!ufNsX@Q82qS3Kil&+QLxzJKH0 z#3r2wnhSykwkuPf4SV*R073;8#(0N+jw&U2Tg(*o9yAb$mN zIq#di{ui80-iA}IkXL)YrpeoQ(jE40dv-_pymjB^KAw_h=spDNbL;V>r))A&Nm_Vg)ze0C-6PlGcssKdjQR}1^XDoQ96+x z5`kpOOay{WZClLf5k(zIW&=Ihe%wR!$3=jszG$XT1mYt}__Lsywj@Ur=}dnrSwR?( zr4s{DGEmsifGGm~$$q@e#4z5yARtS{qh?eD5`9K*Iy#sz`r@!<%Caz`>2!3&vS9p6 zF{r_Nbg(~$s#9=?S3uTcdF;t#M1VeRiKJ=IQ#IN}v&*S36S?s5xT7lHB_68EuPM%( za%V0aCC01juMj-1D)m>2YU9y`S<2(MQh$};`B2HPEzX-t{_5iTQOU0pdX@3z5^IY0 zkd^vg!Rt;X-zTQkdQ{2x<33F8>c!-mYJA)nsdcK{$R*Yl*RM+cZGw*V_Ts`S zRBgVw#9s)$?n`H^ZQqfw;@iJ3PlE3#i=WrULCIg9=a-Zp{$7EUWg2e> z-SFA+e-8X=?V7y_|EJQ=Cq+c%)2}`l?|@J3+Ot9jCWPFJ0A9jF{1L^Mdl2wkG^N2` z<t@H@p}lJYH@xB`VNfGi$0y)6wAGmzr0^ap_-qEp-(rU{M{vr%6{o* z`S|>T(zoaHOHzON_#6j+E!s=Ba#Z-cIt9KaIh8Nk3u*XD+sE@6@X?FQ%A4T(p>H4O zbl<*KEMEuSx{04l;MWVExTxaPK~u>~{WXHmPrQ%updr=bq5FJlFQ1QCzwsved%>sp z?d|PUe#9zW#v%8Rzg3`&WsNcJaDbqs+dh{CBExDEF|CO)Ea1 zXF2}AQ+!S3htHt@3cernbZC8~BA_2A{b{uhY*x}YmA<{dex~&4zLtvI^8@~;;`4c! zBFMGi*ISf63Z z4WqRqxG!Xc_O~D*R(2S#2q-R$mM8WH_q8=ct4tz)RuRVD_D7q7?Z%_6tp`J$MrW|8 zJw)#0FE6o7R^~w%ZJqm!Qqnv3HB-tvqdmAiq1~AEi;VmYN7u`Ll`#@>vu1g*e%7f} zkU64e4&W|E5JI;e25vcwSdaQWsM3OT=-z|m%YGrMR7KC0f|F@OplSS+gfwEn*nUld zb|z)?;id$wGTI)6ZoEHfWHX7lpnDM`@#SoEAY;V(Wt>r5b$z)k2uc>ES75v#=PJDh zwy6r2zhD(xh-)1(mhDd`Vu}8v38QBO1H^dbsL`QDck@6rlR=~vS;7FIU&7D{-1*cy zJo+p8#tNu7tNz~zoiDL;3oHj#aq0?MfX|l}W$7|b@H2SmOvm=T-{#+IHOR^fudB?v z7f881@5>)j4mYx*f_D2B@Nq?x;`$>_9UMCUN+9nI2yWD_8WBOW&3fb4oYCZ zFM*h{fLH-Yd18A$pFR#Amb#)np9gr~!{=(K$U;8K3+>?u~#@PT8K%A(N_pZYS4oZ~qBp-=rK)yL5?7EBj%^ zCwpp(-ToAKloN`N3V$yeR7dmv&XQWOGEOjur`%pw-%(xJM@Xrx&^;v;hO{3px1Uz_ z)5`w0+;C}CvQwn^hRvSOQ!mw88hoF@`pPYnVj39L&-tIO)j?r@q3j=Lf#eFIDahb8 zAm#RaKI8v;ILV3%+Uq}Uv*&Z%q`H_oY^$I9kKN7y@#0b4jRZwNp{NAg_3iYJpz6cJ z_PoFLd`$bdVN302dp>9RKc@XJU`u06A9aB)P2$sr#6!-@^uyYt^Mt2}o=kqLLq>gEz_#>EnX( bDLmWpaQk^(qxo5_{zi52y5A= (a) && (c) <= (b)) @@ -64,39 +68,44 @@ static void pars_match_level(void); // match charbuf content to a level, advance #define IS_UCASE_CHAR(c) INRANGE((c), 'A', 'Z') #define IS_NUMBER_CHAR(c) INRANGE((c), '0', '9') -#define IS_IDENT_CHAR(c) (IS_LCASE_CHAR((c)) || IS_UCASE_CHAR((c)) || IS_NUMBER_CHAR((c)) || (c) == '_') +#define IS_IDENT_CHAR(c) (IS_LCASE_CHAR((c)) || IS_UCASE_CHAR((c)) || IS_NUMBER_CHAR((c)) || (c) == '_' || (c) == '*' || (c) == '?') #define IS_INT_CHAR(c) IS_NUMBER_CHAR((c)) #define IS_FLOAT_CHAR(c) (IS_NUMBER_CHAR((c)) || (c) == '.' || (c) == 'e' || (c) == 'E' || (e) == '+' || (e) == '-') +#define CHAR_TO_LOWER(ucase) ((ucase) + 32) +#define CHAR_TO_UPPER(lcase) ((lcase) - 32) + + static void pars_reset_cmd(void) { pstate.state = PARS_COMMAND; - pstate.charbuf_ptr = 0; - pstate.cur_level_ptr = 0; + pstate.charbuf_i = 0; + pstate.cur_level_i = 0; pstate.cmdbuf_kept = false; - pstate.detected_cmd = NULL; - pstate.arg_ptr = 0; + pstate.matched_cmd = NULL; + pstate.arg_i = 0; } + static void pars_reset_cmd_keeplevel(void) { pstate.state = PARS_COMMAND; - pstate.charbuf_ptr = 0; + pstate.charbuf_i = 0; // rewind to last colon - if (pstate.cur_level_ptr > 0) { - pstate.cur_level_ptr--; // keep prev levels + if (pstate.cur_level_i > 0) { + pstate.cur_level_i--; // keep prev levels } pstate.cmdbuf_kept = true; - pstate.detected_cmd = NULL; - pstate.arg_ptr = 0; + pstate.matched_cmd = NULL; + pstate.arg_i = 0; } -void scpi_receive_byte(const uint8_t b) +void scpi_handle_byte(const uint8_t b) { // TODO handle blob here const char c = (char) b; @@ -105,7 +114,7 @@ void scpi_receive_byte(const uint8_t b) case PARS_COMMAND: // Collecting command - if (pstate.charbuf_ptr == 0 && pstate.cur_level_ptr == 0) { + if (pstate.charbuf_i == 0 && pstate.cur_level_i == 0) { if (IS_WHITESPACE(c)) { // leading whitespace is ignored break; @@ -116,8 +125,8 @@ void scpi_receive_byte(const uint8_t b) if (IS_IDENT_CHAR(c)) { // valid command char - if (pstate.charbuf_ptr < MAX_CMD_LEN) { - pstate.charbuf[pstate.charbuf_ptr++] = c; + if (pstate.charbuf_i < MAX_CMD_LEN) { + pstate.charbuf[pstate.charbuf_i++] = c; } else { printf("ERROR command part too long.\n");//TODO error pstate.state = PARS_DISCARD_LINE; @@ -127,7 +136,7 @@ void scpi_receive_byte(const uint8_t b) // invalid or delimiter if (IS_WHITESPACE(c)) { -// pars_cmd_space(); // whitespace in command - end of command? + pars_cmd_space(); // whitespace in command - end of command, start of args (?) break; } @@ -137,7 +146,7 @@ void scpi_receive_byte(const uint8_t b) break; case '\n': // line terminator -// pars_cmd_newline(); + pars_cmd_newline(); break; case ';': // ends a command, does not reset cmd path. @@ -159,16 +168,17 @@ void scpi_receive_byte(const uint8_t b) break; // TODO + } } static void pars_cmd_colon(void) { - if (pstate.charbuf_ptr == 0) { + if (pstate.charbuf_i == 0) { // No command text before colon - if (pstate.cur_level_ptr == 0 || pstate.cmdbuf_kept) { + if (pstate.cur_level_i == 0 || pstate.cmdbuf_kept) { // top level command starts with colon (or after semicolon - reset level) pars_reset_cmd(); } else { @@ -178,13 +188,40 @@ static void pars_cmd_colon(void) } } else { - // internal colon - pars_match_level(); + // internal colon - partial match + if (pars_match_cmd(true)) { + printf("OK partial cmd, last segment = %s\n", pstate.cur_levels[pstate.cur_level_i - 1]); + } else { + printf("ERROR no such command (colon).\n");//TODO error + pstate.state = PARS_DISCARD_LINE; + } + } +} + + +static void pars_cmd_newline(void) +{ + if (pstate.cur_level_i == 0 && pstate.charbuf_i == 0) { + // nothing before newline + pars_reset_cmd(); + return; + } + + // complete match + if (pars_match_cmd(false)) { + if (pstate.matched_cmd->param_cnt == 0) { + // no param command - OK + pstate.matched_cmd->callback(pstate.args); // args are empty + } else { + printf("ERROR command missing arguments.\n");//TODO error + pars_reset_cmd(); + } + } else { + printf("ERROR no such command (newline) %s.\n", pstate.charbuf);//TODO error + pstate.state = PARS_DISCARD_LINE; } } -#define CHAR_TO_LOWER(ucase) ((ucase) + 32) -#define CHAR_TO_UPPER(lcase) ((lcase) - 32) /** Check if chars equal, ignore case */ @@ -248,12 +285,66 @@ static bool level_str_matches(const char *test, const char *pattern) } +// proto +static bool try_match_cmd(const SCPI_command_t *cmd, bool partial); -static void pars_match_level(void) + +static bool pars_match_cmd(bool partial) { // terminate segment - pstate.charbuf[pstate.charbuf_ptr] = '\0'; + pstate.charbuf[pstate.charbuf_i] = '\0'; + pstate.charbuf_i = 0; // rewind + + char *dest = pstate.cur_levels[pstate.cur_level_i++]; + strcpy(dest, pstate.charbuf); // copy to level table + + for (uint16_t i = 0; i < scpi_cmd_lang_len; i++) { + + const SCPI_command_t *cmd = &scpi_cmd_lang[i]; + + if (cmd->level_cnt > MAX_LEVEL_COUNT) { + // FAIL, too deep. Bad config + continue; + } - //TODO + if (try_match_cmd(cmd, partial)) { + if (partial) { + // match found, OK + return true; + } else { + // exact match found + pstate.matched_cmd = cmd; + return true; + } + } + } + + return false; } + +/** Try to match current state to a given command */ +static bool try_match_cmd(const SCPI_command_t *cmd, bool partial) +{ + if (pstate.cur_level_i > cmd->level_cnt) return false; // command too short + if (pstate.cur_level_i == 0) return false; // nothing to match + + if (partial) { + if (pstate.cur_level_i == cmd->level_cnt) { + return false; // would be exact match + } + } else { + if (pstate.cur_level_i != cmd->level_cnt) { + return false; // can be only partial match + } + } + + // check for match up to current index + for (uint8_t j = 0; j < pstate.cur_level_i; j++) { + if (!level_str_matches(pstate.cur_levels[j], cmd->levels[j])) { + return false; + } + } + + return true; +} diff --git a/scpi_parser.h b/scpi_parser.h index dce2d7a..76dfa49 100644 --- a/scpi_parser.h +++ b/scpi_parser.h @@ -49,4 +49,4 @@ extern const uint16_t scpi_cmd_lang_len; // number of commands extern const SCPI_command_t scpi_cmd_lang[]; // --------------- functions -------------------- - +void scpi_handle_byte(const uint8_t b);