|
@@ -97,40 +97,35 @@ void Builtin::Context::ForgetBuiltin(unsigned ID, IdentifierTable &Table) {
|
|
|
Table.get(GetRecord(ID).Name).setBuiltinID(0);
|
|
|
}
|
|
|
|
|
|
-bool
|
|
|
-Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
|
|
|
- bool &HasVAListArg) {
|
|
|
- const char *Printf = strpbrk(GetRecord(ID).Attributes, "pP");
|
|
|
- if (!Printf)
|
|
|
+bool Builtin::Context::isLike(unsigned ID, unsigned &FormatIdx,
|
|
|
+ bool &HasVAListArg, const char *Fmt) const {
|
|
|
+ assert(Fmt && "Not passed a format string");
|
|
|
+ assert(::strlen(Fmt) == 2 &&
|
|
|
+ "Format string needs to be two characters long");
|
|
|
+ assert(::toupper(Fmt[0]) == Fmt[1] &&
|
|
|
+ "Format string is not in the form \"xX\"");
|
|
|
+
|
|
|
+ const char *Like = ::strpbrk(GetRecord(ID).Attributes, Fmt);
|
|
|
+ if (!Like)
|
|
|
return false;
|
|
|
|
|
|
- HasVAListArg = (*Printf == 'P');
|
|
|
+ HasVAListArg = (*Like == Fmt[1]);
|
|
|
|
|
|
- ++Printf;
|
|
|
- assert(*Printf == ':' && "p or P specifier must have be followed by a ':'");
|
|
|
- ++Printf;
|
|
|
+ ++Like;
|
|
|
+ assert(*Like == ':' && "Format specifier must be followed by a ':'");
|
|
|
+ ++Like;
|
|
|
|
|
|
- assert(strchr(Printf, ':') && "printf specifier must end with a ':'");
|
|
|
- FormatIdx = strtol(Printf, 0, 10);
|
|
|
+ assert(::strchr(Like, ':') && "Format specifier must end with a ':'");
|
|
|
+ FormatIdx = ::strtol(Like, 0, 10);
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
-// FIXME: Refactor with isPrintfLike.
|
|
|
-bool
|
|
|
-Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
|
|
|
- bool &HasVAListArg) {
|
|
|
- const char *Scanf = strpbrk(GetRecord(ID).Attributes, "sS");
|
|
|
- if (!Scanf)
|
|
|
- return false;
|
|
|
-
|
|
|
- HasVAListArg = (*Scanf == 'S');
|
|
|
-
|
|
|
- ++Scanf;
|
|
|
- assert(*Scanf == ':' && "s or S specifier must have be followed by a ':'");
|
|
|
- ++Scanf;
|
|
|
-
|
|
|
- assert(strchr(Scanf, ':') && "printf specifier must end with a ':'");
|
|
|
- FormatIdx = strtol(Scanf, 0, 10);
|
|
|
- return true;
|
|
|
+bool Builtin::Context::isPrintfLike(unsigned ID, unsigned &FormatIdx,
|
|
|
+ bool &HasVAListArg) {
|
|
|
+ return isLike(ID, FormatIdx, HasVAListArg, "pP");
|
|
|
}
|
|
|
|
|
|
+bool Builtin::Context::isScanfLike(unsigned ID, unsigned &FormatIdx,
|
|
|
+ bool &HasVAListArg) {
|
|
|
+ return isLike(ID, FormatIdx, HasVAListArg, "sS");
|
|
|
+}
|