TNB Library
TnbTmlParser.h
[詳解]
1#pragma once
13#include "TnbFilePathManager.h"
14#include "TnbTmlCalculator.h"
15#include "TnbTmlDocuments.h"
17
18
19
20//TNB Library
21namespace TNB
22{
23
24
25
49{
50public:
51
63 struct IListener
64 {
66 virtual ~IListener(void) {}
67
76 virtual bool IsExecutionContinued(void) = 0;
77
84 virtual void OutputLog(LPCTSTR lpszLog, bool boHasErrMsg) = 0;
85 };
86
92 {
97 };
98
99
100 //--------------------------------
101
102
104 CTmlParser(void) : m_piListener(NULL), m_piExpander(NULL), m_eLogLevel(ELL_ABSOLUTE), m_iLogLastLine(0)
105 {
106 m_calc.SetExpander(this);
107 m_variable.IncLevel();
108 m_documents.IncLevel();
109 }
110
113 {
114 }
115
123 void SetTestMode(bool boIsTestMode)
124 {
125 m_calc.SetTestMode(boIsTestMode);
126 }
127
133 bool IsTestMode(void) const
134 {
135 return m_calc.IsTestMode();
136 }
137
142 void Empty(void)
143 {
144// ::PlaySound(NULL, NULL, 0);
145 m_documents.Empty();
146 m_documents.IncLevel();
147 m_variable.Empty();
148 m_variable.IncLevel();
149 m_cInterruptInfo.Empty();
150 m_strLogLastName.Empty();
151 m_iLogLastLine = 0;
152 }
153
158 void SetListener(IListener* piListener = NULL)
159 {
160 m_piListener = piListener;
161 }
162
167 void SetExpander(ITmlExpander* piExpander = NULL)
168 {
169 m_piExpander = piExpander;
170 }
171
177 {
178 m_eLogLevel = eLevel;
179 }
180
188 CTmlResult AddMacroFile(LPCTSTR lpszName, LPCTSTR lpszPath = NULL)
189 {
190 CTmlResult trRet;
191 //
192 CFilePathManager pathMan;
193 CFileReader reader = pathMan.Open(lpszName, lpszPath);
194 if ( reader.CanRead() )
195 {
196 try
197 {
198 CByteVector vc = reader.ReadExactly();
199 vc.Add(0);
200 return AddMacroContents(reader.GetOpenName(), reinterpret_cast<LPCSTR>(vc.ReferBuffer()));
201 }
202 catch ( CTnbException& e )
203 {
204 e;
206 }
207 }
208 else
209 {
211 }
212 m_MessageBug( "ファイル'%s'が読み込めません。", CAscii(lpszName));
213 reader.Close();
214 return trRet;
215 }
216
224 CTmlResult AddMacroContents(LPCTSTR lpszName, LPCSTR lpszData)
225 {
227 CTmlResult res = m_documents.Add(tFunc, CAscii(lpszName), lpszData);
228 if ( res.IsError() )
229 {
230 return res;
231 }
232 else if ( res.IsNop() )
233 {
234 return Result_Success; //同じファイルを読み込んでいた。
235 }
236 //
237 if ( ! tFunc.HasData() )
238 {
239 ASSERTLIB( false ); //おかしい、ありえない?!
240 return Result_Nop;
241 }
242 //あった
243 CTmlGrammar gram(tFunc.lpszFuncAdds, NULL, tFunc.iFuncLine);
244 gram.SetName(CStr(tFunc.strFileName));
245 //
246 CTmlValue tvResult;
247 return ExecMacro(gram, tvResult);
248 }
249
256 void IncMacroLevel(void)
257 {
258 m_documents.IncLevel();
259 m_variable.IncLevel();
260 }
261
268 void DecMacroLevel(void)
269 {
270 m_variable.DecLevel();
271 m_documents.DecLevel();
272 }
273
281 bool ExistFunction(LPCSTR lpszFuncName) const
282 {
284 tFunc = m_documents.FindFunc(lpszFuncName);
285 return tFunc.HasData();
286 }
287
295 CTmlResult ExecFunction(CTmlValue& _answer, LPCSTR lpszFuncName)
296 {
297 CTmlValuesVector aValues;
298 return ExecFunction(_answer, lpszFuncName, aValues);
299 }
300
309 CTmlResult ExecFunction(CTmlValue& _answer, LPCSTR lpszFuncName, const CTmlValuesVector& aValues)
310 {
312 tFunc = m_documents.FindFunc(lpszFuncName);
313 if ( ! tFunc.HasData() )
314 {
315 return Result_Nop;
316 }
317 //あった
318 m_variable.IncLevel();
319 if ( tFunc.pastrParamNames == NULL )
320 {
321 //パラメータなし
322 if ( aValues.GetSize()!=0 )
323 {
324 //引数があるのでエラー
325 m_variable.DecLevel();
326 m_MessageBug("引数のない func '%s'に引数を渡しています。", lpszFuncName);
328 }
329 }
330 else
331 {
332 size_t dim = tFunc.pastrParamNames->GetSize();
333 if ( dim < aValues.GetSize() )
334 {
335 //引数が多すぎ
336 m_MessageBug("func '%s'(引数は %d個)に、%d個のに引数を渡しています。",
337 lpszFuncName,
338 dim,
339 aValues.GetSize()
340
341 );
342 m_variable.DecLevel();
344 }
345 //引数変数、追加
346 for ( size_t i = 0; i < dim; i++ )
347 {
348 CTmlValue value;
349 if ( aValues.GetSize() > i )
350 {
351 value = aValues.At(i);
352 }
353 m_variable.AddValue(tFunc.pastrParamNames->At(i), value);
354 }
355 }
356 //
357 CTmlGrammar gram(tFunc.lpszFuncAdds, NULL, tFunc.iFuncLine);
358 gram.SetName(CStr(tFunc.strFileName));
359 CTmlResult res = ExecMacro(gram, _answer);
360 m_variable.DecLevel();
361 //
362 if ( ! res.IsSuccess() )
363 {
364 if ( CAscii(res.GetFuncName()).IsEmpty() )
365 {
366 //なければ設定
367 res.SetFuncName(lpszFuncName);
368 }
369 }
370 return res;
371 }
372
381 {
382 LPCSTR pp = _gram.GetPointer();
384 CTmlGrammar backGram = _gram;
386 //
387 CTmlResult res;
388 _answer = 0;
389 //
390 CNestInfo cNest;
391 INT_PTR iStartVarLevel = m_variable.GetLevel();
392 INT_PTR iStartContentsLevel = m_documents.GetLevel();
393 //
394 while ( true )
395 {
396 backGram = _gram;
397 //割り込みチェック
398 {
399 CTmlResult r = m_CheckInterrupt();
400 if ( ! r.IsSuccess() )
401 {
402 res = r;
403 break;
404 }
405 }
406 //
407 parts = _gram.PeekNextParts();
408 CTmlGrammar::EPartsKind kind = parts.GetKind();
409 CAscii token = parts.GetString();
410 if ( kind == CTmlGrammar::ERROR_STRING )
411 {
412 //エラー
415 res.SetLine(backGram);
416 m_MessageBug(res, "文字列表記にエラーがあります。");
417 break;
418 }
419 else if ( token == ";" )
420 {
421 _gram.GetNextParts();
422 continue;
423 }
424 else if ( token == "{" )
425 {
426 _gram.GetNextParts();
427 cNest.Inc(cNest.EK_Non);
428 m_variable.IncLevel();
429 m_documents.IncLevel();
430 continue;
431 }
432 else if ( token == "}" || kind == CTmlGrammar::FINAL )
433 {
434 if ( cNest.IsTopDepth() )
435 {
436 m_MessageLog(backGram, ELL_DETAILS, "深さ0で閉じ文字がありました。関数を終わります。");
437 break;
438 }
439 else if ( cNest.GetNowKind() == cNest.EK_While )
440 {
441 m_MessageLog(backGram, ELL_BRANCH, "whileネストの'}'がありました。while文へ戻ります。");
442 _gram = cNest.GetWhileInfo();
443 cNest.Dec();
444 m_variable.DecLevel();
445 m_documents.DecLevel();
446 }
447 else
448 {
449 _gram.GetNextParts();
450 cNest.Dec();
451 m_variable.DecLevel();
452 m_documents.DecLevel();
453 }
454 continue;
455 }
456 //
457 backGram = _gram;
458 EStatementResultType stateResType;
459 CTmlResult r = m_SearchAndExecCommand(_gram, cNest, _answer, stateResType);
460 //
461 if ( r.IsSuccess() )
462 {
463 // ステートメント処理、あり
464 if ( stateResType == ESRT_Return/*return文*/ )
465 {
466 TTRACE0(_T("return文なので関数終了\n"));
467 break;
468 }
469 else if ( stateResType == ESRT_Function/*func文*/ )
470 {
471 if ( cNest.IsTopDepth() )
472 {
473 m_MessageLog(_gram, ELL_DETAILS, "深さ0で'func'がありました。関数を終わります。");
474 break;
475 }
476 else
477 {
479 res.SetScene(Scene_Func);
481 res.SetLine(backGram);
482 m_MessageBug(res, "func文が発見されました。ここには func宣言は記述できません。");
483 break;
484 }
485 }
486 }
487 else if ( r.IsError() )
488 {
489 //エラー
490 res = r;
491 break;
492 }
493 else
494 {
495 //ステートメントではなかったので、数式?
496 CTmlValue v;
497 r = m_calc.TextToValue(v, _gram);
498 if ( r.IsSuccess() )
499 {
500 /*数式だった*/
501 }
502 else if ( r.IsError() )
503 {
504 //エラー
505 res = r;
506 break;
507 }
508 else
509 {
510 /*謎*/
511 CAscii str = backGram.PeekNextParts().GetString();
513 r.SetErrorString(str);
514 r.SetLine(backGram);
515 m_MessageBug(r, "謎の文 '%s...' があります。", str.Left(32));
516 return r;
517 }
518 }
519 }
520 //
521 // 変数レベルを関数開始時に戻す
522 m_variable.DecLevels(iStartVarLevel);
523 m_documents.DecLevels(iStartContentsLevel);
524 //
525 if ( res.IsError() )
526 {
527 if ( res.GetFileLine()==0 )
528 {
529 //エラー行ファイル名が未設定なら、
530 res.SetLine(_gram);
531 }
532 return res;
533 }
534 return Result_Success;
535 }
536
537private:
538
543 class CInterruptFunc
544 {
545 public:
547 CInterruptFunc(void) : m_iLastAccessId(0)
548 {
549 }
551 void Empty(void)
552 {
553 m_iLastAccessId = 0;
554 m_astrFuncInfos.RemoveAll();
555 }
563 int Set(LPCSTR lpszFuncName, DWORD dwTick)
564 {
565 ASSERT( lpszFuncName != NULL && lpszFuncName[0]!=0 );
566 INT_PTR iFindingId = -1;
567 TFuncInfo T;
568 T.dwTick = ::GetTickCount() + dwTick;
569 T.strName = lpszFuncName;
570 size_t len = m_astrFuncInfos.GetSize();
571 for( size_t i = m_iLastAccessId; i < len; i++ )
572 {
573 if ( m_astrFuncInfos[i].strName.IsEmpty() )
574 {
575 m_astrFuncInfos[i] = T;
576 iFindingId = i;
577 break;
578 }
579 }
580 if ( iFindingId < 0 )
581 {
582 for ( size_t i = 0; i < m_iLastAccessId && i < len; i++ )
583 {
584 if ( m_astrFuncInfos[i].strName.IsEmpty() )
585 {
586 m_astrFuncInfos[i] = T;
587 iFindingId = i;
588 break;
589 }
590 }
591 }
592 if ( iFindingId < 0 )
593 {
594 iFindingId = m_astrFuncInfos.Add(T);
595 }
596 TTRACE3( "TML::CInterruptFunc::Set() %dms後に関数[%s]を実行予定 ID=%d\n", dwTick, lpszFuncName, iFindingId );
597 m_iLastAccessId = iFindingId + 1;
598 return ToInt(iFindingId);
599 }
604 void Kill(int iInterruptId)
605 {
606 if ( ToInt(m_astrFuncInfos.GetSize()) > iInterruptId )
607 {
608 if ( ! m_astrFuncInfos[iInterruptId].strName.IsEmpty() )
609 {
610 m_astrFuncInfos[iInterruptId].strName.Empty();
611 m_iLastAccessId = iInterruptId + 1;
612 TTRACE1("CInterruptFunc::Kill() ID=%dの割り込み停止\n", iInterruptId );
613 }
614 }
615 }
622 CAsciiVector Check(void)
623 {
624 CAsciiVector vs;
625 DWORD dwNow = ::GetTickCount();
626 loop ( i, m_astrFuncInfos.GetSize() )
627 {
628 if ( m_astrFuncInfos[i].strName.IsEmpty() )
629 {
630 continue;
631 }
632 int r = static_cast<int>(dwNow - m_astrFuncInfos[i].dwTick);
633 if ( r >= 0 )
634 {
635 TTRACE2( "TML::CInterruptFunc::Check() ID=%dの割込実行 Func=[%s]\n", i,
636 m_astrFuncInfos[i].strName
637 );
638 vs.Add(m_astrFuncInfos[i].strName);
639 m_astrFuncInfos[i].strName.Empty();
640 m_iLastAccessId = i + 1;
641 }
642 }
643 return vs;
644 }
645 private:
647 struct TFuncInfo
648 {
649 DWORD dwTick;
650 CAscii strName;
651 };
652 CVectorT<TFuncInfo> m_astrFuncInfos;
653 size_t m_iLastAccessId;
654 };
655
660 class CNestInfo
661 {
662 public:
664 enum EKind
665 {
666 EK_Non = 0,
667 EK_IfEqu,
668 EK_IfNeq,
669 EK_Switch,
670 EK_While,
671 };
672
674 CNestInfo(void)
675 {
676 m_iDepth = 0;
677 m_aKind.Add(EK_Non/*何でもないネス*/);
678 TTRACE1("ネストレベル=0 NowLvl=%d\n", m_iDepth);
679 }
681 bool IsTopDepth()
682 {
683 return m_iDepth == 0;
684 }
686 EKind GetNowKind(void)
687 {
688 if ( ToInt(m_aKind.GetSize()) <= m_iDepth )
689 {
690 return EK_Non;
691 }
692 return m_aKind.Ref(m_iDepth);
693 }
695 EKind GetLastKind(void)
696 {
697 if ( ToInt(m_aKind.GetSize()) <= (m_iDepth + 1) )
698 {
699 return EK_Non;
700 }
701 return m_aKind.Ref(m_iDepth + 1);
702 }
704 void Inc(EKind eKind)
705 {
706 m_iDepth++;
707 m_aKind.SetSize(m_iDepth);
708 m_aKind.Add(eKind);
709 TTRACE1("ネストレベル++ NowLvl=%d\n", m_iDepth);
710 }
712 void IncWhile(const CTmlGrammar& gram)
713 {
714 Inc(EK_While);
715 TTRACE0(" →whileネストです\n");
716 m_aWhileStartInfo.Insert(0, gram);
717 }
719 CTmlGrammar GetWhileInfo(void)
720 {
721 if ( GetNowKind() == EK_While )
722 {
723 return m_aWhileStartInfo[0];
724 }
725 return CTmlGrammar();
726 }
728 void Dec(void)
729 {
730 if ( m_iDepth > 0 )
731 {
732 if ( GetNowKind() == EK_While )
733 {
734 m_aWhileStartInfo.Remove(0);
735 }
736 m_iDepth--;
737 //参照の可能性があるので、消さない
738 TTRACE1("ネストレベル-- NowLvl=%d\n", m_iDepth);
739 }
740 }
741 private:
742 int m_iDepth;
743 CVectorT<EKind> m_aKind;
744 CVectorT<CTmlGrammar> m_aWhileStartInfo;
745 };
746
747 CTmlDocuments m_documents;
748 CTmlVariableManager m_variable;
749 CTmlCalculator m_calc;
750 CInterruptFunc m_cInterruptInfo;
751 IListener* m_piListener;
752 ITmlExpander* m_piExpander;
753 ELogLevel m_eLogLevel;
754 CAscii m_strLogLastName;
755 INT_PTR m_iLogLastLine;
756
761 CTmlResult m_CheckInterrupt(void)
762 {
763 //リスナーチェック
764 if ( m_piListener != NULL )
765 {
766 if ( ! m_piListener->IsExecutionContinued() )
767 {
768 m_MessageBug("中断します。");
770 }
771 }
772 //割込みチェック
773 CAsciiVector astrFuncs = m_cInterruptInfo.Check();
774 if ( astrFuncs.GetSize()>0 )
775 {
776 //割込みあり
778 CTmlValue tvObject;
779 loop ( i, astrFuncs.GetSize() )
780 {
781 TTRACE1( "時間が来たので [%s]を実行\n", astrFuncs[i] );
782 CTmlResult res = ExecFunction(tvObject, astrFuncs[i], tva);
783 if ( res.IsError() )
784 {
785 return res;
786 }
787 }
788 }
789 return Result_Success;
790 }
791
799 void m_MessageBug(LPCSTR lpszMessage, ...)
800 {
801 CAscii str;
802 va_list args;
803 va_start(args, lpszMessage);
804 str.FormatV(lpszMessage, args);
805 va_end(args);
806 m_MessageBug(m_strLogLastName, m_iLogLastLine, str);
807 }
808
817 void m_MessageBug(const CTmlResult& res, LPCSTR lpszMessage, ...)
818 {
820 {
821 return;
822 }
823 CAscii str;
824 va_list args;
825 va_start(args, lpszMessage);
826 str.FormatV(lpszMessage, args);
827 va_end(args);
828 m_MessageBug(res.GetFileName(), res.GetFileLine(), str);
829 }
830
840 void m_MessageBug(LPCSTR lpszName, INT_PTR iLine, LPCSTR lpszMessage)
841 {
842 CAscii str;
843 if ( iLine > 0 )
844 {
845 str.Format("%s(%d): Error:%s", lpszName, iLine, lpszMessage);
846 }
847 else
848 {
849 str.Format("%s", lpszMessage);
850 }
851 m_strLogLastName = lpszName;
852 m_iLogLastLine = iLine;
853 #ifdef _DEBUG
854 ::OutputDebugStringA(str + "\n");
855 #endif
856 if ( m_piListener != NULL )
857 {
858 m_piListener->OutputLog(CStr(str), true);
859 }
860 }
861
870 void m_MessageLog(ELogLevel elLevel, LPCSTR lpszMessage, ...)
871 {
872 CAscii str;
873 va_list args;
874 va_start(args, lpszMessage);
875 str.FormatV(lpszMessage, args);
876 va_end(args);
877 m_MessageLog("", 0, elLevel, str);
878 }
879
889 void m_MessageLog(const CTmlGrammar& gram, ELogLevel elLevel, LPCSTR lpszMessage , ...)
890 {
891 CAscii str;
892 va_list args;
893 va_start(args, lpszMessage);
894 str.FormatV(lpszMessage, args);
895 va_end(args);
896 m_MessageLog(CAscii(gram.GetName()), gram.GetLine(), elLevel, str);
897 }
898
909 void m_MessageLog(LPCSTR lpszName, INT_PTR iLine, ELogLevel elLevel, LPCSTR lpszMessage)
910 {
911 #ifndef _DEBUG
912 if ( m_eLogLevel<elLevel )
913 {
914 return;
915 }
916 #endif
917 CAscii strLevel;
918 switch(elLevel)
919 {
920 case ELL_DETAILS://詳細
921 strLevel = "Info.";
922 break;
923 case ELL_BRANCH://分岐
924 strLevel = "Branch";
925 break;
926 case ELL_FUNC: //関数
927 strLevel = "Func.";
928 break;
929 case ELL_ABSOLUTE://絶対
930 default:
931 strLevel = "Info.";
932 break;
933 }
934 CAscii str;
935 if ( iLine > 0 )
936 {
937 str.Format("%s(%d): %s:%s", lpszName, iLine, strLevel, lpszMessage);
938 }
939 else
940 {
941 str.Format(" %s:%s", strLevel, lpszMessage);
942 }
943 #ifdef _DEBUG
944 ::OutputDebugStringA(str + "\n");
945 if ( m_eLogLevel < elLevel )
946 {
947 return;
948 }
949 #endif
950 if ( m_piListener != NULL )
951 {
952 m_piListener->OutputLog(CStr(str), false);
953 }
954 }
955
960 void m_DumpVarDim(void)
961 {
964 //
965 INT_PTR iDim1 = aaVava.GetSize();
966 for( INT_PTR i = iDim1 - 1; i >= 0; i-- )
967 {
968 m_MessageLog(ELL_ABSOLUTE, "---変数内容(lvl=%d)", i);
970 INT_PTR iDim2 = aa.GetSize();
971 for( INT_PTR j = 0; j < iDim2; j++ )
972 {
974 if ( T.value.HasData() )
975 {
976 //Data型
977 m_MessageLog(ELL_ABSOLUTE, "%s = [%s](len=%d)",
978 T.name,
979 T.value.GetString(),
980 T.value.GetInteger()
981 );
982 }
983 else
984 {
985 //数値型
986 m_MessageLog(ELL_ABSOLUTE, "%s = %d", T.name, T.value.GetInteger());
987 }
988 }
990 iDim2 = va.GetSize();
991 for( INT_PTR j = 0; j < iDim2; j++ )
992 {
994 INT_PTR iDim3 = T.values.GetSize();
995 for( INT_PTR k = 0; k < iDim3; k++ )
996 {
997 if ( T.values[k].HasData() )
998 {
999 //Data型
1000 m_MessageLog(ELL_ABSOLUTE, "%s(%d) = [%s](len=%d)",
1001 T.name,
1002 k,
1003 T.values[k].GetString(),
1004 T.values[k].GetInteger()
1005 );
1006 }
1007 else
1008 {
1009 //数値型
1010 m_MessageLog(ELL_ABSOLUTE,"%s(%d) = %d",
1011 T.name, k, T.values[k].GetInteger());
1012 }
1013 }
1014 }
1015 }
1016 }
1017
1027 CTmlResult ExpandVariable(CTmlValueCarrier& _answer, LPCSTR lpszToken, const CTmlValuesVector &aValues, bool boIsTestMode)
1028 {
1029 if ( lpszToken == NULL )
1030 {
1031 //テスト用のLOG出力
1032 ASSERT( boIsTestMode );
1033 m_MessageBug(_answer().GetString());
1034 return Result_Success;
1035 }
1036 //本クラスが覚えてる変数をチェック
1037 CTmlValue* V = m_variable.FindValue(lpszToken);
1038 if ( V != NULL )
1039 {
1040 _answer.SetRef(*V);
1041 if ( aValues.GetSize() > 0 )
1042 {
1043 //パラメータがある
1045 }
1046 #ifdef _DEBUG
1047 _answer.Set(lpszToken);
1048 #endif
1049 return Result_Success;
1050 }
1051 //
1052 //本クラスが覚えてる配列をチェック
1053 CTmlValuesVector* A = m_variable.FindArray(lpszToken);
1054 if ( A != NULL )
1055 {
1056 if ( aValues.GetSize()==0 )
1057 {
1058 _answer = ToInt(A->GetSize());
1059 return Result_Success;
1060 }
1061 else if ( aValues.GetSize() == 1 )
1062 {
1063 int i = aValues[0].GetInteger();
1064 if ( i < 0 || i >= ToInt(A->GetSize()) )
1065 {
1067 }
1068 _answer.SetRef(A->Ref(i));
1069 #ifdef _DEBUG
1070 CAscii s;
1071 s.Format("%s(%d)", lpszToken, i);
1072 _answer.Set(s);
1073 #endif
1074 return Result_Success;
1075 }
1076 return CTmlResult::CheckParamNum(aValues.GetSize(), 1);
1077 }
1078 //
1079 if ( m_piExpander != NULL )
1080 {
1081 CTmlResult r = m_piExpander->ExpandVariable(_answer, lpszToken, aValues, boIsTestMode);
1082 if ( ! r.IsNop() )
1083 {
1084 return r;
1085 }
1086 }
1087 //本クラスが知っている関数をチェック
1088 CTmlValue value;
1089 CTmlResult res = ExecFunction(value, lpszToken, aValues);
1090 if ( res.IsError() )
1091 {
1092 return res;
1093 }
1094 else if ( res.IsSuccess() )
1095 {
1096 _answer = value;
1097 return res;
1098 }
1099 //
1100 if ( STRLIB::Compare(lpszToken, "pause") == 0 )
1101 {
1102 //汎用グローバル関数 「指定時間停止」
1103 TTRACE1( "found System Func [%s]\n", lpszToken );
1104 if ( aValues.GetSize() == 1 )
1105 {
1106 if ( boIsTestMode ) { return Result_Success; }
1107 //
1108 int i = aValues[0].GetInteger();
1109 // ::Sleep( i );
1110 CTmlResult r;
1111 DWORD dwStart;
1112 DWORD dwNow;
1113 if ( i < 500 )
1114 {
1115 dwStart = ::GetTickCount();
1116 while ( true )
1117 {
1118 dwNow = ::GetTickCount();
1119 DWORD dw = i;
1120 if ( (dwNow - dwStart) >= dw ) { break; }
1121 r = m_CheckInterrupt();
1122 if ( ! r.IsSuccess() ) { return r; }
1123 }
1124 }
1125 else
1126 {
1127 dwStart = ::GetTickCount();
1128 while ( true )
1129 {
1130 dwNow = ::GetTickCount();
1131 DWORD dw = i;
1132 if ( (dwNow - dwStart) >= dw ) { break; }
1133 r = m_CheckInterrupt();
1134 if ( ! r.IsSuccess() ){ return r; }
1135 ::Sleep(10);
1136 }
1137 }
1138 return Result_Success;
1139 }
1140 return CTmlResult::CheckParamNum(aValues.GetSize(), 1);
1141 }
1142 else if ( STRLIB::Compare(lpszToken, "setinterrupt") == 0 )
1143 {
1144 //汎用グローバル関数 「割り込み設定」
1145 TTRACE1( "found System Func [%s]\n", lpszToken );
1146 if ( aValues.GetSize() == 2 )
1147 {
1148 if ( boIsTestMode ){ return Result_Success; }
1149 //
1150 CAscii strFuncName = aValues[0].GetString();
1151 //
1153 tFunc = m_documents.FindFunc(strFuncName);
1154 if ( ! tFunc.HasData() )
1155 {
1157 }
1158 _answer = m_cInterruptInfo.Set(strFuncName, aValues[1].GetInteger());
1159 return Result_Success;
1160 }
1161 return CTmlResult::CheckParamNum(aValues.GetSize(), 2);
1162
1163 }
1164 else if ( STRLIB::Compare(lpszToken, "killinterrupt") == 0 )
1165 {
1166 //汎用グローバル関数 「割り込み停止」
1167 TTRACE1( "found System Func [%s]\n", lpszToken );
1168 if ( aValues.GetSize() == 0 )
1169 {
1170 if ( boIsTestMode ) { return Result_Success; }
1171 m_cInterruptInfo.Empty();
1172 return Result_Success;
1173 }
1174 else if ( aValues.GetSize() == 1 )
1175 {
1176 if ( boIsTestMode ){ return Result_Success; }
1177 m_cInterruptInfo.Kill(aValues[0].GetInteger());
1178 return Result_Success;
1179 }
1180 return CTmlResult::CheckParamNum(aValues.GetSize(), 1);
1181 }
1182#if 0
1183 else if ( STRLIB::Compare((lpszToken, "playSound" ) == 0 || STRLIB::Compare(lpszToken, "loopSound") == 0 )
1184 {
1185 //汎用グローバル関数 「音」
1186 TTRACE1( "found System Func [%s]\n", lpszToken );
1187 if ( aValues.GetSize() == 1 )
1188 {
1189 if ( boIsTestMode ) { return ETR_Success; }
1190 CCurrentDirMan cDirMan;
1191 cDirMan.SetDirOfFile( m_cText.GetFileName() );
1192 //
1193 CString strWaveName = aValues[0].GetString();
1194 DWORD dwSound = SND_FILENAME | SND_NODEFAULT | SND_ASYNC;
1195 if ( lpszToken[0]=='l' )
1196 {
1197 dwSound |= SND_LOOP;
1198 }
1199 ::PlaySound(strWaveName, NULL, dwSound);
1200 //
1201 return 1;
1202 }
1203 return CTmlResult::CheckParamNum(aValues.GetSize(), 1);
1204 }
1205 else if ( _tcscmp( lpszToken,"stopsound" )==0 )
1206 {
1207 //汎用グローバル関数 「音」
1208 TTRACE1("found System Func [%s]\n", lpszToken);
1209 if ( aValues.GetSize()==0 )
1210 {
1211 if ( boIsTestMode ){return ETR_Success;}
1212 //
1213 ::PlaySound(NULL, NULL, 0);
1214 return 1;
1215 }
1216 return CTmlResult::CheckParamNum(aValues.GetSize(), 0);
1217
1218 }
1219#endif
1220 //無ければ
1221 return Result_Nop;
1222 }
1223
1231 CTmlResult OnChangeValue(LPCSTR lpszName, const CTmlValue& value)
1232 {
1233 //無ければ
1234 if ( m_piExpander != NULL )
1235 {
1236 return m_piExpander->OnChangeValue(lpszName, value);
1237 }
1238 return Result_Nop;
1239 }
1240
1242 enum EStatementResultType
1243 {
1244 ESRT_Normal,
1245 ESRT_Return,
1246 ESRT_Function,
1247 };
1248
1257 CTmlResult m_SearchAndExecCommand(CTmlGrammar& _gram, CNestInfo& _nest, CTmlValue& _answer, EStatementResultType& _stateResType)
1258 {
1259 LPCSTR pp = _gram.GetPointer();
1261 CTmlGrammar backGram = _gram;
1262 CTmlGrammar::CParts parts;
1263 //
1264 bool boIsTestMode = m_calc.IsTestMode();
1265 //
1266 _stateResType = ESRT_Normal;
1267 //
1268 CTmlResult res;
1269 //
1270 parts = _gram.GetNextParts();
1271 if ( parts.GetKind() != CTmlGrammar::TOKEN )
1272 {
1273 /*トークンがない!!*/
1274 _gram = backGram;
1275 return Result_Nop;
1276 }
1277 CAscii token = parts.GetString();
1278 if ( token.IsEqual("func") )
1279 {
1280 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1281 _stateResType = ESRT_Function/*func*/;
1282 }
1283 else if ( token.IsEqual("return") || token.IsEqual("end") )
1284 {
1285 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1286 parts = _gram.PeekNextParts();
1287 if ( strchr(";{}/", parts.GetString()[0]) != NULL )
1288 {
1289 ;
1290 }
1291 else
1292 {
1293 CTmlValue v;
1294 res = m_calc.TextToValue(v, _gram);
1295 if ( res.IsError() )
1296 {
1297 res.SetScene((token[0] == 'r') ? Scene_Return : Scene_End);
1298 m_MessageBug(res, "%s 文の引数式でエラーが発生しました。", token);
1299 return res;
1300 }
1301 _answer = v;
1302 }
1303 //
1304 if ( ! boIsTestMode )
1305 {
1306 //本番モード
1307 if ( token[0] == 'r' )
1308 {
1309 //return
1310 _stateResType = ESRT_Return/*return*/;
1311 }
1312 else
1313 {
1314 //end
1316 }
1317 }
1318 else
1319 {
1320 //テストモード
1321 _answer = 1;
1322 }
1323 }
1324 else if ( token.IsEqual("val") )
1325 {
1326 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1327 //
1328 parts = _gram.GetNextParts();
1329 if ( parts.GetKind() != CTmlGrammar::TOKEN )
1330 {
1332 m_MessageBug(res, "valの後に、変数名指定がありません。");
1333 return res;
1334 }
1335 CAscii valName = parts.GetString();
1336 CTmlValue firstValue;
1337 parts = _gram.PeekNextParts();
1338 if ( CAscii(parts.GetString()) == "=" )
1339 {
1340 _gram.GetNextParts();
1341 res = m_calc.TextToValue(firstValue, _gram);
1342 if ( res.IsError() )
1343 {
1344 res.SetScene(Scene_Val);
1345 res.SetLine(backGram);
1346 m_MessageBug(res, "valの変数初期化の式でエラーが発生しました。");
1347 return res;
1348 }
1349 }
1350 else
1351 {
1352 firstValue = 0;
1353 }
1354 //
1356 if ( m_variable.HasNameInNowLevel(valName) )
1357 {
1358 //同じレベルに同じ名前がある。
1360 res.SetErrorString(valName);
1361 if ( ! m_calc.IsTestMode() )
1362 {
1363 return res;
1364 }
1365 //LOGへ
1366 res.SetLine(_gram);
1367 m_MessageBug(res.ToString());
1368 }
1369 else
1370 {
1371 if ( ! m_variable.AddValue(valName, firstValue) )
1372 {
1374 m_MessageBug(res, "valの変数登録でなぞのエラーが発生しました。");
1375 return res;
1376 }
1377 m_MessageLog(backGram, ELL_DETAILS, "変数宣言 `%s' = [%s](%d)", valName, firstValue.GetString(), firstValue.GetInteger());
1378 }
1379 }
1380 else if ( token.IsEqual("array") )
1381 {
1382 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1383 //
1384 parts = _gram.GetNextParts();
1385 if ( parts.GetKind() != CTmlGrammar::TOKEN )
1386 {
1388 m_MessageBug(res, "arrayの後に、変数名指定がありません。");
1389 return res;
1390 }
1391 CAscii arrayName = parts.GetString();
1392 parts = _gram.PeekNextParts();
1393 if ( ! parts.IsEqualString("(") )
1394 {
1396 m_MessageBug(res, "arrayの配列名の後に括弧がありません。");
1397 return res;
1398 }
1399 else
1400 {
1401 CTmlValue sizeValue;
1402 res = m_calc.TextToValue(sizeValue, _gram);
1403 if ( res.IsError() )
1404 {
1405 res.SetScene(Scene_Array);
1406 res.SetLine(backGram);
1407 m_MessageBug(res, "arrayの配列サイズの式でエラーが発生しました。");
1408 return res;
1409 }
1411 if ( m_variable.HasNameInNowLevel(arrayName) )
1412 {
1413 //同じレベルに同じ名前がある。
1415 res.SetErrorString(arrayName);
1416 if ( m_calc.IsTestMode() )
1417 {
1418 //LOGへ
1419// res.SetLine(CAscii(_gram.GetName()), _gram.GetLine());
1420 res.SetLine(_gram);
1421 m_MessageBug(res.ToString());
1422 }
1423 else
1424 {
1425 return res;
1426 }
1427 }
1428 else
1429 {
1430 if ( ! m_variable.AddArray(arrayName, sizeValue.GetInteger()) )
1431 {
1433 m_MessageBug(res, "arrayの配列サイズが異常値です。");
1434 return res;
1435 }
1436 m_MessageLog(backGram, ELL_DETAILS, "配列宣言 `%s(%d)", arrayName, sizeValue.GetInteger());
1437 }
1438 }
1439 }
1440 else if ( token.IsEqual("if") )
1441 {
1442 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1443 //
1444 CTmlValue boolValue;
1445 res = m_calc.TextToValue(boolValue, _gram);
1446 if ( res.IsError() )
1447 {
1448 res.SetScene(Scene_If);
1449 res.SetLine(backGram);
1450 m_MessageBug(res, "if文の条件式でエラーが発生しました。");
1451 return res;
1452 }
1453 parts = _gram.GetNextParts();
1454 if ( ! parts.IsEqualString("{") )
1455 {
1457 m_MessageBug(res, "if文に`{'がありません。");
1458 return res;
1459 }
1460 //
1461 if ( ! boIsTestMode )
1462 {
1463 //本番モード
1464 if ( boolValue.GetInteger() != 0 )
1465 {
1466 m_MessageLog(ELL_BRANCH, "└条件に合いましたので以下を実行します");
1467 _nest.Inc(CNestInfo::EK_IfEqu);
1468 m_variable.IncLevel();
1469 m_documents.IncLevel();
1470 }
1471 else
1472 {
1473 m_MessageLog(ELL_BRANCH, "└条件に合いませんでした");
1474 _nest.Inc( CNestInfo::EK_IfNeq );
1475 _nest.Dec();
1476 _gram.SkipoutBlock(); //`}'の次に
1477 }
1478 }
1479 else
1480 {
1481 //テストモード
1482 m_MessageLog(ELL_BRANCH, "└テストモードなので以下を実行します");
1483 _nest.Inc(CNestInfo::EK_IfNeq);
1484 m_variable.IncLevel();
1485 m_documents.IncLevel();
1486 }
1487 }
1488 else if ( token.IsEqual("else") )
1489 {
1490 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1491 //
1492 parts = _gram.GetNextParts();
1493 if ( parts.IsEqualString("if") )
1494 {
1495 m_MessageLog(ELL_DETAILS, "else文に続いてif文がありました。");
1496 switch( _nest.GetLastKind() )
1497 {
1498 case CNestInfo::EK_IfEqu:
1499 m_MessageLog(ELL_BRANCH, "└条件に合いましたのでelse文を実行しません");
1500 {
1501 //if文の{までスキップ
1502 CTmlValue boolValue;
1503 res = m_calc.TextToValue(boolValue, _gram);
1504 if ( res.IsError() )
1505 {
1506 res.SetScene(Scene_If);
1507 m_MessageBug(res, "if文の条件式でエラーが発生しました。");
1508 return res;
1509 }
1510 parts = _gram.GetNextParts();
1511 if ( ! parts.IsEqualString("{") )
1512 {
1514 m_MessageBug(res, "if文に`{'がありません。");
1515 return res;
1516 }
1517 _gram.SkipoutBlock(); //`}'の次に
1518 }
1519 break;
1520 case CNestInfo::EK_IfNeq:
1521 m_MessageLog(ELL_BRANCH, "└条件に合わないのでelse の後の if文を実行します");
1522 break;
1523 default:
1525 m_MessageBug(res, "if文がないのにelse文があります。");
1526 return res;
1527 }
1528 }
1529 else if ( ! parts.IsEqualString("{") )
1530 {
1532 m_MessageBug(res, "else文に`{'がありません。");
1533 return res;
1534 }
1535 else
1536 {
1537 switch( _nest.GetLastKind() )
1538 {
1539 case CNestInfo::EK_IfEqu:
1540 m_MessageLog(ELL_BRANCH, "└条件に合いましたのでelse文を実行しません");
1541 _gram.SkipoutBlock(); //`}'の次に
1542 break;
1543 case CNestInfo::EK_IfNeq:
1544 m_MessageLog(ELL_BRANCH,"└条件に合わないのでelse文を実行します");
1545 _nest.Inc(CNestInfo::EK_Non);
1546 m_variable.IncLevel();
1547 m_documents.IncLevel();
1548 break;
1549 default:
1551 m_MessageBug(res, "if文がないのにelse文があります。");
1552 return res;
1553 }
1554 }
1555 }
1556 else if ( token.IsEqual("case") )
1557 {
1558 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1559 //
1560 CTmlValue dummyValue;
1561 res = m_calc.TextToValue(dummyValue, _gram);
1562 if ( res.IsError() )
1563 {
1564 res.SetScene(Scene_Case);
1565 m_MessageBug(res, "case文の式でエラーが発生しました。");
1566 return res;
1567 }
1568 parts = _gram.GetNextParts();
1569 if ( ! parts.IsEqualString(":") )
1570 {
1572 m_MessageBug(res, "case文に`:'がありません。");
1573 return res;
1574 }
1575 }
1576 else if ( token.IsEqual("default") )
1577 {
1578 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1579 //
1580 parts = _gram.GetNextParts();
1581 if ( ! parts.IsEqualString(":") )
1582 {
1584 m_MessageBug(res, "default文に`:'がありません。");
1585 return res;
1586 }
1587 }
1588 else if ( token.IsEqual("switch") )
1589 {
1590 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1591 //
1592 CTmlValue caseValue;
1593 res = m_calc.TextToValue(caseValue, _gram);
1594 if ( res.IsError() )
1595 {
1597 m_MessageBug(res, "switch文の条件式でエラーが発生しました。");
1598 return res;
1599 }
1600 m_MessageLog(ELL_DETAILS, "switch文の引数は[%s](%d)です。", caseValue.GetString(), caseValue.GetInteger());
1601 //
1602 parts = _gram.GetNextParts();
1603 if ( ! parts.IsEqualString("{") )
1604 {
1606 m_MessageBug(res, "switch文に`{'がありません。");
1607 return res;
1608 }
1609 //switch()直後の位置を記憶
1610 CTmlGrammar backGram = _gram;
1611 //defaultの位置
1612 CTmlGrammar defaultGram;
1613 //-- case or default までスキップ
1614 bool boMatchCase = false;
1615 while ( true )
1616 {
1617 parts = _gram.GetNextParts();
1618 CAscii token = parts.GetString();
1619 if ( parts.GetKind() == CTmlGrammar::OPEN_CHAR )
1620 {
1621 //ブロック開始文字
1622 _gram.SkipoutBlock();
1623 continue;
1624 }
1625 else if ( token.IsEqual("}") )
1626 {
1627 break;
1628 }
1629 switch ( parts.GetKind() )
1630 {
1631 case CTmlGrammar::CLOSE_CHAR: // ブロック終端文字
1632 case CTmlGrammar::FINAL: // 終わり
1633 case CTmlGrammar::ERROR_STRING: // 文字列エラー
1634 case CTmlGrammar::ERROR_DEPTH: // 深さエラー
1636 m_MessageBug(res, "`{'が綴じてません。");
1637 return res;
1638 }
1639 if ( token.IsEqual("default") )
1640 {
1641 m_MessageLog(_gram, ELL_DETAILS, "`default文'を確認");
1642 parts = _gram.GetNextParts();
1643 if ( ! parts.IsEqualString(":") )
1644 {
1646 m_MessageBug(res, "switch文に`:'がありません。");
1647 return res;
1648 }
1649 defaultGram = _gram; //記憶!
1650 continue;
1651 }
1652 else if ( token.IsEqual("case") )
1653 {
1654 m_MessageLog(_gram, ELL_DETAILS, "`case文'を確認");
1655 //
1656 CTmlValue v;
1657 res = m_calc.TextToValue(v, _gram);
1658 if ( res.IsError() )
1659 {
1660 res.SetScene(Scene_Case);
1661 m_MessageBug(res, "case文の式でエラーが発生しました。");
1662 return res;
1663 }
1664 parts = _gram.GetNextParts();
1665 if ( ! parts.IsEqualString(":") )
1666 {
1668 m_MessageBug(res, "case文に`:'がありません。");
1669 return res;
1670 }
1671 if ( ! boIsTestMode && caseValue.Compare(m_calc.ReferElementWildResult(), v) )
1672 {
1673 //本番モード & 一致
1674 m_MessageLog(ELL_BRANCH, "一致するcase文がありました");
1675 boMatchCase = true;
1676 break;
1677 }
1678 }
1679 }
1680 //
1681 if ( ! boIsTestMode )
1682 {
1683 //本番モード
1684 if ( ! boMatchCase )
1685 {
1686 if ( defaultGram.GetPointer() != NULL )
1687 {
1688 //defaultを使う
1689 m_MessageLog(ELL_BRANCH, "一致するcase文がないのでdefault文以下を実行します");
1690 _gram = defaultGram;
1691 boMatchCase = true;
1692 }
1693 else
1694 {
1695 m_MessageLog(ELL_BRANCH,"switch構文内に一致する`case'`default'文がありませんでした");
1696 _gram.SkipoutBlock(); //`}'の次に
1697 }
1698 }
1699 if ( boMatchCase )
1700 {
1701 _nest.Inc(CNestInfo::EK_Switch);
1702 m_variable.IncLevel();
1703 m_documents.IncLevel();
1704 }
1705 }
1706 else
1707 {
1708 //テストモード
1709 _gram = backGram;
1710 _nest.Inc( CNestInfo::EK_Switch );
1711 m_variable.IncLevel();
1712 m_documents.IncLevel();
1713 }
1714 }
1715 else if ( token.IsEqual("while") )
1716 {
1717 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1718 //
1719 CTmlValue boolValue;
1720 res = m_calc.TextToValue(boolValue, _gram);
1721 if ( res.IsError() )
1722 {
1723 res.SetScene(Scene_While);
1724 m_MessageBug(res, "while文の条件式でエラーが発生しました。");
1725 return res;
1726 }
1727 //
1728 parts = _gram.GetNextParts();
1729 if ( ! parts.IsEqualString("{") )
1730 {
1732 m_MessageBug(res, "while文に`{'がありません。");
1733 return res;
1734 }
1735 if ( ! boIsTestMode )
1736 {
1737 //本番モード
1738 if ( boolValue.GetInteger() != 0 )
1739 {
1740 m_MessageLog(ELL_BRANCH, "└条件に合いましたので以下を実行します");
1741 _nest.IncWhile(_gram);
1742 m_variable.IncLevel();
1743 m_documents.IncLevel();
1744 }
1745 else
1746 {
1747 m_MessageLog(ELL_BRANCH, "└条件に合いませんでした");
1748 _gram.SkipoutBlock(); //`}'の次に
1749 }
1750 }
1751 else
1752 {
1753 //テストモード
1754 _nest.Inc(CNestInfo::EK_Switch); //テストでは、switchとしておく
1755 m_variable.IncLevel();
1756 m_documents.IncLevel();
1757 }
1758 }
1759 else if ( token.IsEqual("break") )
1760 {
1761 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1762 //
1763 if ( _nest.IsTopDepth() )
1764 {
1766 m_MessageBug(res, "`switch'か`while'文がないのに`break'文があります。");
1767 return res;
1768 }
1769 //
1770 CNestInfo cNestTmp = _nest;
1771 //
1772 CTmlGrammar bg = _gram;
1773 while ( true )
1774 {
1775 if ( cNestTmp.GetNowKind() == CNestInfo::EK_Switch || cNestTmp.GetNowKind() == CNestInfo::EK_While )
1776 {
1777 if ( ! _gram.SkipoutBlock() )
1778 {
1779 _gram = bg;
1781 m_MessageBug(res, "'{'が閉じていません。");
1782 return res;
1783 }
1784 cNestTmp.Dec();
1785 if ( ! boIsTestMode )
1786 {
1787 //本番モード
1788 _nest = cNestTmp;
1789 m_variable.DecLevel();
1790 m_documents.DecLevel();
1791 }
1792 else
1793 {
1794 //テストモード
1795 _gram = bg;
1796 }
1797 break;
1798 }
1799 else
1800 {
1801 if ( ! _gram.SkipoutBlock() )
1802 {
1803 _gram = bg;
1805 m_MessageBug(res, "'{'が閉じていません。");
1806 return res;
1807 }
1808 cNestTmp.Dec();
1809 if ( ! boIsTestMode )
1810 {
1811 //本番モード
1812 m_variable.DecLevel();
1813 m_documents.DecLevel();
1814 }
1815 if ( cNestTmp.IsTopDepth() )
1816 {
1817 _gram = bg;
1819 m_MessageBug(res, "`switch'か`while'文がないのに`break'文があります。");
1820 return res;
1821 }
1822 }
1823 }
1824 }
1825 else if ( token.IsEqual("include") )
1826 {
1827 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1828 //
1829 CTmlValue v;
1830 res = m_calc.TextToValue(v, _gram);
1831 if ( res.IsError() )
1832 {
1834 m_MessageBug(res, "include文の条件式でエラーが発生しました。");
1835 return res;
1836 }
1837 //現在の実行行のPath
1839 res = AddMacroFile(CStr(v.GetString()), str);
1840 if ( ! res.IsSuccess() )
1841 {
1843 m_MessageBug(res, "include文の条件式でエラーが発生しました。");
1844 return res;
1845 }
1846 _answer = v;
1847 }
1848 else if ( token.IsEqual("vardump") )
1849 {
1850 m_MessageLog(backGram, ELL_FUNC, "`%s'文を確認", token);
1851 //**開発用です
1852 if ( ! boIsTestMode )
1853 {
1854 //本番モード
1855 m_DumpVarDim();
1856 }
1857 }
1858 else
1859 {
1860 //しない
1861 _gram = backGram;
1862 return Result_Nop;
1863 }
1864 //
1865// cBackupLine.Destroy();
1866 return Result_Success;
1867 }
1868
1869 friend class CTmlMacroTest;
1870};
1871
1872
1873
1874}; // TNB
#define loop(VAR, CNT)
loop構文.
Definition: TnbDef.h:343
ファイルパス関係のヘッダ
TinyMacroLang 計算関係のヘッダ
TinyMacroLang ドキュメント管理関係のヘッダ
TinyMacroLang 変数管理関係のヘッダ
ファイルパス管理クラス
static CStr GetPathName(LPCTSTR lpszFullPath)
[取得] フォルダ名抽出.
CFileReader Open(LPCTSTR lpszFile, LPCTSTR lpszPath=NULL) const
[操作] ファイルオープン.
ファイル読み込みクラス
Definition: TnbFile.h:338
virtual bool CanRead(void) const
[確認] 読み込み可能か
Definition: TnbFile.h:383
virtual LPCTSTR GetOpenName(void) const
[取得] オープン名取得
Definition: TnbFile.h:373
virtual void Close(void)
[操作] クローズ
Definition: TnbFile.h:351
文法解析用パーツ管理クラス
bool IsEqualString(LPCSTR lpsz) const
[比較] 内容比較
EPartsKind GetKind(void) const
[取得] 種類
const TYP * GetString(void) const
[取得] 内容
文法解析テンプレート
UINT_PTR GetLine(void) const
[取得] 行番号取得
EPartsKind
パーツ種類コード
@ ERROR_DEPTH
深さエラー
@ OPEN_CHAR
ブロック開始文字
@ CLOSE_CHAR
ブロック終端文字
@ ERROR_STRING
文字列エラー
ITE GetPointer(void)
[取得] 現在のイテレータ
CParts GetNextParts(bool boIsToken=true)
[取得] 次のパーツ取得
bool SkipoutBlock(void)
[処理] ブロックからステップアウト.
CStr GetName(void) const
[取得] 名前取得
void SetName(LPCTSTR name)
[設定] 名前設定
CParts PeekNextParts(bool boIsToken=true)
[確認] 次のパーツ確認
void FormatV(const TYP *lpszFormat, va_list V)
[代入] 書式付き文字列代入.
Definition: TnbStr.h:349
bool IsEmpty(void) const
[確認] 空チェック
Definition: TnbStr.h:528
CStrT Left(size_t iSize) const
[作成] 範囲取得.
Definition: TnbStr.h:801
bool IsEqual(const TYP *lpszSubject) const
[確認] 文字列比較
Definition: TnbStr.h:669
void Empty(void)
[削除] 空化
Definition: TnbStr.h:197
void Format(const TYP *lpszFormat,...)
[代入] 書式付き文字列代入.
Definition: TnbStr.h:359
TinyMacroLang 計算
CVectorT< CByteVector > & ReferElementWildResult(void)
[参照] ワイルドカードリザルト.
bool IsTestMode(void) const
[取得] テストモード状態取得
void SetExpander(ITmlExpander *piExpander=NULL)
[設定] 拡張処理指定
CTmlResult TextToValue(CTmlValue &_answer, LPCSTR lpsz)
[処理] 計算.
void SetTestMode(bool boIsTestMode)
[設定] テストモード設定.
TinyMacroLang ドキュメント管理
CTmlResult Add(TFuncInfoRes &_tFuncInfo, LPCSTR lpszName, LPCSTR lpszData)
[追加] ファイル情報追加.
bool DecLevel(void)
[操作] レベル−1
void IncLevel(void)
[操作] レベル+1
void Empty(void)
Empty
INT_PTR GetLevel(void) const
[取得] 現在レベル取得
bool DecLevels(INT_PTR level)
[設定] レベル指定.
TFuncInfoRes FindFunc(LPCSTR lpszFunc) const
[検索] 関数検索.
TinyMacroLang パーサー
Definition: TnbTmlParser.h:49
CTmlResult ExecMacro(CTmlGrammar &_gram, CTmlValue &_answer)
[処理] マクロ実行.
Definition: TnbTmlParser.h:380
CTmlParser(void)
コンストラクタ
Definition: TnbTmlParser.h:104
void DecMacroLevel(void)
[設定] マクロレベル−1.
Definition: TnbTmlParser.h:268
void IncMacroLevel(void)
[設定] マクロレベル+1.
Definition: TnbTmlParser.h:256
bool IsTestMode(void) const
[取得] テストモード状態取得
Definition: TnbTmlParser.h:133
CTmlResult ExecFunction(CTmlValue &_answer, LPCSTR lpszFuncName, const CTmlValuesVector &aValues)
[処理] 指定関数の実行.
Definition: TnbTmlParser.h:309
void SetExpander(ITmlExpander *piExpander=NULL)
[設定] 拡張関数のインターフェイス設定.
Definition: TnbTmlParser.h:167
void SetListener(IListener *piListener=NULL)
[設定] リスナー用インターフェイス設定.
Definition: TnbTmlParser.h:158
CTmlResult ExecFunction(CTmlValue &_answer, LPCSTR lpszFuncName)
[処理] 指定関数の実行.
Definition: TnbTmlParser.h:295
ELogLevel
LOG表示レベル.
Definition: TnbTmlParser.h:92
@ ELL_DETAILS
詳細
Definition: TnbTmlParser.h:96
@ ELL_BRANCH
分岐
Definition: TnbTmlParser.h:95
@ ELL_FUNC
関数/命令
Definition: TnbTmlParser.h:94
@ ELL_ABSOLUTE
絶対
Definition: TnbTmlParser.h:93
CTmlResult AddMacroFile(LPCTSTR lpszName, LPCTSTR lpszPath=NULL)
[追加] マクロファイルの追加.
Definition: TnbTmlParser.h:188
void Empty(void)
[設定] クリア.
Definition: TnbTmlParser.h:142
~CTmlParser(void)
デストラクタ
Definition: TnbTmlParser.h:112
void SetTestMode(bool boIsTestMode)
[設定] テストモード設定/解除.
Definition: TnbTmlParser.h:123
bool ExistFunction(LPCSTR lpszFuncName) const
[確認] 指定関数の有無チェック.
Definition: TnbTmlParser.h:281
void SetLogLevel(ELogLevel eLevel)
[設定] ログレベル、設定.
Definition: TnbTmlParser.h:176
CTmlResult AddMacroContents(LPCTSTR lpszName, LPCSTR lpszData)
[追加] マクロコンテンツの追加.
Definition: TnbTmlParser.h:224
TinyMacroLang 結果状態管理
Definition: TnbTmlResult.h:133
bool IsNop(void) const
[確認] NOP 確認.
Definition: TnbTmlResult.h:264
void SetErrorString(LPCSTR lpszString)
[設定] エラー内容設定
Definition: TnbTmlResult.h:300
LPCSTR GetFuncName(void) const
[取得] エラー発生関数名取得
Definition: TnbTmlResult.h:361
static CTmlResult CheckParamNum(INT_PTR iParamNum, INT_PTR iExpectNum)
[確認] パラメータの数と、期待の数のチェック.
Definition: TnbTmlResult.h:453
LPCSTR GetFileName(void) const
[取得] エラーソースファイル名取得
Definition: TnbTmlResult.h:388
void SetFuncName(LPCSTR lpszFunc)
[設定] エラー発生関数名設定
Definition: TnbTmlResult.h:291
EResult GetResult(void) const
[取得] リザルトコード取得.
Definition: TnbTmlResult.h:334
CAscii ToString(void)
[取得] 文字列取得.
Definition: TnbTmlResult.h:401
void SetScene(EScene eScene)
[設定] シーンコード設定
Definition: TnbTmlResult.h:273
bool IsError(void) const
[確認] ERROR 確認.
Definition: TnbTmlResult.h:254
bool IsSuccess(void) const
[確認] SUCCESS 確認.
Definition: TnbTmlResult.h:244
void SetOperation(EOperation eOperation)
[設定] オペレーションコード設定
Definition: TnbTmlResult.h:282
INT_PTR GetFileLine(void) const
「取得」 エラーソース行番号取得
Definition: TnbTmlResult.h:379
CTmlResult & SetLine(LPCSTR lpszFileName, INT_PTR iFileLine)
[設定] エラーソースファイル名、行数設定
Definition: TnbTmlResult.h:311
TinyMacroLang 値参照管理
Definition: TnbTmlValue.h:654
void Set(LPCSTR lpsz)
[代入] 拡張ネーム指定.
Definition: TnbTmlValue.h:740
void SetRef(CTmlValue &v)
[代入] Value参照指定.
Definition: TnbTmlValue.h:731
TinyMacroLang 値管理
Definition: TnbTmlValue.h:43
INT_PTR Compare(ICollectionT< CByteVector > &_vvbWild, const CTmlValue &other) const
[比較] 比較.
Definition: TnbTmlValue.h:155
int GetInteger(void) const
[取得] 数字取得.
Definition: TnbTmlValue.h:418
CAscii GetString(void) const
[取得] 文字列取得.
Definition: TnbTmlValue.h:439
bool HasData(void) const
[確認] データ型保持確認.
Definition: TnbTmlValue.h:398
TinyMacroLang 変数管理
CTmlValue * FindValue(LPCSTR lpszName)
[検索] 変数名の検索 変数名に対になる値管理のポインタを返します。
bool DecLevel(void)
[設定] レベル−1.
bool AddArray(LPCSTR lpszName, size_t size)
[追加] 配列情報追加.
void IncLevel(void)
[設定] レベル+1.
CArVaVectors & ReferArrayArrays(void)
[取得] 配列情報参照.
void Empty(void)
[設定] Empty
bool HasNameInNowLevel(LPCSTR lpszName) const
[検索] 現レベルに指定名あるか.
CVaVaVectors & ReferVarArrays(void)
[取得] 変数情報参照.
INT_PTR GetLevel(void) const
[取得] 現在のレベル取得.
bool DecLevels(INT_PTR level)
[設定] レベル指定.
CTmlValuesVector * FindArray(LPCSTR lpszName)
[検索] 配列名の検索 配列名に対になる配列管理のポインタを返します。
bool AddValue(LPCSTR lpszName, const CTmlValue &v)
[追加] 変数情報追加.
TinyMacroLang コード管理
Definition: TnbTmlResult.h:48
@ Operation_FileAccess
Fileアクセス中
Definition: TnbTmlResult.h:82
@ Operation_CheckFunc
関数チェック中
Definition: TnbTmlResult.h:79
@ Operation_CheckStatement
ステートメントチェック中
Definition: TnbTmlResult.h:80
@ Operation_Non
未定義
Definition: TnbTmlResult.h:73
@ Scene_Array
array文処理中
Definition: TnbTmlResult.h:56
@ Scene_Break
break文処理中
Definition: TnbTmlResult.h:64
@ Scene_Else
else文処理中
Definition: TnbTmlResult.h:59
@ Scene_Case
case文処理中
Definition: TnbTmlResult.h:61
@ Scene_Non
未定義
Definition: TnbTmlResult.h:54
@ Scene_Include
include文処理中
Definition: TnbTmlResult.h:66
@ Scene_Switch
switch文処理中
Definition: TnbTmlResult.h:60
@ Scene_If
if文処理中
Definition: TnbTmlResult.h:58
@ Scene_Return
return文処理中
Definition: TnbTmlResult.h:65
@ Scene_While
while文処理中
Definition: TnbTmlResult.h:63
@ Scene_Func
func文処理中
Definition: TnbTmlResult.h:57
@ Scene_End
end文処理中
Definition: TnbTmlResult.h:67
@ Scene_Val
val文処理中
Definition: TnbTmlResult.h:55
@ Scene_Default
default文処理中
Definition: TnbTmlResult.h:62
@ Result_Nop
処理なし
Definition: TnbTmlResult.h:89
@ Result_ReadFailure
Read失敗
Definition: TnbTmlResult.h:108
@ Result_UnknownError
その他のエラー
Definition: TnbTmlResult.h:90
@ Result_ManyParam
引数が多すぎます
Definition: TnbTmlResult.h:103
@ Result_OpenFailure
Open失敗
Definition: TnbTmlResult.h:107
@ Result_UnnecessaryParam
引数は不必要です
Definition: TnbTmlResult.h:102
@ Result_UserInterruption
ユーザによる中断
Definition: TnbTmlResult.h:112
@ Result_AlreadyExistName
既にある名前です
Definition: TnbTmlResult.h:101
@ Result_Success
成功
Definition: TnbTmlResult.h:88
@ Result_NotName
名前がありません
Definition: TnbTmlResult.h:100
@ Result_InvalidWordPosition
単語位置が異常です(そこには存在しないはず)
Definition: TnbTmlResult.h:99
@ Result_NotFoundParentheses
括弧が必要なところにない
Definition: TnbTmlResult.h:93
@ Result_NotFoundFunction
必要な関数がありません
Definition: TnbTmlResult.h:111
@ Result_ProgramableInterruption
プログラムによる中断
Definition: TnbTmlResult.h:113
@ Result_NotCloseParentheses
括弧が閉じていない
Definition: TnbTmlResult.h:94
@ Result_OutOfRange
範囲外
Definition: TnbTmlResult.h:105
@ Result_UnknownKeyword
知らないキーワード
Definition: TnbTmlResult.h:98
例外ベースクラス
Definition: TnbException.h:36
virtual size_t GetSize(void) const
[取得] サイズ取得
Definition: TnbVector.h:368
virtual const TYP & At(INDEX index) const
[取得] 要素の参照取得.
Definition: TnbVector.h:233
virtual TYP & Ref(INDEX index)
[取得] 要素の参照取得.
Definition: TnbVector.h:246
virtual const TYP * ReferBuffer(void) const
[取得] データアドレス取得
Definition: TnbVector.h:664
virtual INDEX Add(const TYP &t)
[追加] 要素一つ追加.
Definition: TnbVector.h:383
int Compare(LPCSTR P1, LPCSTR P2, INT_PTR len=-1, DWORD dwCmpFlags=0)
[比較] 文字列比較(ASCII/SJIS用)
Definition: TnbStrLib.h:135
TNB::CStrT< char > CAscii
ASCII文字列クラス
Definition: TnbStr.h:1758
TNB::CStrT< TCHAR > CStr
文字列クラス
Definition: TnbStr.h:1785
int ToInt(LPCSTR lpsz, int iBase=10)
[変換] INT変換(ASCII/SJIS用).
Definition: TnbStrLib.h:367
CGrammarAnalyzerT< char > CTmlGrammar
TinyMacroLang 文章解析
Definition: TnbTmlResult.h:34
void IgnoreUnusedValue(const T &value)
[宣言] 参照しない値宣言.
Definition: TnbDef.h:434
TNB Library
Definition: TnbDoxyTitle.txt:2
TinyMacroLang 検索結果管理
LPCSTR lpszFuncAdds
関数のあるアドレス(関数の頭の { の直後)
INT_PTR iFuncLine
関数のあるファイ行
CAscii strFileName
ファイル名
const CAsciiVector * pastrParamNames
関数の引数名(Arrayの参照)
bool HasData(void) const
[確認] データを持っているか?
TinyMacroLang リスナー
Definition: TnbTmlParser.h:64
virtual bool IsExecutionContinued(void)=0
[通知] 継続確認通知.
virtual void OutputLog(LPCTSTR lpszLog, bool boHasErrMsg)=0
[通知] ログ出力通知.
virtual ~IListener(void)
デストラクタ
Definition: TnbTmlParser.h:66
TinyMacroLang 配列名と内容型
TinyMacroLang 変数名と内容の型
void ReadExactly(size_t size, LPVOID _P) const
[取得] 読み込み.
Definition: TnbReader.h:114
TinyMacroLang 関数拡張インターフェース
virtual CTmlResult OnChangeValue(LPCSTR lpszName, const CTmlValue &val)=0
[処理] 変更(代入)コールバック
virtual CTmlResult ExpandVariable(CTmlValueCarrier &_val, LPCSTR lpszToken, const CTmlValuesVector &aValues, bool boIsTestMode)=0
[処理] 拡張変数、関数の処理