Integrate Cppcheck with Emacs - emacs

Is it possible to integrate Cppcheck with Emacs in a more sophisticated way than simply calling the shell command on the current buffer? I would like Emacs to be able to parse Cppcheck's messages and treat them as messages from a compiler (similar to how compile works), such as using C-x ` to visit the targets of Cppcheck's messages.
Here is some example output Cppcheck:
$ cppcheck --enable=all test.cpp
Checking test.cpp...
[test.cpp:4]: (error) Possible null pointer dereference: p - otherwise it is redundant to check if p is null at line 5
[test.cpp:38]: (style) The scope of the variable 'i' can be reduced
[test.cpp:38]: (style) Variable 'i' is assigned a value that is never used
[test.cpp:23]: (error) Possible null pointer dereference: p
[test.cpp:33]: (error) Possible null pointer dereference: p
Checking usage of global functions..
[test.cpp:36]: (style) The function 'f' is never used
[test.cpp:1]: (style) The function 'f1' is never used
[test.cpp:9]: (style) The function 'f2' is never used
[test.cpp:26]: (style) The function 'f3' is never used

Hmmm... I think this is really simple actually. Just use 'compile', as in M-x compile, and type as the compile command:
cppcheck --template='{file}:{line}:{severity}:{message}' --quiet <filename>
Where the filename is the name of the file on which you wish to run cppcheck. That puts the output of cppcheck into a form that the compilation buffer can parse and gives you the full functionality you get with, for instance, a g++ compile.
The --quiet is probably not necessary but since all I care about are the errors that's what I use.

You can use flymake which ships with Emacs.
The basic idea is to write a flymake command that runs cppcheck and then massages the output into a format the flymake can use. If you then enable flymake in your c++ mode buffers, you'll get on the fly error highlighting.
This is an example of flymake working with my Python buffers using pyflakes.
flymake in general expects output in this form
filename:line_number: class: message
Where filename is the name of the file, number is the line number, class is a string like error or warning indicating the type of message and message is a string indicating the actual error. cppcheck output looks close to this. You should probably write a little wrapper to convert the output of cppcheck to this format and then add a hook to turn on flymake for c++ mode.
With C, adding something like gcc -Wall -o nul -S ${CHK_SOURCES} to your Makefile with under a target check-syntax and running flymake-mode does what's necessary. I think it'll be similar for c++ mode.
For the gory details, you should check out http://flymake.sourceforge.net/

Is it possible to integrate Cppcheck with Emacs in a more sophisticated way
Yes, it is possible. Use flymake. I'm surprised no one has done this yet for cppcheck.
No problem, you can do it yourself. Add cppcheck as a new flavor of flymake tool. To do that, follow an existing example. It's not too complicated to do, but coming in cold, it's hard to know what to do. (I've never seen a guide document that describes how to integrate new tools into flymake). Following an existing working example solves that.
Here's a 7k file that adds PHP CodeSniffer as a flymake tool. http://www.emacswiki.org/emacs/flyphpcs.el
Most of that 7k is comments...
You should be able to modify that to add any arbitrary tool to flymake. The key steps are:
Associate your target file extension (example: .cpp) with a pair of functions (init and cleanup) that do your flymake stuff.
define a function to generate the command line, each time flymake scans your buffer. Ths fn gets the name of the file backing the buffer, and produces a command line. In your case it would run cppcheck with all the appropriate command line parameters. The fn that generates the command line is called by the init fn referenced in #1.
define a regex that matches error messages generated by your tool, and add that regex to the flymake list. This allows flymake to extract error messages from the output of the tool you run. By parsing the output, flymake can get the line numbers and highlight broken lines in your buffer.

based on the answers, flymake sounds good.
you can write a cppcheck parser but it sounds easier to use cppcheck --template option.
cppcheck --template="{file}:{line}:{severity}:{message}" foo.cpp
might match flymake pattern. It is just an idea.

The quickest way is probably to use flymake and add an extra target to your makefile.
This setup is working for me:
check-syntax: cppcheck
g++ -o nul -S ${CHK_SOURCES} $(CFLAGS)
cppcheck:
cppcheck --enable=all --quiet --template={file}:{line}:{severity}:{message} ${CHK_SOURCES}

Related

Autoconf : How to get program output in a string and check if another string is present in that

I am developing a Qt application in Python. It uses a resource file, which needs to be compiled. I am using autotools to manage compilation and installation of my projects.
Now, in order for the resource file to be usable by the application, it needs to be compiled with a certain version of the compilation program (pyrcc). I can get the version by putting the output of pyrcc -version in a variable in configure.ac. But then, I don't know how to check whether the string pyrcc5 is present in the output. If it is not present, I want to tell the user that his PyRCC programm has the wrong version, and abort configure.
Additionally, I would like to avoid the need of an extra variable for the program output, but instead do it like this (Pseudo code):
if "pyrcc5" not in output of "pyrcc -version":
say "pyrcc has wrong version"
exit 1
How can I do this ?
When writing a configure.ac for Autoconf, always remember that you are basically writing a shell script. Autoconf provides a host of macros that afford you a lot of leverage, but you can usually at least get an idea about basic "How can I do X in Autoconf?" questions by asking instead "How would I do X in a portable shell script?"
In particular, for ...
I would like to avoid the need of an extra variable for the program
output, but instead do it like this (Pseudo code):
if "pyrcc5" not in output of "pyrcc -version":
say "pyrcc has wrong version"
exit 1
... the usual tool for a portable shell script to use for such a task is grep, and, happily, the easiest way to apply it to the task does not require an intermediate variable. For example, this implements exactly your pseudocode (without emitting any extraneous messaging to the console):
if ! pyrcc -version | grep pyrcc5 >/dev/null 2>/dev/null; then
echo "pyrcc has wrong version"
exit 1
fi
That pipes the output of pyrcc -version into grep, and relies on the fact that grep exits with a success status if and only if it finds any matches.
You could, in fact, put exactly that in your configure.ac, but it would be more idiomatic to
Use the usual Autoconf mechanisms to locate pyrcc and grep, and to use the versions discovered that way;
Use the Autoconf AS_IF macro to write the if construct, instead of writing it literally;
Use standard Autoconf mechanisms for emitting a "checking..." message and reporting on its result; and
Use the standard Autoconf mechanism for outputting a failure message and terminating.
Of course, all of that makes the above considerably more complex, but also more flexible and portable. It might look like this:
AC_ARG_VAR([PYRCC], [The name or full path of pyrcc. Version 5 is required.])
# ...
AC_PROG_GREP
AC_CHECK_PROGS([PYRCC], [pyrcc5 pyrcc], [])
AS_IF([test "x${PYRCC}" = x],
[AC_MSG_ERROR([Required program pyrcc was not found])])
# ...
AC_MSG_CHECKING([whether ${PYRCC} has an appropriate version])
AS_IF([! pyrcc -version | grep pyrcc5 >/dev/null 2>/dev/null], [
AC_MSG_RESULT([no])
AC_MSG_ERROR([pyrcc version 5 is required, but ${PYRCC} is a different version])
], [
AC_MSG_RESULT([yes])
])
In addition to portability and conventional Autoconf progress messaging, that also gets the builder a way to specify a particular pyrcc executable to configure (by setting variable PYRCC in its environment), documents that in configure's help text, and exports PYRCC as a make variable.
Oh, and I snuck in a check for pyrcc under the name pyrcc5, too, though I don't know whether that's useful in practice.
The final result no longer looks much like the shell script fragment I offered first, I grant. But again, the pure shell script fragment could be used as is, and also, the fully Autoconfiscated version is derived directly from the pure script.

cvs annotate and standard error redirection

First, some background. I'm trying to use cvs annotate within a Perl script invoked from a ksh command line to find out who's using bad hex constants in their source code and dole out justice appropriately. I'd like to use stdout for this program strictly for my own structured output, so I can pipe it to a file or to other programs. But, every call to cvs annotate results in a diagnostic message being printed to the console. It takes the form of:
Annotations for <filename>
***********
It's mucking up my stdout! I played around with annotate on the command line, and I figured that these diagnostic messages were coming from stderr, because running this command directly in ksh:
cvs annotate <filename> 1>yay.txt 2>boo.txt
correctly puts the desired annotated output into yay.txt and the diagnostics into boo.txt. However, things get weirder when I try to run this from within a perl script using backticks.
$muhstring = `cvs annotate $filename 2>boo.txt`;
The desired annotated output does appear in $muhstring, but the diagnostics still get printed to the command line, and boo.txt is created as an empty file. There's an admittedly old post on perlmonks.org that says this syntax should work as written. So, what's the deal? Is this a CVS quirk, have I misread the post, or have things changed since 1999? Or is it something else?
Edit: So, it is not, in fact, mucking up stdout. I tried this in ksh:
perl findbadhexowners.pl badhex.txt > out.txt
and the diagnostic messages still printed to the console, but out.txt only contains the annotations. This is fine for my purposes, and I can continue with other code.
That said, it seems like Perl and cvs specifically are interacting a little strangely, especially considering that redirection in ksh works fine and redirection in Perl for other commands like cd works fine - for example, in Perl
`cd nonexistentDir 1>stdout.txt 2>stderr.txt`;
gives the expected output in both stdout.txt and stderr.txt. It's only using cvs annotate from within Perl that produces this problem.

Running emacs from the command line and handling locked files

I'm using org-mode and am looking to export my agenda (example of an agenda) to a text file so that I can display it with conky. The org-mode manual features this command line example to do this:
emacs -batch -l ~/.emacs -eval '(org-batch-agenda "t")' | lpr
I've modified this like so:
emacs -batch -l ~/.emacs -eval '(org-batch-agenda "e")' \
> ~/org/aux/agenda-export.txt
I have this set as a cron job to run every 5 minutes. It works great unless I actually have emacs open. Then I noticed that the file agenda-export.txt was empty. In running this manually from the coammand line vs. through cron, I get this error (or similar depending on the files I have open):
...~/org/file.org locked by jwhendy (pid 10935): (s, q, p, ?)?
I was going to write a script to perhaps export to agenda-export-test.txt, then perhaps check for an empty file or no lines (wc -l == 0 maybe?). If true, leave the existing file alone and delete agenda-export-test.txt. If not, then move agenda-export-test.txt to agenda-export.txt.
But... when I try to run such a script, I'm met with the same emacs inquiry about whether to steal the lock, proceed, or quit. I'm fine with proceeding, as I don't think org-agenda does anything to the files and thus it wouldn't harm anything... but I don't know how to tell emacs to "force" or choose "proceed" if problems are encountered. I need something non-interactive.
So, to summarize, my thoughts were to try:
passing a --force option or similar to emacs to make it proceed at the pause
see if the exported tmp file has any lines and deal with it accordingly
tell emacs to run in "read only mode" (but I don't think it exists)
The main issue is that with cron, I'm not there to tell the process what to do, and so it just just make an empty file as the exported results. How can I handle this locked file business with a "blind" process like cron that can't respond?
I've tried asking the mailing list as well without a working outcome. [1] I wondered if someone here might have ideas.
[1] http://www.mail-archive.com/emacs-orgmode#gnu.org/msg45056.html
Have you tried copying file without using emacs?
put in your crontab:
cp ~/org/file.org /tmp/export.org && emacs -batch .... /tmp/export.org ..
A regular "cp" command should not copy emacs locks. Of course, once in a while you might get a damaged file if you save agenda just during cp command, but this should not be too bad.

flymake fails with "Wrong type argument: symbolp, (utf-8)"

I'm trying to get flymake to work, but when I run flymake-mode, I get the following error
switched OFF Flymake mode for buffer TdDisassemblerIde.cpp due to fatal status \
PROCERR, warning Failed to launch syntax check process 'make' with args (-s -C ./ \
CHK_SOURCES=TdDisassemblerIde_flymake.cpp SYNTAX_CHECK_MODE=1 check-syntax): Wrong type \
argument: symbolp, (utf-8)
Any clues?
When I have a problem with flymake, I do
M-x set-variable flymake-log-level <RET> 3
And then run flymake again (M-x flymake-mode).
Then look in the *Messages* buffer for a useful error message.
The last time this happened to me, about an hour ago, my check-syntax target in the flymakefile lacked a source module; I had added a module but had forgotten to add it to the list of files that should be included in a flymake compilation. Modifying the makefile corrected it. (This was for C#, but setting flymake-log-level should work to get a diagnosis for you too.)
Answering my own question: the problem was that I had set process-coding-system-alist to contain the symbol utf-8, and apparently flymake does not like that. Setting process-coding-system-alist to nil solved the problem.

Auto-complete command line arguments

In bash, executables such as mplayer and imagemagick's "convert" have a cool auto-complete functionality on their command line arguments. For instance, if I type
mplayer <tab><tab>
in one of my video folders, then mplayer will list all media files located in that folder, and only the media files.
Similarly, if I type
convert -<tab><tab>
then I will see all the possible options of the convert script, which is great.
My question is how to achieve a similar functionality, using bash, ruby or python scripts?
This is an example of BASH's smart completion. A basic description is here, a guide to writing your own extensions is here and another (Debian-based) guide is here. And here's a fuller featured introduction to the complete command (the command that facilitates this behaviour).
The link to writing your own extension in the accepted answer has gone dead. Quoting here from http://web.archive.org/web/20090409201619/http://ifacethoughts.net/2009/04/06/extending-bash-auto-completion/
Bash provides you a way of specifying your keywords, and using them to
auto complete command line arguments for your application. I use vim
as a wiki, task managemer and contacts. The vim helptags system lets
me index the content instead of searching through it, and the speed
shows it. One feature I wanted to add to this was to access these tags
from outside vim.
This can be done in a straight forward way:
$ vim -t tagname
This takes me directly to specific content marked using this tag. However, this will be more productive if I can provide
auto-completion for the tags.
I first defined a Bash function for the vim commandline. I added the
following code to my .bashrc file:
function get {
vim -t $1
} Now I can use get tagname command to get to the content.
Bash programmable completion is done by sourcing the
/etc/bash-completion script. The script lets us add our
auto-completion script /etc/bash-completion.d/ directory and executes
it whenever it is called. So I added a script file called get with the
following code in that directory.
_get()
{
local cur
COMPREPLY=()
#Variable to hold the current word
cur="${COMP_WORDS[COMP_CWORD]}"
#Build a list of our keywords for auto-completion using
#the tags file
local tags=$(for t in `cat /home/anadgouda/wiki/tags | \
awk '{print $1}'`; do echo ${t}; done)
#Generate possible matches and store them in the
#array variable COMPREPLY
COMPREPLY=($(compgen -W "${tags}" $cur))
}
#Assign the auto-completion function _get for our command get.
complete -F _get get Once the /etc/bash-completion is sourced, you will get auto-completion for the tags when you use the get command.
Along with my wiki I use it for all the documentation work and at
times the code too. I also use the tags file created from my code. The
indexing system lets me remember the context instead of the filenames
and directories.
You can tweak this system for any of the tools you use. All you need
to do is get a list of the keywords for your command and give it to
the Bash programmable completion system.
This functionality in bash is provided by bash-completion and similar functionality is included in zsh. If you want to add support for some program not currently supported by one of these tools, you need to write your own extensions for them.
How do I enable bash completion on Ubuntu?
sudo apt-get install bash-completion
source /etc/profile.d/bash_completion.sh
sudo apt i[TAB]