Get the value of a defined variable - makefile

I am trying to write a makefile to automate the work of compiling, pushing the code to a server, and running the code all in one.
The problem is that I don't have a list of servers defined, and there are going to be other people using this makefile.
What I am trying to do is the following.
Let's say there is a code c code
#include<stdio.h>
#define SERVER_NAME "Some Server"
int main(int argc, char** argv)
{
//Some random code
}
Is there any tool which I can use in the makefile, to which I will pass the C file along with all it's dependencies, and the tool will tell me what the (For lack of a better word) variable "SERVER_NAME" is defined to?
I need something of this sort
<Some tool> <c file initially created> <all include files> <any c specific switch>
and the output is something like
SERVER_NAME="Some Server"
I know I can always do a grep on the file and pull the variable, but I want to also take care of conditions like the following.
#include<stdio.h>
#define SERVER1 //This might change to server2
#ifdef SERVER1
#define SERVER_NAME "Some Server 1"
#endif
#ifdef SERVER2
#define SERVER_NAME "Some Server 2"
#endif
int main(int argc, char** argv)
{
//Some random code
}
I know that the C preprocessor is powerful enough to do this work, I just can't figure out what arguments or switches to pass to it.

The gcc preprocessor option -imacros lets you scan the macros in a source file and ignore the rest of it.
Suppose your source file is named foo.cc:
#define SERVER1 //This might change to server2
#ifdef SERVER1
#define SERVER_NAME "Some Server 1"
#endif
#ifdef SERVER2
#define SERVER_NAME "Some Server 2"
#endif
int main(int argc, char** argv)
{
//Some random code
}
Write another source called serverReporter.cc:
#include <iostream>
using std::cout;
using std::endl;
int main()
{
cout << "SERVER_NAME=" << SERVER_NAME << endl;
return 0;
}
Now build (with or without Make):
g++ -imacros foo.cc serverReporter.cc -o serverReporter
and run it.
(There may be a way to get the macro value without running the code, by means of an option like -dD, but I haven't yet gotten that to work.)

Assuming that your header files do not declare any other constants (which may be a bit of a stretch for C++ code), you can compile a file like this:
// Comes from a header file
#define SERVER_NAME "server name"
const char compile_time_server_name[] = SERVER_NAME;
The resulting object file will have the string in its constant data section. For example, if your target is ELF, you can use objcopy from binutils to extract this data:
objcopy -O binary -j .rodata server_name.o server_name.contents
The command xxd server_name.contents shows this:
00000000: 7365 7276 6572 206e 616d 6500 server name.
Note the trailing NUL; you may have to remove that by further scripting. It is probably a good idea to check that the boject file contains only one symbol in the .rodata section, perhaps using nm.

Related

How can I run 'ls' with options from a C program?

I want to execute the command ls -a using execv() on a Linux machine as follows:
char *const ptr={"/bin/sh","-c","ls","-a" ,NULL};
execv("/bin/sh",ptr);
However, this command does not list hidden files. What am I doing wrong?
I'm not sure why you're passing this via /bin/sh... but since you are, you need to pass all the arguments after -c as a single value because these are now to be interpreted by /bin/sh.
The example is to compare the shell syntax of
/bin/sh -c ls -a
to
/bin/sh -c 'ls -a'
The second works, but the first doesn't.
So your ptr should be defined as
char * const ptr[]={"/bin/sh","-c","ls -a" ,NULL};
If you need to get the contents of a directory from a c program, then this is not the best way - you will effectively have to parse the output of ls, which is generally considered a bad idea.
Instead you can use the libc functions opendir() and readdir() to achieve this.
Here is a small example program that will iterate over (and list) all files in the current directory:
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <dirent.h>
int main (int argc, char **argv) {
DIR *dirp;
struct dirent *dp;
dirp = opendir(".");
if (!dirp) {
perror("opendir()");
exit(1);
}
while ((dp = readdir(dirp))) {
puts(dp->d_name);
}
if (errno) {
perror("readdir()");
exit(1);
}
return 0;
}
Note the listing will not be sorted, unlike the default ls -a output.

Empty Working Set from cmd

I want to write a cmd script to periodically empty the working set from the command prompt. For now I empty the working set in the Rammap tool from sysinternals, but that can't be run by a script.
It's probably easiest to compile something like this:
#include <iostream>
#include <windows.h>
int main(int argc, char **argv) {
if (argc != 2) {
std::cerr << "Usage: min_mem <process_id>\n";
return 1;
}
HANDLE process = OpenProcess(PROCESS_SET_QUOTA, false, atoi(argv[1]));
SetProcessWorkingSetSize(process, -1, -1);
}
...and then run it in your script, something like:
mem_min 1234
...but replacing 1234 with the process ID (in decimal) of the process whose memory you want to minimize.
That said: I'd ask that this answer not be upvoted, since it's really a pretty crappy answer to a question that's basically just a gimme the codez I've been weak enough to post it, but would prefer not to get any rep for doing so.

Command-Line arguments not working (char, TCHAR) VS2010

I have following code:
int _tmain(int argc, char** argv) {
bool g_graphics = true;
palPhysics * pp = 0;
#ifndef PAL_STATIC
PF -> LoadPALfromDLL();
#endif
char a[] = "Bullet";
std::string aa;
aa = std::string(argv[1]);
//PF->SelectEngine("Bullet");
DebugBreak();
PF -> SelectEngine(argv[1]);
//PF->SelectEngine(aa);
//debug
// assert(false);
pp = PF -> CreatePhysics();
}
I am trying to read in the command line argument no. 1 in this line:
PF->SelectEngine(argv[1]);
However, I only get the first letter of the argument. I have also tried changing
int _tmain(int argc, char** argv)
to
int _tmain(int argc, TCHAR** argv), but then I get
error:
error C2664: 'palFactory::SelectEngine' : cannot convert parameter 1 from 'TCHAR *' to 'const PAL_STRING &'
PAL_STRING is just a std::string.
This might be a simple one, but I am not sure how to convert TCHAR to std::string, especially since TCHAR is something else depending on compiler /environment settings. Is anyone aware of an easy way to get the command-line arguments to work, such that I don't need to convert anything myself, i..e maybe by changing the tmain function?
Thanks!
C
Update: example of invoking on command line:
Yep. so the way I invoke this on command line is:
progname.exe arg1 arg2,
where arg1 is a physics engine I am trying to load, and arg2 is a dae(physics file with physics info), so I go, specifically:
progname.exe Bullet E:/a.dae
Stepping into the line "PF->SelectEngine(argv[1]);" gives the following code:
bool palFactory::SelectEngine(const PAL_STRING& name) {
#ifdef INTERNAL_DEBUG
printf("palFactory::SelectEngine: this = %p\n", this);
#endif
SetActiveGroup(name); // also calls RebuildRegistry
return isClassRegistered("palPhysics");
}
, in this case, when debugging, I can see that const PAL_STRING& name, i.e. the string, is just "B", instead of what I would expect it to be, which is "Bullet", my command line argument I have passed in the command line.
I've been plauged by this problem for years. The only solution I've been able to find is to NOT USE Visual Studio. I've had to fall back to using other compilers when I must be able to process command-line args. Specifically, I've been using the Digital Mars compiler successfully. It handles the command-line args correctly. I use the VS environment for intellisense and debugging, then compile with DMC to deploy.
---edit below---
Turns out, I just wasn't asking the right question. I finally asked the right question, and got the right answer! See link below.
What is the difference between _tmain() and main() in C++?

How to convert a function address to a symbol

Let's say I have a program like this
// print-addresses.cpp
#include <stdio.h>
void foo() { }
void bar() { }
void moo() { }
int main(int argc, const char** argv) {
printf("%p\n", foo);
printf("%p\n", bar);
printf("%p\n", moo);
return 0;
}
It prints some numbers like
013510F0
013510A0
01351109
How do I convert those numbers back into the correct symbols? Effectively I'd like to be able to do this
print-addresses > address.txt
addresses-to-symbols < address.txt
And have it print
foo
bar
moo
I know this has something to do with the Debug Interface Access SDK but it's not entirely clear to me how I go from an address to a symbol.
This seems like exactly what you're looking for: Retrieving Symbol Information by Address. This uses DbgHelp.dll and relies on calling SymFromAddr. You have to do that (I think) from within the running application, or by reading in a minidump file.
You can also use the DIA, but the calling sequence is a bit more complicated. Call IDiaDataSource::loadDataForExe and IDiaDataSource::openSession to get an IDiaSession, then IDiaSession::getSymbolsByAddr to get IDiaEnumSymbolsByAddr. Then, IDiaEnumSymbolsByAddr::symbolByAddr will let you look up a symbol by address. There is also a way (shown in the example at the last link) to enumerate all symbols.
EDIT: This DIA sample application might be a good starting point for using DIA: http://msdn.microsoft.com/en-us/library/hd8h6f46%28v=vs.71%29.aspx . Particularly check out the parts using IDiaEnumSymbolsByAddr.
You could also parse the output of dumpbin, probably with /SYMBOLS or /DISASM option.
if you are in linux, you could try addr2line
addr2line addr -e execuablebin -f

Qt - Opening a custom file via double-click

I have a program and a .l2p file with some lines of info.
I have run a registry file:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\.l2p\DefaultIcon]
#="\"C:\\Program Files\\ToriLori\\L2P.exe\",0"
[HKEY_CLASSES_ROOT\.l2p\shell\Open\command]
#="\"C:\\Program Files\\ToriLori\\L2P.exe\" \"%1\""
When I double-click the .l2p file the program starts but doesn't load the file. What do I have to do to make it load properly? Example code would be very appreciated.
When you double click on a file the file name is passed as a command line argument to the associated program. You have to parse the command line, get the file name and open it (how to do that depends on how your program works).
#include <iostream>
int main(int argc, char *argv[])
{
for (int i = 1; i < argc; ++i) {
std::cout << "The " << i << "th argument is " << argv[i] << std::endl;
}
}
If you run this program from command line:
>test.exe "path/to/file" "/path/to/second/file"
The 1th argument is path/to/file
The 2th argument is /path/to/second/file
In Qt if you create a QApplication you can also access the command line arguments via QCoreApplications::arguments().
You might want to load the file after having created your main window. You may do something like this:
#include <QApplication>
#include <QTimer>
#include "MainWindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow window;
QTimer::singleShot(0, & window, SLOT(initialize()));
window.show();
return app.exec();
}
This way the slot MainWindow::initialize() (which you have to define) gets called as soon as the event loop has started.
void MainWindow::initialize()
{
QStringList arguments = QCoreApplication::arguments();
// Now you can parse the arguments *after* the main window has been created.
}
If I'm understanding your question correctly, L2P.exe is a Qt program you created and you want to handle a passed argument as specifying a file to open. If that's the case, you just need to read that argument in your main() method and handle it. (This isn't something that happens automatically.) Something like the following, although you obviously want to add a bit of error checking:
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
const QStringList arguments = a.arguments();
// The final argument is assumed to be the file to open.
if (arguments.size() > 1 && QFile::exists(arguments.last())) {
your_app_open(arguments.last());
}
// ... etc.
}

Resources