I am having following code for uvm_re_match:
int temp_int = 20;
temp_int = uvm_re_match(uvm_glob_to_re("abc"), "top.mydut_abc_comp_inst");
$display("\t uvm_re_match USAGE: The result - temp_int = %0d \n",temp_int);
I am getting temp_int = 1, indicating "abc" not found in the string provided.
Any suggestions on uvm_re_match and uvm_glob_to_re usage.
First of all, you have to make sure that you are using UVM together with its DPI code, i.e. the UVM_NO_DPI isn't defined. It's easy to check this by printing the result of uvm_glob_to_re("abc"). If the result is still "abc", then you're using the SystemVerilog version of the function (which just returns the argument) and not the DPI-C implementation. See dpi/uvm_regex.svh for the code.
Assuming you're using the DPI functions, you're making a mistake with your glob expression. A glob expression of "abc" isn't supposed to match your string. You need to use "*abc*" (glob) to match it. You can see that this wouldn't work by looking at the regex versions of the two expressions:
module top;
import uvm_pkg::*;
initial begin
static string re1 = uvm_glob_to_re("abc");
static string re2 = uvm_glob_to_re("*abc*");
$display(re1);
$display(re2);
end
endmodule
You'll see that re1 contains "/^abc$/" which can only ever match "abc". re2 contains /^.*abc.*$/, which matches any "abc" sub-string in a string. You can just ignore the / characters at the beginning and the end as these will get stripped away (not sure why they're there).
If you try to match the two expressions you'll see that the first one doesn't match, whereas the second one does:
if (!uvm_re_match(re1, "top.mydut_abc_comp_inst"))
$display("matches re1");
if (!uvm_re_match(re2, "top.mydut_abc_comp_inst"))
$display("matches re2");
Bonus: another regular expression that would match your string is "abc", which you can see also works with uvm_re_match(...):
if (!uvm_re_match("abc", "top.mydut_abc_comp_inst"))
$display("matches re3");
Related
I want to know how to transform the results of an iterator into an array. I have presented two options below, and both run, but yield the result in the wrong format.
This is the result I am getting vs what is expected.
enter image description here
I am trying to transform the iterator results into an array with Array(), but it does not work.
I tried:
Block code with .keep_if methods
for if conditionals with Array() to make the transformation.
What I expect:
An array of non-negative integers. The input (l) is an array of random integers and strings.
My code options are as follows:
Option 1:
def filter_list(l)
l.delete_if {|li| li.class ==String || li<0}
puts l
end
Option 2:
def filter_list(l)
arr=[]
for i in l
if i.class == Integer && i>=0
arr1=arr.push(i)
end
end
puts Array(arr1)
end
Why don't the above options work?
Why don't the above options work?
You have a syntax error here:
Def filter_list(l)
↑
Method definitions use the def keyword with a lower-case d. What you have written here will be interpreted as a method call to a method named Def, passing filter_list(l) as an argument, i.e. that code will be interpreted as
self.Def(filter_list(l))
Which then means that Ruby is not expecting to see an end keyword.
To output the result in the expected format just use p instead of puts.
From the docs of puts
[...] If called with an array argument, writes each element on a new line. Each given object that isn't a string or array will be converted by calling its to_s method. [...]
Whereas the p method doesn't call to_s but inspect before printing the output:
For each object, directly writes obj.inspect followed by a newline to the program's standard output.
The default string representation, returned by inspect for an array, looks like your expected output.
So, I'm coding in Ada for the first time and have to create this pre-populated array of strings, so I can use a random method and call a different value each time.
poolOfWords: constant array(1..50) of string := ("gum","sin","for","cry","lug","bye","fly",
"ugly", "each","from","work","talk","with","self", "pizza","thing","feign","friend",
"elbow","fault", "dirty","budget","spirit","quaint","maiden","escort","pickax",
"example","tension","quinine","kidney","replica","sleeper", "triangle","kangaroo",
"mahogany","sergeant","sequence","moustache","dangerous","scientist",
"different","quiescent", "magistrate","erroneously","loudspeaker",
"phytotoxic","matrimonial","parasympathomimetic","thigmotropism");
But when I try to compile I get this error: "unconstrained element type in array declaration".
I Googled all over internet and couldn't find a solution to that. I even tried to use unbounded_string, but didn't work as well. It works fine when I pre-populate an array of integers, floats, but when it come to strings it's not working.
Can someone help me and explain what's going on and how to solve it? I really don't want to declare the array and then populate each of the 50 indexes one by one.
Your problem stems from the fact that String in Ada is an unconstrained type. This means, roughly, that you need to specify "something" in order to have a usable type. In the case of String you need to specify the string length, since a String is just an array of Character. If you say something like
X : String;
the compiler complains since it does not know the length of X and it does not know how much memory to reserve for X. You need to say something like
X : String(1..6);
or something like
X : String := "foobar";
Note that in the second case you do not need to specify the index range since the compiler is able to deduce it from the fact that you use a 6-Character string to initialize X.
This explains why it is illegal to declare an array of just String. When you declare an array the compiler needs to know the size of every entry (all the entries must share the same size, this makes access to a random entry of the array very efficient). If you declare an array of just String, the compiler would not know how much memory to allocate to every entry since the length is unspecified.
Note that this instead would work (disclaimer: I have not an Ada compiler at hand now, so I cannot check the code)
subtype ZIP_Code is String (1..5);
type ZIP_Code_Array is array(Positive range <>) of ZIP_Code;
since now the compiler knows the size of every entry of a ZIP_Code_Array (5 Character).
In your case, however, the strings have all different sizes. I can see two possible solutions
If the maximum length is known in advance you can use the subtype approach shown above and pad the strings with spaces. It depends on your context if this is a suitable solution or not
The approach that I typically use is to create an array of Unconstrained_String that I initialize as follows
function "+"(X: String) return Unbounded_String
renames To_Unbounded_String;
poolOfWords: constant array(1..50) of Unbounded_String :=
(+"gum",
+"sin",
+"for",
-- and so on...
);
Note the renames that defines the unary + as an alias for To_Unbounded_String. This is just syntactic sugar that allows you to write +"gum" instead of To_Unbounded_String("gum"). Someone cringes at this type of syntactic sugar (and I am not so keen either), but in this case I think it is worth since it makes the code "lighter." It would be nice to have the definition of unary + near its use, just for clarity.
An alternative to the use of Unbounded_String is to use the generic package Bounded_Strings and define poolOfWords as an array of Bounded_String. A Bounded_String can hold strings with variable length, as long as the length is smaller than the bound specified when instantiating the Bounded_Strings package. In order to convert back and forth String you can use the same "rename trick."
My personal preference goes to the Unbounded_String, unless I have some special reason that forces me to use the Bounded_String.
Another option is to use Ada's standard containers. For example:
Package String_Holder is new Ada.Containers.Indefinite_Holders(
"=" => Ada.Strings.Equal_Case_Insensitive,
Element_Type => String
);
Function "+"( Right : String_Holder.Holder ) return String
renames String_Holder.Element;
Function "+"( Right : String ) return String_Holder.Holder
renames String_Holder.To_Holder;
Allows you to store in the holder varying sized values of type String, so you could forego any dependence on Ada.Strings.Unbounded_String and use something like:
poolOfWords: constant array(Positive range <>) of String_Holder.Holder :=
+"gum", +"sin", +"for", +"cry", -- ...
+"Stuff"
);
Function Get_Word(Index : Positive) return String is
(+poolOfWords(Index)) with Pre => Index in poolOfWords'Range;
Alternatively, you could use Ada.Containers.Indefinite_Vectors like so:
Package String_Vector is new Ada.Containers.Indefinite_Vectors(
"=" => Ada.Strings.Equal_Case_Insensitive,
Index_Type => Positive,
Element_Type => String
);
though there is one problem with this in Ada 2012: You can't initialize such a vector directly within the declaration, but can initialize it via function-call:
Function Populate return String_Vector.Vector is
Begin
Return Result : String_Vector.Vector do
Result.Append( "some" );
Result.Append( "data" );
Result.Append( "HERE" );
End Return;
End Populate;
Being able to say X : String_Vectors.Vector := ("this", "that", "the other") is in Ada 2020 .
I am capturing a string as my Left Boundary (LB) and then dividing that LB into 3 parts with strcpy and putting the value in char MyString. When I play my script, the correlation is not getting captured.
char MyString is capturing the value correctly, as when I'm printing it with lr_output_message it is showing me the correct LB as is from the server response values.
This is exactly what I'm doing...
char MyString[9999];
// original LB value is LB=DesktopQueuedActivitiesLV:0:CreateDate\" label=\"Create Date\" value=\"",
for (i = 0 ; i < 1 ; i++) {
lr_save_int(i,"MyRow");
strcpy(MyString, "DesktopQueuedActivitiesLV:");
strcat(MyString, lr_eval_string("{MyRow}"));
strcat(MyString, ":CreateDate\\\" label=\\\"Create Date\\\" value=\\\"");
lr_output_message("MyString = %s",MyString);
web_reg_save_param("DateReceived",
lr_eval_string("LB={MyString}"),
"RB=\">",
"Ord=1",
LAST);
}
Upon replay can't find the value for DateReceived
If I replace the line lr_eval_string("LB={MyString}") with the actual LB value, then it is working. Also, the lr_output_message("MyString = %s",MyString); is printing the exact same original LB value.
Can't figure it out why MyString is capturing the correct value but can't replace during actual line when playing the web_reg_save_param("DateReceived",. Please help.
You are using a loadrunner parameter designation for a C parameter inside of a loop. Both the loadrunner parameter reference is odd here, as is a re-running of the same correlation statement multiple times, as only the last one would have an affect when executed.
lr_output_message("MyString = %s",MyString);
web_reg_save_param("DateReceived",
lr_eval_string("LB={MyString}"),
Notice, the lr_output_message() is treating MyString as a C variable, but the second parameter of the web_reg_save_param() is treating the same element as a LoadRunner parameter. You either need to convert the C string to a LoadRunner parameter, recommend a different name, such as LR_MyString to differentiate the C string from the LR Parameter or create a C parameter which is in the form of "LB=myleftboundary"
lr_output_message("MyString = %s",MyString);
lr_save_string(MyString, "LR_MyString");
web_reg_save_param("DateReceived",
lr_eval_string("LB={LR_MyString}"),
OR
strcpy(MyString, "LB=DesktopQueuedActivitiesLV:");
strcat(MyString, lr_eval_string("{MyRow}"));
strcat(MyString, ":CreateDate\\\" label=\\\"Create Date\\\" value=\\\"");
lr_output_message("MyString = %s",MyString);
web_reg_save_param("DateReceived",
MyString,
You appear to be on the path of creating a psuedo array with DateReceived due to the loop which is executing once in this test, but you are probably wanting to increase the number of loop entries. In this case you are likely to fail for any number of array elements greater than 1 as you will always have the last time executed as the fulfilled correlation.
I have got array of strings like:
string [] foo = ["zxc", "asd", "qwe"];
I need to create string from them. Like:
"zxc", "asd", "qwe" (yes every elements need be quoted and separate with comma from another, but it should be string, but not array of strings.
How can I do it's in functional style?
import std.algorithm, std.array, std.string;
string[] foo = ["zxc", "asd", "qwe"];
string str = foo.map!(a => format(`"%s"`, a)).join(", ");
assert(str == `"zxc", "asd", "qwe"`);
std.algorithm.map takes a lambda which converts an element in the range into something else, and it returns a lazy range where each element is the result of passing an element from the original range to the lambda function. In this case, the lambda takes the input string and creates a new string which has quotes around it, so the result of passing foo to it is a range of strings which have quotes around them.
std.array.join then takes a range and eagerly concatenates each of its elements with the given separator separating each one and returns a new array, and since it's given a range of strings it returns a string. So, by giving it the result of the call to map and ", " for the separator, you get your string made up of the original strings quoted and separated by commas.
std.algorithm.joiner would do the same thing as join, except that it results in a lazy range instead of an array.
Alternatively, use std.string.format
Your format specifier should be something like this:
auto joinedstring = format("%(\“%s\",%)", stringarray)
this is untested as I'm on mobile, but it's something similar to it!
Is it fine to display the output of Array.toString() to the user, or is there a possibility that the string format could change in future versions of ActionScript 3 or other compilers?
Here's an excerpt describing Array.toString from ECMA-262, which ActionScript 3 follows very closely:
15.4.4.2
Array.prototype.toString ( ) When the toString method is called, the following steps are taken:
1. Let array be the result of calling ToObject on the this value.
2. Let func be the result of calling the [[Get]] internal method of array with argument "join".
3. If IsCallable(func) is false, then let func be the standard built-in method Object.prototype.toString (15.2.4.2).
4. Return the result of calling the [[Call]] internal method of func providing array as the this value and an empty arguments list.
And Array.join:
15.4.4.5
Array.prototype.join (separator) The elements of the array are converted to Strings, and these Strings are then concatenated, separated by occurrences of the separator. If no separator is provided, a single comma is used as the separator. The join method takes one argument, separator, and performs the following steps:
1. Let O be the result of calling ToObject passing the this value as the argument.
2. Let lenVal be the result of calling the [[Get]] internal method of O with argument "length".
3. Let len be ToUint32(lenVal).
4. If separator is undefined, let separator be the single-character String ",".
5. Let sep be ToString(separator).
6. If len is zero, return the empty String.
7. Let element0 be the result of calling the [[Get]] internal method of O with argument "0".
8. If element0 is undefined or null, let R be the empty String; otherwise, Let R be ToString(element0).
9. Let k be 1.
10. Repeat, while k < len
a. Let S be the String value produced by concatenating R and sep.
b. Let element be the result of calling the [[Get]] internal method of O with argument ToString(k).
c. If element is undefined or null, Let next be the empty String; otherwise, let next be ToString(element).
d. Let R be a String value produced by concatenating S and next.
e. Increase k by 1.
11. Return R.
So, the default behavior is very well defined, and won't change.
It is safe to use it as it is. Array.toString() has been the same since AS3 came out.
Return value of Array.toString() is by now equal to that of Array.join().
If you are that concerned about this behaviour not changing, use Array.join() (or, to be completely pedantic, Array.join(',')) explicitly, and you'll be safe. Joining array works this way since ActionScript exists and it's absolutely unlikely that Adobe will change something to it and loose backwards compatibility (and, well, sanity).