I'm trying to write this piece of code in the pch file :
#define someString
if(x == 5) {
if(y == 7) {
someString = #"Test1"
}
else {
someString = #"Test2"
}
}
else {
someString = #"TEST3"
}
but to no avail ..
anybody can help ?
p.s. i don’t want to write it with this notation: (x == 5) ? #“test1” : #“test3”
You can use the #if, #elif, and #else directives for this. Please see following sample code.
#define XVALUE 5
#define YVALUE 7
#if defined(XVALUE) && XVALUE == 5
#if defined(YVALUE) && YVALUE == 7
#define someString #"Test1"
#else
#define someString #"Test2"
#endif
#else
#define someString #"Test3"
#endif
You might want to make function which can replace some inline code resulting in a string value, as following:
#ifdef __OBJC__
static inline NSString* SomeStringInline(int xValue, int yValue)
{
if(xValue == 5)
{
if (yValue == 7) {
return #"Test1";
}
else
{
return #"Test2";
}
}
else
{
return #"Test3";
}
}
#endif
And you invoke this method from like
NSLog(#"%#", SomeStringInline(5, 7));
And output will be "Test1".
Use whatever suites you.
For more help on macros:
Conditional Compilation (#if, #ifdef, #ifndef, #else, #elif, #endif, and defined)
#if, #elif, #else, and #endif Directives
Related
I am trying to wrap the libcups library https://github.com/apple/cups to be used in my Swift project.
I have tried some of the examples in https://www.cups.org/doc/cupspm.html and they are working fine.
However I am struggling when it comes to wrapping the C code to be used in a Swift project.
I have been searching online on how to wrap C libraries in Swift but has not been able to have much progress.
Here is the C code
#include <stdio.h>
#include <cups/cups.h>
typedef struct {
int num_dests;
cups_dest_t *dests;
} my_user_data_t;
int my_dest_cb(my_user_data_t *user_data, unsigned flags, cups_dest_t *dest) {
if (flags & CUPS_DEST_FLAGS_REMOVED) {
user_data->num_dests = cupsRemoveDest(dest->name, dest->instance, user_data->num_dests, &(user_data->dests));
} else {
user_data->num_dests = cupsCopyDest(dest, user_data->num_dests, &(user_data->dests));
}
return 1;
}
int my_get_dests(cups_ptype_t type, cups_ptype_t mask, cups_dest_t **dests) {
my_user_data_t user_data = { 0, NULL };
if (!cupsEnumDests(CUPS_DEST_FLAGS_NONE, 1000, NULL, type, mask, (cups_dest_cb_t)my_dest_cb, &user_data)) {
cupsFreeDests(user_data.num_dests, user_data.dests);
*dests = NULL;
return 0;
} else {
*dests = user_data.dests;
return user_data.num_dests;
}
}
int main(int argc, const char * argv[]) {
cups_dest_t *dests = NULL;
int num_dests = my_get_dests(0, 0, &dests);
printf("Destination found: %d\n", num_dests);
cups_dest_t *dest;
int i;
const char *value;
for (i = num_dests, dest = dests; i > 0; i--, dest++) {
if (dest->instance == NULL) {
value = cupsGetOption("printer-info", dest->num_options, dest->options);
printf("%s (%s)\n", dest->name, value ? value : "No description");
}
}
return 0;
}
Here is the same thing but in Swift
let destinationsCallback: cups_dest_cb_t = { user_data, flags, dest in
// (void *user_data, unsigned flags, cups_dest_t *dest)
var userDataPointer = user_data!.assumingMemoryBound(to: my_user_data_t.self).pointee
var destData = dest!.pointee
if destData.instance != nil {
print("\(String(cString: destData.name))/\(String(cString: destData.instance))")
} else {
print(String(cString: destData.name))
}
if flags == CUPS_DEST_FLAGS_REMOVED {
userDataPointer.num_dests = cupsRemoveDest(destData.name, destData.instance, userDataPointer.num_dests, &(userDataPointer.dests))
} else {
userDataPointer.num_dests = cupsCopyDest(dest, userDataPointer.num_dests, &(userDataPointer.dests))
}
return 1
}
func getDestinations(type: UInt32, mask: UInt32, dests: UnsafeMutablePointer<cups_dest_t>) -> Int32 {
var userData = my_user_data_t(num_dests: 0, dests: nil)
if cupsEnumDests(UInt32(CUPS_DEST_FLAGS_NONE), 1000, nil, type, mask, destinationsCallback, &userData) != 1 {
return 0
} else {
return userData.num_dests
}
}
I am not able to get the userData to return the correct value which I am assuming is due to the way I handle the pointers.
Greatly appreciate if I am able to get some advice.
IMHO the best way to work with such C libraries in Swift is to work with them in Objective-C. Nevertheless, the main issue seems to be that you are not writing back changes to userData, that's why you always get your initial value. You need to update it in your callback like this
let userDataPointer = user_data!.assumingMemoryBound(to: my_user_data_t.self)
var userData = userDataPointer.pointee
...
// make some changes to userData
userDataPointer.pointee = userData
return 1
Also there seems to be some differences between your C code and the Swift one, like checking flags with 'flags == CUPS_DEST_FLAGS_REMOVED' which, in general, is incorrect way to check flags, and comparing result of cupsEnumDests with 1 when in the original code you check that result is not 0.
I have the following C function inside a shared library :
int GetRxDataBlock( char** data )
{
CHECK_FACADE_INITIALIZATION( "getRxDataBlock : Client facade not initialized", __LINE__ );
if ( data == nullptr ) {
printErrorMsg("getRxDataBlock : nullptr", __LINE__);
return -1;
}
int ret = 0;
try {
std::string rxData = g_facade.value()->getRxDataBlock();
*data = (char*) malloc(rxData.size() + 1);
memset(*data, 0, rxData.size() + 1 );
memcpy(*data, rxData.c_str(), rxData.size());
}catch(...) {
ret = -1;
}
return ret;
}
And this is the way I call it from Swift code :
var rxData: UnsafeMutablePointer? = nil
let apiResponse = GetRxDataBlock(&rxData)
print("Rx data : ret = \(apiResponse)")
if let dataStr = rxData {
let rxStr = String(cString: dataStr)
print("Rx data = \(rxStr)")
}
What is the correct way to deallocate memory returned by GetRxDataBlock function ?
malloc()ed memory must be released with free():
if let dataStr = rxData {
// do something with `dataStr`
// ...
free(dataStr)
}
This is also a good use-case for defer, which calls the closure just before the scope of the block is left:
if let dataStr = rxData {
defer { free(dataStr) }
// do something with `dataStr`
// ...
}
On Apple platforms, free() is imported from the standard C library as part of the Darwin module (which is imported by Foundation, AppKit, or UIKit). On Linux you would import Glibc.
Say we have a large block:
mod module {
pub const fiz: u32 = (1 << 0);
// etc...
}
flag = {
if (var & module::fiz) != 0 { module::fiz }
else if (var & module::foo) != 0 { module::foo }
else if (var & module::bar) != 0 { module::bar }
else if (var & module::baz) != 0 { module::baz }
// .. there could be many more similar checks
};
With simply replacement macro its possible to do:
#define TEST(f) ((var) & (f)) != 0 { f }
Allowing:
flag = {
if TEST(module::fiz)
else if TEST(module::foo)
else if TEST(module::bar)
else if TEST(module::baz)
}
It seems Rust doesn't allow a macro to declare part of an if statement.
I managed to avoid repetition using assignment, but its quite ugly.
flag = {
let f;
if (var & {f = module::fiz; f }) != 0 { f }
else if (var & {f = module::foo; f }) != 0 { f }
else if (var & {f = module::bar; f }) != 0 { f }
else if (var & {f = module::baz; f }) != 0 { f }
};
Does Rust provide some convenient/elegant way to allow repetition in this case?
I don't think flag checking is the important part of this question, the issue is that you may want to repeat content in the check again in the body of an if statement, e.g.:
if (foo && OTHER_EXPRESSION) { do(); something_with(OTHER_EXPRESSION) }
else if (foo && SOME_EXPRESSION) { do(); something_with(SOME_EXPRESSION) }
I think you have an X/Y problem here, so I am going to solve this without using if/else.
What you seem to be doing is checking for the presence of a bit pattern, and prioritise the order in which said patterns are checked for (unclear if it matters, but let's assume it does).
So, let's do this the functional way:
let constants = [fiz, foo, bar, baz];
let flag = constants.iter().filter(|v| var & *v == **v).next();
And it just works, no macro or repetitive stuff.
If you want to use macros, you can write it like this:
mod module {
pub const fiz: u32 = (1 << 0);
pub const foo: u32 = (1 << 1);
pub const bar: u32 = (1 << 2);
pub const baz: u32 = (1 << 3);
}
macro_rules! check_bits {
([$($Constant:expr),*]) => {
|var: u32| {
$(if ($Constant & var) != 0 {
return $Constant;
})*
return 0;
}
}
}
fn main() {
let var = 5;
let checker = check_bits!([module::bar, module::fiz, module::foo, module::baz]);
assert_eq!(checker(var), module::bar);
println!("All OK");
}
I believe this can be achieved by counting the instances for each character in that string. Even if a single character in that string is repeated at least twice, we can declare that string as a palindrome.
For example: bbcccc can be rewritten as bccccb or ccbbcc.
edified can be rewritten as deified.
Some book mentioned we should be using hash table. I think we can just use a list and check for the character count.
Do you think the logic is correct?
Yes, the main idea is to count the times of each char existing in the string. And it will be true if the string has at most one char occurs odd times and all others even times.
For example:
aabbcc => acbbca
aabcc => acbca
aabbb => abbba
No. You don't have to use a hash map (as some of the other answers suggest). But the efficiency of the solution will be determined by the algorithm you use.
Here is a solution that only tracks odd characters. If we get 2 odds, we know it can't be a scrambled palindrome. I use an array to track the odd count. I reuse the array index 0 over and over until I find an odd. Then I use array index 1. If I find 2 odds, return false!
Solution without a hash map in javascript:
function isScrambledPalindrome(input) {
// TODO: Add error handling code.
var a = input.split("").sort();
var char, nextChar = "";
var charCount = [ 0 ];
var charIdx = 0;
for ( var i = 0; i < a.length; ++i) {
char = a[i];
nextChar = a[i + 1] || "";
charCount[charIdx]++;
if (char !== nextChar) {
if (charCount[charIdx] % 2 === 1) {
if (charCount.length > 1) {
// A scrambled palindrome can only have 1 odd char count.
return false;
}
charIdx = 1;
charCount.push(0);
} else if (charCount[charIdx] % 2 === 0) {
charCount[charIdx] = 0;
}
}
}
return true;
}
console.log("abc: " + isScrambledPalindrome("abc")); // false
console.log("aabbcd: " + isScrambledPalindrome("aabbcd")); // false
console.log("aabbb: " + isScrambledPalindrome("aabbb")); // true
console.log("a: " + isScrambledPalindrome("a")); // true
Using a hash map, I found a cool way to only track the odd character counts and still determine the answer.
Fun javascript hash map solution:
function isScrambledPalindrome( input ) {
var chars = {};
input.split("").forEach(function(char) {
if (chars[char]) {
delete chars[char]
} else {
chars[char] = "odd" }
});
return (Object.keys(chars).length <= 1);
}
isScrambledPalindrome("aba"); // true
isScrambledPalindrome("abba"); // true
isScrambledPalindrome("abca"); // false
Any string can be palindrome only if at most one character occur odd no. of times and all other characters must occur even number of times.
The following program can be used to check whether a palindrome can be string or not.
vector<int> vec(256,0); //Vector for all ASCII characters present.
for(int i=0;i<s.length();++i)
{
vec[s[i]-'a']++;
}
int odd_count=0,flag=0;
for(int i=0;i<vec.size();++i)
{
if(vec[i]%2!=0)
odd_count++;
if(odd_count>1)
{
flag=1;
cout<<"Can't be palindrome"<<endl;
break;
}
}
if(flag==0)
cout<<"Yes can be palindrome"<<endl;
My code check if can it is palindrome or can be manipulated to Palindrome
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
//Tested on windows 64 bit arhc by using cygwin64 and GCC
bool isPalindrome (char *text);
int main()
{
char text[100]; // it could be N with defining N
bool isPal,isPosPal = false;
printf("Give me a string to test if it is Anagram of Palindrome\n");
gets(text);
isPal = isPalindrome(text);
isPosPal = isAnagramOfPalindrome(text);
if(isPal == false)
{
printf("Not a palindrome.\n");
}
else
{
printf("Palindrome.\n");
}
if(isPosPal == false)
{
printf("Not Anagram of Palindrome\n");
}
else
{
printf("Anagram of Palindrome\n");
}
return 0;
}
bool isPalindrome (char *text) {
int begin, middle, end, length = 0;
length = getLength(text);
end = length - 1;
middle = length/2;
for (begin = 0; begin < middle; begin++)
{
if (text[begin] != text[end])
{
return false;
}
end--;
}
if (begin == middle)
return true;
}
int getLength (char *text) {
int length = 0;
while (text[length] != '\0')
length++;
printf("length: %d\n",length);
return length;
}
int isAnagramOfPalindrome (char *text) {
int length = getLength(text);
int i = 0,j=0;
bool arr[26] = {false};
int counter = 0;
//char string[100]="neveroddoreven";
int a;
for (i = 0; i < length; i++)
{
a = text[i];
a = a-97;
if(arr[a])
{
arr[a] = false;
}
else
{
arr[a] = true;
}
}
for(j = 0; j < 27 ; j++)
{
if (arr[a] == true)
{
counter++;
}
}
printf("counter: %d\n",counter);
if(counter > 1)
{
return false;
}
else if(counter == 1)
{
if(length % 2 == 0)
return false;
else
return true;
}
else if(counter == 0)
{
return true;
}
}
as others have posted, the idea is to have each character occur an even number of times for an even length string, and one character an odd number of times for an odd length string.
The reason the books suggest using a hash table is due to execution time. It is an O(1) operation to insert into / retrieve from a hash map. Yes a list can be used but the execution time will be slightly slower as the sorting of the list will be O(N log N) time.
Pseudo code for a list implementation would be:
sortedList = unsortedList.sort;
bool oddCharFound = false;
//if language does not permit nullable char then initialise
//current char to first element, initialise count to 1 and loop from i=1
currentChar = null;
currentCharCount = 0;
for (int i=0; i <= sortedList.Length; i++) //start from first element go one past end of list
{
if(i == sortedList.Length
|| sortedList[i] != currentChar)
{
if(currentCharCount % 2 = 1)
{
//check if breaks rule
if((sortedList.Length % 2 = 1 && oddCharFound)
|| oddCharFound)
{
return false;
}
else
{
oddCharFound = true;
}
}
if(i!= sortedList.Length)
{
currentCharCount = 1;
currentChar = sortedList[i];
}
}
else
{
currentCharCount++;
}
}
return true;
Here is a simple solution using an array; no sort needed
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a[256] = { 0 };
unsigned char i[] = {"aaBcBccc"};
unsigned char *p = &i[0];
int c = 0;
int j;
int flag = 0;
while (*p != 0)
{
a[*p]++;
p++;
}
for(j=0; j<256; j++)
{
if(a[j] & 1)
{
c++;
if(c > 1)
{
flag = 1;
break;
}
}
}
if(flag)
printf("Nope\n");
else
printf("yup\n");
return 0;
}
C#:
bool ok = s.GroupBy(c => c).Select(g => g.Count()).Where(c => c == 1).Count() < 2;
This solution, however, does use hashing.
Assuming all input characters are lower case letters.
#include<stdio.h>
int main(){
char *str;
char arr[27];
int j;
int a;
j = 0;
printf("Enter the string : ");
scanf("%s", str);
while (*str != '\0'){
a = *str;
a = a%27;
if(arr[a] == *str){
arr[a]=0;
j--;
}else{
arr[a] = *str;
j++;
}
*str++;
}
if(j==0 || j== -1 || j==1){
printf ("\nThe string can be a palindrome\n");
}
}
I am reading a value sent over RS485 which is the value of an encoder I first check if it has returned an E character (the encoder is reporting an error) and if not then do the following
*position = atoi( buffer );
// Also tried *position = (s32) strtol(buffer,NULL,10);
The value in the buffer is 4033536 and position gets set to 33536 this does not happen every time in this function probably 1 in 1000 times maybe although I am not counting. Setting the program counter back and doing the line again if has failed returns the same result but starting the debugger again causes the value to convert correctly.
I am using keil uvision 4, its a custom board using an stm32f103vet6 and the stm32f10 library V2.0.1 This one has really got me stumped never come across something like this before any help would be much appreciated.
Thanks
As no one knows I will just post what I ended up doing which was to write my own function for convertion not ideal but it worked.
bool cdec2s32(char* text, s32 *destination)
{
s32 tempResult = 0;
char currentChar;
u8 numDigits = 0;
bool negative = FALSE;
bool warning = FALSE;
if(*text == '-')
{
negative = TRUE;
text++;
}
while(*text != 0x00 && *text != '\r') //while current character not null or carridge return
{
numDigits++;
if(*text >= '0' && *text <= '9')
{
currentChar = *text;
currentChar -= '0';
if((warning && ((currentChar > 7 && !negative) || currentChar > 8 && negative )) || numDigits > 10) // Check number not too large
{
tempResult = 2147483647;
if(negative)
tempResult *= -1;
*destination = tempResult;
return FALSE;
}
tempResult *= 10;
tempResult += currentChar;
text++;
if(numDigits >= 9)
{
if(tempResult >= 214748364)
{
warning = TRUE; //Need to check next digit as close to limit
}
}
}
else if(*text == '.' || *text == ',')
{
break;
}
else
return FALSE;
}
if(negative)
tempResult *= -1;
*destination = tempResult;
return TRUE;
}