Mandatory options with getopt_long() in C - c

With C/ C++, getopt_long() can be used to parse command line arguments. Is it possible to tell the function that some of the options are mandatory? For example, how can I tell getopt_long that the parsing should give error if startServer is called without mentioning the port below?
./startServer -port 80
Note: I am not talking of option arguments as mandatory but rather the options themselves.

getopt_long() is not part of the C language. It is a GNU invention which is available in some C implementations, but far from all.
The version of getopt_long() in glibc (used in most Linux distributions) does not allow you to specify that an option is mandatory. You'll have to check them explicitly after you're done parsing the command line.

Related

getopt does not order arguments in Windows

It seems that getopt behaves differently in Windows than in Linux. Windows requires a strict ordering of parameters while in Linux I can put the arguments in any order. Consider a program test which uses getopt compiled for Linux (gcc) and Windows (MinGW) and take this command line for example:
test file1.bin file2.bin -o output.txt
Executing this command in Linux would correctly parse -o output.txt as an option(+parameter) regardless of where I put -o output.txt. It could be between file1.bin and file2.bin as well and getopt parsing would still work correctly since it sorts the arguments by putting the optional ones infront of the mandatories.
Executing this command in Windows however results in incorrect parsing, giving me a wrong index in optind variable. It seems that the exact same code when compiled in Windows does not do the sorting part for me. Why is this, can we workaround this?
Transferring my comments to an answer as requested.
GNU getopt() permutes the arguments (so options can occur after non-option arguments) by default. Standard POSIX getopt() does not allow that. You can make GNU getopt() conform to POSIX by exporting the environment variable POSIXLY_CORRECT=1, or by starting the options argument with a + symbol.
Check the manual (or source) for MinGW getopt(), or the Microsoft implementation of it. Given what you see, it probably doesn't do the permutation. However, the linked source code does support permutation — you'll need to investigate what goes on there.
If you decide to use GNU getopt(), you'll need to get a copy of the GNU getopt() source code (maybe from GitHub getopt.c) and include it in your build process. If you use that, you'll also need ansidecl.h and getopt.h at minimum and you will need to tweak the configuration appropriately.
Or you'll have to decide that the GNU extension of permuting options isn't portable and therefore shouldn't be used at all.

Is there a standardized way to parse command line arguments in C?

I'm learning C programming language and trying to do some basic stuff with it. The problem I faced is how to parse command line arguments. I read this answer and tried to find the library summary for unistd.h functions int the standard N1570. But unfortunately it is not defined there (Work only for POSIX compliant OS as far as I can understand).
AFAIK Windows is not really POSIX compliant so something like in the answer I referred to above
#include <unistd.h>
int main(int argc, char *argv[]){
int opt;
while((opt = getopt(argc, argv, "ilv") != -1){
//do some with it
}
}
is not really portable.
QUESTION: The only standardized and portable way to parse command line args is to do it yourself?
Is there a standardized way to parse command line arguments in C?
Yes there is. Not standardized by the C committee, but by others. The most commonly widespread is POSIX with it's Utility Conventions and getopt utility. Using GNU Argument Syntax with argp is just fun and cool. There is also commonly used GNUs getopt_long for supporting long arguments with getopt.
The only standardized and portable way to parse command line args is to do it yourself?
There is none standardized in C11 way to parse command line. The C11 only specifies, that the main arguments are strings, but they're value is just implementation-defined:
If the value of argc is greater than zero, the array members argv[0] through argv[argc-1] inclusive shall contain pointers to strings, which are given implementation-defined values by the host environment prior to program startup. The intent is to supply to the program information determined prior to program startup from elsewhere in the hosted environment.
The C standard doesn't introduce an abstraction of a "command line", so an abstraction consisting of "command line arguments" and furthermore "command line arguments parsing" is just not defined. I think introducing a standardized way to parse command line arguments is out of scope for a C standard.
The most portable way is to write and use the most portable code. Indeed the most portable code would not use any non-standard C libraries and "do it yourself" in a most portable manner.There is little sense to target all possible architectures and environments. If you are going only for GNU/Linux, I would go with getopt if you want to stay portable to some crazy environment and for argp if you want just to target GNU/Linux specific systems. getopt is really widespread, even a library for embedded systems like newlib has getopt and getopt_long implemented. For others, you can just copy/include the code for getopt from other sources into your program, thus protecting against environments that doesn't have it.

C compiler option in Bazel CROSSTOOL file

How does one set C only (not C++) compiler flags in the CROSSTOOL file in Bazel.
compiler_flag can be used for both C and C++, cxx_flag for C++ code. What is the corresponding way to set C only options.
In particular I need to specify -std=c99 as an option. The only way I know of doing this right now is by passing copts = ["-std=c99"] to every target which is messy and error prone.
Looking at the protobuf of CROSSTOOL I don't think it's supported. You could write a Skylark macro called "c_library/c_binary" or something similar, and add your required copt before calling cc_library/cc_binary underneath.

Use #$? symbols in a C function/variable

I'm curious if there's any way to use #, $, or ? in a C function or variable name. I know that linkers allow them (because of C++ name mangling).
Is there any kind of escape code that could allow this (I don't care how ugly it looks)? Or, in standard C, is this completely impossible?
It is not possible in purely standard C.
But if using GCC (or probably Clang/LLVM) you can have $ in identifiers, and you can set the linker name using asm labels
You could perhaps also play GNU ld tricks with ld scripts.
Standard C does not allow any of these (and it can't really allow ? since it's an operator and thus a separate token). GCC (and possibly compatible compilers) allow $ but not the others. However, you could use the GNU C (GCC) extension for making a declaration for an external-linkage name that references a different underlying symbol name; this may achieve what you want, e.g. if you're trying to reference C++ symbols. I believe the syntax is something like adding __asm__("symbol_name") to the end of the function declaration. There are some examples in the glibc headers on most Linux systems.
Alternatively, if you have dlsym, you could use it to look up the names at runtime.

A Windows C compiler that doesn't split arguments in its runtime libraries?

I have heard that in Windows, parameters are passed a single parameter, and then the program splits it into arguments, either in its runtime libraries, or sometimes, in the actual code.
I've heard that most C/C++ compilers do it in runtime libararies (for example, TCC - Tiny C Compiler, which I downloaded)
Are there any C compilers I can download, that don't? Any links to them?
And in such a compiler, would argsv[0] have the whole string?
Added
It's based on what this person (jdedb) said in Super User question Can't pipe or redirect Cygwin grep output, after seeming to suggest that I ask on Stack Overflow.
"It's up to the called program to split the command tail into words, if it wants to operate in Unix (and C language) fashion. (The runtime support libraries of most C and C++ language implementations for Win32 do this splitting behind the scenes."
He said it's the compilers.. But according to Necrolis, it's not the compiler.
(added- Necrolis commented correcting my misreading, compiler!=runtime library)
If you are on Windows, just use GetCommandLine. This is how most CRT wrappers get the command line to split to start with.
As for your actual question, it's not the compiler, but the CRT startup wrapper that they use. If you implement mainCRTstartup, and override the entrypoint with it, you can do whatever you want. A good example of how it works can be seen here.
That "parameter splitting" is the way mandated by the C99 Standard (PDF file) in 5.1.2.2.1.
If an implementation (compiler + library + options) recognizes but does not separate the program name from the other parameters (and parameters from each other) it is not conforming.
Of course, if you use a free-standing implementation none of this applies.

Resources