I really dislike the default indentation used on return type of functions, e.g.
\im (for main function has the return type indented). I would like return type not indented.
Documentation says -- I should rename the snippet $HOME\vimfiles\c-support\codesnippets\main.c to main.c.ni (or main.c.nonindent). But that did not fix the problem.
Any other ideas ?
gvim with c-support by default adds this
int
main ( int argc, char *argv[] )
{
return EXIT_SUCCESS;
} /* ---------- end of function main ---------- */
instead, I would like this
int
main ( int argc, char *argv[] )
{
return EXIT_SUCCESS;
}
Please, have a look at :help cinoptions and :help cinoptions-values.
What you want is probably :set cinoptions=t0 or :set cinoptions+=t0.
Related
I'm working with a large C++ project that presently produces 66 different binaries. Each entrypoint contains its own global variables and main() function, though there's a lot of common code that's provided through a shared library.
For ease of distribution, I would like to distribute a single statically-linked binary, like you'd get from a Go or Rust project. Instead of invoking:
./ProgramFoo
./ProgramBar
I'd like to have a single combined binary that "execs" itself into one of those tools behind the scenes based on argv parameters, sort of like how busybox works:
./CombinedProgram ProgramFoo
./CombinedProgram ProgramBar
Look, I get that there's a "right" way to do this — refactor all 66 source files. Replace all global state with class singletons. Replace all the main() functions with entrypoint functions that could be dispatched from a single, unifying main() function. That sounds like a lot of work and a fair amount of disruption to all the other developers on the project. Is there truly no alternative on the compiler/linker level?
(I also don't want to just archive the binaries inside the CombinedProgram, write them to disk, and exec them. Boo. If I wanted a tarball, I'd just use a tarball.)
My understanding of C/C++ binary production is that the compiler will insert a crt0 startup routine that will initialize all my global state and then invoke main() with the appropriate parameters. Could I... perhaps... sneak some code in before that crt0 that peeks at argv and then proceeds down the correct code path?
Is there truly no alternative on the compiler/linker level?
Not really. Refactoring is the best / least work way to accomplish your task.
% cc -o one busy.c ; ln one two ; ./one ; ./two
one
two
The main() needs to look at ARGV[0] to determine how it was called. Then act on that information.
Simplest example:
#include <stdio.h>
#include <string.h>
int one(int argc, char **argv) {
printf("one\n");
return 1;
}
int two(int argc, char **argv) {
printf("two\n");
return 2;
}
int main(int argc, char **argv) {
char *end = argv[0];
int len = strlen(end);
end += len; // jump to the end of the command.
if (argc >= 1) {
if (!strcmp(end-3, "one")) {
return one(argc, argv);
} else if (!strcmp(end-3, "two")) {
return two(argc, argv);
}
}
}
I don't know of a tool that automatically refactors the commands into functions. The alternative is having one file determine what to do and then exec one of the 66 other statically-linked binaries.
I want to check the value of a variable that I set inside the main function, but the if statement is not inside a function.
Here is what I have so far.
bool condition;
#if(condition)
:
:
:
some code
#endif
int main(int argc, char *argv[])
{
condition = processArgs(argc, argv);
}
From my understanding macros are executed during compilation time and not run time. Is there another way to check the value of the variable condition outside functions. The value of the variable condition is set depending on the command line arguments passed by the user.
So how do I use if statements outside the scope of functions? Because macro if does not work.
If you are doing those tasks using macros(I guessed from the question) then you can try doing:
#define _condition(x) Condition(x)
bool Condition(bool result)
{
if(!result)
{
///some code
}
return false;
}
int main(int argc, char *argv[])
{
bool result=processArgs(argc, argv);
_condition(result);
}
This way you'll be defining a macro for checking the value of the result variable that I added. The macro _condition will call the function for you and you can add any more code in the function without making a mess of the macro because one cant possibly put a function like defining a macro. If you were not doing macros then you can try calling the function directly and not using macros. Macros are a very useful yet complicated stuff so it is hard to make such large functions that you did in the function
You want to add a function:
void myFunction(bool condition)
{
if (condition)
{
// some code
}
// some code
}
int main(int argc, char *argv[])
{
bool condition = processArgs(argc, argv);
myFunction(condition);
}
that way, you tell the compiler when to run it, and what condition to use.
For some reason, I can't start gtest tests from commandline, so I can't pass any arguments to it. I want to run InitGoogleTest already with a parameter defined in code.
Somewhere on the Internet I found a solution like this:
int main(int argc, char **argv) {
char *option[] = { "test.exe", //it doesn't have meaning, just dummy
"--gtest_output=xml:filename" };
int argc1 = 2;
::testing::InitGoogleTest(&argc1, option);
return RUN_ALL_TESTS();
}
This solution didn't produce any errors but didn't create any xml with report either.
Can anyone suggest how to force gtest to write xml from Init?
You can override the output flag by adding
::testing::GTEST_FLAG(output) = "xml:filename";
before the call to InitGoogleTest. You can read more on it at Google Test docs.
class Test
{
public:
int i;
};
int main(int argc, char const *argv[])
{
Test *i = new Test;
return 0;
}
Is it possible to get support for the arrow notation? So if I write i. it automatically gets expand to i->
I am using SublimeClang. If something like this doesn't exist, would it be possible it create such a plugin?
Take a look at Autohotkey for windows, using this tutorial. or on Linux use Autokey, by following this tutorial.
However, how hard can typing one extra character be as chris said? What if not everything is a pointer?
I am trying to learn how to make a program in C++ that when you run it, you can tell it to run and specify options all in one line. For example you can do ipconfig /all in CMD and it runs ipconfig.exe with the option /all. Another example would be shutdown -f which tells the computer to shutdown with the option -f. For example, I want to make a program that downloads something from a URL and call it for example downloader. From command line one would type downloader http://filehere.com /h which would download the file with the /h option which I would define its property in my program. I don't want code or guides on how to make a downloader I am just trying to learn how to specify options like the /h. Are there any guides out there that you know of and could post or any sample code? I have tried searching for guides, but I think I just don't know what this operation is actually called. Thank you.
You typically define your main function to take two arguments: int argc and char *argv[], such as:
int
main(int argc, char *argv[])
{
...
The first argument is how many parameters your program received, argv is a pointer to them. Note, this isn't mandated, you can name them whatever you want, but that's the convention. Just make sure your types match up.
You can use an option-parsing library, but those are often OS-specific. One simple way to check if you received a /h is:
int got_h = 0;
for (int i=0; i<argc; ++i)
if (strcmp(argv[i], "/h") == 0)
got_h = 1;
...
if (got_h)
...
argv[argc] will always be NULL to make iterating through them easier.
Some more information here: http://www.site.uottawa.ca/~lucia/courses/2131-05/labs/Lab3/CommandLineArguments.html
The main function takes two arguments, traditionally named argc and argv:
int main (int argc, char * argv[])
{
// ...
}
argc contains the number of arguments passed on the command line, and the argv array contains such arguments (with argv[0] being the name used to invoke your program); the last element of the argv array (i.e. argv[argc]) contains a NULL pointer.
Depending upon your proficiency and inclination to use pointers, you may prefer to capture the command line as a vector<string>:
// UNTESTED CODE
int main(int argc, char **argv) {
std::vector<std::string> args(argv+1, argv+argc);
if(args.empty()) {
std::cout << "Usage: downloader URL [options]\n";
return 1;
}
if(std::find(args.begin(), args.end(), "/h") != args.end()) {
option_h = true;
}
Download(args[0]);
}