How to get the value of system()? - premake

How do I get the current value of system() in premake5?
(and more generally functions like architecture() or platform())
I tried to print it, but it's a function, and when I try to print the return value of system(), I get "bad argument #1 to 'tostring' (value expected)".

Premake doesn't work that way, there is no "current" version of the data. You have to specify the context in which you'd like the current set of filters to be applied; take a look at src/base/oven.lua to see how the final data sets are built.
If you just want to drop the value of system (or architecture or platform) into an expression later in the process (and you're using Premake 5), check out tokens:
targetdir "bin/%{cfg.system}/%{cfg.architecture}"
Tokens can also evaluate arbitrary Lua expressions.
my_system_map = { -- must be global, so token evaluator can find it
windows = "Win32",
linux = "Posix",
macosx = "Mac"
}
targetdir "bin/%{my_system_map[cfg.system]}"
Helpful?

Related

Robot FW : Collections library : "Copy Dictionary" : How to make a shallow copy of a compound dictionary?

Consider the following code:
In Utils.py:
#keyword
def get_compound_dictionary():
"""
https://docs.python.org/3/library/copy.html
An example compound dictionary
"""
return {'key1': 'value1', 'deep_dict': {'key2': 'value2'}}
In collection-library-tests.robot
*** Settings ***
Documentation A test suite utilizing all collection library keywords
Library Collections
Library Utils.py
# To run:
# robot --pythonpath Resources --noncritical failure-expected -d Results/ Tests/collection-
library-tests.robot
*** Test Cases ***
Use "Copy Dictionary" : Shallow Copy
${compound_python_dictionary} = get compound dictionary
&{shallow_copy} = Copy Dictionary ${compound_python_dictionary} deepcopy=False
# if we modify the contained objects (i.e. deep_dict) through the shallow_copy,
# the original compound_python_dictionary will see the changes in the contained objects
Set To Dictionary ${shallow_copy}[deep_dict] key2=modified
Log ${shallow_copy}
Log ${compound_python_dictionary}
Should Be Equal ${compound_python_dictionary}[deep_dict][key2] modified # fails, why?
The goal is stated in the test case as:
if we modify the contained objects (i.e. deep_dict) through the shallow_copy,
the original compound_python_dictionary will see the changes in the contained objects
Expected Result
Should Be Equal ${compound_python_dictionary}[deep_dict][key2] modified # passes
Observed Result
Note that I am using Robot FW version: Robot Framework 3.1.2 (Python
3.7.4 on linux)
Acc.to the documentation about Copy Dictionary:
The deepcopy argument controls should the returned dictionary be a
shallow or deep copy. By default returns a shallow copy, but that can be
changed by giving deepcopy a true value (see Boolean arguments). This > is a new option in Robot Framework 3.1.2. Earlier versions always
returned shallow copies.
Acc.to the documentation about Boolean Arguments:
Some keywords accept arguments that are handled as Boolean values true or false. If such an argument is given as a string, it is considered false if it is an empty string or equal to FALSE, NONE, NO, OFF or 0, case-insensitively. Other strings are considered true regardless their value.
Note also that i tried also deepcopy=${False}, which yielded the same observed result.
The problem is not with the RF keyword (it very seldom is, they have extensive UT), but with the way you call it, namely this argument:
deepcopy=False
You may be thinking you are passing a boolean value, but in fact you are passing the string "False".
Inside the keyword's implementation there is this branching:
if deepcopy:
return copy.deepcopy(dictionary)
, and as a non-empty string evaluates to True, you are in fact getting a deep copy.
This is the way to pass a real False:
deepcopy=${False}

robotframework - get all the variables/arguments passed to an execution

Is there a way to access all the variables/arguments passed through the command line or variable file (-V option) during robotframework execution. I know in python the execution can access it with 'sys.args' feature.
The answer for getting the CLI arguments is inside your question - just look at the content of the sys.argv, you'll see everything that was passed to the executor:
${args}= Evaluate sys.argv sys
Log To Console ${args}
That'll return a list, where the executable itself (run.py) is the 1st member, and all arguments and their values present the in the order given during the execution:
['C:/my_directories/rf-venv/Lib/site-packages/robot/run.py', '--outputdir', 'logs', '--variable', 'USE_BROWSERSTACK:true', '--variable', 'IS_DEV_ENVIRONMENT:false', '--include', 'worky', 'suites\\test_file.robot']
You explicitly mention variable files; that one is a little bit trickier - the framework parses the files itself, and creates the variables according to its rules. You naturally can see them in the CLI args up there, and the other possibility is to use the built-in keyword Get Variables, which "Returns a dictionary containing all variables in the current scope." (quote from its documentation). Have in mind though that these are all variables - not only the passed on the command line, but also the ones defined in the suite/imported keywords etc.
You have Log Variables to see their names and values "at current scope".
There is no possibility to see the arguments passed to robot.

LLVM converting a Constant to a Value

I am using custom LLVM pass where if I encounter a store to
where the compiler converts the value to a Constant; e.g. there is an explicit store:
X[gidx] = 10;
Then LLVM will generate this error:
aoc: ../../../Instructions.cpp:1056: void llvm::StoreInst::AssertOK(): Assertion `getOperand(0)->getType() == cast<PointerType>(getOperand(1)->getType())->getElementType() && "Ptr must be a pointer to Val type!"' failed.
The inheritance order goes as: Value<-User<-Constant, so this shouldn't be an issue, but it is. Using an a cast on the ConstantInt or ConstantFP has no effect on this error.
So I've tried this bloated solution:
Value *new_value;
if(isa<ConstantInt>(old_value) || isa<ConstantFP>(old_value)){
Instruction *allocInst = builder.CreateAlloca(old_value->getType());
builder.CreateStore(old_value, allocInst);
new_value = builder.CreateLoad(allocResultInst);
}
However this solution creates its own register errors when different type are involved, so I'd like to avoid it.
Does anyone know how to convert a Constant to a Value? It must be a simple issue that I'm not seeing. I'm developing on Ubuntu 12.04, LLVM 3, AMD gpu, OpenCL kernels.
Thanks ahead of time.
EDIT:
The original code that produces the first error listed is simply:
builder.CreateStore(old_value, store_addr);
EDIT2:
This old_value is declared as
Value *old_value = current_instruction->getOperand(0);
So I'm grabbing the value to be stored, in this case "10" from the first code line.
You didn't provide the code that caused this first assertion, but its wording is pretty clear: you are trying to create a store where the value operand and the pointer operand do not agree on their types. It would be useful for the question if you'd provide the code that generated that error.
Your second, so-called "bloated" solution, is the correct way to store old_value into the stack and then load it again. You write:
However this solution creates its own register errors when different type are involved
These "register errors" are the real issue you should be addressing.
In any case, the whole premise of "converting a constant to a value" is flawed - as you have correctly observed, all constants are values. There's no point storing a value into the stack with the sole purpose of loading it again, and indeed the standard LLVM pass "mem2reg" will completely remove such a sequence, replacing all uses of the load with the original value.

Clear the file stat cache in R?

In a RUnit test I have this snippet:
checkTrue(!file.exists(fname))
doSomething()
#cat(fname);print(file.info(fname))
checkTrue(file.exists(fname))
The second call to checkTrue() is failing, even though doSomething() creates a file. I've confirmed the file is there with the commented out line, shown above.
So, I'm wondering if the second call to file.exists is using cached data? In PHP there is a function called clearstatcache that stops this happening. Is there an R equivalent? (Or, perhaps, someone knows that R never caches results of stat calls?)
file.exists does not cache the result of the stat call, so there is no equivalent of PHP's clearstatcache. (Aside: that also means excessive use of calling file.exists, or any stat function, might degrade performance.)
As of R 3.0.1, file.exists uses an internal method. If you follow it through the source you will eventually end up with a call to R_FileExists, in sysutils.c:
Rboolean R_FileExists(const char *path)
{
struct stat sb;
return stat(R_ExpandFileName(path), &sb) == 0;
}
(On Windows it instead uses a call to _stat64 which I've just confirmed also does not do caching.)

Passing arguments to execl

I want to create my own pipeline like in Unix terminal (just to practice). It should take applications to execute in quotes like that:
pipeline "ls -l" "grep" ....
I know that I should use fork(), execl() (exec*) and API to redirect stdin and stdout. But are there any alternatives for execl to execute app with arguments using just one argument which includes application path and arguments? Is there a way not to parse manually ls -l but pass it as one argument to execl?
If you have only a single command line instead of an argument vector, let the shell do the parsing for you:
execl("/bin/sh", "sh", "-c", the_command_line, NULL);
Of course, don't let untrusted remote user input into this command line. But if you are dealing with untrusted remote user input to begin with, you should try to arrange to pass actual a list of isolated arguments to the target application as per normal usage of exec[vl], not a command line.
Realistically, you can only really use execl() when the number of arguments to the command are known at compile time. In a shell, you'll normally use execv() or execvp() instead; these can handle an arbitrary number of arguments to the command to be executed. In theory, you use execv() when the path name of the command is given and execvp() (which does a PATH-based search for the command) when it isn't. However, execvp() handles the 'path given' case, so simply use execvp().
So, for your pipeline command, you'll end up with one child using something equivalent to:
char *args_1[] = { "ls", "-l", 0 };
execvp(args_1[0], args_1);
The other child will end up using something equivalent to:
char *args_2[] = { "grep", "pattern", 0 };
execvp(args_2[0], args_2);
Except, of course, that you'll have created those strings from the command line arguments instead of by initialization as shown. Note that grep requires a pattern to search for.
You've still got plumbing issues to resolve. Make sure you close enough pipe file descriptors. When you dup() or dup2() a pipe to standard input or standard output, you close both the file descriptors from the pipe() function.

Resources