This was the code giving me errors on Perl.
...
else if (exists($framename{$presFrame}) && (($framename{$presFrame}) < = $j))
...
here framename is a hash and presFrame is a key present in framename
Edit:
Realized if/ else syntax is a bit different in Perl as mentioned in correct answer.
I think you mean:
elsif (exists($framename{$presFrame}) && (($framename{$presFrame}) <= $j))
otherwise you'd need braces on the else clause, i.e.
else {
if(...) {
...
}
}
else if (exists($framename{$presFrame}) && (($framename{$presFrame}) < = $j))
Should be:
elsif (exists($framename{$presFrame}) && ($framename{$presFrame} < = $j))
Related
Suppose I have a complex chain of ifs. Now I want to be sure that one of the conditions are triggered, so I add the final line to notify me when nothing was triggered.
if condition1 ...
else if condition2 ...
else if condition3 ...
else print( "Ooops nothing triggered" )
Since I only want to print this in DEBUG mode, I wrap the final line
#if DEBUG
else print( "Ooops nothing triggered" )
#endif
and I get the strangest errors. "Closure expression is unused" and "Expected expression".
Here is some simple working code to illustrate with.
let x = Int ( arc4random_uniform ( 100 ) ) - 50
// This works
if x > 0 { print ( "Positive" ) }
else if x < 0 { print ( "Negative" ) }
else { print ( "Oops - neither" ) }
// After adding the #if this does not compile
if x > 0 { print ( "Positive" ) }
else if x < 0 { print ( "Negative" ) }
#if DEBUG
else { print ( "Oops - neither" ) }
#endif
Obviously Swift's conditional compilation here fails. I wonder why and ask how to to do this so that the test is only applied in DEBUG mode?
FWIW I am not interested in e.g. using switch - the actual logic is complex. How to do this with ifs and else ifs if possible please?
These #ifs don't really work like those preprocessor directives in C. They
According to the grammar, the syntax of these directives are the following:
if-directive-clause → if-directive compilation-condition statements(opt)
elseif-directive-clauses → elseif-directive-clause elseif-directive-clauses(opt)
elseif-directive-clause → elseif-directive compilation-condition statements(opt)
else-directive-clause → else-directive statements(opt)
if-directive → #if
elseif-directive → #elseif
else-directive → #else
endif-directive → #endif
Note that an if-directive-clause consists of #if, then a compilation-condition, then some statements. Not just anything, but statements.
else { print ( "Oops - neither" ) }
is not a statement (or a list of statements).
How about putting the #if inside the else block? That is guaranteed to be a statements:
if x > 0 { print ( "Positive" ) }
else if x < 0 { print ( "Negative" ) }
else {
#if DEBUG
print ( "Oops - neither" )
#endif
}
I'm trying to write an test function for mbedtls which randomly generates a key for AES encryption.
I use the original tutorial Code from mbedtls.
My Programm always stops when executing "mbedtls_ctr_drbg_seed()".
About my environmet: Basic Sourcefiles from STM_CUBEmx, Board: ST32F767 Nucleo, Compiling based on Makefile from STM_Cube
mbedtls_ctr_drbg_context ctr_drbg;
mbedtls_entropy_context entropy;
char *pers="anything";
int ret;
//Start
mbedtls_entropy_init(&entropy);
debugPrintln("Init entropy done");
mbedtls_ctr_drbg_init(&ctr_drbg);
debugPrintln("Init ctr_drbg done");
if((ret=mbedtls_ctr_drbg_seed(&ctr_drbg,mbedtls_entropy_func,&entropy,(unsigned char *) pers,strlen(pers)))!=0){
//Error info
debugPrintln("ERROR ctr_drbg_seed ");
return -1;
}
debugPrintln("Init ctr_drbg_seed done");
if((ret=mbedtls_ctr_drbg_random(&ctr_drbg,key,32))!=0){
return -1;
}
Thank you in advance
From your description,
I am assuming that your application is stuck in the call to mbedtls_ctr_drbg_seed().
Most probable reason, IMHO, is in the functionmbedtls_entropy_func():
do
{
if( count++ > ENTROPY_MAX_LOOP )
{
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
goto exit;
}
if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
goto exit;
done = 1;
for( i = 0; i < ctx->source_count; i++ )
if( ctx->source[i].size < ctx->source[i].threshold )
done = 0;
}
while( ! done );
You should check that your entropy collection increases the collected size, that the threshold is not MAX_INT or something of the sort, and that your hw entropy collector actually returns entropy data.
I have found the reason
STM32 Cube MX places the HAL Init function for the RNG after the mbedtls init
So when I call mbedtls_ctr_drbg_seed() inside mbedtls_init() the RNG hasn't yet been initialized and it iterates forever inside:
do
{
if( count++ > ENTROPY_MAX_LOOP )
{
ret = MBEDTLS_ERR_ENTROPY_SOURCE_FAILED;
goto exit;
}
if( ( ret = entropy_gather_internal( ctx ) ) != 0 )
goto exit;
done = 1;
for( i = 0; i < ctx->source_count; i++ )
if( ctx->source[i].size < ctx->source[i].threshold )
done = 0;
}
while( ! done );
Solution
swap the lines
It is possible to use a string as an operator?
my $ip = "10 > 0.2 && 5 < 1";
if($ip)
{
print "Hello\n\n";
}
else
{
print "wrong\n";
}
How to consider the string > && < as an operator?
A non-empty string will always evaluate to true if you use it like this. What you want to do is to evaluate the content of the string as code, and perl provides the eval-statement for exactly this purpose:
my $ip = "10 > 0.2 && 5 < 1";
if( eval($ip) )
{
print "Hello \n\n";
}
else
{
print "wrong\n";
}
This will give the expected output "wrong".
This works,
print map { $_." x" => $_ } 1..5;
print map { ("$_ x" => $_) } 1..5;
print map { ("$_ x") => $_ } 1..5;
but this throws syntax error,
print map { "$_ x" => $_ } 1..5;
Is this documented bug, undocumented bug, or I can't see why this should not compile?
Why perl thinks this should be map EXPR, LIST instead of map BLOCK LIST
From perlref
Because curly brackets (braces) are used for several other things including BLOCKs, you may occasionally have to disambiguate braces at the beginning of a statement by putting a + or a return in front so that Perl realizes the opening brace isn't starting a BLOCK. The economy and mnemonic value of using curlies is deemed worth this occasional extra hassle.
To make your intentions clearer and to help the parser,
Say +{...} to unambiguously specify a hash reference
#list_of_hashrefs = map +{ "$_ x" => $_ }, 1..5;
Say {; ...} to unambiguously specify a code block
%mappings = map {; "$_ x" => $_ } 1..5;
Why perl thinks this should be map EXPR, LIST instead of map BLOCK LIST?
The relevant section of code is in toke.c, Perl's lexer (the below is from Perl 5.22.0):
/* This hack serves to disambiguate a pair of curlies
* as being a block or an anon hash. Normally, expectation
* determines that, but in cases where we're not in a
* position to expect anything in particular (like inside
* eval"") we have to resolve the ambiguity. This code
* covers the case where the first term in the curlies is a
* quoted string. Most other cases need to be explicitly
* disambiguated by prepending a "+" before the opening
* curly in order to force resolution as an anon hash.
*
* XXX should probably propagate the outer expectation
* into eval"" to rely less on this hack, but that could
* potentially break current behavior of eval"".
* GSAR 97-07-21
*/
t = s;
if (*s == '\'' || *s == '"' || *s == '`') {
/* common case: get past first string, handling escapes */
for (t++; t < PL_bufend && *t != *s;)
if (*t++ == '\\')
t++;
t++;
}
else if (*s == 'q') {
if (++t < PL_bufend
&& (!isWORDCHAR(*t)
|| ((*t == 'q' || *t == 'x') && ++t < PL_bufend
&& !isWORDCHAR(*t))))
{
/* skip q//-like construct */
const char *tmps;
char open, close, term;
I32 brackets = 1;
while (t < PL_bufend && isSPACE(*t))
t++;
/* check for q => */
if (t+1 < PL_bufend && t[0] == '=' && t[1] == '>') {
OPERATOR(HASHBRACK);
}
term = *t;
open = term;
if (term && (tmps = strchr("([{< )]}> )]}>",term)))
term = tmps[5];
close = term;
if (open == close)
for (t++; t < PL_bufend; t++) {
if (*t == '\\' && t+1 < PL_bufend && open != '\\')
t++;
else if (*t == open)
break;
}
else {
for (t++; t < PL_bufend; t++) {
if (*t == '\\' && t+1 < PL_bufend)
t++;
else if (*t == close && --brackets <= 0)
break;
else if (*t == open)
brackets++;
}
}
t++;
}
else
/* skip plain q word */
while (t < PL_bufend && isWORDCHAR_lazy_if(t,UTF))
t += UTF8SKIP(t);
}
else if (isWORDCHAR_lazy_if(t,UTF)) {
t += UTF8SKIP(t);
while (t < PL_bufend && isWORDCHAR_lazy_if(t,UTF))
t += UTF8SKIP(t);
}
while (t < PL_bufend && isSPACE(*t))
t++;
/* if comma follows first term, call it an anon hash */
/* XXX it could be a comma expression with loop modifiers */
if (t < PL_bufend && ((*t == ',' && (*s == 'q' || !isLOWER(*s)))
|| (*t == '=' && t[1] == '>')))
OPERATOR(HASHBRACK);
if (PL_expect == XREF)
{
block_expectation:
/* If there is an opening brace or 'sub:', treat it
as a term to make ${{...}}{k} and &{sub:attr...}
dwim. Otherwise, treat it as a statement, so
map {no strict; ...} works.
*/
s = skipspace(s);
if (*s == '{') {
PL_expect = XTERM;
break;
}
if (strnEQ(s, "sub", 3)) {
d = s + 3;
d = skipspace(d);
if (*d == ':') {
PL_expect = XTERM;
break;
}
}
PL_expect = XSTATE;
}
else {
PL_lex_brackstack[PL_lex_brackets-1] = XSTATE;
PL_expect = XSTATE;
}
Explanation
If the first term after the opening curly is a string (delimited by ', ", or `) or a bareword beginning with a capital letter, and the following term is , or =>, the curly is treated as the beginning of an anonymous hash (that's what OPERATOR(HASHBRACK); means).
The other cases are a little harder for me to understand. I ran the following program through gdb:
{ (x => 1) }
and ended up in the final else block:
else {
PL_lex_brackstack[PL_lex_brackets-1] = XSTATE;
PL_expect = XSTATE;
}
Suffice it to say, the execution path is clearly different; it ends up being parsed as a block.
I'm trying to write a condition for a nested if statement, but haven't found a good example of using or in if statements. The following elsif condition fails and allows the code nested beneath it to fire if $status == 6:
if ($dt1 > $dt2 ) {do one thing}
elsif(($status != 3) || ($status != 6)) { do something else}
else {do something completely different}
I'd like to avoid having another elsif for each condition as the code that actually resides here is several lines long.
Your logic is wrong and your elseif block will always return true. I think you mean to use an AND instead of an OR. Given the following snippet
foreach $status (1 .. 10) {
if (($status != 3) && ($status != 6)) {
print "$status => if\n";
} else {
print "$status => else\n";
}
}
This will output
1 => if
2 => if
3 => else
4 => if
5 => if
6 => else
7 => if
8 => if
9 => if
10 => if
If it helps your thinking, a conditional that is !something || !somethingElse can always be rewritten as !(something && somethingElse). If you apply this to your case above you'd say !(3 && 6), and seeing as a number cannot be 3 and 6 at the same time, it's always false
You said you're asking this because the code is several lines long. Fix that problem. :)
if( $dt1 > $dt2 ) { do_this_thing() }
elsif( ($status != 3) || ($status != 6) ) { do_this_other_thing() }
else { do_something_completely_different() }
Now you don't have several lines in the block and everything is next to each other. You have to figure out what those conditions will be because any value is either not 3 or not 6. :)
Perhaps you meant to use and:
if( $dt1 > $dt2 ) { do_this_thing() }
elsif( $status != 3 and $status != 6 ) { do_this_other_thing() }
else { do_something_completely_different() }
Putting print statements with var names/values into each branch can be helpful.
You could see that the elsif branch is always run, because $status != 3 || $status != 6 is true for any value of $status.