Printing --help text on GNU/Linux with the standard format - c

On GNU/Linux terminal, when I add --help to commands from GNU packages, I get a help text that is formatted in a very consistent way. These help texts list the options accepted by that command with this format:
option characters, long options ............ [aligned] explanation of the option
For example, this is a part of the help text of the man command:
Usage: man [OPTION...] [SECTION] PAGE...
-C, --config-file=FILE use this user configuration file
-d, --debug emit debugging messages
-D, --default reset all options to their default values
--warnings[=WARNINGS] enable warnings from groff
Main modes of operation:
-f, --whatis equivalent to whatis
-k, --apropos equivalent to apropos
-K, --global-apropos search for text in all pages
-l, --local-file interpret PAGE argument(s) as local filename(s)
-w, --where, --path, --location
print physical location of man page(s)
-W, --where-cat, --location-cat
print physical location of cat file(s)
I was wondering if there was a standard way (possibly used by GNU packages) to print with the same format, without having to deal with tab stops etc. I have found getopt from POSIX API to parse these options, but I can't find a way to print a list of them.

The GNU tools use argp, which is part of the GNU C library. It offers more options than getopt, including help.
See: https://www.gnu.org/software/libc/manual/html_node/Argp.html

Related

how to print all the undefined function calls along with file name from shared object?

I am trying to print all the Undefined function calls from a shared object file along with file name.
I tried with "nm" command, It print all the undefined function calls .But could not get the file name.
Example:
bash$ nm -u my_test.so
:
U _ZNSs4_Rep20_S_empty_rep_storageE##GLIBCXX_3.4
:
Environment : Ubuntu 18.04 , X86 Arch (Intel processor)
Study in details the specification of the DWARF format (which is the format used by debugging information on Linux). So you could extract the information (but it is not exactly simple) by parsing the DWARF inside your ELF binary.
Consider looking inside the source code of Ian Taylor's libbacktrace. It is doing this extraction of file name from DWARF inside ELF.
Perhaps your real problem is getting precise backtrace information, and then that libbacktrace is exactly what you need!
You might also use gdb : it is extensible and scriptable in Python (or Guile) and you could write your own specialized script.
Perhaps you'll better solve your real problem with some GCC plugin working when you compile your code.
Read How to write shared libraries by Drepper and read more about ELF.
You could for example collect all the undefined symbols in your shared library using nm (or readelf). Then a second script will find the occurrences of these in your source code. It could be even a simple awk script (or some for shell loop using grep), or something as sophisticated as a GCC plugin.
Your example shows (probably) a mangled C++ name. You could use nm -C to get it unmangled. And later write a GCC plugin to find all the GIMPLE CALL instructions using it.
Writing a GCC plugin may take some time, in particular if you are not familiar with GCC internals.

UNIX: C: cc compiler. Command Line: How to display the binary file header on screen

I am looking for the unix command to display the header portion in Hex for any excutable that has been compiled by the cc compiler.
I had this once and now I cant remember it.
I just want to see what the compiler code that is at the start of any c programs that I compile
I am aware that I can use 'hexdump [filename]' however that doesnt isolate the header portion .
Hope i have explained myself well enough.....
The command readelf is available on most Linux systems and has the ability to display many parts of an ELF file. You can use readelf -H to get a short synopsis of the various options.
To get just the file header you can use readelf -h or readelf --fileheader to display the file header.
To see it in hex, you can use the command xxd. Given that the elf header is 64 bytes (on a 64-bit machine), you can use xxd -l 64
Objdump command in Linux is used to provide thorough information on object files. This command is mainly used by the programmers who work on compilers, but still its a very handy tool for normal programmers also when it comes to debugging. In this article, we will understand how to use objdump command through some examples.
Basic syntax of objdump is :
objdump [options] objfile...
There is a wide range of options available for this command.
For example, factorial is the c program that I have to compiled.
1.Display object format specific file header contents using
-p option
The following example prints the object file format specific information.
$ objdump -p factorial
Display the contents of all headers using -x option
Information related to all the headers in the object file can be retrieved using the -x option.
objdump -x factorial

Need to figure our what a specific symbol is replaced to after macro expansion [duplicate]

Let's say I have a source file with many preprocessor directives. Is it possible to see how it looks after the preprocessor is done with it?
cl.exe, the command line interface to Microsoft Visual C++, has three different options for outputting the preprocessed file (hence the inconsistency in the previous responses about Visual C++):
/E: preprocess to stdout (similar to GCC's -E option)
/P: preprocess to file
/EP: preprocess to stdout without #line directives
If you want to preprocess to a file without #line directives, combine the /P and /EP options.
Most compilers have an option to just run the preprocessor. e.g., gcc provides -E:
-E Stop after the preprocessing stage; do not run the compiler proper.
The output is in the form of preprocessed source code, which is sent
to the standard output.
So you can just run:
gcc -E foo.c
If you can't find such an option, you can also just find the C preprocessor on your machine. It's usually called cpp and is probably already in your path. Invoke it like this:
cpp foo.c
If there are headers you need to include from other directories , you can pass -I/path/to/include/dir to either of these, just as you would with a regular compile.
For Windows, I'll leave it to other posters to provide answers as I'm no expert there.
Right-click on the file on the Solution Explorer, goto Properties. Under Configuration Properties->C/C++->Preprocessor, "Generate Preprocessed File" is what you are looking for. Then right-click on the file in the Solution Explorer and select "Compile". The preprocessed file is created in the output directory (e.g. Release, Debug) with an extension .i (thanks to Steed for his comment).
You typically need to do some postprocessing on the output of the preprocessor, otherwise all the macros just expand to one liners, which is hard to read and debug. For C code, something like the following would suffice:
gcc -E code.c | sed '/^\#/d' | indent -st -i2 > code-x.c
For C++ code, it's actually a lot harder. For GCC/g++, I found this Perl script useful.
I don't know anything about Microsoft compiler, but on GCC you can use this:
gcc -E -P -o result.c my_file.h
If you want to see comments use this:
gcc -E -C -P -o result.c my_file.h
More options avaliable on this page.
Try cl /EP if you are using Microsoft's C++ compiler.
As bk1e and Andreas M. answered, the /P option for the compiler will cause it to preprocess a file. However, in my project using VS2005 and Platform Builder (for an embedded ARM processor), the project did not present an option in the dialog box (as described by Jim B) to enable that option.
I could run CL manually and add /P, but it failed because I did not know all of the appropriate command-line options that were invisibly being activated by Platform Builder during the full build. So I needed to know all of those options.
My solution was to go look in the build.log file, and find the line that executed
CL blah-blah-blah myfile.c
I copied this line to the clipboard. The "blah-blah-blah" part contained the build options, and was huge.
Back in the IDE, I right-clicked on myfile.c, chose "Open Build Window", and then in that window I pasted the build command-line, and added a "/P".
CL /P blah-blah-blah myfile.c
Done. The myfile.i file was produced, which contained the preprocessor output.
In Visual Studio you can compile a file (or project) with /P.
CPIP is a new C/C++ preprocessor written in Python. If you want a detailed visual representation of a preprocessed file, give it a shot.
CPIP is a C/C++ pre-processor implemented in Python. Most pre-processors regard pre-processing as a dirty job that just has to be done as soon as possible. This can make it very hard to track down subtle defects at the pre-processing stage as pre-processors throw away a lot of useful information in favor of getting the result as cheaply as possible.
Few developers really understand pre-processing, to many it is an obscure bit of black magic. CPIP aims to improve that and by recording every detail of preprocessing so CPIP can can produce some wonderfully visual information about file dependencies, macro usage and so on.
CPIP is not designed to be a replacement for cpp (or any other established pre-processor), instead CPIP regards clarity and understanding as more important than speed of processing.
On Windows OS, a simple one line answer to this question is to use the below command in DOS prompt to see the preprocessed file:
CL /P /C myprogram.c
This will generate a file called myprogram.i. Open it and look out for your expanded preprocessors.

[Makefile]Adding colors doesn't work on OS X

I recently switched to a Macbook Air and thus to OS X.
I imported some of my current projects to it and tried to compile them with my Makefile.
My Makefile has some custom imput adding colors with /bin/echo -e "\033[0;31m" for example + the text. It's working great on my old computer (OpenSuse distrib) but it doesn't even compile my binary anymore on my Mac.
Here's what I get when I try to prompt a custom line through my Makefile :
-e \033[0;31m (MY TEXT) \033[00m
As I use custom imput when compiling my .o files, none of them are get compiled so my project build fail.
My Makefile work great without these custom output but I'd like to know why they don't work on OS X.
I can post my Makefile code if some people request it for further investigation.
This is similar, but not quite a duplicate of Color termcaps Konsole?. The problem is that -e is not an option of OSX echo (which follows POSIX). If you take out the -e, it will work as you expect.
The -e option is used in some implementations to allow \e as a synonym for \033 (but your example uses the latter anyway).
Whether you use echo or printf for POSIX scripts is largely a matter of taste, since both accept the same set of backslash sequences. For example printf, of course, accepts % sequences for formatting numbers, but C++ programmers have gotten into the habit of (cout vs echo) not using the printf-style calls.
For reference.
printf - write formatted output
echo - write arguments to standard output

Finding path of Builtins and executables for commands in Linux

I am trying to implement 'whereis' command in C. But I was able to implement it partially. When I ever I try 'whereis' in Linux shell, lets say for e.g. whereis ls .. I get the following results
$ whereis ls
/bin/ls
/usr/share/man/man1p/ls.1p.gz
/usr/share/man/man1/ls.1.gz
I am able to get the first path using the PATH env.variable. But I have no clue how to find the other two paths. Any pointers how to find those paths.
On Linux (but not on all systems, e.g. Mac OS), whereis searches in $MANPATH (or some other default places) for matching files, which for ls are something like this:
$MANPATH/man(.+)/ls\.\1(\.gz)?
If you really need to know how whereis works, you can simply look at its source....
man whereis (Ubuntu 11.04) mentions the following paths:
/{bin,sbin,etc}
/usr/{lib,bin,old,new,local,games,include,etc,src,man,sbin,X386,TeX,g++-include}
/usr/local/{X386,TeX,X11,include,lib,man,etc,bin,games,emacs}
Another option generally available is which. It will return the fully-qualified path and executable name for the executable. For example:
$ which ls
/usr/bin/ls
It may help you in your whereis endevour and is also useful for portability in scripts to set the executable where it may be located in different places on different distributions:
my_ls=$(which ls 2>/dev/null)
[ -x "$my_ls" ] || {
echo "ls not found"
exit 1
}

Resources