QScriptEngine: bad expression considered valid - c++

I need to implement a simple math expression calculator like 1+2*(3.4 + 0.1)
I thought it'd be quite easy to implement the stuff using
QScriptEngine::evaluate()
but there is a problem: some invalid expressions is considered valid and evaluated to something instead of producing an error.
Example:
QString expression = "1 + 2*("; // <---- wrong expression
auto checkResult = QScriptEngine::checkSyntax(expression);
if (checkResult.state() == QScriptSyntaxCheckResult::Valid)
{
QScriptEngine engine;
auto scriptResult = engine.evaluate(expression);
if (scriptResult.isValid() && scriptResult.isNumber())
{
double value = scriptResult.toNumber(); // <---- the value is 3.0, instead of an error
}
}
So my question is: am I missing something and there is a way I can check the syntax of an expression before a QScriptEngine::evaluate() using Qt?
Another way is to use Lepton library (or similiar one), but I'd prefer to not include other 3rd party components.

Unfortunately there was a configuration/Qt issue. Updating to the latest Qt5.5 & rebuilding the project solved the problem. Thank you #hyde.

Related

How to do string formatting in BetterC mode?

I'd like to use something like the "Concepts" package from Atila Neves.
I implemented the check of an object against a type signature myself in a simple naive way. I can check struct objects against interfaces which I define within compile-time-evaluated delegate blocks to make them work with BetterC. I only used compile-time function evaluation with enums which receive return values of executed delegate code blocks.
Now I faced problems with std.format.format which uses TypeInfo for %s formatters which gives errors when compiling in BetterC. For code generation I'd like to use token strings because they have syntax highlighting. But proper usage of them requires string interpolation or string formatting. core.stdc.stdio.snprintf is no alternative because CTFE can only interprete D source code.
This is not technically a problem. I can just turn token strings into WYSIWYG strings.
But I wonder why I can't use it. The official documentation says, compile-time features are unrestricted for BetterC (I assume this includes TypeInfo). Either it is plain wrong or I am doing it wrong.
template implementsType(alias symbol, type)
if (isAbstractClass!type)
{
enum implementsType = mixin(implementsTypeExpr);
enum implementsTypeExpr =
{
import std.format : format;
auto result = "";
static foreach(memberName; __traits(allMembers, type))
{
result ~= format(
q{__traits(compiles, __traits(getMember, symbol, "%1$s")) && }~
q{covariantSignature!(__traits(getMember, symbol, "%1$s"), __traits(getMember, type, "%1$s")) && }
, memberName);
}
return (result.length >= 3)? result[0 .. $-3] : result;
}();
}
TypeInfo are not available with BetterC.
There's a bc-string dub package that provides a limited string formatter that will work in BetterC.

Preferred way of extracting and matching protobuf message typename from an Any package

I've been using Any to package dynamic messages for protobuf.
On the receiver end, I use Any.type_url() to match the enclosed message types.
Correct me if I'm wrong, knowing that .GetDescriptor() is unavailable with Any, I still want to make the matching less of a clutter. I tried to extract the message type with brute force like this:
MyAny pouch;
// unpacking pouch
// Assume the message is "type.googleapis.com/MyTypeName"
....
const char* msgPrefix = "type.googleapis.com/";
auto lenPrefix = strlen(msgPrefix);
const std::string& msgURL = pouch.msg().type_url();
MamStr msgName = msgURL.substr(lenPrefix, msgURL.size());
if (msgName == "MyTypeName") {
// do stuff ...
}
But I'm still wondering if there are cleaner way of skipping the prefix to get the "basename" of the type URL.
Thanks!
You could try
std::string getBaseName(std::string const & url) {
return url.substr(url.find_last_of("/\\") + 1);
}
if it suits you well.
Although there are some cases, it may not explode it correctly.
Let's say you have two params as basename: http://url.com/example/2
This will get the latest, which is 2...
If you are not looking for cross-platform support, you can always go for https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/splitpath-wsplitpath?view=vs-2019

How can I get macro name from CStyleCastExpr matcher in clang-tidy?

I using clang-tidy for a while and creating some own checks. But now I stuck in this issue. I have a cstyle cast expression from which I want to get a macro name as string.
#define H_KEY 5;
float *a;
a = (float *)H_KEY; // I want to print out "H_KEY" from this expression
So I registered a matcher like this
void PointersCastCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(cStyleCastExpr().bind("cStyleCastExpr"), this);
}
I'm able to catch every cstyle cast and get a subExpr from it like this.
const Expr * subExpr = cStyleCast->getSubExpr();
So the clang tidy now give me information that I have "int" type sub-expression which is correct but I don't know how can I get the name of it.
What I tried was dynamic cast to DeclRefExpr, but this not pass. Also tried dynamic cast to BuiltinType, then I want to get a declaration but with no luck.
So please help. I think this should not be difficult.
Thank you!
If someone run in this issue, I resolve it like this.
if (subExpr->getExprLoc().isMacroID()) {
SourceManager &SM = *Result.SourceManager;
LangOptions LangOpts = getLangOpts();
StringRef subExprText = Lexer::getSourceText(CharSourceRange::getTokenRange(subExpr->getSourceRange()), SM, LangOpts);}
Maybe there is better approach but this one fits my needs.

How to get an explanatory string from std::regex_error?

My program is throwing an std::regex_error(). I'd like to know what the error is, since the regex looks legit to me. I did essentially this:
try {
// offending code
} catch (std::regex_error& e) {
log_error("Regex error: " << e.what() << ", " << e.code());
}
The output is:
Regex error: regex_error, 4
This isn't particularly helpful. What does 4 mean? The en.cppreference.com entry for code() only says:
Returns the std::regex_constants::error_type that was passed to the std::regex_error constructor.
The entry for error_type gives a list of error codes, all of whose exact values are "unspecified".
Do I have no recourse but to do something like this?
switch (e.code()) {
case std::regex_constants::error_collate: return "error_collate";
case std::regex_constants::error_ctype: return "error_ctype";
// etc ...
}
This is a quality-of-implementation issue in the standard C++ library, which is a nice way of saying that it's a bug. GCC bug 67361, to be exact ("std::regex_error::what() should say something about the error_code").
There is a recently submitted patch in the bug report, so I suppose that it will eventually show up as an upgrade. [Update: According to the bug report above, it was fixed in v6.1 (released April 26, 2016) but the bug report was not marked as resolved until November 19, 2018. Anyway, if you have a reasonably recent distribution, this should not be a problem any more.]
In the meantime, you have little option but to roll your own code->message conversion function. (Or, as an interim debugging method, consult include/bits/regex_error.h)
An alternative to using the switch is to define your own enum for each regex error code and cast the result to that, giving you better runtime debugging aid.
enum class RegexError {
collate = std::regex_constants::error_collate,
ctype = std::regex_constants::error_ctype,
// etc
};
RegexError errorCode = static_cast<RegexError>( e.code() );
// your debugger will now show you what the meaning of errorCode is
That way you don't need to use strings.
However, if you want to display the error to the user in a human-readable fashion then you will need to use strings, but you can use a map to store them:
map<RegexError, wchar_t const * const> errorMessages;
errorMessages[RegexError::collate] = L"the expression contains an invalid collating element name";
errorMessages[RegexError::ctype ] = L"the expression contains an invalid character class name";
// etc

Avoiding Code Repetitions in the Methods of a C++ Class?

Imaging a class which is doing the following thing
class AClass
{
AClass() : mode(0) {}
void a()
{
if (mode != 0) throw ("Error mode should be 0");
// we pass the test, so now do something
...
mode = 1;
}
void b()
{
if (mode != 1) throw("Error mode should be 1");
// we pass the test, so now do something
...
}
int mode;
};
The class contains many methods (easily than 20) and for each one of these methods we need to do a check on the value of mode which is obviously a lot of code duplication. Furthermore, we can identify two categories of methods, those who will throw an error if mode !=0 and those who will throw an error if mode != 1. Could it somehow be possible to group these methods in two categories (category A = method who throw an error if mode != 0) and category B for method who throw an error if mode != 1)?
EDIT: Looking at the current answers I realise the way I formulate the question and the problem is probably not clear enough. What I want to avoid is to have to call for a function in each method of the class. Whether we write code at the beginning of the methods or put this code in a function and call this function is not the problem. The question is whether we can avoid this all together. Whether there is a technique that would help to automatically check whether the call to a method of a class is valid depending on some context.
AClass is actually an API in the context of my project. a(), b(), etc. are some functions that the programmer can call if she/he wants to use the API however some of these methods can only be called in some precise order. For example you can see in the code that a() sets mode = 1. So the programmer could do something like this:
a(); // mode = 0 so it's good
b(); // mode = 1 so it's good
but this code needs to fail (it will compile of course but at execution time I need to throw an error mentioning that the context in which b() was called was wrong.
b(); // mode 0 so it won't work
a(); // it will compile but throw an exception
I tried to see if any pattern could work for doing this but couldn't find anything at all. It seems impossible to me and I believe the only option is really to write the necessary code. Could anyone though suggest something? Thank you very much.
Just add private member functions:
void assert_mode_0() {
assert_mode(0);
}
void assert_mode_1() {
assert_mode(1);
}
void assert_mode(int m) {
if (mode != m)
throw msg[m];
}
with a suitable definition of msg, of course.
Aside from implementing the check in a dedicated method (a great suggestion), you could also consider decomposing the behavior in AClass into two distinct classes, or delegate the specific portion to a new pair of classes. This seems especially appropriate if the mode is invariant for an instance (as it is in the example).
Well I guess the simplest solution would be defining a macro or some inline function like this:
#define checkErrorMode0(x) \
if ((x) != 0) throw ("Error mode should be 0");
#define checkErrorMode1(x) \
if ((x) != 1) throw ("Error mode should be 1");
// or, probably within your class
inline void checkErrorMode0(int x){
if ( x != 0 ) throw ("Error mode should be 0");
}
inline void checkErrorMode1(int x){
if ( x != 1 ) throw ("Error mode should be 1");
}
So you could simply call one of these methods inside of the functions that require them.
But most likely there is a more elegant workaround for what you want to do.
After looking into the problem a bit more, it seems that the closest helpful answer is (by Nick):
Try looking into Aspect Oriented Software Development en.wikipedia.org/wiki/Aspect-oriented_software_development – Nick
The Wikipedia page is not easy to read and doesn't provide a C++ example, so it stays very abstract at first, but if you search for Aspect Oriented Programming and C++ you will find links with examples.
The idea behind it (and it just a very quick summary) is to find a way of adding "services" or "functionalities" to a class. These services can notably be added at compile time through the use of templates. This is what I was intuitively experimenting with as an attempt at solving my problem, and I am glad to see this technique has been around for many years.
This document is a good reference:
Aspect-Oriented Programming & C++ By Christopher Diggins, August 01, 2004.
And I found this link with example useful to understand the concept:
Implementing Aspects using Generative Programming by Calum Grant.