How to have Lua script changes during runtime take effect / reload script? - objective-c

I am doing the below in C++/Objective-C app to load a lua script. Works fine, lua_getglobal successfully gets me the value of "testnum". However the value never changes when I update the script during the application run and the next time I go through this part of the code path.
L = luaL_newstate();
luaL_openlibs(L);
lua_settop(L, 0);
int err;
NSString * luaFilePath = [[NSBundle mainBundle] pathForResource:#"Test" ofType:#"lua"];
err = luaL_loadfile(L, [luaFilePath cStringUsingEncoding:[NSString defaultCStringEncoding]]);
err = lua_pcall(L, 0, 0, 0);
if (0 != err) {
luaL_error(L, "error: %s",
lua_tostring(L, -1));
return;
}
lua_getglobal(L, "testnum");
int num = lua_tointeger(L, -1);
The lua file (Test.lua) is simply
testnum = 100
I'm changing the value of testnum but it always remains 100 (or whatever it was set to at the start up) in the C++/Objective-C application. I can even delete the testnum var entirely and it's still 100 and lua_getglobal does not complain (except if I do that at the start up), num's value will be whatever it was at the start up of the main application. What is needed to reload the script and get whatever the latest number while the application is running.

You're doing it roughly right but I don't think Lua is the issue here, the issue is that the files in the bundle won't change until you rebuild the application.
If you were just loading a file rather than using a bundle then what you have would work.

Related

How to decompress pbzip2 data in memory buffer by using libbz2 library in C++

I have a working version of decompressing bzip2 data where I call the bz2_bzdecompress API. It goes something like this
while (bytes_input < len) {
isDone = false;
// Initialize the input buffer and its length
size_t in_buffer_size = len -bytes_input;
the_bz2_stream.avail_in = in_buffer_size;
the_bz2_stream.next_in = (char*)data +bytes_input;
size_t out_buffer_size =
output_size -bytes_uncompressed; // size of output buffer
if (out_buffer_size == 0) { // out of space in the output buffer
break;
}
the_bz2_stream.avail_out = out_buffer_size;
the_bz2_stream.next_out =
(char*)output +bytes_uncompressed; // output buffer
ret = BZ2_bzDecompress(&the_bz2_stream);
if (ret != BZ_OK && ret != BZ_STREAM_END) {
throw Bzip2Exception("Bzip2 failed. ", ret);
}
bytes_input += in_buffer_size - the_bz2_stream.avail_in;
bytes_uncompressed += out_buffer_size - the_bz2_stream.avail_out;
*data_consumed =bytes_input;
if (ret == BZ_STREAM_END) {
ret = BZ2_bzDecompressEnd(&the_bz2_stream);
if (ret != BZ_OK) {
throw Bzip2Exception("Bzip2 fail. ", ret);
}
isDone = true;
}
}
This works great for native bzip2 compressed files, but for pbzip2 (Parallel Bzip2) and "Splittable" bzip2 data, it throws a "BZ_PARAM_ERROR".
I see that pbzip2 in their documentation says this-
Data compressed with pbzip2 is broken into multiple streams and each
stream is bzip2 compressed looking like this:
[-----|-----|-----|-----|-----|-----|-----|-----|-----]
If you are writing software with libbzip2 to decompress data created
with pbzip2, you must take into account that the data contains
multiple bzip2 streams so you will encounter end-of-stream markers
from libbzip2 after each stream and must look-ahead to see if there
are any more streams to process before quitting. The bzip2 program
itself will automatically handle this condition.
Source:http://compression.ca/pbzip2/
Can someone please tell me how to handle this? Should I be using some other libzip2 API?
Also, pbzip2 files are compatible with the normal "bunzip2" command. How is that bzip2 handles this gracefully while my code throws a BZ_PARAM_ERROR?
Thanks.
After your BZ2_bzDecompressEnd() you need to call BZ2_bzDecompressInit() again (you must have called it initially before that loop), if there is still data left to decompress, i.e. bytes_input < len.
To decompress each of the |-----| blocks, you need to do an init, some number of decompress calls, and an end. So if you still have input left, then you need to do another init, n*decompress, end.
Make sure that you do a final end, in order to avoid a big memory leak.
You're getting a BZ_PARAM_ERROR because you are trying to use an uninitialized bz_stream to decompress. Once you do BZ2_bzDecompressEnd(), you can't use that bz_stream any more, unless you do a BZ2_bzDecompressInit() on it.

Call to CFURLCreateFromFileSystemRepresentation sometimes fails

I have an application that loads in a bundle and in doing so I call CFURLCreateFromFileSystemRepresentation before CFBundleCreate: -
bundlePackageURL = CFURLCreateFromFileSystemRepresentation(
kCFAllocatorDefault,
(const UInt8*)bundlePackageFileSystemRepresentation,
strlen(bundlePackageFileSystemRepresentation),
true );
Most of the time, running the same application and loading the same bundle that resides in the application bundle's Resource directory, the function works and returns a valid CFURL. However, with exactly the same parameters passed in to the function, the call sometimes fails.
I now have code to handle the failure: -
CFURLRef bundlePackageURL = NULL;
int attempt = 0;
while((bundlePackageURL == NULL) && (attempt++ < 12000))
{
bundlePackageURL = CFURLCreateFromFileSystemRepresentation(
kCFAllocatorDefault,
(const UInt8*)bundlePackageFileSystemRepresentation,
strlen(bundlePackageFileSystemRepresentation),
true );
// failed to load, so try again
if(bundlePackageURL == NULL)
fprintf(stdout, "Retrying to obtain CFURL: %d...\n", attempt);
}
As you can see, this makes up to 12000 attempts to call the function and when it fails, I've seen it take anything between a few hundred to over 10000 repeated calls before it succeeds.
Can anyone please explain why the function may be failing at times and if this is normal?

What is causing this command line error?

I am trying to programatically call the "top" command. The following is the code used:
char buffer [128];
char* threadsPointer;
char* procPointer;
NSString* numberOfThreadsString;
NSString* numberOfProcString;
FILE* output = popen("/usr/bin/top", "r");
while (fgets(buffer, sizeof(buffer), output) != NULL)
{
if ((procPointer = strstr(buffer, "Processes:")) != NULL)
{
procPointer += strlen("Proceses: ");
strcpy(buffer, procPointer);
numberOfProcString = [NSString stringWithUTF8String: buffer];
}
if ((threadsPointer = strstr(buffer, "sleeping,")) != NULL)
{
threadsPointer += strlen("sleeping, ");
strcpy(buffer, threadsPointer);
numberOfThreadsString = [NSString stringWithUTF8String: buffer];
}
}
NSLog(#"Proc: %#\nThreads: %#\n\n\n", numberOfProcString, numberOfThreadsString);
Instead of giving valid output, I keep getting the error: "Error opening terminal: unknown". I commended out the whole piece of code to identify the problem, and realized that its the line: FILE* output = popen ("/usr/bin/top", "r"); that is causing the error.
Does anyone have an idea of what I am doing wrong? Note I am on Mountain Lion OS X building an app for OSX not iOS.
top on MacOSX requires that its standard output or standard error be connected to a valid terminal to run. When you invoke it without a terminal (or a $TERM environment variable set to a valid terminal name, like "vt100"), it gives you that error: Error opening terminal: unknown.
You really shouldn't be using top for this, since it's an interactive program that requires a terminal. You should just be using ps.
you can try "top -l 1".
"-l 1" mean 1 sample, I think it should run top in non-interactive mode, print the result and exit.
On linux the command is "top -n 1" ("-n 1" mean run only 1 iteration, which should be equivalent to "top -l 1" on mac osx).
If you want specific information or all the details you should use "/proc" filesystem.
You can readdir() and fopen() all the files in /proc which contains currently running processes and get a lot of information, like for example what files are open by some process, or what ports is the process listening on.
'top' command opens a terminal and waits for user input. You won't be able to use it in a an automated script

How to run two loops at the same time?

I have been developing a very simple text game using Objective C and Xcode. It is almost done but I am having a problem, the scanf method stops the loop and asks for user input while I need the computer to be running the rest of the loop, the solution I came up with was running two while loops at the same time, one being the logic loop and another being a loop for user input.
I have been doing my research and it looks like using threads are the way to go, I just have not found a tutorial that will break it down for a n00b in Objective C (I am decent in java, I just have never worked with threads). If anybody could explain them or link me to a very broken down tutorial that would be great. Or if anybody has another idea I am open to anything else.
Necessary Code (The scanf I am having a problem with has asterisks on the line):
while(running != 0)
{
if(gameState == 1)
{
if(timeToGenerateNum == true)
{
while(randNumber < 10000000)
{
randNumber = arc4random() % 100000000;
}
NSLog(#"%i", randNumber);
timeToGenerateNum = false;
}
else
{
while(time <= 2500)
{
NSLog(#"Testing");
time++;
******************scanf("%i", &userNum);************************
if(userNum == randNumber)
{
score += time;
time = 0;
timeToGenerateNum = true;
}
}
NSLog(#"Game Over! Your score was %i!", score);
running = 0;
}
}
else if(gameState == 2)
{
NSLog(#"To play, simply type in the number that appears on the screen.");
NSLog(#"But be careful, you only have a short amount of time before GAME OVER!");
NSLog(#"The quicker you type in the number the more score you get!");
NSLog(#"Are you ready to start, if so type '1' and press enter!");
scanf("%i", &gameState);
}
}
You're going to have to learn a bit about BSD (Unix, Linux) input/output to pull this off: replace your call to scanf with a non-blocking function you write to acquire input from the user's keyboard.
This function should immediately return whatever the user typed, or immediately return with a zero character count if she didn't type anything.
Read up on the select(2) system call, and keep in mind that keyboard input (standard input) is the first file descriptor, file descriptor zero.

Realloc not expanding my array

I'm having trouble implementing realloc in a very basic way.
I'm trying to expand the region of memory at **ret, which is pointing to an array of structs
with ret = realloc(ret, newsize); and based on my debug strings I know newsize is correctly increasing over the course of the loop (going from the original size of 4 to 8 to 12 etc.), but when I do sizeof(ptr) it's still returning the original size of 4, and the things I'm trying to place into the newly allocated space can't be found (I think I've narrowed it down to realloc() which is why I'm formatting the question like this)
I can post the function in it's entirety if the problem isn't immediately evident to you, I'm just trying to not "cheat" with my homework too much (the code is kind of messy right now anyway, with heavy use of printf() for debug).
[EDIT] Alright, so based on your answers I'm failing at debugging my code, so I guess I'll post the whole function so you can tell me more about what I'm doing wrong.
(You can ignore the printf()'s since most of that is debug that isn't even working)
Booking **bookingSelectPaid(Booking **booking) {
Booking **ret = malloc(sizeof(Booking*));
printf("Initial address of ret = %p\n", ret);
size_t i = 0;
int numOfPaid = 0;
while (booking[i] != NULL)
{
if (booking[i]->paid == 1)
{
printf("Paying customer! sizeof(Booking*) = %d\n", (int)sizeof(Booking*));
++numOfPaid;
size_t newsize = sizeof(Booking*) * (numOfPaid + 1);
printf("Newsize = %d\n", (int)newsize);
Booking **temp = realloc(NULL, (size_t)newsize);
if (temp != NULL)
printf("Expansion success! => %p sizeof(new pointer) = %d ret = %p\n", temp, (int)sizeof(temp), ret);
ret = realloc(ret, newsize);
ret[i] = booking[i];
ret[i+1] = NULL;
}
++i;
printf("Sizeof(ret) = %d numOfPaid = %d\n", (int)sizeof(ret), numOfPaid);
}
return ret; }
[EDIT2] --> http://pastebin.com/xjzUBmPg
[EDIT3] Just to be clear, the printf's, the temp pointer and things of that nature are debug, and not part of the intended functionality. The line that is puzzling me is either the one with realloc(ret, newsize); or ret[i] = booking[i]
Basically I know for sure that booking contains a table of structs that ends in NULL, and I'm trying to bring the ones that have a specific value set to 1 (paid) onto the new table, which is what my main() is trying to get from this function... So where am I going wrong?
I think the problem here is that your sizeof(ptr) only returns the size of the pointer, which will depend on your architecture (you say 4, so that would mean you're running a 32-bit system).
If you allocate memory dynamically, you have to keep track of its size yourself.
Because sizeof(ptr) returns the size of the pointer, not the allocated size
Yep, sizeof(ptr) is a constant. As the other answer says, depends on the architecture. On a 32 bit architecture it will be 4 and on a 64 bit architecture it will be 8. If you need more help with questions like that this homework help web site can be great for you.
Good luck.