Hexadecimal numbers in static method calls - msbuild

Is it possible to somehow use hexadecimal numbers in a static method call in MSBuild? I've tried a few different variations, but I'm getting this error:
error MSB4186: Invalid static method invocation syntax:
"[MSBuild]::BitwiseAnd(0x1, $(FxCopExit))". Input string was not in a
correct format. Static method invocation should be of the form:
$([FullTypeName]::Method()), e.g. $([System.IO.Path]::Combine('a', 'b')).
I'm trying to do this:
<Warning Text="Assembly loading exception" Condition="$([MSBuild]::BitwiseAnd(0x8, $(FxCopExit))) == 0x8"/>
It's worth noting that the 0x8 on the right hand side of the condition is acceptable, so if I instead do
<Warning Text="Assembly loading exception" Condition="$([MSBuild]::BitwiseAnd(8, $(FxCopExit))) == 0x8"/>
Everything works out fine. Since the error codes I'm mapping are defined in hexadecimal, I'd much prefer to keep them in hex here as well, for future readers of the script...

As far as I can find out, it is not possible. The only way to keep the hexadecimal is to wrap it in a conversion:
<Warning Text="Assembly loading exception" Condition="$([MSBuild]::BitwiseAnd($([System.Convert]::ToInt32(`0x8`, 16)), $(FxCopExit))) == 0x8"/>
I'm not sure if this is actually better/more readable than just rewriting the number in decimal and documenting, but this is technically correct, at least...

Related

How to make a class that inherits the same methods as IO::Path?

I want to build a class in Raku. Here's what I have so far:
unit class Vimwiki::File;
has Str:D $.path is required where *.IO.e;
method size {
return $.file.IO.s;
}
I'd like to get rid of the size method by simply making my class inherit the methods from IO::Path but I'm at a bit of a loss for how to accomplish this. Trying is IO::Path throws errors when I try to create a new object:
$vwf = Vimwiki::File.new(path => 't/test_file.md');
Must specify a non-empty string as a path
in block <unit> at t/01-basic.rakutest line 24
Must specify a non-empty string as a path
I always try a person's code when looking at someone's SO. Yours didn't work. (No declaration of $vwf.) That instantly alerts me that someone hasn't applied Minimal Reproducible Example principles.
So I did and less than 60 seconds later:
IO::Path.new
Yields the same error.
Why?
The doc for IO::Path.new shows its signature:
multi method new(Str:D $path, ...
So, IO::Path's new method expects a positional argument that's a Str. You (and my MRE) haven't passed a positional argument that's a Str. Thus the error message.
Of course, you've declared your own attribute $path, and have passed a named argument to set it, and that's unfortunately confused you because of the coincidence with the name path, but that's the fun of programming.
What next, take #1
Having a path attribute that duplicates IO::Path's strikes me as likely to lead to unnecessary complexity and/or bugs. So I think I'd nix that.
If all you're trying to do is wrap an additional check around the filename, then you could just write:
unit class Vimwiki::File is IO::Path;
method new ($path, |) { $path.IO.e ?? (callsame) !! die 'nope' }
callsame redispatches the ongoing routine call (the new method call), with the exact same arguments, to the next best fitting candidate(s) that would have been chosen if your new one containing the callsame hadn't been called. In this case, the next candidate(s) will be the existing new method(s) of IO::Path.
That seems fine to get started. Then you can add other attributes and methods as you see fit...
What next, take #2
...except for the IO::Path bug you filed, which means you can't initialize attributes in the normal way because IO::Path breaks the standard object construction protocol! :(
Liz shows one way to workaround this bug.
In an earlier version of this answer, I had not only showed but recommended another approach, namely delegation via handles instead of ordinary inheritance. I have since concluded that that was over-complicating things, and so removed it from this answer. And then I read your issue!
So I guess the delegation approach might still be appropriate as a workaround for a bug. So if later readers want to see it in action, follow #sdondley's link to their code. But I'm leaving it out of this (hopefully final! famous last words...) version of this answer in the hope that by the time you (later reader) read this, you just need to do something really simple like take #1.

Casting Qt5 QHelpEngine need obsolete casting

I am attempting to install a help browser starting from
http://www.walletfox.com/course/qhelpengineexample.php
For the line
tWidget->addTab(helpEngine->contentWidget(), tr("Contents"));
I receive error message
no known conversion from QHelpIndexWidget* to QWidget*
and really, if I make explicite casting with
tWidget->addTab((QWidget*)helpEngine->contentWidget(), tr("Contents"));
the program compiles and runs fine. What is going on here?
Most likely you forgot to #include <QHelpIndexWidget>.
Then the compiler can't deduct that a QHelpIndexWidget inherits from QWidget.
If you would try to access the QHelpIndexWidget*, like e.g.
qDebug() << helpEngine->indexWidget()->objectName();
without the include, you would get the better compiler error "QHelpIndexWidget is of incomplete type" or similar, which means that the type is forward declared, but the complete declaration is not accessible.
Additionally, I would suggest avoiding c-style casts and use static_cast<TYPE>(var) instead.

How does printf() work without variable list in its argument?

the following code:
#include<stdio.h>
void main()
{
int i=100,j=200;
printf("%d.....%d");
}
gives
200.....100
as the output.
Could someone explain how printf works without datalist
It provides a warning at compile time (warning: too few arguments for format), and is not documented, therefore it's undefined behaviour and should not be used. Different compilers are likely to have different behaviours and behaviour may even change between versions of the same compiler.
Try reading about it on Wikipedia for more info.
It is some garbage value in the stack since you haven't provided any integer arguments. printf() function doesn't know there are no arguments present and it will search the related stack location and print what ever there is. And as mentioned in Robadob's answer, behavior will change according to the compiler.

Input string was not in a correct format? Prod Error

My error message is as listed in the header "Input string was not in a correct format" however the stack trace is even more cryptic
Microsoft.VisualBasic.CompilerServices.Conversions.ParseDouble(String Value, NumberFormatInfo NumberFormat) at Microsoft.VisualBasic.CompilerServices.Conversions.ToDouble(String Value, NumberFormatInfo NumberFormat)
This is worse due to the fact that nowhere in the project does it use "ParseDouble". I believe that this has something to do with the objectfactorylibrary but can't pin anything down.
Has anyone seen something similar or point me in a general direction?
Edit:
Additional information, this is a production only issue with local, dev, and QA unable to reproduce the error in any environment but Production.
The stack trace is referring to a method inside of the .NET Framework code, called ParseDouble. It does not exist in your code. This is why the entire namespace is included, so that you can tell where the method is defined. If it starts with Microsoft or System, it's not something you wrote.
You probably used the CDbl operator (it's that thing that looks like a function call to the uninitiated), and internally, the .NET Framework translated that to a call to the Conversions.ToDouble method, which internally calls the Conversions.ParseDouble method. These are implementation details that you should not have to be concerned with. Keep traveling up the stack trace until you find the last method called that is part of your code.
As far as why your code is throwing that error, it's almost impossible to say without seeing some code that reproduces it.
However, my psychic debugging powers tell me that you're probably trying to parse a string value into a number, and the method is failing because the string does not contain a valid number. Check the value of the string you're passing into the method and update your question. It's probably an issue of the language settings on your computer. Do you use a language where , (a comma) is the decimal separator rather than . (a period)?
It's basically telling you that you that it tried to convert a string to a number but couldn't as the string was not numeric (could have alpha or other characters in it).
The stack trace should point you towards the offending piece of code, if you're lucky you will have a line number. If this is a piece of code that usually works then take a look at the data (whatever it is).

Write a compiler for a language that looks ahead and multiple files?

In my language I can use a class variable in my method when the definition appears below the method. It can also call methods below my method and etc. There are no 'headers'. Take this C# example.
class A
{
public void callMethods() { print(); B b; b.notYetSeen();
public void print() { Console.Write("v = {0}", v); }
int v=9;
}
class B
{
public void notYetSeen() { Console.Write("notYetSeen()\n"); }
}
How should I compile that? what i was thinking is:
pass1: convert everything to an AST
pass2: go through all classes and build a list of define classes/variable/etc
pass3: go through code and check if there's any errors such as undefined variable, wrong use etc and create my output
But it seems like for this to work I have to do pass 1 and 2 for ALL files before doing pass3. Also it feels like a lot of work to do until I find a syntax error (other than the obvious that can be done at parse time such as forgetting to close a brace or writing 0xLETTERS instead of a hex value). My gut says there is some other way.
Note: I am using bison/flex to generate my compiler.
My understanding of languages that handle forward references is that they typically just use the first pass to build a list of valid names. Something along the lines of just putting an entry in a table (without filling out the definition) so you have something to point to later when you do your real pass to generate the definitions.
If you try to actually build full definitions as you go, you would end up having to rescan repatedly, each time saving any references to undefined things until the next pass. Even that would fail if there are circular references.
I would go through on pass one and collect all of your class/method/field names and types, ignoring the method bodies. Then in pass two check the method bodies only.
I don't know that there can be any other way than traversing all the files in the source.
I think that you can get it down to two passes - on the first pass, build the AST and whenever you find a variable name, add it to a list that contains that blocks' symbols (it would probably be useful to add that list to the corresponding scope in the tree). Step two is to linearly traverse the tree and make sure that each symbol used references a symbol in that scope or a scope above it.
My description is oversimplified but the basic answer is -- lookahead requires at least two passes.
The usual approach is to save B as "unknown". It's probably some kind of type (because of the place where you encountered it). So you can just reserve the memory (a pointer) for it even though you have no idea what it really is.
For the method call, you can't do much. In a dynamic language, you'd just save the name of the method somewhere and check whether it exists at runtime. In a static language, you can save it in under "unknown methods" somewhere in your compiler along with the unknown type B. Since method calls eventually translate to a memory address, you can again reserve the memory.
Then, when you encounter B and the method, you can clear up your unknowns. Since you know a bit about them, you can say whether they behave like they should or if the first usage is now a syntax error.
So you don't have to read all files twice but it surely makes things more simple.
Alternatively, you can generate these header files as you encounter the sources and save them somewhere where you can find them again. This way, you can speed up the compilation (since you won't have to consider unchanged files in the next compilation run).
Lastly, if you write a new language, you shouldn't use bison and flex anymore. There are much better tools by now. ANTLR, for example, can produce a parser that can recover after an error, so you can still parse the whole file. Or check this Wikipedia article for more options.