Doxygen-style comments in vim for C++ - vim

I'd like to automate inserting comment snippets for C++ files. Google search suggested c.vim plugin. I installed it. Now when I create a file, I get template like following.
/* =====================================================================================
*
* Filename: Foo.h
*
* Description: :
*
* Version: 1.0
* Created: 04/14/2014 08:35:44 PM
* Revision: none
* Compiler: gcc
*
* Author: YOUR NAME (),
* Organization:
*
* =====================================================================================
*/
From :h csupport I catch I can create my own templates for comments. Is there simpler way to get doxygen-style comments in project? Or maybe these templates are available somewhere?

If you only need these comments and not the other features of c.vim, I'd recommend you to use some snippets plugin, such as Snipmate or Ultisnips. Creating such snippets with these plugins is very easy and they are very powerful.

You can use Doxygen plugin for vim. It's available here. Simply enter :Dox to add your comments.
For example,
/**
* #brief
*
* #param list
* #param size
* #param key
* #param rec
*
* #return
*/
bool jw_search ( int *list, int size, int key, int& rec )
{
return true;
}

lh-cpp & mu-template come with tunable project headers (the default is quite bad I have to admit). You'll have to override templates/c/internals/c-file-header.template to something like:
VimL: let s:filename = s:path_from_root(expand('%:p'))
VimL: let s:prj_dox_group = lh#option#get('my_prj_dox_group', lh#marker#txt('group'))
/**#file <+s:filename+>
* #ingroup <+s:prj_dox_group+>
* #author <+Author()+>
* <p>Licence:<p> Your Project Licence
*/
(All the other stuff is already taken care of: include guards will be added automatically in header files, and foo.h will be automatically included in foo.c(pp))
Then in a local_vimrc-like plugin, you'll have to set:
" File: /root/path/of/the/project/_vimrc_local.vim
:let b:my_prj_dox_group = "gMain" " you can override it in subfolders
:let b:sources_root = '/root/path/of/the/project' " for mu-template
:let b:includes = [b:sources_root . '/**'] " I can't remember which ftplugin uses b:includes
:let b:included_paths = [b:sources_root] " for ftplugin/c/c_AddInclude.vim
:let g:alternateSearchPath = 'sfr:.' " (or equivalent) for a.vim and for foo.cpp to include foo.h
BTW, lh-cpp also comes with the :DOX command that'll parse a function signature to automatically generate its doxygen caption (#param[in/out/0], #return, #ingroup, #throw (noexcept and the deprecated exception specifications are analysed), ... will be filled as automagically as possible)
If we take Saraht's example, it becomes:
/**
* «brief explanation».
* «details»
* #param[«in,»out] list «list-explanations»
* #param[in] size «size-explanations»
* #param[in] key «key-explanations»
* #param[«in,»out] rec «rec-explanations»
*
* #return «bool»
* «#throw »
* #pre <tt>list != NULL</tt>«»
*/
bool jw_search ( int* list, int size, int key, int& rec )
NB: «» occurrences mark placeholders
PS: I have no idea how it will behave if your keep c.vim as I don't use it.

Related

why schedule() does not lead to deadlock while using the default prepare_arch_switch()

In Linux 2.6.11.12, before the shedule() function to select the "next" task to run, it will lock the runqueue
spin_lock_irq(&rq->lock);
and the, before calling context_switch() to perform the context switching, it will call prepare_arch_switch(), which is a no-op by default:
/*
* Default context-switch locking:
*/
#ifndef prepare_arch_switch
# define prepare_arch_switch(rq, next) do { } while (0)
# define finish_arch_switch(rq, next) spin_unlock_irq(&(rq)->lock)
# define task_running(rq, p) ((rq)->curr == (p))
#endif
that is, it will hold the rq->lock until switch_to() return, and then, the macro finish_arch_switch() actually releases the lock.
Suppose that, there are tasks A, B, and C. And now A calls schedule() and switch to B (now, the rq->lock is locked). Sooner or later, B calls schedule(). At this point, how would B to get rq->lock since it is locked by A?
There is also some arch-dependent implememtation, such as:
/*
* On IA-64, we don't want to hold the runqueue's lock during the low-level context-switch,
* because that could cause a deadlock. Here is an example by Erich Focht:
*
* Example:
* CPU#0:
* schedule()
* -> spin_lock_irq(&rq->lock)
* -> context_switch()
* -> wrap_mmu_context()
* -> read_lock(&tasklist_lock)
*
* CPU#1:
* sys_wait4() or release_task() or forget_original_parent()
* -> write_lock(&tasklist_lock)
* -> do_notify_parent()
* -> wake_up_parent()
* -> try_to_wake_up()
* -> spin_lock_irq(&parent_rq->lock)
*
* If the parent's rq happens to be on CPU#0, we'll wait for the rq->lock
* of that CPU which will not be released, because there we wait for the
* tasklist_lock to become available.
*/
#define prepare_arch_switch(rq, next) \
do { \
spin_lock(&(next)->switch_lock); \
spin_unlock(&(rq)->lock); \
} while (0)
#define finish_arch_switch(rq, prev) spin_unlock_irq(&(prev)->switch_lock)
In this case, I'm very sure that this version will do things right since it unlock the rq->lock before calling context_switch().
But what happens to the default implementation? How it can do things right?
I found a comment in context_switch() of linux 2.6.32.68, that tells the story under the code:
/*
* Since the runqueue lock will be released by the next
* task (which is an invalid locking op but in the case
* of the scheduler it's an obvious special-case), so we
* do an early lockdep release here:
*/
yet we don't switch to another task with the lock locked, the next task will unlock it, and if the next task is newly created, the function ret_from_fork() will also eventually call finish_task_switch() to unlock the rq->lock

How can I build and test libffi under cygwin with mingw32?

After checking (most recent) tag v3.2.1:
% sh autogen.sh
% ./configure CC=i686-pc-mingw32-gcc
% make check
All tests appear to fail.
Using CC=gcc, tests seem to work properly. Unfortunately I need the resulting build to have no cygwin dependencies, since I'm building a JNI DLL.
I tried building libffi using MSYS2 environment and mingw-w64 and I hit the same wall:
a) all tests seem to fail when I run make check
b) when I try to compile the libffi Hello World example with -lffi,
the linker complains about unresolved references to all ffi-related symbols (the symbols are indeed included in libffi.a, but probably due to circular dependencies and the order of object files, the linker fails to collect all the symbols)
Fortunately, if I drop -lffi and instead include all object files (*.o) created by libffi make operation, the created executable runs just fine.
Here's a link to the libffi Hello World example I used:
http://www.chiark.greenend.org.uk/doc/libffi-dev/html/Closure-Example.html
[EDIT]
After some additional experiments, I managed to compile the program by replacing -lffi with -Wl,--whole-archive,-lffi,--no-whole-archive. This way, the linker would include all object files from libffi.a and everything would work just fine.
Here's the Hello World example (hello.c) with detailed steps I used, in case someone finds this info useful:
/*
* Steps for building libffi on Windows and running this Hello World example:
*
* 1. Download and install the latest version of MSYS2
* a) download the latest (64-bit or 32-bit) installer from http://msys2.github.io
* b) run the installer accepting default settings
* c) execute the following commands to update the system core
* pacman -Sy pacman
* pacman -Syu
* pacman -Su
* d) restart MSYS2, if requested to do so
* e) execute the following command to install development tools
* for 64-bit gcc:
* pacman --needed -S base-devel dejagnu mingw-w64-x86_64-gcc
* for 32-bit gcc:
* pacman --needed -S base-devel dejagnu mingw-w64-i686-gcc
* f) restart MSYS2
* 2. Download and compile the latest version of libffi
* a) download the latest source code bundle from https://github.com/libffi/libffi/releases
* b) unpack the source code bundle in MSYS2 tmp directory (e.g. C:\msys64\tmp)
* c) execute the following MSYS2 commands to compile libffi (adapt the version number):
* cd /tmp/libffi-3.2.1
* ./autogen.sh
* ./configure --prefix=/tmp/out --enable-static --disable-shared
* make
* d) optionally, execute the following command to run the tests:
* make check
* e) copy the distributable files to the configured /tmp/out directory
* make install
* the following files are needed for the next step:
* /tmp/out/lib/libffi.a
* /tmp/out/lib/libffi-3.2.1/include/ffi.h
* /tmp/out/lib/libffi-3.2.1/include/ffitarget.h
* 3. Compile this example
* a) copy this file to MSYS2 tmp directory (e.g. C:\msys64\tmp\hello.c)
* b) execute the following MSYS2 command to compile the example:
* gcc -I /tmp/out/lib/libffi-3.2.1/include -L /tmp/out/lib -lffi -o /tmp/hello /tmp/hello.c
* c) run the example (/tmp/hello.exe), the output should be:
* Hello World!
*
* Troubleshooting
*
* If the tests seem to fail and the compilation in step 3b) above reports undefined references to 'ffi_*' symbols,
* try compiling using the following command instead:
* gcc -I /tmp/out/lib/libffi-3.2.1/include -L /tmp/out/lib -Wl,--whole-archive,-lffi,--no-whole-archive -o /tmp/hello /tmp/hello.c
* Another alternative is to try linking the original libffi object files (*.o) and drop -lffi as follows:
* For 64-bit version:
* export SRC=/tmp/libffi-3.2.1/x86_64-w64-mingw32/src
* gcc -I /tmp/out/lib/libffi-3.2.1/include -o /tmp/hello /tmp/hello.c $SRC/prep_cif.o $SRC/types.o $SRC/raw_api.o $SRC/java_raw_api.o $SRC/closures.o $SRC/x86/ffi.o $SRC/x86/win64.o
* For 32-bit version:
* export SRC=/tmp/libffi-3.2.1/i686-w64-mingw32/src
* gcc -I /tmp/out/lib/libffi-3.2.1/include -o /tmp/hello /tmp/hello.c $SRC/prep_cif.o $SRC/types.o $SRC/raw_api.o $SRC/java_raw_api.o $SRC/closures.o $SRC/x86/ffi.o $SRC/x86/win32.o
*/
#include <stdio.h>
#include <ffi.h>
/* Acts like puts with the file given at time of enclosure */
void puts_binding(ffi_cif* cif, void* ret, void* args[], void* stream) {
*(ffi_arg*) ret = fputs(*(char**) args[0], (FILE*) stream);
}
typedef int (*puts_t)(char*);
int main() {
ffi_cif cif; /* The call interface */
ffi_type* args[1]; /* The array of pointers to function argument types */
ffi_closure* closure; /* The allocated closure writable address */
void* bound_puts; /* The allocated closure executable address */
int rc; /* The function invocation return code */
/* Allocate closure (writable address) and bound_puts (executable address) */
closure = ffi_closure_alloc(sizeof(ffi_closure), &bound_puts);
if (closure) {
/* Initialize the array of pointers to function argument types */
args[0] = &ffi_type_pointer;
/* Initialize the call interface describing the function prototype */
if (ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 1, &ffi_type_sint, args) == FFI_OK) {
/* Initialize the closure, setting stream to stdout */
if (ffi_prep_closure_loc(closure, &cif, puts_binding, stdout, bound_puts) == FFI_OK) {
rc = ((puts_t) bound_puts)("Hello World!");
/* rc now holds the result of the call to fputs */
}
}
}
/* Deallocate both closure, and bound_puts */
ffi_closure_free(closure);
return 0;
}

fallocate() command equivalent in OS X?

Is there a fallocate() equivalent in OS X?
I would like to aggregate all of those equivalent in OS X questions into some doc/table or whatever for everyone. Anybody knows something familiar?
What about using:
mkfile -n 1m test.tmp
It's not the same command but serves the same purpose.
Note that fallocate uses decimal multipliers, whereas mkfile uses binary multipliers.
mkfile man
fallocate() doesn't exist on OSX. You can "fake" it though; Mozilla fakes it in their FileUtils class. See this file:
http://hg.mozilla.org/mozilla-central/file/3d846420a907/xpcom/glue/FileUtils.cpp#l61
Here's the code, in case that link goes stale:
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Taras Glek <tglek#mozilla.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#if defined(XP_UNIX)
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#elif defined(XP_WIN)
#include <windows.h>
#endif
#include "nscore.h"
#include "private/pprio.h"
#include "mozilla/FileUtils.h"
bool
mozilla::fallocate(PRFileDesc *aFD, PRInt64 aLength)
{
#if defined(HAVE_POSIX_FALLOCATE)
return posix_fallocate(PR_FileDesc2NativeHandle(aFD), 0, aLength) == 0;
#elif defined(XP_WIN)
return PR_Seek64(aFD, aLength, PR_SEEK_SET) == aLength
&& 0 != SetEndOfFile((HANDLE)PR_FileDesc2NativeHandle(aFD));
#elif defined(XP_MACOSX)
int fd = PR_FileDesc2NativeHandle(aFD);
fstore_t store = {F_ALLOCATECONTIG, F_PEOFPOSMODE, 0, aLength};
// Try to get a continous chunk of disk space
int ret = fcntl(fd, F_PREALLOCATE, &store);
if(-1 == ret){
// OK, perhaps we are too fragmented, allocate non-continuous
store.fst_flags = F_ALLOCATEALL;
ret = fcntl(fd, F_PREALLOCATE, &store);
if (-1 == ret)
return false;
}
return 0 == ftruncate(fd, aLength);
#elif defined(XP_UNIX)
// The following is copied from fcntlSizeHint in sqlite
/* If the OS does not have posix_fallocate(), fake it. First use
** ftruncate() to set the file size, then write a single byte to
** the last byte in each block within the extended region. This
** is the same technique used by glibc to implement posix_fallocate()
** on systems that do not have a real fallocate() system call.
*/
struct stat buf;
int fd = PR_FileDesc2NativeHandle(aFD);
if (fstat(fd, &buf))
return false;
if (buf.st_size >= aLength)
return false;
const int nBlk = buf.st_blksize;
if (!nBlk)
return false;
if (ftruncate(fd, aLength))
return false;
int nWrite; // Return value from write()
PRInt64 iWrite = ((buf.st_size + 2 * nBlk - 1) / nBlk) * nBlk - 1; // Next offset to write to
do {
nWrite = 0;
if (PR_Seek64(aFD, iWrite, PR_SEEK_SET) == iWrite)
nWrite = PR_Write(aFD, "", 1);
iWrite += nBlk;
} while (nWrite == 1 && iWrite < aLength);
return nWrite == 1;
#endif
return false;
}
For those wanting to create fake data files for testing, mkfile is pretty elegant. An alternative is to use dd:
dd if=/dev/zero of=zfile count=1024 bs=1024
As you can see with od -b zfile, it's full of zeros. If you want random data (which you may want for testing workflows with data compression, for example), then use "/dev/random" in place of "/dev/zero":
dd if=/dev/random of=randfile count=1024 bs=1024

How to find definition of structure when reading c program on linux?

I am reading source code of xl2tpd, and face lots of problems when reading this code. For example I cannot find where the structure lac is defined. How do I find the definition of this structure?
I have used ctags and vim to read this code, but failed to find the structure. I googled and could not find the structure. Is there any method that can make the code reading process more comfortable? That is, I can jump to definition of most variables, functions and structures?
try cscope with vim. follow steps below -
1) run cscope -R in xl2tpd directory . it will create file cscope.out
2) open file with vim where structure lac is used
3) use :cs f g <lac> . now it will show the files where lac is defined .
4) choose file.h. it contain the definition .
if you are perticulerly interested in definition of struct lac it is below -
struct lac
{
struct lac *next;
struct host *lns; /* LNS's we can connect to */
struct schedule_entry *rsched;
int tun_rws; /* Receive window size (tunnel) */
int call_rws; /* Call rws */
int rxspeed; /* Tunnel rx speed */
int txspeed; /* Tunnel tx speed */
int active; /* Is this connection in active use? */
int hbit; /* Permit hidden AVP's? */
int lbit; /* Use the length field? */
int challenge; /* Challenge authenticate the peer? */
unsigned int localaddr; /* Local IP address */
unsigned int remoteaddr; /* Force remote address to this */
char authname[STRLEN]; /* Who we authenticate as */
char password[STRLEN]; /* Password to authenticate with */
char peername[STRLEN]; /* Force peer name to this */
char hostname[STRLEN]; /* Hostname to report */
char entname[STRLEN]; /* Name of this entry */
int authpeer; /* Authenticate our peer? */
int authself; /* Authenticate ourselves? */
int pap_require; /* Require PAP auth for PPP */
int chap_require; /* Require CHAP auth for PPP */
int pap_refuse; /* Refuse PAP authentication for us */
int chap_refuse; /* Refuse CHAP authentication for us */
int idle; /* Idle timeout in seconds */
int autodial; /* Try to dial immediately? */
int defaultroute; /* Use as default route? */
int redial; /* Redial if disconnected */
int rmax; /* Maximum # of consecutive redials */
int rtries; /* # of tries so far */
int rtimeout; /* Redial every this many # of seconds */
char pppoptfile[STRLEN]; /* File containing PPP options */
int debug;
struct tunnel *t; /* Our tunnel */
struct call *c; /* Our call */
};
When going through third-party code, there are a few tools that I have found invaluable:
Source Navigator
lxr
ctags
and, of course, the oldest and greatest of all: grep
I believe that the Eclipse CDT also allows you to quickly find the definition of any variable you are looking at, but I have not actually used it - I prefer using console programs for my actual C coding.
None of those are vim-based, although at least ctags can be used via vim or emacs. Nevertheless, they can be very useful when exploring a new codebase that you know nothing about...
Are you talking about this?
The source code already comes with a tags file.
Loading any file (common.h in my case) in Vim you can use :tag lac to jump to the first definition of lac or :tselect lac to choose between the 3 occurrences in this project and :tag gconfig to jump to the unique definition of gconfig.
See :help tags.
I'm using vim + cscope and have the same issue with you. I find a way to workaround this issue.
in vim, search the text instead of the definition. for example, in the linux kernel source code, if you're trying to find "struct file",
commands this:
cs find t struct file {
you will have a accurate definition timely in most cases, take care, no quotation mark for the text "struct file {".
hope it will help you.

What is the return value of sched_find_first_bit if it doesn't find anything?

The kernel is 2.4.
On a side note, does anybody knows a good place where I can search for that kind of information? Searching Google for function definitions is frustrating.
If you plan on spending any significant time searching through or understanding the Linux kernel, I recommend downloading a copy and using Cscope.
Using Cscope on large projects (example: the Linux kernel)
I found the following in a copy of the Linux kernel 2.4.18.
The key seems to be the comment before this last piece of code below. It appears that the return value of sched_find_first_bit is undefined if no bit is set.
From linux-2.4/include/linux/sched.h:185
/*
* The maximum RT priority is configurable. If the resulting
* bitmap is 160-bits , we can use a hand-coded routine which
* is optimal. Otherwise, we fall back on a generic routine for
* finding the first set bit from an arbitrarily-sized bitmap.
*/
#if MAX_PRIO 127
#define sched_find_first_bit(map) _sched_find_first_bit(map)
#else
#define sched_find_first_bit(map) find_first_bit(map, MAX_PRIO)
#endif
From linux-2.4/include/asm-i386/bitops.h:303
/**
* find_first_bit - find the first set bit in a memory region
* #addr: The address to start the search at
* #size: The maximum size to search
*
* Returns the bit-number of the first set bit, not the number of the byte
* containing a bit.
*/
static __inline__ int find_first_bit(void * addr, unsigned size)
{
int d0, d1;
int res;
/* This looks at memory. Mark it volatile to tell gcc not to move it around */
__asm__ __volatile__(
"xorl %%eax,%%eax\n\t"
"repe; scasl\n\t"
"jz 1f\n\t"
"leal -4(%%edi),%%edi\n\t"
"bsfl (%%edi),%%eax\n"
"1:\tsubl %%ebx,%%edi\n\t"
"shll $3,%%edi\n\t"
"addl %%edi,%%eax"
:"=a" (res), "=&c" (d0), "=&D" (d1)
:"1" ((size + 31) >> 5), "2" (addr), "b" (addr));
return res;
}
From linux-2.4/include/asm-i386/bitops.h:425
/*
* Every architecture must define this function. It's the fastest
* way of searching a 140-bit bitmap where the first 100 bits are
* unlikely to be set. It's guaranteed that at least one of the 140
* bits is cleared.
*/
static inline int _sched_find_first_bit(unsigned long *b)
{
if (unlikely(b[0]))
return __ffs(b[0]);
if (unlikely(b[1]))
return __ffs(b[1]) + 32;
if (unlikely(b[2]))
return __ffs(b[2]) + 64;
if (b[3])
return __ffs(b[3]) + 96;
return __ffs(b[4]) + 128;
}
From linux-2.4/include/asm-i386/bitops.h:409
/**
* __ffs - find first bit in word.
* #word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static __inline__ unsigned long __ffs(unsigned long word)
{
__asm__("bsfl %1,%0"
:"=r" (word)
:"rm" (word));
return word;
}

Resources