Parasoft / Misra C++ 2008 : Expression of 'signed' type should not be cast to 'unsigned' type - type-conversion

I am coding in C++14. The company requires all code to pass Parasoft / Misra C++ 2008 checks.
I receive a string which ends in a digit from 1 to N and I need to convert it to uint8_t and subtract 1 to use it as an array index.
// NumberString is guaranteed to contain a single digit as a std::string
const uint8_t Number = static_cast<uint8_t>(std::stoi(NumberString) - 1);
causes Parasoft to report
Expression of 'signed' type should not be cast to 'unsigned' type
I have tried many ways to rewrite it, but to no avail. How can I get rid of that Parasoft message?
I am at my wit's end and even considering stuffing an extra (unused) element zer0 at the front of that array. Surely there must be a way to avoid that?

Related

Compare integer with string in NSPredicate

I have in project array of workout programs (code for them are on Objective-C) and in every program I have #property (nullable, nonatomic, copy) NSString *scheduleStr; for program durations. This property stores values such as 1 week, 2 weeks, 3 weeks and etc. I need to filter all values bigger than 6 weeks. I'm trying to apply NSPredicate:
predicates.append(NSPredicate(format: "scheduleStr.integerValue >= 6"))
and after this I'm receiving only programs with length 6-9 weeks, but nothing more than 10 weeks, but for sure I have several programs in database with length equal 12 weeks.
If I'm trying to apply something like this:
predicates.append(NSPredicate(format: "scheduleStr.integerValue >= 10"))
I will receive almost all the programs. How to get all programs with more than selected values?
The problem is that, although you specify integerValue, when using the predicate as part of a fetch, CoreData treats your string as a string. In string terms, 10 weeks is "less than" 6 weeks, so it's excluded from the results.
You should store the number (as an Int) instead of storing the string. Adding the text " weeks" is then something you do for display purposes. If you store the number, rather than the string, then CoreData can do a numerical comparison and your predicate will work as you expect.
If you really don't want to do that, there is one workaround, and one hack. The workaround is to filter the objects in memory rather than as part of a fetch. The integerValue will then be correctly interpreted and the comparison will be numerical.
The hack is to force CoreData to treat your string as though it is a number, by using a numeric function, like abs (assuming you only have a positive number of weeks, taking the absolute value leaves the value unchanged):
predicates.append(NSPredicate(format: "abs:(scheduleStr) >= 6"))
To get the integer part in the string in your case you can look into something like:
Suppose element is your string then
let component = element.components(separatedBy: .letters) // this will give you the non letter values
let integerValues = component.filter({ $0 != "" })
print(integerValues[0]) // As first value in your input string is an integer
This will give you the integer part of the string which can be used to filter the array.

Function which takes a string as parameter

In kdb I would like to have a function which takes a string as a parameter.
myfunc: {[strParam]
....
}
However when I tried to invoke the function.
q) myfunc["test"]
It complains of length error. It seems that function sees "test" as passing 4 char parameters. How can I make the function expect a string?
A string in kdb is defined as a list of characters and so functions using them have to be able to deal with this.
q)count "test"
4
You can also use a symbol instead casting from a string using `symbol$"test". A symbol is atomic and fixed width so can be useful to use as keys to a dictionary or in a table. Some functions for strings will still work on symbols e.g
q)upper `test
`TEST
while list operation will not work and you will have to turn it back into a string using string `test before using those operations.
When a length error is thrown and you go into the debug mode as shown by the q prompt having two brackets q)), you can use the functions .z.ex to show the failed function and .z.ey to see the failed arguments to narrow down which part is throwing the error.
The error can appear due to multiple reasons.
q)f:{[p] show p} //it works fine with any number of elements
q)f["abc"]
"abc"
f:{[p] enlist[`k]!p} //needs a list of single element
f["abc"]
'length
f[enlist "abc"]
(enlist `k)!enlist "abc"
q)f:{[p] 1 2 3 4!p} //the length of values is different from the length of keys
q)f["abc"]
'length
q)f["abcd"]
(1j, 2j, 3j, 4j)!"abcd"

Generate unique random strings

I am writing a very small URL shortener with Dancer. It uses the REST plugin to store a posted URL in a database with a six character string which is used by the user to access the shorted URL.
Now I am a bit unsure about my random string generation method.
sub generate_random_string{
my $length_of_randomstring = shift; # the length of
# the random string to generate
my #chars=('a'..'z','A'..'Z','0'..'9','_');
my $random_string;
for(1..$length_of_randomstring){
# rand #chars will generate a random
# number between 0 and scalar #chars
$random_string.=$chars[rand #chars];
}
# Start over if the string is already in the Database
generate_random_string(6) if database->quick_select('urls', { shortcut => $random_string });
return $random_string;
}
This generates a six char string and calls the function recursively if the generated string is already in the DB. I know there are 63^6 possible strings but this will take some time if the database gathers more entries. And maybe it will become a nearly infinite recursion, which I want to prevent.
Are there ways to generate unique random strings, which prevent recursion?
Thanks in advance
We don't really need to be hand-wavy about how many iterations (or recursions) of your function there will be. I believe at every invocation, the expected number of iterations is geomtrically distributed (i.e. number of trials before first success is governed by the geomtric distribution), which has mean 1/p, where p is the probability of successfully finding an unused string. I believe that p is just 1 - n/63^6, where n is the number of currently stored strings. Therefore, I think that you will need to have stored 30 billion strings (~63^6/2) in your database before your function recurses on average more than 2 times per call (p = .5).
Furthermore, the variance of the geomtric distribution is 1-p/p^2, so even at 30 billion entries, one standard deviation is just sqrt(2). Therefore I expect ~99% of the time that the loop will take fewerer than 2 + 2*sqrt(2) interations or ~ 5 iterations. In other words, I would just not worry too much about it.
From an academic stance this seems like an interesting program to work on. But if you're on the clock and just need random and distinct strings I'd go with the Data::GUID module.
use strict;
use warnings;
use Data::GUID qw( guid_string );
my $guid = guid_string();
Getting rid of recursion is easy; turn your recursive call into a do-while loop. For instance, split your function into two; the "main" one and a helper. The "main" one simply calls the helper and queries the database to ensure it's unique. Assuming generate_random_string2 is the helper, here's a skeleton:
do {
$string = generate_random_string2(6);
} while (database->quick_select(...));
As for limiting the number of iterations before getting a valid string, what about just saving the last generated string and always building your new string as a function of that?
For example, when you start off, you have no strings, so let's just say your string is 'a'. Then the next time you build a string, you get the last built string ('a') and apply a transformation on it, for instance incrementing the last character. This gives you 'b'. and so on. Eventually you get to the highest character you care for (say 'z') at which point you append an 'a' to get 'za', and repeat.
Now there is no database, just one persistent value that you use to generate the next value. Of course if you want truly random strings, you will have to make the algorithm more sophisticated, but the basic principle is the same:
Your current value is a function of the last stored value.
When you generate a new value, you store it.
Ensure your generation will produce a unique value (one that did not occur before).
I've got one more idea based on using MySQL.
create table string (
string_id int(10) not null auto_increment,
string varchar(6) not null default '',
primary key(string_id)
);
insert into string set string='';
update string
set string = lpad( hex( last_insert_id() ), 6, uuid() )
where string_id = last_insert_id();
select string from string
where string_id = last_insert_id();
This gives you an incremental hex value which is left padded with non-zero junk.

How to limit the number of times a rule can repeat in XTEXT?

My language has certain keywords which only accept values of certain length range (say, between 5 and 10 decimal numbers). This id correct:
KeyWord = 01234
This is incorrect:
KeyWord = 1234
I have a rule;
KeyWord:
'KeyWord' '=' INT+;
How to limit the number of times INT can repeat? This would so much easier if it was a more regexp-like syntax
I would implement this as a validation check instead of trying to fit this in the grammar itself. See http://www.eclipse.org/Xtext/documentation/2_1_0/050-validation.php
This will result in better error recovery and better error messages. It even allows quick-fixes.

Need to replace use of strcpy_s in C code used in iPhone project

I have a C SDK I need to use in an iPhone project, and the example code was written for use with Visual Studio. It includes use of strcpy_s, which is a Microsoft-only string function.
file_header.header_size = FIT_FILE_HDR_SIZE;
strcpy_s((FIT_UINT8 *)&file_header.data_type, sizeof(".FIT"), ".FIT"); << problem!
I've tried changing to strcpy and strncpy like so
strncpy((FIT_UINT8 *)&file_header.data_type, ".FIT", sizeof(".FIT"));
But I get this warning:
warning: pointer targets in passing argument 1 of 'builtin_strncpy_chk' differ in signedness
warning: pointer targets in passing argument 1 of '__inline_strncpy_chk' differ in signedness
warning: call to builtin_strncpy_chk will always overflow destination buffer
The struct file_header is this:
typedef struct
{
FIT_UINT8 header_size; // FIT_FILE_HDR_SIZE (size of this structure)
FIT_UINT8 protocol_version; // FIT_PROTOCOL_VERSION
FIT_UINT16 profile_version; // FIT_PROFILE_VERSION
FIT_UINT32 data_size; // Does not include file header or crc. Little endian format.
FIT_UINT8 data_type[4]; // ".FIT"
} FIT_FILE_HDR;
FIT_UINT8 is typedef Unsigned char.
So we can see that it is given an length of 4 in the typedef, and the strcpy_s takes the data_type by reference and copys ".FIT" to it. Where am I going wrong with strncpy? If you haven't guessed by now I'm not much of a C programmer :)
Edit: this does not give me an error, but it is correct?
strncpy((void *)&file_header.data_type, ".FIT", sizeof(file_header.data_type));
With any "safe string" operations, the size should almost always be the size of the destination buffer; if you use the size of the source string, you might as well call memcpy.
If you want C99 conformance:
strncpy(file_header.data_type, ".FIT", sizeof file_header.data_type);
However, strlcpy (a BSDism, available in iOS) is preferred by many, because it guarantees that the destination will be nul-terminated:
strlcpy(file_header.data_type, ".FIT", sizeof file_header.data_type);
Note, however that the nul-terminated string ".FIT" doesn't actually fit in the allotted space, as it requires 5 characters (1 for the trailing nul). If you use strlcpy, you will see that the resulting string is just ".FI" because strlcpy guarantees nul-termination, and truncates your string if necessary.
If you require nul-termination then, you probably want to increase the size of the data_type array to 5. As caf correctly points out, this looks like a file header, in which case nul-termination is probably not required; in that case strncpy is preferred; I might even use memcpy, and avoid giving a future developer the idea that the field is a string.
Don't use
sizeof(".FIT")
use
strlen(".FIT")