How to embed shell snippets in doxygen documentation - shell

When installing my package, the user should at some point type
./wand-new "`cat wandcfg_install.spell`"
Or whatever the configuration file is called. If I put this line inside \code ... \endcode, doxygen thinks it is C++ or... Anyway, the word "new" is treated as keyword. How do I avoid this is in a semantically correct way?
I think \verbatim is disqualified because it actually is code, right?
(I guess the answer is to poke that Dimitri should add support for more languages inside a code block like LaTeX listings package, or at least add an disableparse option to code in the meantime)

Doxygen, as of July 2017, does not officially support documenting Shell/Bash scripting language, not even as an extension. There is an unofficial filter called bash-doxygen. Simple to setup: only one file download and three flags adjustments:
Edit the Doxyfile to map shell files to C parser: EXTENSION_MAPPING = sh=C
Set your shell script file names pattern as Doxygen inputs, like
e.g.: FILE_PATTERNS = *.sh
Mention doxygen-bash.sed in either the INTPUT_FILTER or the
FILTER_PATTERN directive of your Doxyfile. If doxygen-bash.sed is in
your $PATH, then you can just invoke it as is, else use sed -n -f /path/to/doxygen-bash.sed --.
Please note that since it uses C language parsing, some limitations apply, as stated in the main README page of bash-doxygen, one of them, at least in my tests, that the \code {.sh} recognises shell syntax, but all lines in the code block begin with an asterisk (*), apparently as a side-effect of requiring that all Doxygen doc sections have lines starting with double-hashes (##).

Related

How to implement file-substitution macro in bash?

I have a set of text files and a set of GoLang files. The GoLang files contain directives such as the following:
//go:embed hello.txt
var s string
I want to write a bash script which takes the above code and substitutes the following in its place:
var s string = "<contents of hello.txt>"
Specifically, I want to bash script to go through all GoLang source files and replace all go:embed/string declaration pairs with a string defined to be the contents of the file specified in the embed directive.
I'm wondering if there is an existing program which can be configured to do the above. Otherwise, I'm planning on writing the algorithm myself.
Further explaination:
I am trying to replicate GoLang's embed directive (https://tip.golang.org/pkg/embed/).
We are not yet on GoLang 1.16, so we cannot use this functionality, but we are replicating it as closely as possible so that moving over to the standard implementation is as painless as possible.
Below is an attempt at solving your problem:
for i in file1 file2; do
awk '/^\/\/go:embed /{f=$2;next}/^var/&&f{printf"%s = \"",$0;system("cat "f);print"\"";f=0;next}1' < "$i" > "$i.new"
done
The awk script prints all normal lines, only if it encounters the embed directive this line will be skipped (and the file name remembered in variable f). A subsequent line starting with var will then be extended by the content of the file with the remembered name (using the system call "cat").
Beware, there are no error checks at all, no attempt to fix quotes and whatever. So for practical use - unless the file contents you are about to embed are known to be good-natured - you probably have to take a more sophisticated approach.

ctags tag address as a line number

I am creating an IDE and I wish to implement jump to definition.
I found the perfect tool for it: ctags (https://github.com/universal-ctags/ctags)
Now the only problem is that the tags file that ctags create looks something like this:
QLineNumberArea 2point56mb.py /^class QLineNumberArea(QWidget):$/;" c
I understand the format: {tagname}Tab{tagfile}Tab{tagaddress}
So from what I understand: tagname: QLineNumberArea, tagfile: 2point56mb.py and tagaddress: /^class QLineNumberArea(QWidget):$/;" c`
The tagaddress looks like gibberish but it's a vim/ex editor command that takes you to the definition.
Now from what I read on this website: https://github.com/cztchoice/ctags/wiki/Tag-Format
Under Security it states:
Specifically, these two Ex commands are allowed:
A decimal line number:
89
A search command. It is a regular expression pattern, as used by Vi, enclosed in // or ??:
/^int c;$/
?main()?
Now here comes the problem:
I need my tags file to have a line number, instead of the search command.
I tried looking the documentation for ctags (http://docs.ctags.io/en/latest/) but I couldn't find anything that would help me.
Does anyone know how make ctags give tag addresses as a line number, rather than a search command?
That documentation is only for the changes introduced by universal ctags. What you're looking for is the documentation for exuberant ctags:
−−excmd=type
Determines the type of EX command used to locate tags in the source file. [Ignored in etags mode]
Which can also be achieved with -n.

What is the best way to create a configuration file in bash?

I use bash to configure many of my build tools.
I want to use variables to set certain things so that the build tools can be used in many environments.
Currently I do
exports var=val
and then I do
$var
when I need to use it.
Is this the best way to go about it, as I know there are many ways to do things in bash.
**Example**
#!/bin/bash
path_bash="$HOME/root/config/bash/"
source "${path_bash}_private.sh"
source "${path_bash}config.sh"
source "${path_bash}utility.sh"
source "${path_bash}workflow.sh"
source "${path_bash}net.sh"
source "${path_bash}makeHTM.sh"
#
#
#
# Divider - Commands
#
#
#
cd ~/root
Skip the export unless you really need it (that is, unless you need that variable to propagate to unrelated (=execed) processes that you execute).
If you do export, it's usually a good idea to capitalize the variable (export VAR=val) to make it apparent that it will spread to executed binaries.
When you refer to a shell variable, you usually want to double quote it ("$var") unless you need glob expansion and whitespace-splitting (splitting on $IFS characters, to be exact) done on that variable expansion.
sparrow automation framework gives you an opportunity to configure bash scripts in many ways :
passing command line named parameters
configuration files in yaml format
configuration files in json format
configuration files in config::general format
Of course you need to pack your bash scripts into sparrow plugins first to get this behavior , but this is not a big deal . Follow https://github.com/melezhik/sparrow#configuring-tasks for details .
PS. disclosure - I am the sparrow tool author .

Find and replace in file with script

I want to find and replace the VALUE into a xml file :
<test name="NAME" value="VALUE"/>
I have to filter by name (because there are lot of lines like that).
Is it possible ?
Thanks for you help.
Since you tagged the question "bash", I assume that you're not trying to use an XML library (although I think an XML expert might be able to give you something like an XSLT processor command that solves this question very robustly), but that you're simply interested in doing search & replace from the commandline.
I am using perl for this:
perl -pi -e 's#VALUE#replacement#g' *.xml
See perlrun man page: Very shortly put, the -p switches perl into text processing mode, -i stands for "in-place", and -e let's you specify an expression to apply to all lines of input.
Also note (if you are not too familiar with that already) that you may use other characters than # (common ones are %, a comma, etc.) that don't clash with your search & replacement strings.
There is one small caveat: perl will read & write all files given on the commandline, even those that did not change. Thus, the files' modification times will be updated even if they did not change. (I usually work around that with some more shell magic, e.g. using grep -l or grin -l to select files for perl to work on.)
EDIT: If I understand your comments correctly, you also need help with the regular expression to apply. Let me briefly suggest something like this then:
perl -pi -e 's,(name="NAME" value=)"[^"]*",\1"NEWVALUE",g' *.xml
Related: bash XHTML parsing using xpath
You can use SED:
SED 's/\(<test name=\"NAME\"\) value=\"VALUE\"/\1 value=\"YourValue\"/' test.xml
where test.xml is the xml document containing the given node. This is very fragile, and you can work to make it more flexible if you need to do this substitution multiple times. For instance, the current statement is case sensitive, so it won't substitute the value on a node with the name="name", but you can add a case insensitivity flag to the end of the statement, like so:
('s/\(<test name=\"NAME\"\) value=\"VALUE\"/\1 value=\"YourValue\"/I').
Another option would be to use XSLT, but it would require you to download an external library. It's pretty versatile, and could be a viable option for more complex modifications to an XML document.

How to add comments to an Exuberant Ctags config file?

What character can I use to put comments in an Exuberant Ctags .ctags file?
I would like to add comments with explanations, and perhaps to disable some regexps.
But I can't find any comment character which ctags-exuberant accepts!
I keep getting the warning:
ctags: Warning: Ignoring non-option in /home/joey/.ctags
which is better than an error, but still a little annoying.
I have tried # // /* ... */ and ; as comments, but ctags tries to parse them all!
Here is an example file with some comments which ctags will complain about:
# Add some more rules for Javascript
--langmap=javascript:+.jpp
--regex-javascript=/^[ \t]*var ([a-zA-Z_$][0-9a-zA-Z_$]*).*$/\1/v,variable/
--regex-javascript=/^[ \t]*this\.([a-zA-Z_$][0-9a-zA-Z_$]*)[ \t]*=.*$/\1/e,export/
--regex-javascript=/^[ \t]*([a-zA-Z_$][0-9a-zA-Z_$]*):.*$/\1/p,property/
--regex-javascript=/^\<function\>[ \t]*([a-zA-Z_$][0-9a-zA-Z_$]*)/\1/f,function/
# Define tags for the Coffeescript language
--langdef=coffee
--langmap=coffee:.coffee
--regex-coffee=/^class #?([a-zA-Z_$][0-9a-zA-Z_$]*)( extends [a-zA-Z_$][0-9a-zA-Z_$]*)?$/\1/c,class/
--regex-coffee=/^[ \t]*(#|this\.)([a-zA-Z_$][0-9a-zA-Z_$]*).*$/\2/e,export/
--regex-coffee=/^[ \t]*#?([a-zA-Z_$][0-9a-zA-Z_$]*):.*[-=]>.*$/\1/f,function/
--regex-coffee=/^[ \t]*([a-zA-Z_$][0-9a-zA-Z_$]*)[ \t]+=.*[-=]>.*$/\1/f,function/
--regex-coffee=/^[ \t]*([a-zA-Z_$][0-9a-zA-Z_$]*)[ \t]+=[^->\n]*$/\1/v,variable/
--regex-coffee=/^[ \t]*#?([a-zA-Z_$][0-9a-zA-Z_$]*):.*$/\1/p,property/
You can't! I looked through the source code (thanks to apt-get source). There are no checks for lines to ignore. The relevant code is in parseFileOptions() in options.c
But sometimes comments are a neccessity, so as a workaround I put a comment in as a regexp, in such as way that it is unlikely to ever match anything.
--regex-coffee=/^(COMMENT: Disable next line when using prop tag)/\1/X,XXX/
The ^ helps the match to fail quickly, whilst the ( ) wrapper is purely for visual effect.
Your comment should be a valid regexp, to avoid warnings on stderr. (That means unescaped /s must be avoided, and if you use any [ ] ( or )s they should be paired up.) See Tom's solution to avoid these restrictions.
As #joeytwiddle points out, comments are not supported by the parser, but there is a work-around.
Example .ctags file:
--regex-C=/$x/x/x/e/ The ctags parser currently doesn't support comments
--regex-C=/$x/x/x/e/ This is a work-around which works with '/' characters
--regex-C=/$x/x/x/e/ http://stackoverflow.com/questions/10973224/how-to-add-comments-to-an-exuberant-ctags-config-file
--regex-C=/$x/x/x/e/
--regex-C=/$x/x/x/e/ You can add whatever comment text you want here.
You can use '#' as the start of comment if you are using Universal-ctag(https://ctags.io).
Given that comments don't work, what about a .ctags.readme file...
For most things you don't actually need a comment, e.g. you don't really need the comment below.
# Define tags for the Coffeescript language
--langdef=coffee
--langmap=coffee:.coffee
I can see however that you might want to add comments explaining some mind bending regex, so for each line that absolutely needs it you can copy paste it into the .ctags.readme file as a markdown file:
Forgive me father for I have regexed
It was purely because I wanted some lovely coffee properties
```
--regex-coffee=/^[ \t]*#?([a-zA-Z_$][0-9a-zA-Z_$]*):.*$/\1/p,property/
```
Keeping .ctags.readme and .ctags in sync
You could have a block at the bottom of the ctags file separated with a line break, then delete this final block.
If you only have the one line break in your .ctags file this sed will delete all the lines after the line break.
Then do some grepping for the --regex lines to append the lines from .ctags.readme into .ctags.
sed -i '/^\s*$/,$d' .ctags
grep "^--regex" .ctags.readme >> .ctags

Resources