Pass command line argument to a sub function - c

I have a C program main routine which calls heirarchically several levels of functions. Eg :
main -> MyFunc -> MySubFunc -> MySub2Func
and I have a condition in MySub2Func which needs to be checked against a command line argument. Eg:
if (myvar == argv[1])
Other than passing argv as a parameter to subfunction , is there any other way I could acheive this. (because I need to do this in several functions lying at different heirarchical levels)
Each of the sub-functions lie in different C files. My aim is to perform a debug by temporarily checking a particular local variable against a cmd line argument (and taking further actions accordingly) .. hence modifying the entire heirarchy is unfortunately not desirable for my purpose.
[update from comment]
sorry that I forgot to mention .. i am trying to perform a debug by temporarily checking a particular local variable against a cmd line argument (and taking further actions accordingly) .. hence modifying the entire heirarchy is unfortunately not desirable for my purpose ..

The common approach is to "decouple" the two; the functions further down the call tree really shouldn't care or know about main()'s arguments, i.e. the command argument vector itself.
Instead, it should be abstracted into application-specific options, which are passed from main(), which parses the options out of the command line arguments, down to all application-specific functions that need them.

You might use global variables that are set in the main() function:
int g_argc;
char **g_argv;
int main(int argc, char **argv) {
g_argc = argc;
g_argv = argv;
MyFunc();
}
...
void MyFunc() {
MySubFunc();
}
...
void MySubFunc() {
MySub2Func();
}
...
void MySub2Func() {
if (myvar == g_argv[1]) {
do_the_thing();
}
}

As unwind said, the functions further down the chain should really not know anything about main's arguments. You should parse the command line arguments once setting the program's configuration. Additionally you should provide query functions for this configuration e.g.
/* --- config.c */
typedef struct {
int debug_enabled;
} config_t;
static config_t configuration;
int debug_enabled() {
return configuration->debug_enabled;
}
void initialize_config() {
/* set default parameters */
}
int set_config_from_cmd(int argc, char** argv){
/* parse CMD parameters and set config */
}
/* --- main.c */
int main(int argc, char** argv)
{
initialize_config();
if ( set_config_from_cmd(argc, argv) == -1 ) {
exit(-1);
}
/* do stuff, call functions */
}
int myfunction() {
if ( debug_enabled() ) {
printf("debug!");
}
/* do stuff */
}
Notice that I put the configuration related stuff into a separate file in order to hide the internals of the configuration structure. Only the interface e.g. debug_enabled() etc is exposed.

[for debugging]
Put this in a header included by all modules involved:
extern int g_argc;
extern char ** g_argv;
Define g_argc and g_argv globally in the main module
int g_argc = 0;
char ** g_argv = NULL;
Then in main() just do
int main(int argv, char ** argv)
{
g_argc = argc;
g_argv = argv;
and access g_argc and g_argv from the modules in question.

Related

Using a switch to map function pointers to strings

I'm working on a network service that based on commands it receives over the network, it has workers perform different jobs. I want to have a log entry for every time a certain worker is tasked with doing some job.
I have a function (say function_caller) which, among other things, calls another function which it receives its pointer as an argument. I'd like to have my logger notify what kind of function function_caller calls.
Originally I wanted the function_caller to receive some enum instead of a function pointer, provide the enum to the logger, and then use a helper function which returns a suitable pointer based on the enum. However, function_caller is already deeply tangled in the codebase I'm working on, and it looks like it would be a lot of work to refactor all the functions that call function_caller to choose the right enum and use a new argument.
So my next idea was having a switch that for every function pointer will have some string representation of, but I've never stumbled upon something like that (and struggled to find anyone even mentioning such an idea on Google), so I have a feeling I might be missing some serious downsides to this option.
The only significant problem I see is that every developer that decides to pass a new kind of function pointer to function_caller will have to somehow know to update the switch, otherwise it will fail.
Am I missing anything else? Or maybe there's some other approach I should consider?
How about something like this? Instead of a switch, store a table of functions and their name strings. The table can even be kept dynamically updated, unlike a switch case. You will not need to walk along the edge of the standard as well!
#include <stdio.h>
typedef void (*callback_t) (void);
void first (void) { printf("%d", 1); };
void second (void) { printf("%d", 2); };
void third (void) { printf("%d", 3); };
typedef struct fntable_t
{
callback_t fn;
char *name;
} fntable_t;
fntable_t fntable[] =
{
{ first, "first" },
{ second, "second" },
{ third, "third" }
};
char* log_str(callback_t c)
{
for(int i = 0; i < sizeof(fntable) / sizeof(fntable_t); i++)
{
if(fntable[i].fn == c)
return fntable[i].name;
}
return "unknown";
}
void function_caller(callback_t c)
{
printf("%s",log_str(c));
c();
}
int main(void)
{
function_caller(first);
function_caller(second);
function_caller(third);
return 0;
}
You could replace function_caller with a wrapper macro of the same name that calls the renamed function function_caller_internal which gets an additional string argument. The wrapper macro can then pass an additional stringified function name.
This works only if function_caller is always called with a function name, not a function pointer variable.
Example:
#include <stdio.h>
static void funcA(void)
{
printf("This is funcA\n");
}
static void funcB(void)
{
printf("This is funcB\n");
}
/* renamed function gets an additional string argument */
static void function_caller_internal(void (*func)(void), const char *name)
{
printf("calling %s\n", name);
func();
}
/* wrapper macro stringifies the function name to pass it the additional argument */
#define function_caller(func) function_caller_internal(func, #func)
int main(void)
{
/* unchanged calls */
function_caller(funcA);
function_caller(funcB);
return 0;
}
This prints
calling funcA
This is funcA
calling funcB
This is funcB
If you can change the API of the functions, then consider using __func__ to get the textual name of each function. If you can have a function pointer type along the lines of this:
typedef void func_t (const char** name);
Then you can have each function return its name to the caller.
void foo (const char** name)
{
/* do foo stuff here */
*name = __func__;
}
void bar (const char** name)
{
/* do bar stuff here */
*name = __func__;
}
Example:
#include <stdio.h>
typedef void func_t (const char** name);
void foo (const char** name)
{
/* do foo stuff here */
*name = __func__;
}
void bar (const char** name)
{
/* do bar stuff here */
*name = __func__;
}
const char* function_caller (func_t* func, const char** name)
{
func(name);
return *name;
}
int main(void)
{
static func_t*const func [] =
{
foo,
bar,
};
const char* name;
for(size_t i=0; i<sizeof func/sizeof *func; i++)
{
puts( function_caller(func[i], &name) );
}
}
Assuming your codebase has sane variable names and function names, you can add a char * argument to your function caller:
void function_caller(char *name, int fpnt());
and then provide a macro:
#define function_caller_autoname(fpnt) function_caller(#fpnt, fpnt)
(Or, for spaghetti code, you can provide a macro with the same name as the function).
The #fpnt will be expanded by the proceprocessor to a string literal with the function name.
Then when your codebase called:
function_caller(some_function)
refactor it to:
function_caller_autoname(some_function)
# will be expanded to by the processor:
# function_caller("some_function", some_function)
or refactor it manually to provide the name/identificator/description of the function:
function_caller("Some function: ", some_function)
That way you can pass a custom string that describes the function along with the pointer. Also, each developer can pass a custom description string.

Is it possible to call functions from arrays in C? [duplicate]

This question already has answers here:
How can I use an array of function pointers?
(12 answers)
Closed 4 years ago.
When I was making my terminal i was wondering if I can call a function by array.
(This code is not done yet so please code is a bit messy.)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <unistd.h>
#include <limits.h>
#define true 1
#define false 0
typedef int bool;
/* Static */
static char Input[CHAR_MAX];
static char CurrentDirectory[CHAR_MAX];
static char *Command;
static char *Argument;
static char *Commands[]={"test","test2"};
/* Functions */
int Check_Command();
int test();
int test2();
/* --------- */
int main(){
printf("#######################\n\tterminal\n\tType \"help\" for the list of commands\n#######################\n");
prompt:
printf(">");
fgets(Input,CHAR_MAX,stdin);
int res=Check_Command();
if(res==0){printf("Unknown Command!\n");}
goto prompt;
}
/* Check_Command() function returns 0 if doesn't suceed and returns 1 of it suceeds */
int Check_Command(){
//Since input variable is static, no need to send in arguments
Input[strcspn(Input,"\r\n")]=0;
Command=strtok(Input," ");
Argument=strtok(NULL," ");
int x=0;
while(x<sizeof(Commands)){
if(strcmp(Command,Commands[x])==0){
Commands[x](); <----- Can I call a function like this?
return 1;
}
x++;
}
return 0;
}
/* Commands */
int test(){
printf("Success!\n");
getchar();
exit(0);
}
int test2(){
print("Success [2] \n");
getchar();
exit(0);
}
If this possible then this would be lit, Im too lazy to make commands into a executable and using if statements for all commands.
if you are too lazy to read the whole code here is a basic concept (UNTESTED):
static *Commands[]={"test","test2"};
int main(){
char *Command="test";
int x=0;
while(x<sizeof(Commands)){
if(strcmp(Command,Commands)==0){
Commands[x]();
}
x++
}
}
int test(){
printf("Hi");
}
int test2(){
printf("hey");
}
Edit:
static char Commands[]={test,test2}; DOES NOT WORK
This also includes the "possible duplicate" answer. (Im using Mingw, Windows 10)
It appears that you want to be able to take in a string such as test2 from the user, and then invoke the function test2(). There are two main ways you can approach this:
Homebrew structure mapping names to function pointers.
Using 'dynamic library loading' and function name resolution.
Array of structures
For the first, you define a structure such as:
struct FuncName
{
const char *name;
int (*function)(void);
};
And you can then define an array of these:
struct FuncName functions[] =
{
{ "test", test },
{ "test2", test2 },
};
enum { NUM_FUNCTIONS = sizeof(functions) / sizeof(functions[0]) };
When you get a name from the user, you can search through the array of names and find the matching function pointer to call.
int invoke_function(const char *name)
{
for (int i = 0; i < NUM_FUNCTIONS; i++)
{
if (strcmp(name, functions[i].name) == 0)
{
return (*functions[i].function)();
// Or just: return functions[i].function();
}
}
return -1; // No match found
}
This works reliably on all systems, but the demerit is that you must create the table of function pointers when you compile the program.
Dynamic library
The alternative is to use functions dlopen() and dlsym() from the <dlsym.h> header on Unix (POSIX) systems, or the equivalent on Windows.
Normally, you expect to find the functions in dynamically loaded libraries loaded with dlopen(), but there's usually a way to search the main executable for the names instead (pass a null pointer as the file name to dlopen() on POSIX systems). You can then call dlsym() to get the function pointer corresponding to the name you specify, which you can call.
void *dlh = dlopen(NULL, RTLD_NOW);
int (*funcptr)(void) = (int (*)(void))dlsym("test", dlh);
return (*funcptr)();
This omits error checking and you need the cast to convert from an object pointer (void *) to a function pointer because the C standard does not require that to be doable, but POSIX does (see the specification of
dlsym() already linked to).
Non-uniform function signatures
With both solutions, life is easy if all the callable functions have the same interface. Life is much messier if the different functions have different interfaces (so some expect no arguments, some expect one, some expect two, and the types of the arguments vary between functions, as do the return types). Expect to use lots of casts and be prepared to bludgeon the compiler into submission — isolate the code from everything else so as to leave the non-portable part well separated from the main code.
Beware: no compiler was consulted about the validity of any of this code!

Can anyone explain a misunderstanding with functions?

I want to understand why we write this DWORD MyExceptionHandler(void);
and this int foo(char *buf);, two times in this example.
Why we just write those functions without writing the definition:
DWORD MyExceptionHandler(void);
int foo(char *buf);
Example:
#include <windows.h>
#include <stdio.h>
DWORD MyExceptionHandler(void);
int foo(char *buf);
int main(int argc, char *argv[])
{
HMODULE l;
l = LoadLibrary("msvcrt.dll");
l = LoadLibrary("netapi32.dll");
printf("\n\nHeapoverflow program.\n");
if(argc != 2)
return printf("ARGS!");
foo(argv[1]);
return 0;
}
DWORD MyExceptionHandler(void)
{
printf("In exception handler....");
ExitProcess(1);
return 0;
}
int foo(char *buf)
{
HLOCAL h1 = 0, h2 = 0;
HANDLE hp;
__try{
hp = HeapCreate(0,0x1000,0x10000);
if(!hp){
return printf("Failed to create heap.\n");
}
h1 = HeapAlloc(hp,HEAP_ZERO_MEMORY,260);
printf("HEAP: %.8X %.8X\n",h1,&h1);
// Heap Overflow occurs here:
strcpy(h1,buf);
// This second call to HeapAlloc() is when we gain control
h2 = HeapAlloc(hp,HEAP_ZERO_MEMORY,260);
printf("hello");
}
__except(MyExceptionHandler())
{
printf("oops...");
}
return 0;
}
A function has to be declared before you can call it. There are two ways to do it:
You can put the entire function definition before the definitions of any functions that call it. The definition serves as a declaration as well.
You can put a prototype of the function before the definitions of any functions that call it. This simply declares the function's parameter and return types. The definition can be put later, or even in another compilation unit that you link with later.
Many programmers like to put prototypes of all their functions at the beginning of the file. This allows them to put the definitions in any order, rather than keeping track of which calls which so you can get all the dependencies right. In particular, it allows you to put the main() function first, which can make it easier to follow the logic of the program.

Multiple instances of main method in C

I've got an issue with an assignment, but I'm not asking for help to do the assignment, just single problem.
My code is like this:
#include "linux/kernel.h"
#include "linux/unistd.h"
#include <linux/slab.h>
typedef _msg_t msg_t;
struct msg_t { /* members here */ };
static msg_t *bottom = NULL;
static msg_t *top = NULL;
int function_one (argA, argB) {
/* function is working, no need to show code*/
}
int function_two (argA, argB) {
/* function is working, so no need I guess to show the code*/
}
int main(int argc, char ** argv) {
char *in = "This is a testing message";
char msg[50];
int mlen;
function_one(in, strlen(in)+1);
mlen = function_two(msg, 50);
}
Here's the problem: When I do the make command from the directory, I get the error
/home/<username hidden by me>/dm510/linux-3.18.2/arch/um/os-linux/main.c:118:
multipli definition of 'main'
arch/um/kernel/built-in.o:
/home/<username hidden again>/dm510/linux-3.18.2/arch/um/kernel/file_i_created.c:60
first defined here"
What does this error mean? I only defined the main method one time in my own file
The message says you have (at least) two C files, main.c and file_i_created.c that are included in the build. Both have main() functions. (In C, the term is "function", not "method".) Remove one of those source files, or remove/rename the main() function in one of them.
You have multiple approaches here:
Usually there is only one main in a program. If so, decide, which is the actual main and rename the other one
If both mains are essential, you could try putting them in seperate namespaces
Really can't tell without seeing the file_i_created.c code though. Could be something else as well.

Parameters to factory method in C

I need to create an instance of my abstract data type, but creating the instance needs some parameters. Now, how should I pass these parameters to the function? There's a lot of parameters, and I would love to have most of them the default value. I see several ways to solve this, however I can not decide which is best.
First option:
MyADT_t *my_adt_create( const char* a_long_config_string);
..where a_long_config_string is a string like "param1=value;param2=value"
This is appealing, but I guess there will be a messy parsing of the string (and error checking) inside the function.
Second option:
MyADT_t *my_adt_create( int paramc, char *paramv[]);
This mimics the command line input style main(int argc, char *argv[]) and could may be implemented with an command line option library, like getopt or popt.
Third option:
Use an variadic function like:
MyADT_t *my_adt_create( int mandatory_param, ...);
..and then in the function read the parameters in pairs of parameter and value. Maybe not much different from second option, but still different.
Additional info: I guess some of the parameters for the factory method will be provided from the command line options. Does this make the choice any simpler?
Edit
To clearify: What if I want my program to launch like this:
myprog --some-general-opt=hello --adt-optinon-a=value --adt-option-b=value
or maybe:
myprog --some-general-opt=hello --adt-options='a_long_config_string'
Another option: use a struct. Pop it in an .h file somewhere, and pass that to the method: that way, you get type-safety, and it's totally obvious to the calling function what's going on.
Example of your struct typedef (uncompiled):
typedef struct {
int size;
char content_flags;
...
} ADT_PARAMS;
Then, in your ADT.c file:
MyADT_t *my_adt_create(ADT_PARAMS *p) {
...
}
To handle the arguments coming in off the command line, there is a getargs function which solves the problem of getting named arguments generally, I personally prefer to knock something up with sscanf, so something like
const char *fmt = "--%s=%s";
int main(int argc, char **argv)
{
int i;
const ADT_PARAMS p = {..default ADT parameters}
for(i = 1; i < argc; i++) {
char *key, *value;
char *cur = *(argv + i);
if(!sscanf(fmt, &key, &value)) {
fprintf(stderr, "Error reading argument: '%s'\n", cur);
return 1;
}
if(!strcmp(key,"some-value")) {
p.some-value = ...
}
}
}

Resources