annotate tools/llvm-rc/ResourceScriptParser.cpp @ 148:63bd29f05246

merged
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Wed, 14 Aug 2019 19:46:37 +0900
parents c2174574ed3a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
1 //===-- ResourceScriptParser.cpp --------------------------------*- C++-*-===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
2 //
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
4 // See https://llvm.org/LICENSE.txt for license information.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
6 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
7 //===---------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
8 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
9 // This implements the parser defined in ResourceScriptParser.h.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
10 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
11 //===---------------------------------------------------------------------===//
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
12
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
13 #include "ResourceScriptParser.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
14 #include "llvm/Option/ArgList.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
15 #include "llvm/Support/FileSystem.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
16 #include "llvm/Support/Path.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
17 #include "llvm/Support/Process.h"
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
18
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
19 // Take an expression returning llvm::Error and forward the error if it exists.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
20 #define RETURN_IF_ERROR(Expr) \
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
21 if (auto Err = (Expr)) \
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
22 return std::move(Err);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
23
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
24 // Take an expression returning llvm::Expected<T> and assign it to Var or
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
25 // forward the error out of the function.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
26 #define ASSIGN_OR_RETURN(Var, Expr) \
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
27 auto Var = (Expr); \
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
28 if (!Var) \
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
29 return Var.takeError();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
30
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
31 namespace llvm {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
32 namespace rc {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
33
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
34 RCParser::ParserError::ParserError(const Twine &Expected, const LocIter CurLoc,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
35 const LocIter End)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
36 : ErrorLoc(CurLoc), FileEnd(End) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
37 CurMessage = "Error parsing file: expected " + Expected.str() + ", got " +
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
38 (CurLoc == End ? "<EOF>" : CurLoc->value()).str();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
39 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
40
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
41 char RCParser::ParserError::ID = 0;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
42
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
43 RCParser::RCParser(std::vector<RCToken> TokenList)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
44 : Tokens(std::move(TokenList)), CurLoc(Tokens.begin()), End(Tokens.end()) {}
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
45
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
46 bool RCParser::isEof() const { return CurLoc == End; }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
47
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
48 RCParser::ParseType RCParser::parseSingleResource() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
49 // The first thing we read is usually a resource's name. However, in some
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
50 // cases (LANGUAGE and STRINGTABLE) the resources don't have their names
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
51 // and the first token to be read is the type.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
52 ASSIGN_OR_RETURN(NameToken, readTypeOrName());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
53
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
54 if (NameToken->equalsLower("LANGUAGE"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
55 return parseLanguageResource();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
56 else if (NameToken->equalsLower("STRINGTABLE"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
57 return parseStringTableResource();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
58
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
59 // If it's not an unnamed resource, what we've just read is a name. Now,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
60 // read resource type;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
61 ASSIGN_OR_RETURN(TypeToken, readTypeOrName());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
62
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
63 ParseType Result = std::unique_ptr<RCResource>();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
64 (void)!Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
65
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
66 if (TypeToken->equalsLower("ACCELERATORS"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
67 Result = parseAcceleratorsResource();
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
68 else if (TypeToken->equalsLower("BITMAP"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
69 Result = parseBitmapResource();
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
70 else if (TypeToken->equalsLower("CURSOR"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
71 Result = parseCursorResource();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
72 else if (TypeToken->equalsLower("DIALOG"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
73 Result = parseDialogResource(false);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
74 else if (TypeToken->equalsLower("DIALOGEX"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
75 Result = parseDialogResource(true);
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
76 else if (TypeToken->equalsLower("HTML"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
77 Result = parseHTMLResource();
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
78 else if (TypeToken->equalsLower("ICON"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
79 Result = parseIconResource();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
80 else if (TypeToken->equalsLower("MENU"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
81 Result = parseMenuResource();
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
82 else if (TypeToken->equalsLower("RCDATA"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
83 Result = parseUserDefinedResource(RkRcData);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
84 else if (TypeToken->equalsLower("VERSIONINFO"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
85 Result = parseVersionInfoResource();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
86 else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
87 Result = parseUserDefinedResource(*TypeToken);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
88
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
89 if (Result)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
90 (*Result)->setName(*NameToken);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
91
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
92 return Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
93 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
94
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
95 bool RCParser::isNextTokenKind(Kind TokenKind) const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
96 return !isEof() && look().kind() == TokenKind;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
97 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
98
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
99 const RCToken &RCParser::look() const {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
100 assert(!isEof());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
101 return *CurLoc;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
102 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
103
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
104 const RCToken &RCParser::read() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
105 assert(!isEof());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
106 return *CurLoc++;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
107 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
108
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
109 void RCParser::consume() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
110 assert(!isEof());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
111 CurLoc++;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
112 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
113
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
114 // An integer description might consist of a single integer or
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
115 // an arithmetic expression evaluating to the integer. The expressions
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
116 // can contain the following tokens: <int> ( ) + - | & ~ not. Their meaning
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
117 // is the same as in C++ except for 'not' expression.
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
118 // The operators in the original RC implementation have the following
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
119 // precedence:
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
120 // 1) Unary operators (- ~ not),
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
121 // 2) Binary operators (+ - & |), with no precedence.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
122 //
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
123 // 'not' expression is mostly useful for style values. It evaluates to 0,
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
124 // but value given to the operator is stored separately from integer value.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
125 // It's mostly useful for control style expressions and causes bits from
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
126 // default control style to be excluded from generated style. For binary
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
127 // operators the mask from the right operand is applied to the left operand
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
128 // and masks from both operands are combined in operator result.
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
129 //
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
130 // The following grammar is used to parse the expressions Exp1:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
131 // Exp1 ::= Exp2 || Exp1 + Exp2 || Exp1 - Exp2 || Exp1 | Exp2 || Exp1 & Exp2
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
132 // Exp2 ::= -Exp2 || ~Exp2 || not Expr2 || Int || (Exp1).
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
133 // (More conveniently, Exp1 is a non-empty sequence of Exp2 expressions,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
134 // separated by binary operators.)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
135 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
136 // Expressions of type Exp1 are read by parseIntExpr1(Inner) method, while Exp2
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
137 // is read by parseIntExpr2().
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
138 //
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
139 // The original Microsoft tool handles multiple unary operators incorrectly.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
140 // For example, in 16-bit little-endian integers:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
141 // 1 => 01 00, -1 => ff ff, --1 => ff ff, ---1 => 01 00;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
142 // 1 => 01 00, ~1 => fe ff, ~~1 => fd ff, ~~~1 => fc ff.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
143 // Our implementation differs from the original one and handles these
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
144 // operators correctly:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
145 // 1 => 01 00, -1 => ff ff, --1 => 01 00, ---1 => ff ff;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
146 // 1 => 01 00, ~1 => fe ff, ~~1 => 01 00, ~~~1 => fe ff.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
147
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
148 Expected<RCInt> RCParser::readInt() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
149 ASSIGN_OR_RETURN(Value, parseIntExpr1());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
150 return (*Value).getValue();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
151 }
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
152
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
153 Expected<IntWithNotMask> RCParser::parseIntExpr1() {
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
154 // Exp1 ::= Exp2 || Exp1 + Exp2 || Exp1 - Exp2 || Exp1 | Exp2 || Exp1 & Exp2.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
155 ASSIGN_OR_RETURN(FirstResult, parseIntExpr2());
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
156 IntWithNotMask Result = *FirstResult;
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
157
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
158 while (!isEof() && look().isBinaryOp()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
159 auto OpToken = read();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
160 ASSIGN_OR_RETURN(NextResult, parseIntExpr2());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
161
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
162 switch (OpToken.kind()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
163 case Kind::Plus:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
164 Result += *NextResult;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
165 break;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
166
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
167 case Kind::Minus:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
168 Result -= *NextResult;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
169 break;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
170
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
171 case Kind::Pipe:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
172 Result |= *NextResult;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
173 break;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
174
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
175 case Kind::Amp:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
176 Result &= *NextResult;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
177 break;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
178
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
179 default:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
180 llvm_unreachable("Already processed all binary ops.");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
181 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
182 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
183
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
184 return Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
185 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
186
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
187 Expected<IntWithNotMask> RCParser::parseIntExpr2() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
188 // Exp2 ::= -Exp2 || ~Exp2 || not Expr2 || Int || (Exp1).
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
189 static const char ErrorMsg[] = "'-', '~', integer or '('";
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
190
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
191 if (isEof())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
192 return getExpectedError(ErrorMsg);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
193
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
194 switch (look().kind()) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
195 case Kind::Minus: {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
196 consume();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
197 ASSIGN_OR_RETURN(Result, parseIntExpr2());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
198 return -(*Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
199 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
200
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
201 case Kind::Tilde: {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
202 consume();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
203 ASSIGN_OR_RETURN(Result, parseIntExpr2());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
204 return ~(*Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
205 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
206
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
207 case Kind::Int:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
208 return RCInt(read());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
209
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
210 case Kind::LeftParen: {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
211 consume();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
212 ASSIGN_OR_RETURN(Result, parseIntExpr1());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
213 RETURN_IF_ERROR(consumeType(Kind::RightParen));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
214 return *Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
215 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
216
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
217 case Kind::Identifier: {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
218 if (!read().value().equals_lower("not"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
219 return getExpectedError(ErrorMsg, true);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
220 ASSIGN_OR_RETURN(Result, parseIntExpr2());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
221 return IntWithNotMask(0, (*Result).getValue());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
222 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
223
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
224 default:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
225 return getExpectedError(ErrorMsg);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
226 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
227 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
228
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
229 Expected<StringRef> RCParser::readString() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
230 if (!isNextTokenKind(Kind::String))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
231 return getExpectedError("string");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
232 return read().value();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
233 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
234
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
235 Expected<StringRef> RCParser::readFilename() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
236 if (!isNextTokenKind(Kind::String) && !isNextTokenKind(Kind::Identifier))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
237 return getExpectedError("string");
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
238 return read().value();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
239 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
240
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
241 Expected<StringRef> RCParser::readIdentifier() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
242 if (!isNextTokenKind(Kind::Identifier))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
243 return getExpectedError("identifier");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
244 return read().value();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
245 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
246
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
247 Expected<IntOrString> RCParser::readIntOrString() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
248 if (!isNextTokenKind(Kind::Int) && !isNextTokenKind(Kind::String))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
249 return getExpectedError("int or string");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
250 return IntOrString(read());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
251 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
252
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
253 Expected<IntOrString> RCParser::readTypeOrName() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
254 // We suggest that the correct resource name or type should be either an
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
255 // identifier or an integer. The original RC tool is much more liberal.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
256 if (!isNextTokenKind(Kind::Identifier) && !isNextTokenKind(Kind::Int))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
257 return getExpectedError("int or identifier");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
258 return IntOrString(read());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
259 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
260
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
261 Error RCParser::consumeType(Kind TokenKind) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
262 if (isNextTokenKind(TokenKind)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
263 consume();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
264 return Error::success();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
265 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
266
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
267 switch (TokenKind) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
268 #define TOKEN(TokenName) \
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
269 case Kind::TokenName: \
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
270 return getExpectedError(#TokenName);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
271 #define SHORT_TOKEN(TokenName, TokenCh) \
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
272 case Kind::TokenName: \
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
273 return getExpectedError(#TokenCh);
134
3a76565eade5 update 5.0.1
mir3636
parents: 121
diff changeset
274 #include "ResourceScriptTokenList.def"
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
275 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
276
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
277 llvm_unreachable("All case options exhausted.");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
278 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
279
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
280 bool RCParser::consumeOptionalType(Kind TokenKind) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
281 if (isNextTokenKind(TokenKind)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
282 consume();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
283 return true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
284 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
285
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
286 return false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
287 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
288
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
289 Expected<SmallVector<RCInt, 8>> RCParser::readIntsWithCommas(size_t MinCount,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
290 size_t MaxCount) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
291 assert(MinCount <= MaxCount);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
292
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
293 SmallVector<RCInt, 8> Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
294
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
295 auto FailureHandler =
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
296 [&](llvm::Error Err) -> Expected<SmallVector<RCInt, 8>> {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
297 if (Result.size() < MinCount)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
298 return std::move(Err);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
299 consumeError(std::move(Err));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
300 return Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
301 };
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
302
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
303 for (size_t i = 0; i < MaxCount; ++i) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
304 // Try to read a comma unless we read the first token.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
305 // Sometimes RC tool requires them and sometimes not. We decide to
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
306 // always require them.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
307 if (i >= 1) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
308 if (auto CommaError = consumeType(Kind::Comma))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
309 return FailureHandler(std::move(CommaError));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
310 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
311
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
312 if (auto IntResult = readInt())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
313 Result.push_back(*IntResult);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
314 else
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
315 return FailureHandler(IntResult.takeError());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
316 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
317
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
318 return std::move(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
319 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
320
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
321 Expected<uint32_t> RCParser::parseFlags(ArrayRef<StringRef> FlagDesc,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
322 ArrayRef<uint32_t> FlagValues) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
323 assert(!FlagDesc.empty());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
324 assert(FlagDesc.size() == FlagValues.size());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
325
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
326 uint32_t Result = 0;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
327 while (isNextTokenKind(Kind::Comma)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
328 consume();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
329 ASSIGN_OR_RETURN(FlagResult, readIdentifier());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
330 bool FoundFlag = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
331
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
332 for (size_t FlagId = 0; FlagId < FlagDesc.size(); ++FlagId) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
333 if (!FlagResult->equals_lower(FlagDesc[FlagId]))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
334 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
335
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
336 Result |= FlagValues[FlagId];
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
337 FoundFlag = true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
338 break;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
339 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
340
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
341 if (!FoundFlag)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
342 return getExpectedError(join(FlagDesc, "/"), true);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
343 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
344
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
345 return Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
346 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
347
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
348 uint16_t RCParser::parseMemoryFlags(uint16_t Flags) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
349 while (!isEof()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
350 const RCToken &Token = look();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
351 if (Token.kind() != Kind::Identifier)
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
352 return Flags;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
353 const StringRef Ident = Token.value();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
354 if (Ident.equals_lower("PRELOAD"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
355 Flags |= MfPreload;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
356 else if (Ident.equals_lower("LOADONCALL"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
357 Flags &= ~MfPreload;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
358 else if (Ident.equals_lower("FIXED"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
359 Flags &= ~(MfMoveable | MfDiscardable);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
360 else if (Ident.equals_lower("MOVEABLE"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
361 Flags |= MfMoveable;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
362 else if (Ident.equals_lower("DISCARDABLE"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
363 Flags |= MfDiscardable | MfMoveable | MfPure;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
364 else if (Ident.equals_lower("PURE"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
365 Flags |= MfPure;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
366 else if (Ident.equals_lower("IMPURE"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
367 Flags &= ~(MfPure | MfDiscardable);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
368 else if (Ident.equals_lower("SHARED"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
369 Flags |= MfPure;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
370 else if (Ident.equals_lower("NONSHARED"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
371 Flags &= ~(MfPure | MfDiscardable);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
372 else
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
373 return Flags;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
374 consume();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
375 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
376 return Flags;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
377 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
378
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
379 Expected<OptionalStmtList>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
380 RCParser::parseOptionalStatements(OptStmtType StmtsType) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
381 OptionalStmtList Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
382
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
383 // The last statement is always followed by the start of the block.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
384 while (!isNextTokenKind(Kind::BlockBegin)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
385 ASSIGN_OR_RETURN(SingleParse, parseSingleOptionalStatement(StmtsType));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
386 Result.addStmt(std::move(*SingleParse));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
387 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
388
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
389 return std::move(Result);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
390 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
391
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
392 Expected<std::unique_ptr<OptionalStmt>>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
393 RCParser::parseSingleOptionalStatement(OptStmtType StmtsType) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
394 ASSIGN_OR_RETURN(TypeToken, readIdentifier());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
395 if (TypeToken->equals_lower("CHARACTERISTICS"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
396 return parseCharacteristicsStmt();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
397 if (TypeToken->equals_lower("LANGUAGE"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
398 return parseLanguageStmt();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
399 if (TypeToken->equals_lower("VERSION"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
400 return parseVersionStmt();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
401
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
402 if (StmtsType != OptStmtType::BasicStmt) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
403 if (TypeToken->equals_lower("CAPTION"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
404 return parseCaptionStmt();
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
405 if (TypeToken->equals_lower("CLASS"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
406 return parseClassStmt();
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
407 if (TypeToken->equals_lower("EXSTYLE"))
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
408 return parseExStyleStmt();
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
409 if (TypeToken->equals_lower("FONT"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
410 return parseFontStmt(StmtsType);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
411 if (TypeToken->equals_lower("STYLE"))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
412 return parseStyleStmt();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
413 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
414
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
415 return getExpectedError("optional statement type, BEGIN or '{'",
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
416 /* IsAlreadyRead = */ true);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
417 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
418
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
419 RCParser::ParseType RCParser::parseLanguageResource() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
420 // Read LANGUAGE as an optional statement. If it's read correctly, we can
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
421 // upcast it to RCResource.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
422 return parseLanguageStmt();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
423 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
424
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
425 RCParser::ParseType RCParser::parseAcceleratorsResource() {
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
426 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
427 parseMemoryFlags(AcceleratorsResource::getDefaultMemoryFlags());
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
428 ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
429 RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
430
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
431 auto Accels = llvm::make_unique<AcceleratorsResource>(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
432 std::move(*OptStatements), MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
433
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
434 while (!consumeOptionalType(Kind::BlockEnd)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
435 ASSIGN_OR_RETURN(EventResult, readIntOrString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
436 RETURN_IF_ERROR(consumeType(Kind::Comma));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
437 ASSIGN_OR_RETURN(IDResult, readInt());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
438 ASSIGN_OR_RETURN(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
439 FlagsResult,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
440 parseFlags(AcceleratorsResource::Accelerator::OptionsStr,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
441 AcceleratorsResource::Accelerator::OptionsFlags));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
442 Accels->addAccelerator(*EventResult, *IDResult, *FlagsResult);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
443 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
444
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
445 return std::move(Accels);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
446 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
447
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
448 RCParser::ParseType RCParser::parseCursorResource() {
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
449 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
450 parseMemoryFlags(CursorResource::getDefaultMemoryFlags());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
451 ASSIGN_OR_RETURN(Arg, readFilename());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
452 return llvm::make_unique<CursorResource>(*Arg, MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
453 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
454
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
455 RCParser::ParseType RCParser::parseDialogResource(bool IsExtended) {
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
456 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
457 parseMemoryFlags(DialogResource::getDefaultMemoryFlags());
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
458 // Dialog resources have the following format of the arguments:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
459 // DIALOG: x, y, width, height [opt stmts...] {controls...}
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
460 // DIALOGEX: x, y, width, height [, helpID] [opt stmts...] {controls...}
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
461 // These are very similar, so we parse them together.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
462 ASSIGN_OR_RETURN(LocResult, readIntsWithCommas(4, 4));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
463
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
464 uint32_t HelpID = 0; // When HelpID is unset, it's assumed to be 0.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
465 if (IsExtended && consumeOptionalType(Kind::Comma)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
466 ASSIGN_OR_RETURN(HelpIDResult, readInt());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
467 HelpID = *HelpIDResult;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
468 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
469
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
470 ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
471 IsExtended ? OptStmtType::DialogExStmt
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
472 : OptStmtType::DialogStmt));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
473
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
474 assert(isNextTokenKind(Kind::BlockBegin) &&
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
475 "parseOptionalStatements, when successful, halts on BlockBegin.");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
476 consume();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
477
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
478 auto Dialog = llvm::make_unique<DialogResource>(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
479 (*LocResult)[0], (*LocResult)[1], (*LocResult)[2], (*LocResult)[3],
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
480 HelpID, std::move(*OptStatements), IsExtended, MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
481
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
482 while (!consumeOptionalType(Kind::BlockEnd)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
483 ASSIGN_OR_RETURN(ControlDefResult, parseControl());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
484 Dialog->addControl(std::move(*ControlDefResult));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
485 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
486
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
487 return std::move(Dialog);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
488 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
489
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
490 RCParser::ParseType RCParser::parseUserDefinedResource(IntOrString Type) {
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
491 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
492 parseMemoryFlags(UserDefinedResource::getDefaultMemoryFlags());
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
493 if (isEof())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
494 return getExpectedError("filename, '{' or BEGIN");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
495
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
496 // Check if this is a file resource.
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
497 switch (look().kind()) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
498 case Kind::String:
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
499 case Kind::Identifier:
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
500 return llvm::make_unique<UserDefinedResource>(Type, read().value(),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
501 MemoryFlags);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
502 default:
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
503 break;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
504 }
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
505
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
506 RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
507 std::vector<IntOrString> Data;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
508
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
509 // Consume comma before each consecutive token except the first one.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
510 bool ConsumeComma = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
511 while (!consumeOptionalType(Kind::BlockEnd)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
512 if (ConsumeComma)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
513 RETURN_IF_ERROR(consumeType(Kind::Comma));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
514 ConsumeComma = true;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
515
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
516 ASSIGN_OR_RETURN(Item, readIntOrString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
517 Data.push_back(*Item);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
518 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
519
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
520 return llvm::make_unique<UserDefinedResource>(Type, std::move(Data),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
521 MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
522 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
523
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
524 RCParser::ParseType RCParser::parseVersionInfoResource() {
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
525 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
526 parseMemoryFlags(VersionInfoResource::getDefaultMemoryFlags());
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
527 ASSIGN_OR_RETURN(FixedResult, parseVersionInfoFixed());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
528 ASSIGN_OR_RETURN(BlockResult, parseVersionInfoBlockContents(StringRef()));
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
529 return llvm::make_unique<VersionInfoResource>(
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
530 std::move(**BlockResult), std::move(*FixedResult), MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
531 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
532
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
533 Expected<Control> RCParser::parseControl() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
534 // Each control definition (except CONTROL) follows one of the schemes below
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
535 // depending on the control class:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
536 // [class] text, id, x, y, width, height [, style] [, exstyle] [, helpID]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
537 // [class] id, x, y, width, height [, style] [, exstyle] [, helpID]
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
538 // Note that control ids must be integers.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
539 // Text might be either a string or an integer pointing to resource ID.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
540 ASSIGN_OR_RETURN(ClassResult, readIdentifier());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
541 std::string ClassUpper = ClassResult->upper();
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
542 auto CtlInfo = Control::SupportedCtls.find(ClassUpper);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
543 if (CtlInfo == Control::SupportedCtls.end())
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
544 return getExpectedError("control type, END or '}'", true);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
545
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
546 // Read caption if necessary.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
547 IntOrString Caption{StringRef()};
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
548 if (CtlInfo->getValue().HasTitle) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
549 ASSIGN_OR_RETURN(CaptionResult, readIntOrString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
550 RETURN_IF_ERROR(consumeType(Kind::Comma));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
551 Caption = *CaptionResult;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
552 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
553
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
554 ASSIGN_OR_RETURN(ID, readInt());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
555 RETURN_IF_ERROR(consumeType(Kind::Comma));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
556
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
557 IntOrString Class;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
558 Optional<IntWithNotMask> Style;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
559 if (ClassUpper == "CONTROL") {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
560 // CONTROL text, id, class, style, x, y, width, height [, exstyle] [, helpID]
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
561 ASSIGN_OR_RETURN(ClassStr, readString());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
562 RETURN_IF_ERROR(consumeType(Kind::Comma));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
563 Class = *ClassStr;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
564 ASSIGN_OR_RETURN(StyleVal, parseIntExpr1());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
565 RETURN_IF_ERROR(consumeType(Kind::Comma));
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
566 Style = *StyleVal;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
567 } else {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
568 Class = CtlInfo->getValue().CtlClass;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
569 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
570
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
571 // x, y, width, height
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
572 ASSIGN_OR_RETURN(Args, readIntsWithCommas(4, 4));
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
573
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
574 if (ClassUpper != "CONTROL") {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
575 if (consumeOptionalType(Kind::Comma)) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
576 ASSIGN_OR_RETURN(Val, parseIntExpr1());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
577 Style = *Val;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
578 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
579 }
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
580
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
581 Optional<uint32_t> ExStyle;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
582 if (consumeOptionalType(Kind::Comma)) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
583 ASSIGN_OR_RETURN(Val, readInt());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
584 ExStyle = *Val;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
585 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
586 Optional<uint32_t> HelpID;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
587 if (consumeOptionalType(Kind::Comma)) {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
588 ASSIGN_OR_RETURN(Val, readInt());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
589 HelpID = *Val;
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
590 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
591
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
592 return Control(*ClassResult, Caption, *ID, (*Args)[0], (*Args)[1],
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
593 (*Args)[2], (*Args)[3], Style, ExStyle, HelpID, Class);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
594 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
595
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
596 RCParser::ParseType RCParser::parseBitmapResource() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
597 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
598 parseMemoryFlags(BitmapResource::getDefaultMemoryFlags());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
599 ASSIGN_OR_RETURN(Arg, readFilename());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
600 return llvm::make_unique<BitmapResource>(*Arg, MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
601 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
602
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
603 RCParser::ParseType RCParser::parseIconResource() {
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
604 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
605 parseMemoryFlags(IconResource::getDefaultMemoryFlags());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
606 ASSIGN_OR_RETURN(Arg, readFilename());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
607 return llvm::make_unique<IconResource>(*Arg, MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
608 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
609
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
610 RCParser::ParseType RCParser::parseHTMLResource() {
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
611 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
612 parseMemoryFlags(HTMLResource::getDefaultMemoryFlags());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
613 ASSIGN_OR_RETURN(Arg, readFilename());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
614 return llvm::make_unique<HTMLResource>(*Arg, MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
615 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
616
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
617 RCParser::ParseType RCParser::parseMenuResource() {
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
618 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
619 parseMemoryFlags(MenuResource::getDefaultMemoryFlags());
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
620 ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
621 ASSIGN_OR_RETURN(Items, parseMenuItemsList());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
622 return llvm::make_unique<MenuResource>(std::move(*OptStatements),
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
623 std::move(*Items), MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
624 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
625
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
626 Expected<MenuDefinitionList> RCParser::parseMenuItemsList() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
627 RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
628
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
629 MenuDefinitionList List;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
630
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
631 // Read a set of items. Each item is of one of three kinds:
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
632 // MENUITEM SEPARATOR
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
633 // MENUITEM caption:String, result:Int [, menu flags]...
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
634 // POPUP caption:String [, menu flags]... { items... }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
635 while (!consumeOptionalType(Kind::BlockEnd)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
636 ASSIGN_OR_RETURN(ItemTypeResult, readIdentifier());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
637
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
638 bool IsMenuItem = ItemTypeResult->equals_lower("MENUITEM");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
639 bool IsPopup = ItemTypeResult->equals_lower("POPUP");
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
640 if (!IsMenuItem && !IsPopup)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
641 return getExpectedError("MENUITEM, POPUP, END or '}'", true);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
642
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
643 if (IsMenuItem && isNextTokenKind(Kind::Identifier)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
644 // Now, expecting SEPARATOR.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
645 ASSIGN_OR_RETURN(SeparatorResult, readIdentifier());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
646 if (SeparatorResult->equals_lower("SEPARATOR")) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
647 List.addDefinition(llvm::make_unique<MenuSeparator>());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
648 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
649 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
650
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
651 return getExpectedError("SEPARATOR or string", true);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
652 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
653
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
654 // Not a separator. Read the caption.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
655 ASSIGN_OR_RETURN(CaptionResult, readString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
656
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
657 // If MENUITEM, expect also a comma and an integer.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
658 uint32_t MenuResult = -1;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
659
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
660 if (IsMenuItem) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
661 RETURN_IF_ERROR(consumeType(Kind::Comma));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
662 ASSIGN_OR_RETURN(IntResult, readInt());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
663 MenuResult = *IntResult;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
664 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
665
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
666 ASSIGN_OR_RETURN(FlagsResult, parseFlags(MenuDefinition::OptionsStr,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
667 MenuDefinition::OptionsFlags));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
668
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
669 if (IsPopup) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
670 // If POPUP, read submenu items recursively.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
671 ASSIGN_OR_RETURN(SubMenuResult, parseMenuItemsList());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
672 List.addDefinition(llvm::make_unique<PopupItem>(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
673 *CaptionResult, *FlagsResult, std::move(*SubMenuResult)));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
674 continue;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
675 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
676
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
677 assert(IsMenuItem);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
678 List.addDefinition(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
679 llvm::make_unique<MenuItem>(*CaptionResult, MenuResult, *FlagsResult));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
680 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
681
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
682 return std::move(List);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
683 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
684
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
685 RCParser::ParseType RCParser::parseStringTableResource() {
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
686 uint16_t MemoryFlags =
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
687 parseMemoryFlags(StringTableResource::getDefaultMemoryFlags());
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
688 ASSIGN_OR_RETURN(OptStatements, parseOptionalStatements());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
689 RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
690
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
691 auto Table = llvm::make_unique<StringTableResource>(std::move(*OptStatements),
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
692 MemoryFlags);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
693
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
694 // Read strings until we reach the end of the block.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
695 while (!consumeOptionalType(Kind::BlockEnd)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
696 // Each definition consists of string's ID (an integer) and a string.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
697 // Some examples in documentation suggest that there might be a comma in
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
698 // between, however we strictly adhere to the single statement definition.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
699 ASSIGN_OR_RETURN(IDResult, readInt());
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
700 consumeOptionalType(Kind::Comma);
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
701 ASSIGN_OR_RETURN(StrResult, readString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
702 Table->addString(*IDResult, *StrResult);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
703 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
704
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
705 return std::move(Table);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
706 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
707
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
708 Expected<std::unique_ptr<VersionInfoBlock>>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
709 RCParser::parseVersionInfoBlockContents(StringRef BlockName) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
710 RETURN_IF_ERROR(consumeType(Kind::BlockBegin));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
711
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
712 auto Contents = llvm::make_unique<VersionInfoBlock>(BlockName);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
713
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
714 while (!isNextTokenKind(Kind::BlockEnd)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
715 ASSIGN_OR_RETURN(Stmt, parseVersionInfoStmt());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
716 Contents->addStmt(std::move(*Stmt));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
717 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
718
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
719 consume(); // Consume BlockEnd.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
720
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
721 return std::move(Contents);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
722 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
723
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
724 Expected<std::unique_ptr<VersionInfoStmt>> RCParser::parseVersionInfoStmt() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
725 // Expect either BLOCK or VALUE, then a name or a key (a string).
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
726 ASSIGN_OR_RETURN(TypeResult, readIdentifier());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
727
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
728 if (TypeResult->equals_lower("BLOCK")) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
729 ASSIGN_OR_RETURN(NameResult, readString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
730 return parseVersionInfoBlockContents(*NameResult);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
731 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
732
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
733 if (TypeResult->equals_lower("VALUE")) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
734 ASSIGN_OR_RETURN(KeyResult, readString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
735 // Read a non-empty list of strings and/or ints, each
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
736 // possibly preceded by a comma. Unfortunately, the tool behavior depends
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
737 // on them existing or not, so we need to memorize where we found them.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
738 std::vector<IntOrString> Values;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
739 std::vector<bool> PrecedingCommas;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
740 RETURN_IF_ERROR(consumeType(Kind::Comma));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
741 while (!isNextTokenKind(Kind::Identifier) &&
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
742 !isNextTokenKind(Kind::BlockEnd)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
743 // Try to eat a comma if it's not the first statement.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
744 bool HadComma = Values.size() > 0 && consumeOptionalType(Kind::Comma);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
745 ASSIGN_OR_RETURN(ValueResult, readIntOrString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
746 Values.push_back(*ValueResult);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
747 PrecedingCommas.push_back(HadComma);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
748 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
749 return llvm::make_unique<VersionInfoValue>(*KeyResult, std::move(Values),
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
750 std::move(PrecedingCommas));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
751 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
752
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
753 return getExpectedError("BLOCK or VALUE", true);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
754 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
755
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
756 Expected<VersionInfoResource::VersionInfoFixed>
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
757 RCParser::parseVersionInfoFixed() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
758 using RetType = VersionInfoResource::VersionInfoFixed;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
759 RetType Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
760
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
761 // Read until the beginning of the block.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
762 while (!isNextTokenKind(Kind::BlockBegin)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
763 ASSIGN_OR_RETURN(TypeResult, readIdentifier());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
764 auto FixedType = RetType::getFixedType(*TypeResult);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
765
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
766 if (!RetType::isTypeSupported(FixedType))
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
767 return getExpectedError("fixed VERSIONINFO statement type", true);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
768 if (Result.IsTypePresent[FixedType])
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
769 return getExpectedError("yet unread fixed VERSIONINFO statement type",
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
770 true);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
771
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
772 // VERSION variations take multiple integers.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
773 size_t NumInts = RetType::isVersionType(FixedType) ? 4 : 1;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
774 ASSIGN_OR_RETURN(ArgsResult, readIntsWithCommas(NumInts, NumInts));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
775 SmallVector<uint32_t, 4> ArgInts(ArgsResult->begin(), ArgsResult->end());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
776 Result.setValue(FixedType, ArgInts);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
777 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
778
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
779 return Result;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
780 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
781
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
782 RCParser::ParseOptionType RCParser::parseLanguageStmt() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
783 ASSIGN_OR_RETURN(Args, readIntsWithCommas(/* min = */ 2, /* max = */ 2));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
784 return llvm::make_unique<LanguageResource>((*Args)[0], (*Args)[1]);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
785 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
786
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
787 RCParser::ParseOptionType RCParser::parseCharacteristicsStmt() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
788 ASSIGN_OR_RETURN(Arg, readInt());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
789 return llvm::make_unique<CharacteristicsStmt>(*Arg);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
790 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
791
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
792 RCParser::ParseOptionType RCParser::parseVersionStmt() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
793 ASSIGN_OR_RETURN(Arg, readInt());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
794 return llvm::make_unique<VersionStmt>(*Arg);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
795 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
796
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
797 RCParser::ParseOptionType RCParser::parseCaptionStmt() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
798 ASSIGN_OR_RETURN(Arg, readString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
799 return llvm::make_unique<CaptionStmt>(*Arg);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
800 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
801
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
802 RCParser::ParseOptionType RCParser::parseClassStmt() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
803 ASSIGN_OR_RETURN(Arg, readIntOrString());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
804 return llvm::make_unique<ClassStmt>(*Arg);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
805 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
806
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
807 RCParser::ParseOptionType RCParser::parseFontStmt(OptStmtType DialogType) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
808 assert(DialogType != OptStmtType::BasicStmt);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
809
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
810 ASSIGN_OR_RETURN(SizeResult, readInt());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
811 RETURN_IF_ERROR(consumeType(Kind::Comma));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
812 ASSIGN_OR_RETURN(NameResult, readString());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
813
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
814 // Default values for the optional arguments.
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
815 uint32_t FontWeight = 0;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
816 bool FontItalic = false;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
817 uint32_t FontCharset = 1;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
818 if (DialogType == OptStmtType::DialogExStmt) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
819 if (consumeOptionalType(Kind::Comma)) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
820 ASSIGN_OR_RETURN(Args, readIntsWithCommas(/* min = */ 0, /* max = */ 3));
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
821 if (Args->size() >= 1)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
822 FontWeight = (*Args)[0];
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
823 if (Args->size() >= 2)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
824 FontItalic = (*Args)[1] != 0;
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
825 if (Args->size() >= 3)
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
826 FontCharset = (*Args)[2];
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
827 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
828 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
829 return llvm::make_unique<FontStmt>(*SizeResult, *NameResult, FontWeight,
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
830 FontItalic, FontCharset);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
831 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
832
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
833 RCParser::ParseOptionType RCParser::parseStyleStmt() {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
834 ASSIGN_OR_RETURN(Arg, readInt());
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
835 return llvm::make_unique<StyleStmt>(*Arg);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
836 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
837
147
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
838 RCParser::ParseOptionType RCParser::parseExStyleStmt() {
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
839 ASSIGN_OR_RETURN(Arg, readInt());
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
840 return llvm::make_unique<ExStyleStmt>(*Arg);
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
841 }
c2174574ed3a LLVM 10
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents: 134
diff changeset
842
121
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
843 Error RCParser::getExpectedError(const Twine &Message, bool IsAlreadyRead) {
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
844 return make_error<ParserError>(
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
845 Message, IsAlreadyRead ? std::prev(CurLoc) : CurLoc, End);
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
846 }
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
847
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
848 } // namespace rc
803732b1fca8 LLVM 5.0
kono
parents:
diff changeset
849 } // namespace llvm