MythTV  master
ParseText.cpp
Go to the documentation of this file.
1 /* ParseText.cpp
2 
3  Copyright (C) David C. J. Matthews 2004, 2008 dm at prolingua.co.uk
4 
5  This program is free software; you can redistribute it and/or
6  modify it under the terms of the GNU General Public License
7  as published by the Free Software Foundation; either version 2
8  of the License, or (at your option) any later version.
9 
10  This program is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  GNU General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with this program; if not, write to the Free Software
17  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18  Or, point your browser to http://www.gnu.org/copyleft/gpl.html
19 
20 */
21 
22 /*
23 Parser for the textual form of MHEG5.
24 This is very basic and is only there to enable some test programs to be run.
25 */
26 
27 #include "ParseText.h"
28 #include "ParseNode.h"
29 #include "BaseClasses.h"
30 #include "ASN1Codes.h"
31 #include "Root.h"
32 #include "Groups.h"
33 #include <cctype>
34 #include "Ingredients.h" // For GetEventType
35 #include "Text.h" // For GetJustification etc
36 #include "Engine.h"
37 #include "Logging.h"
38 
39 
40 #ifndef WIN32
41 #define stricmp strcasecmp
42 #endif
43 
44 
46 {
47  free(m_string);
48 }
49 
50 // Get the next character.
52 {
53  if ((int)m_p >= m_data.size())
54  {
55  m_ch = EOF;
56  }
57  else
58  {
59  // NOLINTNEXTLINE(bugprone-signed-char-misuse)
60  m_ch = m_data[m_p++];
61  }
62 }
63 
64 // Maximum length of a tag (i.e. a symbol beginning with a colon). Actually the longest is around 22 chars.
65 #define MAX_TAG_LENGTH 30
66 
67 const char *rchTagNames[] =
68 {
69  ":Application",
70  ":Scene",
71  ":StdID",
72  ":StdVersion",
73  ":ObjectInfo",
74  ":OnStartUp",
75  ":OnCloseDown",
76  ":OrigGCPriority",
77  ":Items",
78  ":ResidentPrg",
79  ":RemotePrg",
80  ":InterchgPrg",
81  ":Palette",
82  ":Font", // Occurs twice.
83  ":CursorShape",
84  ":BooleanVar",
85  ":IntegerVar",
86  ":OStringVar",
87  ":ObjectRefVar",
88  ":ContentRefVar",
89  ":Link",
90  ":Stream",
91  ":Bitmap",
92  ":LineArt",
93  ":DynamicLineArt",
94  ":Rectangle",
95  ":Hotspot",
96  ":SwitchButton",
97  ":PushButton",
98  ":Text",
99  ":EntryField",
100  ":HyperText",
101  ":Slider",
102  ":TokenGroup",
103  ":ListGroup",
104  ":OnSpawnCloseDown",
105  ":OnRestart",
106  "", // Default attributes - encoded as a group in binary
107  ":CharacterSet",
108  ":BackgroundColour",
109  ":TextCHook",
110  ":TextColour",
111  ":Font",
112  ":FontAttributes",
113  ":InterchgPrgCHook",
114  ":StreamCHook",
115  ":BitmapCHook",
116  ":LineArtCHook",
117  ":ButtonRefColour",
118  ":HighlightRefColour",
119  ":SliderRefColour",
120  ":InputEventReg",
121  ":SceneCS",
122  ":AspectRatio",
123  ":MovingCursor",
124  ":NextScenes",
125  ":InitiallyActive",
126  ":CHook",
127  ":OrigContent",
128  ":Shared",
129  ":ContentSize",
130  ":CCPriority",
131  "" , // Link condition - always replaced by EventSource, EventType and EventData
132  ":LinkEffect",
133  ":Name",
134  ":InitiallyAvailable",
135  ":ProgramConnectionTag",
136  ":OrigValue",
137  ":ObjectRef",
138  ":ContentRef",
139  ":MovementTable",
140  ":TokenGroupItems",
141  ":NoTokenActionSlots",
142  ":Positions",
143  ":WrapAround",
144  ":MultipleSelection",
145  ":OrigBoxSize",
146  ":OrigPosition",
147  ":OrigPaletteRef",
148  ":Tiling",
149  ":OrigTransparency",
150  ":BBBox",
151  ":OrigLineWidth",
152  ":OrigLineStyle",
153  ":OrigRefLineColour",
154  ":OrigRefFillColour",
155  ":OrigFont",
156  ":HJustification",
157  ":VJustification",
158  ":LineOrientation",
159  ":StartCorner",
160  ":TextWrapping",
161  ":Multiplex",
162  ":Storage",
163  ":Looping",
164  ":Audio",
165  ":Video",
166  ":RTGraphics",
167  ":ComponentTag",
168  ":OrigVolume",
169  ":Termination",
170  ":EngineResp",
171  ":Orientation",
172  ":MaxValue",
173  ":MinValue",
174  ":InitialValue",
175  ":InitialPortion",
176  ":StepSize",
177  ":SliderStyle",
178  ":InputType",
179  ":CharList",
180  ":ObscuredInput",
181  ":MaxLength",
182  ":OrigLabel",
183  ":ButtonStyle",
184  ":Activate",
185  ":Add",
186  ":AddItem",
187  ":Append",
188  ":BringToFront",
189  ":Call",
190  ":CallActionSlot",
191  ":Clear",
192  ":Clone",
193  ":CloseConnection",
194  ":Deactivate",
195  ":DelItem",
196  ":Deselect",
197  ":DeselectItem",
198  ":Divide",
199  ":DrawArc",
200  ":DrawLine",
201  ":DrawOval",
202  ":DrawPolygon",
203  ":DrawPolyline",
204  ":DrawRectangle",
205  ":DrawSector",
206  ":Fork",
207  ":GetAvailabilityStatus",
208  ":GetBoxSize",
209  ":GetCellItem",
210  ":GetCursorPosition",
211  ":GetEngineSupport",
212  ":GetEntryPoint",
213  ":GetFillColour",
214  ":GetFirstItem",
215  ":GetHighlightStatus",
216  ":GetInteractionStatus",
217  ":GetItemStatus",
218  ":GetLabel",
219  ":GetLastAnchorFired",
220  ":GetLineColour",
221  ":GetLineStyle",
222  ":GetLineWidth",
223  ":GetListItem",
224  ":GetListSize",
225  ":GetOverwriteMode",
226  ":GetPortion",
227  ":GetPosition",
228  ":GetRunningStatus",
229  ":GetSelectionStatus",
230  ":GetSliderValue",
231  ":GetTextContent",
232  ":GetTextData",
233  ":GetTokenPosition",
234  ":GetVolume",
235  ":Launch",
236  ":LockScreen",
237  ":Modulo",
238  ":Move",
239  ":MoveTo",
240  ":Multiply",
241  ":OpenConnection",
242  ":Preload",
243  ":PutBefore",
244  ":PutBehind",
245  ":Quit",
246  ":ReadPersistent",
247  ":Run",
248  ":ScaleBitmap",
249  ":ScaleVideo",
250  ":ScrollItems",
251  ":Select",
252  ":SelectItem",
253  ":SendEvent",
254  ":SendToBack",
255  ":SetBoxSize",
256  ":SetCachePriority",
257  ":SetCounterEndPosition",
258  ":SetCounterPosition",
259  ":SetCounterTrigger",
260  ":SetCursorPosition",
261  ":SetCursorShape",
262  ":SetData",
263  ":SetEntryPoint",
264  ":SetFillColour",
265  ":SetFirstItem",
266  ":SetFontRef",
267  ":SetHighlightStatus",
268  ":SetInteractionStatus",
269  ":SetLabel",
270  ":SetLineColour",
271  ":SetLineStyle",
272  ":SetLineWidth",
273  ":SetOverwriteMode",
274  ":SetPaletteRef",
275  ":SetPortion",
276  ":SetPosition",
277  ":SetSliderValue",
278  ":SetSpeed",
279  ":SetTimer",
280  ":SetTransparency",
281  ":SetVariable",
282  ":SetVolume",
283  ":Spawn",
284  ":Step",
285  ":Stop",
286  ":StorePersistent",
287  ":Subtract",
288  ":TestVariable",
289  ":Toggle",
290  ":ToggleItem",
291  ":TransitionTo",
292  ":Unload",
293  ":UnlockScreen",
294  ":GBoolean",
295  ":GInteger",
296  ":GOctetString",
297  ":GObjectRef",
298  ":GContentRef",
299  ":NewColourIndex",
300  ":NewAbsoluteColour",
301  ":NewFontName",
302  ":NewFontRef",
303  ":NewContentSize",
304  ":NewCCPriority",
305  ":IndirectRef",
306  /* UK MHEG */
307  ":SetBackgroundColour",
308  ":SetCellPosition",
309  ":SetInputRegister",
310  ":SetTextColour",
311  ":SetFontAttributes",
312  ":SetVideoDecodeOffset",
313  ":GetVideoDecodeOffset",
314  ":GetFocusPosition",
315  ":SetFocusPosition",
316  ":SetBitmapDecodeOffset",
317  ":GetBitmapDecodeOffset",
318  ":SetSliderParameters",
319  /* Pseudo-operations. These are encoded as LinkCondition in binary. */
320  ":EventSource",
321  ":EventType",
322  ":EventData",
323  ":ActionSlots"
324 };
325 
326 // Some example programs use these colour names
327 static struct
328 {
329  const char *m_name;
330  unsigned char m_r, m_g, m_b, m_t;
331 } colourTable[] =
332 {
333  { "black", 0, 0, 0, 0 },
334  { "transparent", 0, 0, 0, 255 },
335  { "gray"/*sic*/, 128, 128, 128, 0 },
336  { "darkgray"/*sic*/, 192, 192, 192, 0 },
337  { "red", 255, 0, 0, 0 },
338  { "darkred", 128, 0, 0, 0 },
339  { "blue", 0, 0, 255, 0 },
340  { "darkblue", 0, 0, 128, 0 },
341  { "green", 0, 255, 0, 0 },
342  { "darkgreen", 0, 128, 0, 0 },
343  { "yellow", 255, 255, 0, 0 },
344  { "cyan", 0, 255, 255, 0 },
345  { "magenta", 255, 0, 255, 0 }
346 };
347 
348 
349 // Search for a tag and return it if it exists. Returns -1 if it isn't found.
350 static int FindTag(const char *p)
351 {
352  for (int i = 0; i < (int)(sizeof(rchTagNames) / sizeof(rchTagNames[0])); i++)
353  {
354  if (stricmp(p, rchTagNames[i]) == 0)
355  {
356  return i;
357  }
358  }
359 
360  return -1;
361 }
362 
363 
364 // Ditto for the enumerated types
365 #define MAX_ENUM 30
366 
367 void MHParseText::Error(const char *str) const
368 {
369  MHERROR(QString("%1- at line %2\n").arg(str).arg(m_lineCount));
370 }
371 
372 // Lexical analysis. Get the next symbol.
374 {
375  while (true)
376  {
377 
378  switch (m_ch)
379  {
380  case '\n':
381  m_lineCount++;
382  [[clang::fallthrough]];
383  case ' ':
384  case '\r':
385  case '\t':
386  case '\f':
387  // Skip white space.
388  GetNextChar();
389  continue;
390 
391  case '/':
392  {
393  // Comment.
394  GetNextChar();
395 
396  if (m_ch != '/')
397  {
398  Error("Malformed comment");
399  }
400 
401  do
402  {
403  GetNextChar();
404  }
405  while (m_ch != '\n' && m_ch != '\f' && m_ch != '\r');
406 
407  continue; // Next symbol
408  }
409 
410  case ':': // Start of a tag
411  {
412  m_nType = PTTag;
413  char buff[MAX_TAG_LENGTH+1];
414  char *p = buff;
415 
416  do
417  {
418  *p++ = m_ch;
419  GetNextChar();
420 
421  if (p == buff + MAX_TAG_LENGTH)
422  {
423  break;
424  }
425  }
426  while ((m_ch >= 'a' && m_ch <= 'z') || (m_ch >= 'A' && m_ch <= 'Z'));
427 
428  *p = 0;
429 
430  // Look it up and return it if it's found.
431  m_nTag = FindTag(buff);
432 
433  if (m_nTag >= 0)
434  {
435  return;
436  }
437 
438  // Unrecognised tag.
439  Error("Unrecognised tag");
440  break;
441  }
442 
443  case '"': // Start of a string
444  {
445  m_nType = PTString;
446  // MHEG strings can include NULs. For the moment we pass back the length and also
447  // null-terminate the strings.
448  m_nStringLength = 0;
449 
450  while (true)
451  {
452  GetNextChar();
453 
454  if (m_ch == '"')
455  {
456  break; // Finished the string.
457  }
458 
459  if (m_ch == '\\')
460  {
461  GetNextChar(); // Escape character. Include the next char in the string.
462  }
463 
464  if (m_ch == '\n' || m_ch == '\r')
465  {
466  Error("Unterminated string");
467  }
468 
469  // We grow the buffer to the largest string in the input.
470  auto *str = (unsigned char *)realloc(m_string, m_nStringLength + 2);
471 
472  if (str == nullptr)
473  {
474  Error("Insufficient memory");
475  }
476 
477  m_string = str;
479  }
480 
481  GetNextChar(); // Skip the closing quote
483  return;
484  }
485 
486  case '\'': // Start of a string using quoted printable
487  {
488  m_nType = PTString;
489  m_nStringLength = 0;
490 
491  // Quotable printable strings contain escape sequences beginning with the
492  // escape character '='. The strings can span lines but each line must
493  // end with an equal sign.
494  while (true)
495  {
496  GetNextChar();
497 
498  if (m_ch == '\'')
499  {
500  break;
501  }
502 
503  if (m_ch == '\n')
504  {
505  Error("Unterminated string");
506  }
507 
508  if (m_ch == '=') // Special code in quoted-printable.
509  {
510  // Should be followed by two hex digits or by white space and a newline.
511  GetNextChar();
512 
513  if (m_ch == ' ' || m_ch == '\t' || m_ch == '\r' || m_ch == '\n')
514  {
515  // White space. Remove everything up to the newline.
516  while (m_ch != '\n')
517  {
518  if (!(m_ch == ' ' || m_ch == '\t' || m_ch == '\r'))
519  {
520  Error("Malformed quoted printable string");
521  }
522 
523  GetNextChar();
524  }
525 
526  continue; // continue with the first character on the next line
527  }
528 
529  int byte = 0;
530 
531  if (m_ch >= '0' && m_ch <= '9')
532  {
533  byte = m_ch - '0';
534  }
535  else if (m_ch >= 'A' && m_ch <= 'F')
536  {
537  byte = m_ch - 'A' + 10;
538  }
539  else if (m_ch >= 'a' && m_ch <= 'f')
540  {
541  byte = m_ch - 'a' + 10;
542  }
543  else
544  {
545  Error("Malformed quoted printable string");
546  }
547 
548  byte *= 16;
549  GetNextChar();
550 
551  if (m_ch >= '0' && m_ch <= '9')
552  {
553  byte += m_ch - '0';
554  }
555  else if (m_ch >= 'A' && m_ch <= 'F')
556  {
557  byte += m_ch - 'A' + 10;
558  }
559  else if (m_ch >= 'a' && m_ch <= 'f')
560  {
561  byte += m_ch - 'a' + 10;
562  }
563  else
564  {
565  Error("Malformed quoted printable string");
566  }
567 
568  m_ch = byte; // Put this into the string.
569  }
570 
571  // We grow the buffer to the largest string in the input.
572  auto *str = (unsigned char *)realloc(m_string, m_nStringLength + 2);
573 
574  if (str == nullptr)
575  {
576  Error("Insufficient memory");
577  }
578 
579  m_string = str;
581  }
582 
583  GetNextChar(); // Skip the closing quote
585  return;
586  }
587 
588  case '`': // Start of a string using base 64
589  // These can, presumably span lines.
590  MHERROR("Base 64 string is not implemented");
591  break;
592 
593  case '#': // Start of 3-byte hex constant.
594  MHERROR("3-byte hex constant is not implemented");
595  break;
596 
597  case '-':
598  case '0':
599  case '1':
600  case '2':
601  case '3':
602  case '4':
603  case '5':
604  case '6':
605  case '7':
606  case '8':
607  case '9':
608  {
609  m_nType = PTInt;
610  bool negative = m_ch == '-';
611 
612  if (negative)
613  {
614  GetNextChar();
615 
616  if (m_ch < '0' || m_ch > '9')
617  {
618  Error("Expected digit after '-'");
619  }
620  }
621 
622  // Start of a number. Hex can be represented as 0xn.
623  // Strictly speaking hex values cannot be preceded by a minus sign.
624  m_nInt = m_ch - '0';
625  GetNextChar();
626 
627  if (m_nInt == 0 && (m_ch == 'x' || m_ch == 'X'))
628  {
629  MHERROR("Hex constant is not implemented");
630  }
631 
632  while (m_ch >= '0' && m_ch <= '9')
633  {
634  m_nInt = m_nInt * 10 + m_ch - '0';
635  // TODO: What about overflow?
636  GetNextChar();
637  }
638 
639  if (negative)
640  {
641  m_nInt = -m_nInt;
642  }
643 
644  return;
645  }
646 
647  case 'a':
648  case 'b':
649  case 'c':
650  case 'd':
651  case 'e':
652  case 'f':
653  case 'g':
654  case 'h':
655  case 'i':
656  case 'j':
657  case 'k':
658  case 'l':
659  case 'm':
660  case 'n':
661  case 'o':
662  case 'p':
663  case 'q':
664  case 'r':
665  case 's':
666  case 't':
667  case 'u':
668  case 'v':
669  case 'w':
670  case 'x':
671  case 'y':
672  case 'z':
673  case 'A':
674  case 'B':
675  case 'C':
676  case 'D':
677  case 'E':
678  case 'F':
679  case 'G':
680  case 'H':
681  case 'I':
682  case 'J':
683  case 'K':
684  case 'L':
685  case 'M':
686  case 'N':
687  case 'O':
688  case 'P':
689  case 'Q':
690  case 'R':
691  case 'S':
692  case 'T':
693  case 'U':
694  case 'V':
695  case 'W':
696  case 'X':
697  case 'Y':
698  case 'Z':
699  {
700  // Start of an enumerated type.
701  m_nType = PTEnum;
702  char buff[MAX_ENUM+1];
703  char *p = buff;
704 
705  do
706  {
707  *p++ = m_ch;
708  GetNextChar();
709 
710  if (p == buff + MAX_ENUM)
711  {
712  break;
713  }
714  }
715  while ((m_ch >= 'a' && m_ch <= 'z') || (m_ch >= 'A' && m_ch <= 'Z') || m_ch == '-');
716 
717  *p = '\0';
718 
719  if (stricmp(buff, "NULL") == 0)
720  {
721  m_nType = PTNull;
722  return;
723  }
724 
725  if (stricmp(buff, "true") == 0)
726  {
727  m_nType = PTBool;
728  m_fBool = true;
729  return;
730  }
731 
732  if (stricmp(buff, "false") == 0)
733  {
734  m_nType = PTBool;
735  m_fBool = false;
736  return;
737  }
738 
739  // Look up the tag in all the tables. Fortunately all the enumerations
740  // are distinct so we don't need to know the context.
742 
743  if (m_nInt > 0)
744  {
745  return;
746  }
747 
749 
750  if (m_nInt > 0)
751  {
752  return;
753  }
754 
756 
757  if (m_nInt > 0)
758  {
759  return;
760  }
761 
763 
764  if (m_nInt > 0)
765  {
766  return;
767  }
768 
770 
771  if (m_nInt > 0)
772  {
773  return;
774  }
775 
776  m_nInt = MHSlider::GetStyle(buff);
777 
778  if (m_nInt > 0)
779  {
780  return;
781  }
782 
783  // Check the colour table. If it's there generate a string containing the colour info.
784  for (auto & colour : colourTable)
785  {
786  if (stricmp(buff, colour.m_name) == 0)
787  {
788  m_nType = PTString;
789  auto *str = (unsigned char *)realloc(m_string, 4 + 1);
790 
791  if (str == nullptr)
792  {
793  Error("Insufficient memory");
794  }
795 
796  m_string = str;
797  m_string[0] = colour.m_r;
798  m_string[1] = colour.m_g;
799  m_string[2] = colour.m_b;
800  m_string[3] = colour.m_t;
801  m_nStringLength = 4;
803  return;
804  }
805  }
806 
807  Error("Unrecognised enumeration");
808  break;
809  }
810 
811  case '{': // Start of a "section".
812  // The standard indicates that open brace followed by a tag should be written
813  // as a single word. We'll be more lenient and allow spaces or comments between them.
815  GetNextChar();
816  return;
817 
818  case '}': // End of a "section".
820  GetNextChar();
821  return;
822 
823  case '(': // Start of a sequence.
825  GetNextChar();
826  return;
827 
828  case ')': // End of a sequence.
829  m_nType = PTEndSeq;
830  GetNextChar();
831  return;
832 
833  case EOF:
834  m_nType = PTEOF;
835  return;
836 
837  default:
838  Error("Unknown character");
839  GetNextChar();
840  }
841  }
842 }
843 
845 {
846  MHParseNode *pRes = nullptr;
847 
848  try
849  {
850  switch (m_nType)
851  {
852  case PTStartSection: // Open curly bracket
853  {
854  NextSym();
855 
856  // Should be followed by a tag.
857  if (m_nType != PTTag)
858  {
859  Error("Expected ':' after '{'");
860  }
861 
862  auto *pTag = new MHPTagged(m_nTag);
863  pRes = pTag;
864  NextSym();
865 
866  while (m_nType != PTEndSection)
867  {
868  pTag->AddArg(DoParse());
869  }
870 
871  NextSym(); // Remove the close curly bracket.
872  break;
873  }
874 
875  case PTTag: // Tag on its own.
876  {
877  int nTag = m_nTag;
878  auto *pTag = new MHPTagged(nTag);
879  pRes = pTag;
880  NextSym();
881 
882  switch (nTag)
883  {
884  case C_ITEMS:
885  case C_LINK_EFFECT:
886  case C_ACTIVATE:
887  case C_ADD:
888  case C_ADD_ITEM:
889  case C_APPEND:
890  case C_BRING_TO_FRONT:
891  case C_CALL:
892  case C_CALL_ACTION_SLOT:
893  case C_CLEAR:
894  case C_CLONE:
895  case C_CLOSE_CONNECTION:
896  case C_DEACTIVATE:
897  case C_DEL_ITEM:
898  case C_DESELECT:
899  case C_DESELECT_ITEM:
900  case C_DIVIDE:
901  case C_DRAW_ARC:
902  case C_DRAW_LINE:
903  case C_DRAW_OVAL:
904  case C_DRAW_POLYGON:
905  case C_DRAW_POLYLINE:
906  case C_DRAW_RECTANGLE:
907  case C_DRAW_SECTOR:
908  case C_FORK:
910  case C_GET_BOX_SIZE:
911  case C_GET_CELL_ITEM:
914  case C_GET_ENTRY_POINT:
915  case C_GET_FILL_COLOUR:
916  case C_GET_FIRST_ITEM:
919  case C_GET_ITEM_STATUS:
920  case C_GET_LABEL:
922  case C_GET_LINE_COLOUR:
923  case C_GET_LINE_STYLE:
924  case C_GET_LINE_WIDTH:
925  case C_GET_LIST_ITEM:
926  case C_GET_LIST_SIZE:
928  case C_GET_PORTION:
929  case C_GET_POSITION:
932  case C_GET_SLIDER_VALUE:
933  case C_GET_TEXT_CONTENT:
934  case C_GET_TEXT_DATA:
936  case C_GET_VOLUME:
937  case C_LAUNCH:
938  case C_LOCK_SCREEN:
939  case C_MODULO:
940  case C_MOVE:
941  case C_MOVE_TO:
942  case C_MULTIPLY:
943  case C_OPEN_CONNECTION:
944  case C_PRELOAD:
945  case C_PUT_BEFORE:
946  case C_PUT_BEHIND:
947  case C_QUIT:
948  case C_READ_PERSISTENT:
949  case C_RUN:
950  case C_SCALE_BITMAP:
951  case C_SCALE_VIDEO:
952  case C_SCROLL_ITEMS:
953  case C_SELECT:
954  case C_SELECT_ITEM:
955  case C_SEND_EVENT:
956  case C_SEND_TO_BACK:
957  case C_SET_BOX_SIZE:
963  case C_SET_CURSOR_SHAPE:
964  case C_SET_DATA:
965  case C_SET_ENTRY_POINT:
966  case C_SET_FILL_COLOUR:
967  case C_SET_FIRST_ITEM:
968  case C_SET_FONT_REF:
971  case C_SET_LABEL:
972  case C_SET_LINE_COLOUR:
973  case C_SET_LINE_STYLE:
974  case C_SET_LINE_WIDTH:
976  case C_SET_PALETTE_REF:
977  case C_SET_PORTION:
978  case C_SET_POSITION:
979  case C_SET_SLIDER_VALUE:
980  case C_SET_SPEED:
981  case C_SET_TIMER:
982  case C_SET_TRANSPARENCY:
983  case C_SET_VARIABLE:
984  case C_SET_VOLUME:
985  case C_SPAWN:
986  case C_STEP:
987  case C_STOP:
988  case C_STORE_PERSISTENT:
989  case C_SUBTRACT:
990  case C_TEST_VARIABLE:
991  case C_TOGGLE:
992  case C_TOGGLE_ITEM:
993  case C_TRANSITION_TO:
994  case C_UNLOAD:
995  case C_UNLOCK_SCREEN:
996  case C_CONTENT_REFERENCE:
997  case C_TOKEN_GROUP_ITEMS:
998  case C_POSITIONS:
999  case C_MULTIPLEX:
1000  {
1001  // These are parenthesised in the text form. We have to remove the
1002  // parentheses otherwise we will return a sequence which will not be
1003  // be compatible with the binary form.
1004  if (m_nType != PTStartSeq)
1005  {
1006  Error("Expected '('");
1007  }
1008 
1009  NextSym();
1010 
1011  while (m_nType != PTEndSeq)
1012  {
1013  pTag->AddArg(DoParse());
1014  }
1015 
1016  NextSym(); // Remove the close parenthesis.
1017  break;
1018  }
1019  case C_ORIGINAL_CONTENT:
1020  case C_NEW_GENERIC_BOOLEAN:
1021  case C_NEW_GENERIC_INTEGER:
1025  case C_ORIGINAL_VALUE:
1026  // These always have an argument which may be a tagged item.
1027  {
1028  // Is it always the case that there is at least one argument so if we haven't
1029  // had any arguments yet we should always process a tag as an argument?
1030  pTag->AddArg(DoParse());
1031  break;
1032  }
1033  default:
1034 
1035  // This can be followed by an int, etc but a new tag is dealt with by the caller.
1036  while (m_nType == PTBool || m_nType == PTInt || m_nType == PTString || m_nType == PTEnum || m_nType == PTStartSeq)
1037  {
1038  pTag->AddArg(DoParse());
1039  }
1040 
1041  }
1042 
1043  break;
1044  }
1045 
1046  case PTInt:
1047  {
1048  pRes = new MHPInt(m_nInt);
1049  NextSym();
1050  break;
1051  }
1052 
1053  case PTBool:
1054  {
1055  pRes = new MHPBool(m_fBool);
1056  NextSym();
1057  break;
1058  }
1059 
1060  case PTString:
1061  {
1062  MHOctetString str;
1063  str.Copy(MHOctetString((const char *)m_string, m_nStringLength));
1064  pRes = new MHPString(str);
1065  NextSym();
1066  break;
1067  }
1068 
1069  case PTEnum:
1070  {
1071  pRes = new MHPEnum(m_nInt);
1072  NextSym();
1073  break;
1074  }
1075 
1076  case PTNull:
1077  {
1078  pRes = new MHPNull;
1079  NextSym();
1080  break;
1081  }
1082 
1083  case PTStartSeq: // Open parenthesis.
1084  {
1085  auto *pSeq = new MHParseSequence;
1086  pRes = pSeq;
1087  NextSym();
1088 
1089  while (m_nType != PTEndSeq)
1090  {
1091  pSeq->Append(DoParse());
1092  }
1093 
1094  NextSym(); // Remove the close parenthesis.
1095  break;
1096  }
1097 
1098  default:
1099  Error("Unexpected symbol");
1100  }
1101 
1102  return pRes;
1103  }
1104  catch (...)
1105  {
1106  delete(pRes);
1107  throw;
1108  }
1109 }
1110 
1111 
1112 // Run the parser
1114 {
1115  GetNextChar(); // Initialise m_ch
1116  NextSym(); // Initialise the symbol values.
1117  return DoParse();
1118 }
1119 
C_LAUNCH
#define C_LAUNCH
Definition: ASN1Codes.h:199
C_SET_COUNTER_POSITION
#define C_SET_COUNTER_POSITION
Definition: ASN1Codes.h:222
C_GET_OVERWRITE_MODE
#define C_GET_OVERWRITE_MODE
Definition: ASN1Codes.h:189
MHParseText::GetNextChar
void GetNextChar()
Definition: ParseText.cpp:51
C_FORK
#define C_FORK
Definition: ASN1Codes.h:170
MHParseText::m_string
unsigned char * m_string
Definition: ParseText.h:58
C_GET_CELL_ITEM
#define C_GET_CELL_ITEM
Definition: ASN1Codes.h:173
C_PUT_BEHIND
#define C_PUT_BEHIND
Definition: ASN1Codes.h:208
C_GET_ITEM_STATUS
#define C_GET_ITEM_STATUS
Definition: ASN1Codes.h:181
C_DRAW_RECTANGLE
#define C_DRAW_RECTANGLE
Definition: ASN1Codes.h:168
MHParseText::m_fBool
bool m_fBool
Definition: ParseText.h:57
C_SET_FILL_COLOUR
#define C_SET_FILL_COLOUR
Definition: ASN1Codes.h:228
Groups.h
C_SCROLL_ITEMS
#define C_SCROLL_ITEMS
Definition: ASN1Codes.h:214
C_DEL_ITEM
#define C_DEL_ITEM
Definition: ASN1Codes.h:159
C_SEND_TO_BACK
#define C_SEND_TO_BACK
Definition: ASN1Codes.h:218
C_SET_BOX_SIZE
#define C_SET_BOX_SIZE
Definition: ASN1Codes.h:219
C_GET_ENTRY_POINT
#define C_GET_ENTRY_POINT
Definition: ASN1Codes.h:176
C_GET_FIRST_ITEM
#define C_GET_FIRST_ITEM
Definition: ASN1Codes.h:178
MHParseText::m_nStringLength
int m_nStringLength
Definition: ParseText.h:59
MHParseText::m_lineCount
int m_lineCount
Definition: ParseText.h:47
C_MODULO
#define C_MODULO
Definition: ASN1Codes.h:201
C_TOKEN_GROUP_ITEMS
#define C_TOKEN_GROUP_ITEMS
Definition: ASN1Codes.h:104
MHParseText::DoParse
MHParseNode * DoParse()
Definition: ParseText.cpp:844
ASN1Codes.h
C_SET_PORTION
#define C_SET_PORTION
Definition: ASN1Codes.h:239
MHParseText::m_nTag
int m_nTag
Definition: ParseText.h:55
MHText::GetJustification
static int GetJustification(const char *str)
Definition: Text.cpp:150
C_DRAW_POLYLINE
#define C_DRAW_POLYLINE
Definition: ASN1Codes.h:167
C_TOGGLE
#define C_TOGGLE
Definition: ASN1Codes.h:253
C_DRAW_LINE
#define C_DRAW_LINE
Definition: ASN1Codes.h:164
MAX_TAG_LENGTH
#define MAX_TAG_LENGTH
Definition: ParseText.cpp:65
MHPTagged
Definition: ParseNode.h:84
arg
arg(title).arg(filename).arg(doDelete))
MHParseText::m_ch
int m_ch
Definition: ParseText.h:54
C_DRAW_SECTOR
#define C_DRAW_SECTOR
Definition: ASN1Codes.h:169
C_SET_CACHE_PRIORITY
#define C_SET_CACHE_PRIORITY
Definition: ASN1Codes.h:220
C_GET_AVAILABILITY_STATUS
#define C_GET_AVAILABILITY_STATUS
Definition: ASN1Codes.h:171
C_TOGGLE_ITEM
#define C_TOGGLE_ITEM
Definition: ASN1Codes.h:254
C_SET_ENTRY_POINT
#define C_SET_ENTRY_POINT
Definition: ASN1Codes.h:227
C_GET_SLIDER_VALUE
#define C_GET_SLIDER_VALUE
Definition: ASN1Codes.h:194
C_GET_LINE_STYLE
#define C_GET_LINE_STYLE
Definition: ASN1Codes.h:185
C_OPEN_CONNECTION
#define C_OPEN_CONNECTION
Definition: ASN1Codes.h:205
C_GET_RUNNING_STATUS
#define C_GET_RUNNING_STATUS
Definition: ASN1Codes.h:192
C_SPAWN
#define C_SPAWN
Definition: ASN1Codes.h:247
MHParseText::PTInt
@ PTInt
Definition: ParseText.h:49
C_POSITIONS
#define C_POSITIONS
Definition: ASN1Codes.h:106
MHSlider::GetStyle
static int GetStyle(const char *str)
Definition: Visible.cpp:712
MHOctetString
Definition: BaseClasses.h:106
C_SET_LINE_STYLE
#define C_SET_LINE_STYLE
Definition: ASN1Codes.h:235
MAX_ENUM
#define MAX_ENUM
Definition: ParseText.cpp:365
MHParseText::Error
void Error(const char *str) const
Definition: ParseText.cpp:367
colourTable
static struct @11 colourTable[]
C_SET_OVERWRITE_MODE
#define C_SET_OVERWRITE_MODE
Definition: ASN1Codes.h:237
C_RUN
#define C_RUN
Definition: ASN1Codes.h:211
C_SUBTRACT
#define C_SUBTRACT
Definition: ASN1Codes.h:251
C_DESELECT
#define C_DESELECT
Definition: ASN1Codes.h:160
C_GET_LINE_COLOUR
#define C_GET_LINE_COLOUR
Definition: ASN1Codes.h:184
MHParseText::m_data
QByteArray m_data
Definition: ParseText.h:62
C_SET_COUNTER_END_POSITION
#define C_SET_COUNTER_END_POSITION
Definition: ASN1Codes.h:221
C_STEP
#define C_STEP
Definition: ASN1Codes.h:248
C_GET_LIST_SIZE
#define C_GET_LIST_SIZE
Definition: ASN1Codes.h:188
C_READ_PERSISTENT
#define C_READ_PERSISTENT
Definition: ASN1Codes.h:210
C_GET_INTERACTION_STATUS
#define C_GET_INTERACTION_STATUS
Definition: ASN1Codes.h:180
C_SET_SPEED
#define C_SET_SPEED
Definition: ASN1Codes.h:242
C_SEND_EVENT
#define C_SEND_EVENT
Definition: ASN1Codes.h:217
C_ADD
#define C_ADD
Definition: ASN1Codes.h:149
C_QUIT
#define C_QUIT
Definition: ASN1Codes.h:209
C_ADD_ITEM
#define C_ADD_ITEM
Definition: ASN1Codes.h:150
C_SET_POSITION
#define C_SET_POSITION
Definition: ASN1Codes.h:240
C_GET_TEXT_CONTENT
#define C_GET_TEXT_CONTENT
Definition: ASN1Codes.h:195
C_TRANSITION_TO
#define C_TRANSITION_TO
Definition: ASN1Codes.h:255
MHPNull
Definition: ParseNode.h:135
FindTag
static int FindTag(const char *p)
Definition: ParseText.cpp:350
MHParseText::PTNull
@ PTNull
Definition: ParseText.h:50
C_SET_VARIABLE
#define C_SET_VARIABLE
Definition: ASN1Codes.h:245
C_GET_HIGHLIGHT_STATUS
#define C_GET_HIGHLIGHT_STATUS
Definition: ASN1Codes.h:179
hardwareprofile.config.p
p
Definition: config.py:33
C_SET_SLIDER_VALUE
#define C_SET_SLIDER_VALUE
Definition: ASN1Codes.h:241
ParseNode.h
C_GET_BOX_SIZE
#define C_GET_BOX_SIZE
Definition: ASN1Codes.h:172
C_MOVE_TO
#define C_MOVE_TO
Definition: ASN1Codes.h:203
C_UNLOCK_SCREEN
#define C_UNLOCK_SCREEN
Definition: ASN1Codes.h:257
C_SET_TIMER
#define C_SET_TIMER
Definition: ASN1Codes.h:243
MHParseText::~MHParseText
~MHParseText() override
Definition: ParseText.cpp:45
C_STOP
#define C_STOP
Definition: ASN1Codes.h:249
C_CALL
#define C_CALL
Definition: ASN1Codes.h:153
C_GET_ENGINE_SUPPORT
#define C_GET_ENGINE_SUPPORT
Definition: ASN1Codes.h:175
C_DRAW_ARC
#define C_DRAW_ARC
Definition: ASN1Codes.h:163
C_ACTIVATE
#define C_ACTIVATE
Definition: ASN1Codes.h:148
ParseText.h
m_t
unsigned char m_t
Definition: ParseText.cpp:330
C_UNLOAD
#define C_UNLOAD
Definition: ASN1Codes.h:256
MHParseText::PTEndSeq
@ PTEndSeq
Definition: ParseText.h:50
MHParseSequence
Definition: ParseNode.h:75
C_SET_INTERACTION_STATUS
#define C_SET_INTERACTION_STATUS
Definition: ASN1Codes.h:232
C_ITEMS
#define C_ITEMS
Definition: ASN1Codes.h:41
C_GET_CURSOR_POSITION
#define C_GET_CURSOR_POSITION
Definition: ASN1Codes.h:174
rchTagNames
const char * rchTagNames[]
Definition: ParseText.cpp:67
MHParseText::PTTag
@ PTTag
Definition: ParseText.h:49
C_GET_LIST_ITEM
#define C_GET_LIST_ITEM
Definition: ASN1Codes.h:187
C_DRAW_OVAL
#define C_DRAW_OVAL
Definition: ASN1Codes.h:165
C_SCALE_BITMAP
#define C_SCALE_BITMAP
Definition: ASN1Codes.h:212
C_PRELOAD
#define C_PRELOAD
Definition: ASN1Codes.h:206
C_CLONE
#define C_CLONE
Definition: ASN1Codes.h:156
C_PUT_BEFORE
#define C_PUT_BEFORE
Definition: ASN1Codes.h:207
MHText::GetLineOrientation
static int GetLineOrientation(const char *str)
Definition: Text.cpp:169
Engine.h
MHPEnum
Definition: ParseNode.h:106
Ingredients.h
C_NEW_GENERIC_OCTETSTRING
#define C_NEW_GENERIC_OCTETSTRING
Definition: ASN1Codes.h:260
C_SET_PALETTE_REF
#define C_SET_PALETTE_REF
Definition: ASN1Codes.h:238
C_DEACTIVATE
#define C_DEACTIVATE
Definition: ASN1Codes.h:158
C_GET_SELECTION_STATUS
#define C_GET_SELECTION_STATUS
Definition: ASN1Codes.h:193
MHParseText::PTStartSection
@ PTStartSection
Definition: ParseText.h:49
MHSlider::GetOrientation
static int GetOrientation(const char *str)
Definition: Visible.cpp:692
C_GET_VOLUME
#define C_GET_VOLUME
Definition: ASN1Codes.h:198
Text.h
C_DRAW_POLYGON
#define C_DRAW_POLYGON
Definition: ASN1Codes.h:166
C_MULTIPLEX
#define C_MULTIPLEX
Definition: ASN1Codes.h:125
C_NEW_GENERIC_INTEGER
#define C_NEW_GENERIC_INTEGER
Definition: ASN1Codes.h:259
C_SET_LINE_COLOUR
#define C_SET_LINE_COLOUR
Definition: ASN1Codes.h:234
MHParseText::PTString
@ PTString
Definition: ParseText.h:49
C_MOVE
#define C_MOVE
Definition: ASN1Codes.h:202
C_SELECT_ITEM
#define C_SELECT_ITEM
Definition: ASN1Codes.h:216
MHPString
Definition: ParseNode.h:125
Root.h
MHPBool
Definition: ParseNode.h:115
m_name
const char * m_name
Definition: ParseText.cpp:329
C_SET_CURSOR_POSITION
#define C_SET_CURSOR_POSITION
Definition: ASN1Codes.h:224
C_SCALE_VIDEO
#define C_SCALE_VIDEO
Definition: ASN1Codes.h:213
MHParseText::PTEOF
@ PTEOF
Definition: ParseText.h:51
C_NEW_GENERIC_OBJECT_REF
#define C_NEW_GENERIC_OBJECT_REF
Definition: ASN1Codes.h:261
C_SELECT
#define C_SELECT
Definition: ASN1Codes.h:215
C_APPEND
#define C_APPEND
Definition: ASN1Codes.h:151
C_CLEAR
#define C_CLEAR
Definition: ASN1Codes.h:155
C_DESELECT_ITEM
#define C_DESELECT_ITEM
Definition: ASN1Codes.h:161
C_SET_FIRST_ITEM
#define C_SET_FIRST_ITEM
Definition: ASN1Codes.h:229
C_CLOSE_CONNECTION
#define C_CLOSE_CONNECTION
Definition: ASN1Codes.h:157
MHParseText::PTStartSeq
@ PTStartSeq
Definition: ParseText.h:50
MHText::GetStartCorner
static int GetStartCorner(const char *str)
Definition: Text.cpp:190
C_DIVIDE
#define C_DIVIDE
Definition: ASN1Codes.h:162
C_LINK_EFFECT
#define C_LINK_EFFECT
Definition: ASN1Codes.h:96
C_STORE_PERSISTENT
#define C_STORE_PERSISTENT
Definition: ASN1Codes.h:250
MHParseText::m_p
unsigned int m_p
Definition: ParseText.h:61
BaseClasses.h
C_SET_HIGHLIGHT_STATUS
#define C_SET_HIGHLIGHT_STATUS
Definition: ASN1Codes.h:231
C_GET_TOKEN_POSITION
#define C_GET_TOKEN_POSITION
Definition: ASN1Codes.h:197
stricmp
#define stricmp
Definition: ParseText.cpp:41
C_GET_FILL_COLOUR
#define C_GET_FILL_COLOUR
Definition: ASN1Codes.h:177
MHParseNode
Definition: ParseNode.h:38
C_ORIGINAL_CONTENT
#define C_ORIGINAL_CONTENT
Definition: ASN1Codes.h:91
C_NEW_GENERIC_CONTENT_REF
#define C_NEW_GENERIC_CONTENT_REF
Definition: ASN1Codes.h:262
C_GET_POSITION
#define C_GET_POSITION
Definition: ASN1Codes.h:191
C_SET_COUNTER_TRIGGER
#define C_SET_COUNTER_TRIGGER
Definition: ASN1Codes.h:223
C_MULTIPLY
#define C_MULTIPLY
Definition: ASN1Codes.h:204
C_GET_LAST_ANCHOR_FIRED
#define C_GET_LAST_ANCHOR_FIRED
Definition: ASN1Codes.h:183
C_SET_FONT_REF
#define C_SET_FONT_REF
Definition: ASN1Codes.h:230
C_LOCK_SCREEN
#define C_LOCK_SCREEN
Definition: ASN1Codes.h:200
MHParseText::PTEndSection
@ PTEndSection
Definition: ParseText.h:50
C_SET_VOLUME
#define C_SET_VOLUME
Definition: ASN1Codes.h:246
MHParseText::PTEnum
@ PTEnum
Definition: ParseText.h:49
C_SET_CURSOR_SHAPE
#define C_SET_CURSOR_SHAPE
Definition: ASN1Codes.h:225
MHERROR
#define MHERROR(__text)
Definition: Logging.h:42
Logging.h
m_r
unsigned char m_r
Definition: ParseText.cpp:330
MHParseText::PTBool
@ PTBool
Definition: ParseText.h:51
C_GET_LINE_WIDTH
#define C_GET_LINE_WIDTH
Definition: ASN1Codes.h:186
C_SET_LABEL
#define C_SET_LABEL
Definition: ASN1Codes.h:233
C_SET_LINE_WIDTH
#define C_SET_LINE_WIDTH
Definition: ASN1Codes.h:236
MHParseText::m_nType
ParseTextType m_nType
Definition: ParseText.h:52
C_SET_TRANSPARENCY
#define C_SET_TRANSPARENCY
Definition: ASN1Codes.h:244
m_g
unsigned char m_g
Definition: ParseText.cpp:330
MHParseText::Parse
MHParseNode * Parse() override
Definition: ParseText.cpp:1113
MHPInt
Definition: ParseNode.h:96
C_GET_PORTION
#define C_GET_PORTION
Definition: ASN1Codes.h:190
MHParseText::NextSym
void NextSym()
Definition: ParseText.cpp:373
C_GET_TEXT_DATA
#define C_GET_TEXT_DATA
Definition: ASN1Codes.h:196
C_BRING_TO_FRONT
#define C_BRING_TO_FRONT
Definition: ASN1Codes.h:152
C_TEST_VARIABLE
#define C_TEST_VARIABLE
Definition: ASN1Codes.h:252
m_b
unsigned char m_b
Definition: ParseText.cpp:330
C_ORIGINAL_VALUE
#define C_ORIGINAL_VALUE
Definition: ASN1Codes.h:100
C_NEW_GENERIC_BOOLEAN
#define C_NEW_GENERIC_BOOLEAN
Definition: ASN1Codes.h:258
C_SET_DATA
#define C_SET_DATA
Definition: ASN1Codes.h:226
MHOctetString::Copy
void Copy(const MHOctetString &str)
Definition: BaseClasses.cpp:131
MHParseText::m_nInt
int m_nInt
Definition: ParseText.h:56
C_CONTENT_REFERENCE
#define C_CONTENT_REFERENCE
Definition: ASN1Codes.h:102
C_CALL_ACTION_SLOT
#define C_CALL_ACTION_SLOT
Definition: ASN1Codes.h:154
C_GET_LABEL
#define C_GET_LABEL
Definition: ASN1Codes.h:182