BASH Programming
BASH Programming
TO
by Mike G mikkey at dynamo.com.ar
This article intends to help you to start programming basic-intermediate shell scripts.
It does not intend to be an advanced document (see the title). I am NOT an expert nor
guru shell programmer. I decided to write this because I'll learn a lot and it might be
useful to other people. Any feedback will be apreciated, specially in the patch form :)
1. Introduction
1.1 Getting the latest version
1.2 Requisites
1.3 Uses of this document
4. Pipes
4.1 What they are and why you'll want to use them
4.2 Sample: simple pipe with sed
4.3 Sample: an alternative to ls -l *.txt
5. Variables
5.1 Sample: Hello World! using variables
5.2 Sample: A very simple backup script (little bit better)
5.3 Local variables
6. Conditionals
6.1 Dry Theory
6.2 Sample: Basic conditional example if .. then
6.3 Sample: Basic conditional example if .. then ... else
6.4 Sample: Conditionals with variables
8. Functions
8.1 Functions sample
8.2 Functions with parameters sample
9. User interfaces
9.1 Using select to make simple menus
9.2 Using the command line
10. Misc
10.1 Reading user input with read
10.2 Arithmetic evaluation
10.3 Finding bash
10.4 Getting the return value of a program
10.5 Capturing a commands output
10.6 Multiple source files
11. Tables
11.1 String comparison operators
11.2 String comparison examples
11.3 Arithmetic operators
11.4 Arithmetic relational operators
11.5 Useful commands
1. Introduction
1.1 Getting the latest version
http://www.linuxdoc.org/HOWTO/Bash-Prog-Intro-HOWTO.html
1.2 Requisites
Familiarity with GNU/Linux command lines, and familiarity with basic programming
concepts is helpful. While this is not a programming introduction, it explains (or at
least tries) many basic concepts.
A little note for seeing this things: with the less command you can view both stdout
(which will remain on the buffer) and the stderr that will be printed on the screen, but
erased as you try to 'browse' the buffer.
Here, a file called 'ls-l.txt' will be created and it will contain what you would see on
the screen if you type the command 'ls -l' and execute it.
Here, a file called 'grep-errors.txt' will be created and it will contain what you would
see the stderr portion of the output of the 'grep da *' command.
Here, the stdout portion of the command is sent to stderr, you may notice that in
differen ways.
3.5 Sample: stderr 2 stdout
This will cause the stderr ouput of a program to be written to the same filedescriptor
than stdout.
grep * 2>&1
Here, the stderr portion of the command is sent to stdout, if you pipe to less, you'll see
that lines that normally 'dissapear' (as they are written to stderr) are being kept now
(because they're on stdout).
This (thinking on the cron entry) will delete every file called 'core' in any directory.
Notice that you should be pretty sure of what a command is doing if you are going to
wipe it's output.
4. Pipes
This section explains in a very simple and practical way how to use pipes, nd why you
may want it.
4.1 What they are and why you'll want to use them
Pipes let you use (very simple, I insist) the output of a program as the input of another
one
Here, the following happens: first the command ls -l is executed, and it's output,
instead of being printed, is sent (piped) to the sed program, which in turn, prints what
it has to.
4.3 Sample: an alternative to ls -l *.txt
Probably, this is a more difficult way to do ls -l *.txt, but it is here for illustrating
pipes, not for solving such listing dilema.
ls -l | grep "\.txt$"
Here, the output of the program ls -l is sent to the grep program, which, in turn, will
print lines which match the regex "\.txt$".
5. Variables
You can use variables as in any programming languages. There are no data types. A
variable in bash can contain a number, a character, a string of characters.
You have no need to declare a variable, just assigning a value to its reference will
create it.
Line 2 creates a variable called STR and assigns the string "Hello World!" to it. Then
the VALUE of this variable is retrieved by putting the '$' in at the beginning. Please
notice (try it!) that if you don't use the '$' sign, the output of the program will be
different, and probably not what you want it to be.
This script introduces another thing. First of all, you should be familiarized with the
variable creation and assignation on line 2. Notice the expression '$(date +%Y%m
%d)'. If you run the script you'll notice that it runs the command inside the
parenthesis, capturing its output.
Notice that in this script, the output filename will be different every day, due to the
format switch to the date command(+%Y%m%d). You can change this by specifying
a different format.
echo ls
echo $(ls)
6. Conditionals
Conditionals let you decide whether to perform an action or not, this decision is taken
by evaluating an expression.
Conditionals have other forms such as: if expression then statement1 else statement2.
Here 'statement1' is executed if 'expression' is true,otherwise 'statement2' is executed.
if [expression];
then
fi
The code to be executed if the expression within braces is true can be found after the
'then' word and before 'fi' which indicates the end of the conditionally executed code.
The for loop is a little bit different from other programming languages. Basically, it
let's you iterate over a series of 'words' within a string.
The while executes a piece of code if the control expression is true, and only stops
when it is false (or a explicit break is found within the executed code.
The until loop is almost equal to the while loop, except that the code is executed
while the control expression evaluates to false.
If you suspect that while and until are very similar you are right.
On the second line, we declare i to be the variable that will take the different values
contained in $( ls ).
The third line could be longer if needed, or there could be more lines before the done
(4).
'done' (4) indicates that the code that used the value of $i has finished and $i can take
a new value.
This script has very little sense, but a more useful way to use the for loop would be to
use it to match only certain files on the previous example
This script 'emulates' the well known (C, Pascal, perl, etc) 'for' structure
8. Functions
As in almost any programming language, you can use functions to group pieces of
code in a more logical way or practice the divine art of recursion.
Calling a function is just like calling another program, you just write its name.
When running the script you'll notice that first: the function 'hello' is called, second
the 'quit' function, and the program never reaches line 10.
This script is almost identically to the previous one. The main difference is the
funcion 'e'. This function, prints the first argument it receives. Arguments, within
funtions, are treated in the same manner as arguments given to the script.
9. User interfaces
9.1 Using select to make simple menus
#!/bin/bash
OPTIONS="Hello Quit"
select opt in $OPTIONS; do
if [ "$opt" = "Quit" ]; then
echo done
exit
elif [ "$opt" = "Hello" ]; then
echo Hello World
else
clear
echo bad option
fi
done
If you run this script you'll see that it is a programmer's dream for text based menus.
You'll probably notice that it's very similar to the 'for' construction, only rather than
looping for each 'word' in $OPTIONS, it prompts the user.
What this script does should be clear to you. The expression in the first conditional
tests if the program has received an argument ($1) and quits if it didn't, showing the
user a little usage message. The rest of the script should be clear at this point.
10. Misc
10.1 Reading user input with read
In many ocations you may want to prompt the user for some input, and there are
several ways to achive this. This is one of those ways:
#!/bin/bash
echo Please, enter your name
read NAME
echo "Hi $NAME!"
As a variant, you can get multiple values with read, this example may clarify this.
#!/bin/bash
echo Please, enter your firstname and lastname
read FN LN
echo "Hi! $LN, $FN !"
If you expected to see '2' you'll be disappointed. What if you want BASH to evaluate
some numbers you have? The solution is this:
echo $((1+1))
This will produce a more 'logical' output. This is to evaluate an arithmetic expression.
You can achieve this also like this:
echo $[1+1]
If you need to use fractions, or more math or you just want it, you can use bc to
evaluate arithmetic expressions.
if i ran "echo $[3/4]" at the command prompt, it would return 0 because bash only
uses integers when answering. If you ran "echo 3/4|bc -l", it would properly return
0.75.
'find ./ -name bash' from the root dir will work, usually.
ls -l /bin/bash
ls -l /sbin/bash
ls -l /usr/local/bin/bash
ls -l /usr/bin/bash
ls -l /usr/sbin/bash
ls -l /usr/local/sbin/bash
This illustrates how to capture the return value of a program, I assume that the
directory dada does not exist. (This was also suggested by mike)
#!/bin/bash
cd /dada &> /dev/null
echo rv: $?
cd $(pwd) &> /dev/null
echo rv: $?
__TO-DO__
11. Tables
11.1 String comparison operators
(1) s1 = s2
(2) s1 != s2
(3) s1 < s2
(4) s1 > s2
(5) -n s1
(6) -z s1
(1) s1 matches s2
(3) __TO-DO__
(4) __TO-DO__
(6) s1 is null
I quote here a note from a mail, sent buy Andreas Beck, refering to use if [ $1 = $2 ].
This is not quite a good idea, as if either $S1 or $S2 is empty, you will get a parse
error. x$1=x$2 or "$1"="$2" is better.
11.3 Arithmetic operators
+
% (remainder)
-gt (>)
-le (<=)
-ge (>=)
-eq (==)
-ne (!=)
Sed is a non-interactive editor. Instead of altering a file by moving the cursor on the
screen, you use a script of editing instructions to sed, plus the name of the file to edit.
You can also describe sed as a filter. Let's have a look at some examples:
$sed 's/to_be_replaced/replaced/g' /tmp/dummy
Sed replaces the string 'to_be_replaced' with the string 'replaced' and reads from the
/tmp/dummy file. The result will be sent to stdout (normally the console) but you can
also add '> capture' to the end of the line above so that sed sends the output to the file
'capture'.
$sed 12, 18d /tmp/dummy
Sed shows all lines except lines 12 to 18. The original file is not altered by this
command.
"test123
test
tteesstt"
$awk '/test/ {print}' /tmp/dummy
test123
test
The pattern AWK looks for is 'test' and the action it performs when it found a line in
the file /tmp/dummy with the string 'test' is 'print'.
$awk '/test/ {i=i+1} END {print i}' /tmp/dummy
When you're searching for many patterns, you should replace the text between the
quotes with '-f file.awk' so you can put all patterns and actions in 'file.awk'.
grep (print lines matching a search pattern)
We've already seen quite a few grep commands in the previous chapters, that display
the lines matching a pattern. But grep can do more.
$grep "look for this" /var/log/messages -c
12
The string "look for this" has been found 12 times in the file /var/log/messages.
[ok, this example was a fake, the /var/log/messages was tweaked :-)]
In the following example, we see that the output is not what we expected. The dummy
file, as used in this example, contains the following text: "bash introduction howto
test file"
$wc --words --lines --bytes /tmp/dummy
2 5 34 /tmp/dummy
Wc doesn't care about the parameter order. Wc always prints them in a standard order,
which is, as you can see: .
"b
a"
$sort /tmp/dummy
a
b
Bc is accepting calculations from command line (input from file. not from redirector
or pipe), but also from a user interface. The following demonstration shows some of
the commands. Note that
1 == 5
0.05 == 0.05
5 != 5
2^8
256
sqrt(9)
while (i != 9) {
i = i + 1;
print i
123456789
quit
Clears screen and prompt appears at (y1,x1). Note that (y0,x0) is the upper left corner.
$tput cols
80
It it higly recommended to be familiarized with these programs (at least). There are
tons of little programs that will let you do real magic on the command line.
#!/bin/sh
# renna: rename multiple files according to several rules
# written by felix hudson Jan - 2000
#first check for the various 'modes' that this program has
#if the first ($1) condition matches then we execute that portion
of the
#program and then exit
#we now get rid of the mode ($1) variable and prefix ($2)
prefix=$2 ; shift ; shift
if [$1 = ]; then
echo "no files given"
exit 0
fi
# this for loop iterates through all of the files that we gave
the program
# it does one rename per file given
for file in $*
do
mv ${file} $prefix$file
done
if [$1 = ]; then
echo "no files given"
exit 0
fi
for file in $*
do
mv ${file} $file$suffix
done
exit 0
fi
# i included this bit as to not damage any files if the user does
not specify
# anything to be done
# just a safety measure
if [ $# -lt 3 ] ; then
echo "usage: renna r [expression] [replacement] files... "
exit 0
fi
# this for loop iterates through all of the files that we give
the program
# it does one rename per file given using the program 'sed'
# this is a sinple command line program that parses standard
input and
# replaces a set expression with a give string
# here we pass it the file name ( as standard input) and replace
the nessesary
# text
for file in $*
do
new=`echo ${file} | sed s/${OLD}/${NEW}/g`
mv ${file} $new
done
exit 0
fi
# done!
criteria=$1
re_match=$2
replace=$3
for i in $( ls *$criteria* );
do
src=$i
tgt=$(echo $i | sed -e "s/$re_match/$replace/")
mv $src $tgt
done
14.2 Translations
Italian: by William Ghelfi (wizzy at tiscalinet.it) is here
I guess there are more translations, but I don't have any info of them, if you have it,
please, mail it to me so I update this section.
14.3 Thanks to
People who translated this document to other languages (previous section).
Nathan Hurst for sending a lot of corrections.
Jon Abbott for sending comments about evaluating arithmetic expressions.
Felix Hudson for writing the renna script
Kees van den Broek (for sending many corrections, re-writting usefull comands
section)
Mike (pink) made some suggestions about locating bash and testing files
Fiesh make a nice suggestion for the loops section.
Lion suggested to mention a common error (./hello.sh: Command not found.)
Andreas Beck made several corrections and coments.
14.4 History
New translations included and minor correcitons.
v0.4 disapperd from its location due to my ex-boss and thid doc found it's new place
at the proper url: www.linuxdoc.org.
This document is a guide to quickly setting up the Vim color editor on Linux or Unix
systems. The information here will improve the productivity of programmers because
the Vim editor supports syntax color highlighting and bold fonts, improving the
"readability" of program code. A programmer's productivity improves 2 to 3 times
with a color editor like Vim. The information in this document applies to all operating
sytems where Vim works, such as Linux, Windows 95/NT, Apple Mac, IBM OSes, VMS,
BeOS and all flavors of Unix like Solaris, HPUX, AIX, SCO, Sinix, BSD, Ultrix etc.. (it
means almost all operating systems on this planet!)
1. Introduction
1.1 Before you Install
1.2 Install Vim on Redhat Linux
1.3 Install Vim on GNU Debian Linux
1.4 Install Vim on Unixes
1.5 Install Vim on Microsoft Windows 95/NT
1.6 Install Vim on VMS
1.7 Install Vim on OS/2
1.8 Install Vim on Apple Macintosh
5. VIM Usage
6. Vi companions
6.1 Ctags for ESQL
6.2 Ctags for JavaScript programs, Korn, Bourne shells
6.3 Debugger gdb
10. Vi Tutorial
10.1 Cursor Movement Commands
10.2 Repeat Counts
10.3 Deleting Text
10.4 Changing Text
10.5 Yanking (Copying) Text
10.6 Filtering text
10.7 Marking Lines and Characters
10.8 Naming Buffers
10.9 Substitutions
10.10 Miscellaneous "Colon Commands"
10.11 Setting Options
10.12 Key Mappings
10.13 Editing Multiple Files
10.14 Final Remarks
If you do not have the Vim package (RPM, DEB, tar, zip) then download the Vim
source code by ftp from the official Vim site
rpm -i vim*.rpm
OR do this -
rpm -i vim-enhanced*.rpm
rpm -i vim-X11*.rpm
rpm -i vim-common*.rpm
rpm -i vim-minimal*.rpm
You can see the list of files the vim rpm installs by -
and browse output using j,k, CTRL+f, CTRL+D, CTRL+B, CTRL+U or using arrow keys,
page up/down keys. See 'man less'.
Note that the RPM packages for Redhat Linux use a Motif interface. If you have
installed the GTK libraries on your system, consider compiling Vim from the source
code for a clean GUI interface. For information on compiling Vim from the source
code, see "Install Vim on Unixes", below.
It will download the latest version of vim, install it, configure it. The first package
listed is vim, the standard editor, compiled with X11 support, vim-rt is the vim
runtime, it holds all the syntax and help files.
You will need both the Unix and Extra archives to build vim.exe for VMS. For using
Vim's full power you will need the runtime files as well. Get these files ( see Before
you Install )
[email protected]
[email protected]
[email protected]
[email protected]
[email protected]
Compiling
Unpack the Unix and Extra archives together into one directory. In the <.SRC>
subdirectory you should find the make file OS_VMS.MMS. By editing this file you
may choose between building the character, GUI and debug version. There are also
additional options for Perl, Python and Tcl support.
You will need either the DECSET mms utility or the freely available clone of it called
mmk (VMS has no make utility in the standard distribution). You can download mmk
from http://www.openvms.digital.com/freeware/MMK/
will start building your own customised version of Vim. The equivalent command for
mmk is:
> mmk /descrip=os_vms.mms
Deploy
Vim uses a special directory structure to hold the document and runtime files:
Use:
to get vim.exe to find its document, filetype, and syntax files, and to specify a
directory where temporary files will be located. Copy the "runtime" subdirectory of
the vim distribution to vimruntime.
Note: Logicals $VIMRUNTIME and $TMP are optional. Read more at :help runtime
Practical usage
Usually you want to run just one version of Vim on your system, therefore it is
enough to dedicate one directory for Vim. Copy all Vim runtime directory structure to
the deployment position. Add the following lines to your LOGIN.COM (in
SYS$LOGIN directory). Set up logical $VIM as:
The easiest way is just rename example files. You may leave the menu file
(MENU.VIM) and files vimrc and gvimrc in the original $VIM directory. It will be
default setup for all users, and for users is enough just to have their own additions or
resetting in home directory in files .vimrc and .gvimrc. It should work without
problems.
Note: Remember, system rc files (default for all users) do not have the leading "." So,
system rc files are:
> VIM$:vimrc
> VIM$:gvimrc
> VIM$:menu.vim
> sys$login:.vimrc
> sys$login:.gvimrc
You can check that everything is on the right place with the :version command.
Example LOGIN.COM:
Note: This set-up should be enough if you are working in a standalone server or
clustered environment, but if you want to use Vim as an internode editor, it should
suffice. You just have to define the "whole" path:
> $ define VIM "<server_name>[""user password""]::device:<path>"
> $ vi*m :== "mcr VIM:VIM.EXE"
as for example:
You can also use $VIMRUNTIME logical to point to proper version of Vim if you
have multiple versions installed at the same time. If $VIMRUNTIME is not defined
Vim will borrow value from $VIM logical. You can find more information about
$VIMRUNTIME logical by typing :help runtime as a Vim command.
VMS is not a native X window environment, so you can not start Vim in GUI mode
"just like that". But it is not too complicated to get a running Vim.
> $ mc device:<path>VIM.EXE -g
or type :gui as a command to the Vim command prompt. For more info :help
gui
and start Vim as in point 1. You can find more help in VMS documentation or
type: help set disp in VMS prompt.
Examples:
At present there is no native PM version of the GUI version of vim: The OS/2 version
is a console application. However, there is now a Win32s-compatible GUI version,
which should be usable by owners of Warp 4 (which supports Win32s) in a Win-OS/2
session. The notes in this file refer to the native console version.
To run Vim, you need the emx runtime environment (at least rev. 0.9b). This is
generally available as (ask Archie about it):
Eric Fischer
5759 N. Guilford Ave
Indianapolis IN 46220 USA
Email to [email protected]
Mac Bug Report When reporting any Mac specific bug or feature change, makes sure
to include the following address in the "To:" or "Copy To:" field.
Vim compiles out of the box with the supplied CodeWarrior project when using
CodeWarrior 9. If you are using a more recent version (e. g. CW Pro) you have to
convert the project first. When compiling Vim for 68k Macs you have to open the
"size" resource in ResEdit and enable the "High level events aware" button to get drag
and drop working. You have to increase the memory partition to at least 1024 kBytes
to prevent Vim from crashing due to low memory.
vim:ts=8:sw=8:tw=78:
Get these two zip files ( see Before you Install ) Unpack the zip files using the
Winzip http://www.winzip.com. Both the zip files (vim*rt.zip and vim*56.zip) must
be unpacked in the same directory like say c:\vim.
For Windows 95/98, set the environment variable VIM in autoexec.bat by adding this
line -
set VIM=c:\vim\vim56
For Windows NT, add the environment variable VIM to the Control Panel | System |
Environment | System Properties dialog:
VIM=c:\vim\vim56
The VIM variable should point to whereever you installed the vim56 directory. You
can also set your PATH to include the gvim.exe's path.
You may need to logoff and relogin to set your environment. At an MS-DOS prompt
type -
set vim
And you should see - VIM=c:\vim\vim56
bash$ cd $HOME
bash$ gvim .bash_profile
set -o vi
alias ls='ls --color '
alias cp='cp -i '
alias mv='mv -i '
alias rm='rm -i '
alias vi='gvim '
alias vip='gvim ~/.bash_profile & '
alias sop='. ~/.bash_profile '
alias mys='mysql -uroot -p '
PATH=$PATH:"/cygdrive/c/Program Files/mysql/bin"
With color ls, when you do ls you will see all the directory names and files in different
colors (it looks great!!). With set -o vi, you can use the command line history editing
just as in linux.
2.3 Setup Window colors
The default background color of MS DOS prompt window is black and white text.
You must change the color, fontsize and window size to make it more pleasing. On
MS Windows 2000, click on button Start->Run and type "cmd" and hit return. On MS
Windows 95/98/NT click on Start->Programs->MSDOS Prompt which will bring up
MSDOS window. Right click on the top left corner of the MSDOS prompt window
and select properties. Select color background and enter R=255, G=255, B=190 (red,
green, blue) for lightyellow background and text foreground color to black (R=0,
G=0, B=0). This sets background to light yellow and text foreground to black and this
combination is most pleasing to human eyes. If you have problems with colors in
cygwin bash window when doing 'man ls', set the text color to "marune".
cd $HOME
cp /usr/doc/vim-common-5.3/gvimrc_example ~/.gvimrc
Comment lines in .gvimrc begin with double-quotes ("). You can customize gvim by
editing the file $HOME/.gvimrc and put the following lines -
" This line is a comment .... one which begins with double-quotes
" The best is the bold font, try all of these and pick one....
set guifont=8x13bold
"set guifont=9x15bold
"set guifont=7x14bold
"set guifont=7x13bold
"
" Highly recommended to set tab keys to 4 spaces
set tabstop=4
set shiftwidth=4
"
" The opposite is 'set wrapscan' while searching for strings....
set nowrapscan
"
" The opposite is set noignorecase
set ignorecase
set autoindent
"
" You may want to turn off the beep sounds (if you want quite) with visual
bell
" set vb
It is very strongly recommended that you set the tabstop to 4 and shiftwidth to 4.
The tabstop is the number of spaces the TAB key will indent while editing with gvim.
The shiftwidth is the number of spaces the lines will be shifted with ">>" or "<<" vi
commands. Refer to Vi tutorials Vim Tutorial for more details.
To see the list of available fonts on Linux/Unix see the command xlsfonts. Type -
" Vim
" An example for a gvimrc file.
" The commands in this are executed when the GUI is started.
"
" To use it, copy it to
" for Unix and OS/2: ~/.gvimrc
" for Amiga: s:.gvimrc
" for MS-DOS and Win32: $VIM\_gvimrc
" set the X11 font to use. See 'man xlsfonts' on unix/linux
" set guifont=-misc-fixed-medium-r-normal--14-130-75-75-c-70-iso8859-1
set guifont=8x13bold
"set guifont=9x15bold
"set guifont=7x14bold
"set guifont=7x13bold
"
" Highly recommended to set tab keys to 4 spaces
set tabstop=4
set shiftwidth=4
"
" The opposite is 'set wrapscan' while searching for strings....
set nowrapscan
"
" The opposite is set noignorecase
set ignorecase
"
" You may want to turn off the beep sounds (if you want quite) with visual
bell
" set vb
" For Win32 version, have "K" lookup the keyword in a help file
"if has("win32")
" let winhelpfile='windows.hlp'
" map K :execute "!start winhlp32 -k <cword> " . winhelpfile <CR>
"endif
" Hide the mouse pointer while typing
set mousehide
endif
See also sample vimrc used for console mode vim command from /usr/doc/vim-
common-5.3/vimrc_example.
You can also edit the ~/.gvimrc file to change the background colors
gvim $HOME/.gvimrc
The best background color is lightyellow or white, with black foreground.
highlight Normal guibg=lightyellow
If a file type you want to use is not detected, then there are two ways to add
it. Method 1: You can modify the $VIMRUNTIME/filetype.vim file, but this is not
recommended as it will be overwritten when you install a new version of Vim.
"
*************************************************************
" Filename : $HOME/vim/myfiletypes.vim
" See the document by typing :help autocmd within vim session
" see also the doc at /usr/share/vim/doc/autocmd.txt
" This file will setup the autocommands for new filetypes
" using the existing syntax-filetypes.
" For example when you open foo.prc it will use syntax of plsql
" Basically does :set filetype=prc inside vim
" Add a line in $HOME/.gvimrc as below:
" so $HOME/vim/myfiletypes.vim
"
*************************************************************
augroup filetype
au!
au! BufRead,BufNewFile *.phc set filetype=php
au! BufRead,BufNewFile *.mine set filetype=mine
au! BufRead,BufNewFile *.xyz set filetype=drawing
au! BufRead,BufNewFile *.prc set filetype=plsql
augroup END
Then add a line in your $HOME/.vimrc and $HOME/.gvimrc file to source in the file
"myfiletypes.vim". (CAUTION: You MUST put this in both vimrc and gvimrc files
in order for this to work) Example:
so $HOME/vim/myfiletypes.vim
NOTE: Make sure that you set "so myfiletypes.vim" before switching on file type
detection. This is must be before any ":filetype on" or ":syntax on" command.
Your file will then be sourced in after the default FileType autocommands have been
installed. This allows you to overrule any of the defaults, by using ":au!" to remove
any existing FileType autocommands for the same pattern. Only the autocommand to
source the scripts.vim file is given later. This makes sure that your autocommands in
"myfiletypes.vim" are used before checking the contents of the file.
gvim foo.pc
:so $VIM/syntax/esqlc.vim
The syntax source files are at /usr/share/vim/syntax/*.vim. Vim supports more than
120 different syntax files for different languages like C++, PERL, VHDL,
JavaScript,...and so on!!
Each syntax file supports one or more default file name extensions, for example,
JavaScript syntax file supports the *.js extension. If you happen to use an extension
that conflicts with another default syntax file (such as adding JavaScript to a *.html
file) than you can source in the additional syntax file with the command :so
$VIM/syntax/javascript.vim. To avoid all of this typing, you can create a soft link like
-
ln -s $VIM/syntax/javascript.vim js
gvim foo.html (... this file contains javascript functions and HTML)
:so js
5. VIM Usage
You can use Vim in two modes - one with GUI and other without GUI. To use GUI
use command -
gvim foo.cpp
It is very strongly recommended that you always use gvim instead of vim, since GUI
mode with colors will definitely improve your productivity.
You can mark the text using the mouse to do cut, copy and paste.
You can use the Menu bar which has - File, Edit, Window, Tools, Synatx and
Help buttons.
Also in near future in gvim - a second menu bar will display the list of files
being edited, and you can switch files by clicking on the filenames, until then
you can use vi commands - :e#, :e#1, :e#2, :e#3, :e#4, ....so on to select the
files.
6. Vi companions
Generally Vim is used in conjunction with other powerful tools
like ctags and gdb. ctags is for very rapid navigation through millions of lines of
"C/C++" code and gdb is for debugging the "C/C++" code. A brief introduction of
these two indispensable commands will be given in this chapter.
ctags is the most powerful command available for coding C, C++, Java, Perl,
Korn/Bourne shell scripts or Fortran. Developers very extensively use ctags to
navigate through thousands of functions within C/C++ programs. See 'man ctags' on
Unix. It is very important that you learn how to use ctags to develop programs in C
or C++, Java, etc.. Navigation is the single most important task while doing
development of C or C++ code. Using ctags you can very quickly read the code by
jumping from a calling line to the called function, drill down deeper into nested
function calls, and unwind back all the way up to the top. You can go back and forth
from function to function very quickly.
Without NAVIGATION you will be completely lost! ctags is like the magnetic
COMPASS needle for the programmers.
Usage of ctags :
ctags *.cpp
gvim -t foo_function
gvim -t main
This will edit the C++ program file which contains the function foo_function() and will
automatically place the cursor on the first line of the function foo_function(). The
second command takes you to the line with the main() function definition.
Inside the Vim editor, you can jump to a function by typing : (colon) tag < function
name >as below -
:tag sample_function
If you want to jump into the function from a line in file which contains the function
name, place the cursor just before the function name and press CTRL+](press control
key and left-square-bracket key simultaneously).
// example code
switch(id_number) {
Case 1:
if ( foo_function( 22, "abcef") == 3 )
^
|
|
|
Place the cursor here (just before foo_function) and press
CTRL+]
This takes you to the function named "foo_function".
To come back to this line press CTRL+t
To go back to the calling line press CTRL+t (Control key and letter 't' together). Keep
pressing CTRL+t to unwind and go to the first line where you started the navigation.
That is you can keep pressing CTRL+] and then keep pressing CTRL+t to go back. You
can repeat these as many times as you want to have complete navigation through all
the functions of C or C++.
#!/bin/sh
which_tag=ctags
aa=`ls *.$ESQL_EXTN`
#echo $aa
for ii in $aa
do
#echo $ii
jj=`echo $ii | cut -d'.' -f1`
#echo $jj
if [ ! -f $jj.cpp ]; then
echo " "
echo " "
echo "***********************************************"
echo "ESQL *.cpp files does not exist.. "
echo "You must generate the *.cpp from *.pc file"
echo "using the Oracle Pro*C pre-compiler or Sybase"
echo "or Informix esql/c pre-compiler."
echo "And then re-run this command"
echo "***********************************************"
echo " "
exit
fi
rm -f tags
$which_tag $jj.cpp
kk=s/$jj\.cpp/$jj\.pc/g
# Now handle all the C++/C files - exclude the ESQL *.cpp files
rm -f tags $tag_file2
bb=`ls *.cpp *.c`
aa=`ls *.$ESQL_EXTN`
for mm in $bb
do
ee=`echo $mm | cut -d'.' -f1`
file_type="NOT_ESQL"
# Exclude the ESQL *.cpp and *.c files
for nn in $aa
do
dd=`echo $nn | cut -d'.' -f1`
if [ "$dd" = "$ee" ]; then
file_type="ESQL"
break
fi
done
rm -f tags
$which_tag $mm
cat tags >> $tag_file2
done
mv -f $tag_file2 tags
cat $tag_file1 >> tags
rm -f $tag_file1
#!/bin/sh
tmp_tag=tags_file
tmp_tag2=tags_file2
\rm -f $tmp_tag
aa=`ls *.$ans`
for ii in $aa
do
jj=`echo $ii | cut -d'.' -f1`
#echo $jj
cp $ii $jj.c
ctags $jj.c
echo "s/$jj.c/$ii/g" > $tmp_tag2
sed -f $tmp_tag2 tags >> $tmp_tag
\rm -f tags $jj.c
done
To debug C++/C programs use 'gdb' tool. See 'man gdb'. You must compile your
programs with -g3 option like
gcc -g3 foo.c foo_another.c sample.c
Pressing TAB key twice is the command line completion, which will save you lots of
typing time. This is one of the most important technique of using gdb.
Or inside the gvim session type :help to get the help page. See also Vim Tutorial To
see the settings type :set all or :set. To see list of options type :options. To see topics
on set type :help set.
VIM - main help file
Jump to a subject: Position the cursor on a tag between |bars| and hit
CTRL-].
With the mouse: ":set mouse=a" to enable the mouse (in xterm or GUI).
Double-click the left mouse button on a tag between |
bars|.
http://www.egroups.com/group/vim
http://www.egroups.com/group/vimdev
http://www.egroups.com/group/vimannounce
9. Vim Tutorial
9.1 Vim Hands-on Tutorial
On Linux system see the tutorial at /usr/doc/vim-common-5.*/tutor, on other unix
systems go to directory where vim is installed and look for doc directory.
bash$ cd /usr/doc/vim-common*/tutor
bash$ less README.txt
bash$ cp tutor $HOME
bash$ cd $HOME
bash$ less tutor
There are many Vi Tutorials on internet. In Yahoo (Lycos, excite or Hotbot) enter "Vi
Tutorial" in search field and search engine will return many pointers.
10. Vi Tutorial
In this tutorial, we describe some "advanced" vi concepts and commands, so you can
appreciate the power of vi and so you decide how to build your knowledge
of vi commands. Nearly all vi references list the available commands, but many don't
bother to discuss how the commands interrelate; this topic is the main purpose of this
tutorial.
Please edit a large text file (say, wknight) so you can experiment with each command
as it is described. Keep in mind these commands will only work in Command Mode,
not Insert Mode; if you start getting your "commands" in your text, press the ESC key
to return to Command Mode.
cursor keys : As we've seen, cursor keys move by single character amounts
left, down, up, and right. Movement above the top of the file, below the bottom,
to the right of the end of a line, or left of the beginning is not allowed (no line
wrapping).
hjkl : When vi was written (around 1978), many terminals on UNIX systems
did not have cursor keys! h, j, k, and l were chosen as commands to move left,
down, up, and right, respectively. Try them! Most vi diehards prefer these to
the cursor keys because
o (a) they are in the same place on all keyborads, and
o (b) they fit nicely under the fingers, unlike most cursor keys, which are
arranged in a box or "T" or some other nonlinear shape.
0 : ("zero", not "oh") Move to the beginning of current line. (To try this and the
next few commands, use the cursor keys or h j k l to move to an indented text
line that contains few "e" characters. If you can't find an indented line in your
file, create one by inserting a few space characters at the beginning of a line.)
^ : Move to first non-white character of current line. (For indented line, 0 and ^
are different.)
$ : Move to last character of current line.
tC : Move to (but not on) next character c in current line. (Press 0, then press
te. This will move to the first e in the curent line.)
fC : Find (move on top of) next character c in current line. (Press fe, and the
cursor will find - that is, move on top - the next e in the current line.)
TC : Move to (but not on) the previous character c in current line (Press $, then
Te.)
FC : Find (move on top of) the previous character c in current line. (Press Fe.)
n| : Move to column n in current line. (Try 20 |. The digits 2 and 0 will not be
displayed as you type them, but when you press | the cursor will move to
column 20.) Try some experiments with t f T F | . When you do something
illegal, vi will beep your terminal.
w : Forward to beginning of next "small" word ( a "small" word consists of
unbroken alphanumeric characters or punctuation characters, but not mixed
alphanumeric and punctuation). Try tapping w a dozen times or so - note what
happens at punctuation.
W : Forward to beginning of next "big" word (alphanumeric and punctuation
mixed). Try W a dozen times or so.
b : Backward to beginning of "small" word.
B : Backward to beginning of "big" word.
e : Forward to end of "small" word.
E : Forward to end of "big" word.
+ Return : Move to first non-white space character on next line. (+ and the
Return key have the same effect.)
- : Move to first non-white space character on previous line.
) : Move to the end of sentence. (A sentence ends either at a blank line or at a
period or examination mark followed by two space characters or at the end of a
line. A period or exclamation mark followed by one space character does not
end a sentence; this is correct behaviour, according to traditional rules of how
sentences should appear in typed documents, but often appears wrong to those
who have never suffered through a formal typing class.)
( : Move to beginning of sentence.
} : Move to end of paragraph. (Paragraphs are seperated with blank lines,
by vi's definition.)
{ : Move to beginning of paragraph.
H : Move to home position (top line) on the screen
M : Move to middle line on the screen.
L : Move to last line on the screen.
nG : Move to line n. If n is not given, move to the last line in the file. (Try 15G
to move to line 15, for example. The CTRL-G command displays the name of
the file, some status information, and the current line number. To move to the
top of the file: 1G)
CTRL-d : Scroll down half-screen (see note).
CTRL-u : Scroll up half-screen (see note).
CTRL-f : Move forward one-screen (see note).
CTRL-b : Move backward one-screen (see note).
Note : These four scrolling/paging commands cannot be used with the delete,
change, yank, or filter commands.
/reg_exp : Move to next occurrence of the regular expression reg_exp When
you press /, the cursor drops to the lower left corner of the screen and waits for
you to type in the regular expression. Press the Return key to finish; vi then
searches forward for the next occurrence of the regular expression. For
example, press /the followed by Return. This moves forward to the next
occurrence of the, perhaps imbedded in the middle of some longer word (other,
weather, etc.). If you just press / and then Return, vi searches for the next
occurrence of whatever the last regular expression was that you searched for.
n : Has the same effect as pressing / and then Return; i.e., searches for the next
occurrence of whatever the last regular expression was that you searched for.
?reg_exp : Searches backward, rather than forward. If no reg_exp is given, it
searches for the last regular expression that was entered. Both / and ? wrap
around, so searching "below" the bottom or "above" the top of the file is legal.
N : Same as pressing ? and then Return.
For some commands (e.g., ^) the repeat count is ignored; for others (e.g., / and ? ) it is
illegal
The d command can be used as a "prefix" on most of the movement commands above
to delete nearly arbitrary chunks of text. When used with d, the movement commands
are called target specifiers. d can be given a repeat count. (As you try these
experiments, remember to press u after each command to undo the deletion).
x is actually just an abbreviation of d1; that is, delete one character right.
For example, put the cursor on the beginning of a word (press w to get to the
beginning of the next word). Then, press cw to change that word. On the screen, the
last character in the word being changed will be replaced with a $ symbol indicating
the boundary of the change; type in a new word (you will overwrite the original word
on the screen) and press the ESC key when done. Your input may be longer or shorter
than the word being changed.
Put the cursor at the beginning of a line containing at least three words, and try c3w to
change three words. Try c$ to change to the end of the current line. In all cases where
the change affects only the current line, the boundary of the change is indicated with
$.
When a change affects more than just the current line, vi deletes the original text from
the screen and toggles into Insert Mode. For example, try c3+ to change the current
and the next three lines; vi deletes the four original lines from the screen and toggles
into Insert Mode in a new blank line. As usual, press the ESC key when you have
finished entering your new text.
The simplest form of yank is yy to yank the current line; after yy, try p to put a copy
of the yanked line after the cursor. Following yy, you can make as many copies of the
yanked line as you want by moving up and down in the file and pressing p.
To copy multiple lines, try, for example, 5yy (yank the current and next four lines). p
puts a copy of the yanked lines after the cursor; the sequence 5yyp "works" but it
probably doesn't do what you would like. The P command is like p, but puts a copy of
the yanked text ahead of the cursor; try the sequence 5yyP.
Some examples will help illustrate. Create a line in your file containing just the word
who and absolutely no other text. Put the cursor on this line, and press !!This
command is analogous to dd, cc, or yy, but instead of deleting, changing, or yanking
the current line, it filters the current line. When you press the second !, the cursor
drops down to the lower left corner of the screen and a single ! is displayed,
prompting you to enter the name of a filter. As the filter name, type sh and press the
Return key. sh (the Bourne shell) is a filter! It reads standard input, does some
processing of its input (that is, executes commands), and sends its output (the output
of those commands) to standard output. Filtering the line containing who through sh
causes the line containing who to be replaced with a list of the current users on the
system - right in your file!
Try repeating this process with date. That is, create a line containing nothing but the
word date, then put the cursor on the line, and press !!sh and the Return key. The line
containing date is replaced with the output of the date command.
Put your cursor on the first line of the output of who. Count the number of lines.
Suppose, for example, the number is six. Then select those six lines to be filtered
through sort; press 6!!sort and the Return key. The six lines will be passed through
sort, and sort's output replaces the original six lines.
The filter command can only be used on complete lines, not on characters or words.
Some other filter commands (here, < CR > means press Return):
!/the < CR > sort < CR > : Sort from the current line up to and including the
next line containing the
!1Ggrep the < CR > : Replace from the current line to and including Line 1
with just the lines that contain the
!Gawk '{print $1}' < CR > : From the current line to the end of file, replace
every line with just its first word.
Now, move the cursor off the marked character and to a different line ( use the cursor
keys, CTRL-u, or whatever). To return to the marked line, press 'a (that is, single
quote, then a). This moves to the first non-white space character on the line containing
mark a.
Move off that line again. To return to the marked character, press `a (that is,
backquote, then a). This moves on top of the character marked with a.
Marking is usually used with deleting, changing, yanking or filtering. For example,
move the cursor to a line other than the one containing mark a, and then press d'a (d,
single quote, a). This deletes from the current line to and including the line marked
with a.
Put the cursor in the middle of a different word and press mb to set mark b. Now,
move the cursor away from that word (but only a few lines, so you can see what we're
about to do more easily), and then press d`b (d, backquote, b). This deletes from the
current CHARACTER to and including the CHARACTER marked with b.
As another example, to sort the output of who, mark the first line (ma), then move the
cursor to the last line and press !'asort and the Return key.
If you jump to a mark and decide you want to jump back to whatever you jumped
from, you can press '' (jump back to line) or `` (jump back to character).
If you wish to delete, change, or yank multiple sections of text and remember them all
(up to a maximum of 26), you can give a buffer name ahead of the delete change or
yank command. A buffer name has the form "c (double quote, lowercase c).
For example, press "ayy to yank the current line into buffer a, then move to a different
line and press "byy to yank that line into buffer b. Now, move elsewhere in the file
and press "ap and "bp to put copies of the text stored in buffers a and b.
Some other named buffer commands:
"a6yy : Yank six lines (current and next five) into buffer a
"bd1G : Delete from the curernt line to and including Line 1, storing the
deleted lines in buffer b
"cy'c : Yank from the current line to the line marked c into buffer c (marks and
buffers are distinct, and may have the same name without confusing vi)
10.9 Substitutions
To substitute one chunk of text for another in lines throughout your file, use the :s
command. Some substitute examples:
:1,$s/the/THE/g From Line 1 to the last line (line $), substitute for the text
THE; do this globally in each line where the occurrs
:'a,.s/.*/ha ha/ From the line marked a to the current line (line .), substitute for
everything on the line the text ha ha
For example, if you want to see line numbers for the lines in the file you're editing,
use the command :set number. To turn off line numbering, use the command :set
nonumber. Most options can be abbreviated; :set nu turns on line numbering and :set
nonu turns off line numbering.
If you :set nomagic, the special meanings of regular expression characters (period,
asterisk, square bracket, etc.) are switched off. Use :set magic to restore the special
meanings.
Some options take a value. For example, :set tabstop=4 causes tabs to be displayed as
four space characters, rather than the usual eight.
If you find you always want certain options set certain ways, you can put the set
commands you want ina file .exrc, or you can set up the environment variable
EXINIT to specify the options you want.
For example, if your login shell is Bourne shell, this line could go in your .profile file:
If your login shell is a C shell, this line could go in your .login file:
setenv EXINIT 'set nomagic nu tabstop=4'
Note: In this command, each control character is shown as ^C, where C is some
uppercase letter. For example, CTRL-M is shown as ^M. Also, when you enter this
command you will not see the CTRL-v characters as shown: each CTRL-v merely
suppresses the usual special meaning of the following control character, so when you
press the sequence ^V^M, all you will see on the screen is ^M. In this command, ^M
is the Return key and ^[ is the ESC key.
:map ^A 55+?^$^V^Mcc^V^L^V^M^V^M^V^M^V^[
Three colon commands are used to move through the multiple files:
:n Move to the next file in the argument list (you must save changes with :w
or vi will print an error message)
:N Move to the previous file in the argument list (you must save changes
with :w or vi will print an error message)
:rew Rewind and start over with the first file in the argument list
The :n, :N, and :rew commands are somewhat clumsy, but there are some important
benefits: the contents of named buffers ("a, "b, "c, etc.) are remembered across files,
so you can use :n and :rew with p and P to copy text back and forth between files.
Also, the most recent search string for the / and ? commands remembered across files,
so you can do repetitive searches in multiple files rather easily.
For example, try the following experiment: First get out of vi, then execute vi with
croc and wknight as arguments:
$ vi croc wknight
In croc, search for the
"ayy
Now go to the next file (you've made no change to croc, so this will work):
:n < CR >
Search for the "next" line containing the, without retyping the search string:
"ap
Move down two lines, and yank the current line into buffer b:
jj"byy
:w < CR >
Search again, and put a copy of buffer b after the found line:
n"bp
ZZ
You will not be a vi expert after reading this tutorial, but you will have a good
appreciation of vi's capabilities. Only time and effort can make a vi expert. But the
efficiency and universality of vi make this effort pay off in the long run.
You may have decided you hate vi. So be it! But be aware that vi remains the standard
UNIX text editor - the one editor you can count on being available on every UNIX
system you'll use - so even if you prefer to use something else day-to-day, you'd be
well advised to know the bare minimum vi material covered in this tutorial.
1. command mode - Normal and initial state; others return here (use ESC to abort
a partially typed command)
2. input mode - entered by specific commands a i A I o O c C s S R and ended
by ESC or abnormally with interrupt
3. line mode - i.e. waiting for input after a : , / , ? or a ! command (end with CR,
abort with CTRL-c). CTRL is the control key: CTRL-c means "control c"
11.7 Movement
Arrows Move the cursor
CTRL-d Scroll half page down
CTRL-u Scroll half page up
CTRL-f Scroll a full page down
CTRL-b Scroll a full page up
:0 Move to start of file
:n Move to line number n
:$ Move to end of file
0 Move to start of line
^ Move to first non-blank character
$ Move to end of line
CR Move to the start of next line
- Move to the start of previous line
% Find matching bracket
G goto line (last line default)
]] next section/function
[[ previous section/function
11.14 Delete
x Delete the character under the cursor
X Delete the charater before the cursor
D Delete to the end of line
d^ Delete back to start of line
dd Delete the current line
ndd Delete n lines starting with the current one
dnw Delete n words starting from cursor
11.19 General
:sh Forks a shell (to be exited with CTRL-d)
:!command Forks a shell to execute command
:set number Switch on line numbering
:set nonumber Switch off line numbering
You can also find this document at the following mirrors sites -
http://www.caldera.com/LDP/HOWTO
http://www.linux.ucla.edu/LDP
http://www.cc.gatech.edu/linux/LDP
http://www.redhat.com/mirrors/LDP
Other mirror sites near you (network-address-wise) can be found
at http://www.linuxdoc.org/mirrors.html select a site and go to directory
/LDP/HOWTO/xxxxx-HOWTO.html
You can get this HOWTO document as a single file tar ball in HTML, DVI,
Postscript or SGML formats from
-ftp://www.linuxdoc.org/pub/Linux/docs/HOWTO/other-formats/ and http://
www.linuxdoc.org/docs.html#howto
Plain text format is
in: ftp://www.linuxdoc.org/pub/Linux/docs/HOWTO and http://www.linuxdoc
.org/docs.html#howto
Single HTML file format is in: http://www.linuxdoc.org/docs.html#howto
Single HTML file can be created with command (see man sgml2html) -
sgml2html -split 0 xxxxhowto.sgml
Translations to other languages like French, German, Spanish, Chinese,
Japanese are
in ftp://www.linuxdoc.org/pub/Linux/docs/HOWTO andhttp://www.linuxdoc.
org/docs.html#howto Any help from you to translate to other languages is
welcome.
The document is written using a tool called "SGML-Tools" which can be got from
- http://www.sgmltools.org Compiling the source you will get the following
commands like
Or you can use Ghostscript command ps2pdf. ps2pdf is a work-alike for nearly all the
functionality of Adobe's Acrobat Distiller product: it converts PostScript files to
Portable Document Format (PDF) files. ps2pdf is implemented as a very small
command script (batch file) that invokes Ghostscript, selecting a special "output
device" called pdfwrite. In order to use ps2pdf, the pdfwrite device must be included
in the makefile when Ghostscript was compiled; see the documentation on building
Ghostscript for details.
13.2 Convert Linuxdoc to Docbook format
This document is written in linuxdoc SGML format. The Docbook SGML format
supercedes the linuxdoc format and has lot more features than linuxdoc. The linuxdoc
is very simple and is easy to use. To convert linuxdoc SGML file to Docbook SGML
use the program ld2db.sh and some perl scripts. The ld2db output is not 100% clean
and you need to use the clean_ld2db.pl perl script. You may need to manually correct
few lines in the document.
The ld2db.sh is not 100% clean, you will get lots of errors when you run
And you may have to manually edit some of the minor errors after running the perl
script. For e.g. you may need to put closing tag < /Para> for each < Listitem>
Then use the tool HtmlToHlp. You can also use sgml2rtf and then use the RTF files for
generating winhelp files.
You can read postscript file using the program 'gv' (ghostview) or 'ghostscript'. The
ghostscript program is in ghostscript*.rpm package and gv program is in gv*.rpm
package in Redhat Linux which can be located through ControlPanel | Applications |
Graphics menu buttons. The gv program is much more user friendly than ghostscript.
Also ghostscript and gv are available on other platforms like OS/2, Windows 95 and
NT, you view this document even on those platforms.
Get ghostscript for Windows 95, OS/2, and for all OSes
from http://www.cs.wisc.edu/~ghost
You can read HTML format document using Netscape Navigator, Microsoft Internet
explorer, Redhat Baron Web browser or any of the 10 other web browsers.
You can read the latex, LyX output using LyX a X-Windows front end to latex.
This document is a guide to quickly setting up the Vim color editor on Linux or Unix
systems. The information here will improve the productivity of programmers because
the Vim editor supports syntax color highlighting and bold fonts, improving the
"readability" of program code. A programmer's productivity improves 2 to 3 times
with a color editor like Vim. The information in this document applies to all operating
sytems where Vim works, such as Linux, Windows 95/NT, Apple Mac, IBM OSes, VMS,
BeOS and all flavors of Unix like Solaris, HPUX, AIX, SCO, Sinix, BSD, Ultrix etc.. (it
means almost all operating systems on this planet!)
1. Introduction
1.1 Before you Install
1.2 Install Vim on Redhat Linux
1.3 Install Vim on GNU Debian Linux
1.4 Install Vim on Unixes
1.5 Install Vim on Microsoft Windows 95/NT
1.6 Install Vim on VMS
1.7 Install Vim on OS/2
1.8 Install Vim on Apple Macintosh
5. VIM Usage
6. Vi companions
6.1 Ctags for ESQL
6.2 Ctags for JavaScript programs, Korn, Bourne shells
6.3 Debugger gdb
10. Vi Tutorial
10.1 Cursor Movement Commands
10.2 Repeat Counts
10.3 Deleting Text
10.4 Changing Text
10.5 Yanking (Copying) Text
10.6 Filtering text
10.7 Marking Lines and Characters
10.8 Naming Buffers
10.9 Substitutions
10.10 Miscellaneous "Colon Commands"
10.11 Setting Options
10.12 Key Mappings
10.13 Editing Multiple Files
10.14 Final Remarks
11. Vim Reference Card
11.1 Vi states
11.2 Shell Commands
11.3 Setting Options
11.4 Notations used
11.5 Interrupting, cancelling
11.6 File Manipulation
11.7 Movement
11.8 Line Positioning
11.9 Character positioning
11.10 Words, sentences, paragraphs
11.11 Marking and returning
11.12 Corrections during insert
11.13 Adjusting the screen
11.14 Delete
11.15 Insert, change
11.16 Copy and Paste
11.17 Operators (use double to affect lines)
11.18 Search and replace
11.19 General
11.20 Line Editor Commands
11.21 Other commands
This document provides a comprehensive list of C++ URL pointers, links to C++ online
textbooks, and programming tips on C++. This document also provides a C++ library
which imitates Java-language, and which has various methods to avoid memory
problems in C++. Using this library you can compile Java's source code under C++. This
document serves as a "Home of C++ language". The information given here will help
you to program properly in C++ language and applies to all the operating systems
that is - Linux, MS DOS, BeOS, Apple Macintosh OS, Microsoft Windows
95/98/NT/2000, OS/2, IBM OSes (MVS, AS/400 etc..), VAX VMS, Novell Netware, all
flavors of Unix like Solaris, HPUX, AIX, SCO, Sinix, BSD, etc.. and to all other operating
systems which support "C++" compiler (it means almost all the operating systems on
this planet).
1. Introduction
1.1 C++ v/s Java
1.2 Which one Ada95, "C", "C++" or Java ??
1.3 Problems facing the current C++ compilers
1.4 COOP - C++ Object Oriented Programming-language
7. String.h file
7.1 StringBuffer.h
7.2 StringTokenizer.h
9. File Class
10. C++ Zap (Delete) function
11. Pointers are problems
12. Usage of my_malloc and my_free
12.1 Garbage Collector for C++
22. Templates
23. STL References
23.1 Overview of the STL
23.2 Header Files
23.3 The Container Classes Interface
23.4 Vectors
23.5 Iterators and the STL
23.6 Lists
23.7 Sets
23.8 Maps
23.9 STL Algorithms
This document is not a textbook on C++, and there are already several excellent "on-
line Text books" on internet. If you are new to C++ and you never programmed in C+
+, then it is strongly suggested that you first read the online C++ Textbooks given in
the chapter C++ Online Textbooks and then follow the subsequent chapters. It is
suggested that you purchase a textbook on C++ for reference from online bookstores
like amazon or barnes.
Java is much closer to Ada95 than C++. Java is derived from Ada95. Ada95 gets the
maximum points as per David Wheeler's Ada comparison chart. Ada got 93%, Java
72%, C++ 68% and C got 53%. C++ and Java are closer in points(only 4%
difference), hence Java is not a very big revolution as compared to C++. On other
hand, Ada is a very big revolution and improvement over C++. The scores are like 4
students taking exams and student with highest score is Ada (93%). Who knows?
Perhaps in future Ada95 will replace Java!! Development costs of Ada is half of C++
as per Stephen F. Zeigler. Ada95 is available at -
Java is platform independent language more suitable for developing GUI running
inside web-browsers (Java applets) but runs very slow. Prefer to use web-server-side
programming "Fast-CGI" with C++ and HTML, DHTML, XML to get better
performance. Hence, the golden rule is "Web-server side programming use C++ and
web-client side (browser) programming use Java applets". The reason is - the server-
side OS (Linux) is under your control and never changes, but you will never know
what the client side web-browser OS is. It can be Internet appliance device (embedded
linux+netscape) or computers running Windows 95/98/NT/2000 or Linux, Apple
Mac, OS/2, Netware, Solaris etc..
The advantage of Java language is that you can create "Applets (GUI)" which can run
on any client OS platform. Java was created to replace the Microsoft Windows 95/NT
GUI APIs like MS Visual Basic or MS Visual C++. In other words - "Java is the
cross-platform Windows-GUI API language of next century". Many web-browsers
like Netscape supports Java applets and web-browser like Hot Java is written in java
itself. But the price you pay for cross-platform portability is the performance,
applications written in Java run very slow.
In "C" programming - memory leaks, memory overflows are very common due to
usage of features like -
The usage of char * and strcpy causes horrible memory problems due
to "overflow", "fence past errors", "memory corruption", "step-on-others-toe"(hurting
other variable's memory locations) or "memory leaks". The memory problems are
extremely hard to debug and are very time consuming to fix and trouble-shoot.
Memory problems bring down the productivity of programmers. This document helps
in increasing the productivity of programmers via different methods addressed to
solve the memory defects in "C++". Memory related bugs are very tough to crack, and
even experienced programmers take several days or weeks to debug memory related
problems. Memory bugs may be hide inside the code for several months and can
cause unexpected program crashes. The memory bugs due to usage of char
* and pointers in C/C++ is costing $2 billion every year in time lost due to debugging
and downtime of programs. If you use char * and pointers in C++ then it is a very
costly affair, especially if your program size is greater than 10,000 lines of code.
Hence, the following techniques are proposed to overcome the faults of "C" language.
Give preference in the following order -
To use "C char *", you would put all your "C" programs in a separate file and link to
"C++" programs using the linkage-specification statement extern "C" -
extern "C" {
#include <stdlib.h>
}
extern "C" {
comp();
some_c_function();
}
The extern "C" is a linkage specification and is a flag that everything within the
enclosing block (brace-surrounded) uses C linkage, not C++ linkage.
The 'String class' utilises the constructor and destructor features to automate memory
management and provides access to functions like ltrim, substring, etc..
See also related 'string class' in the C++ compiler. The string class is part of the
standard GNU C++ library and provides many string manipulation functions. Because
the C++ 'string class' and 'String class' library provides many string manipulation
functions, there is less need to use the character pointer approach to write your own
string functions. Also, C++ programmers must be encouraged to use 'new', 'delete'
operators instead of using 'malloc' or 'free'.
The 'String class' does everything that char * or char [] does. It can completely
replace char datatype. Plus added benefit is that programmers do not have to worry
about the memory problems and memory allocation at all.
Therefore, I propose that we create a new version of C++ that does not allow the use
of the bad features of C.
I propose that this new version of C++ be called COOP (say koop), which is an
acronym for C++ Object Oriented Programming-language" . COOP should be
pronounced like chicken coop. (The logo of COOP language is a big fat Hen inside
coop!) I propose that the file extension for COOP files be .coo, which will not conflict
with .c for C programs or .cpp for C++ programs.
To begin with, write the COOP as a front end to C++. That is COOP pre-processes the
code syntax and then uses the standard C++ compiler to compile the program. COOP
acts as a front end to C++ compiler. (To start with, COOP will be a very good
project/thesis topic for university students)
COOP will borrow some best ideas from Microsoft C#, Microsoft put lot of
efforts, and you can simply utilize them. Specs are at csharp-specs and seeC#
overview.
Is a subset of C++ language but will force programmer to use obejct oriented
programming.
Pure Object-oriented langauge but retains syntax of C++.
Remove all bad or confusing features of C++ in COOP, for e.g. multiple-
inheritance, operator overloading, limit usage of pointers, etc...
Prevent writing "C" like programming in COOP, something which C++ currently
allows. Delete all C features which are considered bad or
redundant/duplicates, like printf, fprintf, malloc, struct, free etc..
No downward compatibility to "C" language.
Code written in COOP will be easy to maintain and is easily
understandable/readable.
Code written in "COOP" will be re-usable (thru components, modules,
objects). Supports re-usable software components, thereby facilitating Rapid
Application Development.
COOP is simple, robust, OOP, has bare mininum syntax (avoiding confusing,
redundant, extra constructs of C++ for e.g remove struct and use class)
Also borrow ideas from -
Java - Sun Microsystem put lot of effort, and you can simply utilize that.
Connective C++ at http://www.quintessent.com/products/cc++.
Start by downloading the sample file 'string_multi.h' from Appendix A . That file is
reproduced below:
// ******************************************************************
// Sample program to demonstrate constructing your own string class
// by deriving from the String class and stdlib's "string" class
// ******************************************************************
#ifndef __STRING_MULTI_H_
#define __STRING_MULTI_H_
#include <string>
#include "String.h"
#endif // __STRING_MULTI_H_
The String class in this document is tested with all the above compilers. It works fine
with MS Visual C++ compiler v6.0, Borland C++ v5.2, Borland C++ compiler v5.5.1 and
Bloodshed compiler.
4. Download String
All the programs, examples are given in Appendix of this document. You can
download as a single tar zip, the String class, libraries and example programs from
The program example_String.cpp (and also given in Appendix A ) has regression test
module which you can use to run the regression tests several millions of times
automatically. After running the regression tests on the String class you can certify
that the String class program is a ROCK SOLID and a BULLET-PROOF program.
I tested the String class with repeat cycle = 50000 and it ran and completed the
program without crash. While it is running I did not notice any memory leak. On
linux, I used /usr/bin/gtop, unix top command, KDEStart->System->KDE System
Gaurd and KDEStart->System->Process management to monitor the cpu and memory
usage.
I recommend that you start the regression test with repeat cycle equal to 10 million or
greater. The greater the repeat cycle number the greater will be your confidence!!
Start the test and go to lunch and come back to see the results!!
The 'String class' is a complete replacement for char and char * datatype. You can
use 'String class' just like char and get much more functionalities. You should link
with the library 'libString.a' which you can build from the makefile given in Appendix
A and copy the library to /usr/lib or /lib directory where all the "C++" libraries are
located. To use the 'libString.a' compile your programs like -
String aa;
Equal to ==
Not equal to !=
Assignment =
Add to itself and Assignment +=
String concatenation or addition +
String aa;
String bb("Bill Clinton");
6.2 Functions
The functions provided by String class has the same name as that of Java language's
String class. The function names and the behaviour is exactly same as that of Java's
String class. StringBuffer class is also provided. This will facilitate portability of code
between Java and C++ (you can cut and paste and do minimum changes to code). The
code from Java's function body can be copied into C++ member function body and
with very mininum changes the code will compile under C++. Another advantage is
that developers coding in both Java and C++ do not need to remember two different
syntax or function names.
String aa;
aa = 34; // The '=' operator will convert int to string
cout << "The value of aa is : " << aa.val() << endl;
aa = 34 + 234.878;
cout << "The value of aa is : " << aa.val() << endl;
// The output aa will be '268.878'
Refer to Appendix A String.h for details about the String class function names. The
same file String.h is reproduced here in next section.
7. String.h file
In C++ (or any object oriented language), you just read the "class data-structure" (i.e.
interface) to begin using that object. You just need to understand the interface and not
the implementation of the interface. In case of String class, you just need to read and
understand the String class in String.h file. You do not need to read the entire
implementation (String.cpp) in order to use String class. The object oriented classes
are real time saver and they very neatly hide the implementation.
(In object oriented Java language there is the equivalent called 'interface' , which
hides the implementation details.)
//
// Author : Al Dev Email: [email protected]
// Use string class or String class
//
// To prevent memory leaks - a char class to manage character variables
// Always prefer to use String or string class
// instead of char[] or char *
//
#ifndef __STRING_H_ALDEV_
#define __STRING_H_ALDEV_
// do not use iostream as program becomes bulky..
#ifdef NOT_MSWINDOWS
#include <iostream>
#else
#include <iostream.h> // some compilers like .h here. Why???
#endif // NOT_MSWINDOWS
//class StringBuffer;
// I compiled and tested this string class on Linux (Redhat 7.1) and
// MS Windows Borland C++ version 5.2 (win32). This should also work
// using MS Visual C++ compiler
class String
{
public:
String();
String(const char bb[]); // needed by operator+
String(const char bb[], int start, int slength); // subset of
chars
String(int bb); // needed by operator+
String(unsigned long bb); // needed by operator+
String(long bb); // needed by operator+
String(float bb); // needed by operator+
String(double bb); // needed by operator+
String(const String & rhs); // Copy Constructor needed by
operator+
//String(StringBuffer sb); // Java compatibility - but causes
compile problem on MS windows and core dumps
String(int bb, bool dummy); // for StringBuffer class
virtual ~String(); // Made virtual so that when base class is
deleted
// then the derived
class destructor is called.
String toUpperCase();
String toLowerCase();
//////////////////////////////////////////////////////
// List of additonal functions not in java
//////////////////////////////////////////////////////
String ltrim();
void ltrim(bool dummy); // Directly changes object. dummy to
get different signature
String rtrim();
void rtrim(bool dummy); // Directly changes object. See also
chopall().
// dummy to get different signature
bool isNull();
bool isInteger();
bool isInteger(int pos);
bool isNumeric();
bool isNumeric(int pos);
bool isEmpty(); // same as length() == 0
bool isUpperCase();
bool isUpperCase(int pos);
bool isLowerCase();
bool isLowerCase(int pos);
bool isWhiteSpace();
bool isWhiteSpace(int pos);
bool isBlackSpace();
bool isBlackSpace(int pos);
bool isAlpha();
bool isAlpha(int pos);
bool isAlphaNumeric();
bool isAlphaNumeric(int pos);
bool isPunct();
bool isPunct(int pos);
bool isPrintable();
bool isPrintable(int pos);
bool isHexDigit();
bool isHexDigit(int pos);
bool isCntrl();
bool isCntrl(int pos);
bool isGraph();
bool isGraph(int pos);
void clear();
int toInteger();
long parseLong();
double toDouble();
String token(char separator = ' '); // see also
StringTokenizer, explode()
String crypt(char *original, char *salt);
String getline(FILE *infp = stdin); // see also putline()
//String getline(fstream *infp = stdin); // see also putline()
String dump(); // Dump the string like 'od -c' (octal dump)
does
///////////////////////////////////////////////
// List of duplicate function names
///////////////////////////////////////////////
// char * c_str() // use val()
// bool find(); // Use regionMatches()
// bool search(); // Use regionMatches()
// bool matches(); // Use regionMatches()
// int rindex(String str2, int startIndex = 0); Use
lastIndexOf()
// String blanks(int slength); // Use repeat()
// String append(String str2); // Use concat() or + operator
// String prepend(String str2); // Use + operator. See also
append()
// String split(char separator = ' '); // Use token(),
explode() or StringTokenizer class
bool contains(char *str2, int startIndex = 0); // use
indexOf()
// void empty(); Use is_empty()
// void vacuum(); Use clear()
// void erase(); Use clear()
// void zero(); Use clear()
// bool is_float(); Use is_numeric();
// bool is_decimal(); Use is_numeric();
// bool is_Digit(); Use is_numeric();
// float float_value(); Use toDouble();
// float tofloat(); Use toDouble();
// double double_value(); Use toDouble();
// double numeric_value(); Use toDouble();
// int int_value(); Use toInteger()
// int tonumber(); Use toInteger()
// String get(); Use substring() or val() but prefer java's
substring
// String getFrom(); Use substring() or val() but prefer
java's substring
// String head(int len); Use substring(0, len)
// String tail(int len); Use substring(length()-len, length())
// String cut(); Use deleteCharAt() or deleteStr()
// String cutFrom(); Use deleteCharAt() or deleteStr()
// String paste(); Use insert()
// String fill(); Use replace()
// char firstChar(); // Use substring(0, 1);
// char lastChar(); // Use substring(length()-1, length());
// String findNext(); Use token(), explode() or
StringTokenizer class
protected:
char *sval; // Not safe to make sval public
void verifyIndex(unsigned long index) const; // not "inline"
because MS Win32 complains
void verifyIndex(unsigned long index, char *aa) const;// not
"inline" - MS Win32 complains
private:
// Note: All the private variables and functions begin
// with _ (underscore)
#endif // __STRING_H_ALDEV_
7.1 StringBuffer.h
//
// Author : Al Dev Email: [email protected]
//
#ifndef __STRINGBUFFER_H_ALDEV_
#define __STRINGBUFFER_H_ALDEV_
int capacity();
StringBuffer append(String str2);
// See also operator +
//{ *this += str2; return *this;} // This is causing
core dumps...
StringBuffer reverse();
private:
StringBuffer *_pStringBuffer;
inline void allocpStringBuffer();
inline void Common2AllCstrs();
};
#endif // __STRINGBUFFER_H_ALDEV_
7.2 StringTokenizer.h
//
// Author : Al Dev Email: [email protected]
//
#ifndef __STRINGTOKENIZER_H_ALDEV_
#define __STRINGTOKENIZER_H_ALDEV_
int countTokens();
bool hasMoreElements();
bool hasMoreTokens();
String nextElement(); // in java returns type 'Object'
String nextToken();
String nextToken(String delimiters);
private:
int CurrentPosition; // current index on string
int TotalTokens;
int RemainingTokens;
char * ListOfDl; // list of delimiters
char * WorkStr; // temp work string
char * OrigStr; // original string passed
bool DlFlag; // delimiter flag
inline void vPrepWorkStr(char *delimiters = NULL);
};
#endif // __STRINGTOKENIZER_H_ALDEV_
In all the files where you do include String.h, insert these lines:
// If you do not like the class name String, then you can rename using typedef
typedef String StringSomethingElseIwant;
.......etc...
}
9. File Class
You would use the File class to manipulate the operating system files. This class is an
imitation of Java's File class and will be very useful in C++ programming. Using this
File class in C++ you can do if file exists() ?, if directory exists() ?, file length() and
other functions.
To make delete operators even more cleaner, make a Zap() inline function. Define a
zap() function like this:
// In C++ the reason there are 2 forms of the delete operator is - because
// there is no way for C++ to tell the difference between a pointer to
// an object and a pointer to an array of objects. The delete operator
// relies on the programmer using "[]" to tell the two apart.
// Hence, we need to define zaparr function below.
// To delete array of pointers
template <class T>
inline void zaparr(T & x)
{
{assert(x != NULL);}
delete [] x;
x = NULL;
}
The zap() function will delete the pointer and set it NULL. This will ensure that even
if multiple zap()'s are called on the same deleted pointer then the program will not
crash. Please see the function zap_example() in example_String.cpp.
zap(pLastname);
zap(pJobDescription);
There is nothing magical about this, it just saves repetative code, saves typing time
and makes programs more readable. The C++ programmers often forget to reset the
deleted pointer to NULL, and this causes annoying problems causing core dumps and
crashes. The zap() takes care of this automatically. Do not stick a typecast in the zap()
function -- if something errors out on the above zap() function it likely has another
error somewhere.
WARNING : Do not use free() to free memory allocated with 'new' or 'delete' to free
memory allocated with malloc. If you do, then results will be unpredictable.
Avoid using pointers as much as possible and use references. Pointers are really a
great pain. It is possible to write an application without using pointers. You should
pointers only in those cases where references will not work.
A reference is an alias; when you create a reference, you initialize it with the name of
another object, the target. From the moment on, the reference acts as an alternative
name of the target, and anything you do to the reference is really done to the target.
int weight;
int & rweight = weight;
DOG aa;
DOG & rDogRef = aa;
Do's of references -
Do not's of references -
The my_malloc and my_realloc is defined as below. It allocates little more memory
(SAFE_MEM = 5) and initializes the space and if it cannot allocate it exits the
program. The 'call_check(), remove_ptr()' functions are active only when
DEBUG_MEM is defined in makefile and are assigned to ((void)0) i.e. NULL for
non-debug production release. They enable the total-memory used tracing.
See my_malloc.cpp. and the header file my_malloc.h. for full implementation of the
my_malloc program.
char *aa;
int *bb;
float *cc;
aa = (char *) my_malloc(sizeof(char)* 214);
bb = (int *) my_malloc(sizeof(int) * 10);
cc = (float *) my_malloc(sizeof(int) * 20);
Note that in my_realloc you do not need to cast the datatype as the variable itself is
passed and correct my_realloc is called which returns the proper datatype pointer.
The my_realloc has overloaded functions for char*, int* and float*.
See the file debug.cpp for implementation of debug routines. And see the
file my_malloc.cpp for sample which uses debug.h and debug functions.
All public variables must begin with m like mFooVar. The m stands
for member.
All protected variables must begin with mt, like mtFooVar and methods with t,
like tFooNum(). The t stands for protected.
All private variables must begin with mv, like mvFooVar and methods with v,
like vFooLone(). The v stands for private.
All public, protected and private variables must begin with uppercase
after m like F in mFooVar.
All pointer variables must be prefixed with p, like
o Public variables mpFooVar and methods like FooNum()
o Protected variables mtpFooVar and methods with t like tFooNum()
o Private variables mvpFooVar and methods with v like vFooNum()
The compiler should generate error if the code does not follow above standard. The
C++ compiler can provide a flag option to bypass strict coding standard to compile
old source code, and for all new code being developed will follow the uniform world-
wide coding standard.
In the sample code given below t stands for protected, v stands for private, m stands
for member-variable and p stands for pointer.
class SomeFunMuncho
{
public:
int mTempZimboniMacho; // Only temporary variables should
be public as per OOP
float *mpTempArrayNumbers;
int HandleError();
float getBonyBox(); // Public accessor as per OOP design
float setBonyBox(); // Public accessor as per OOP design
protected:
float mtBonyBox;
int *mtpBonyHands;
char *tHandsFull();
int tGetNumbers();
private:
float mvJustDoIt;
char mvFirstName[30];
int *mvpTotalValue;
char *vSubmitBars();
int vGetNumbers();
};
When your program grows by millions of lines of code, then you will greatly
appreciate the naming convention as above. The readability of code improves,
because just by looking at the variable name like mvFirstName you can tell that it is
member of a class and is a private variable.
Internet has vast amounts of documentation on C++. Visit the search engines like
Yahoo, Lycos, Infoseek, Excite. Type in the keywords 'C++ tutorials' 'C++
references' 'C++ books' . You can narrow down the search criteria by clicking
on Advanced search and select search by exact phrase
http://www.yahoo.com
http://www.lycos.com
http://www.infoseek.com
http://www.excite.com
http://www.mamma.com
As memory (RAM) prices are dropping and CPU speeds are increasing, scripting
language like PIKE will EXPLODE in popularity. PIKE will become most widely
used scripting language as it is object oriented and it's syntax is very identical to that
of C++ language.
Programming productivity will increase by five times by using the Pike C++ scripting
language. And Pike is very useful for 'proof of concept' and developing prototypes
rapidly.
The Roxen Web server is completely written in Pike, which demonstrates how
powerful Pike is. Pike runs much faster than Java for some operations and is quite
efficient in using memory resources.
22. Templates
http://babbage.cs.qc.edu/STL_Docs/templates.htm Mirror
at: http://www.mike95.com/c_plusplus/tutorial/templates
This tells about #pragma template :
- http://www.dgp.toronto.edu/people/JamesStewart/270/9697f/notes/Nov25
-tut.html
Very GOOD site: http://www.cplusplus.com/doc/tutorial/tut5-
1.html http://www.cplusplus.com/doc/tutorial
For certification of C++: goto http://examware.com and click on "Tutorials"
and then C/C++ button
C++ Open books: http://www.softpanorama.org/Lang/cpp.shtml and click on
tutorials
Templates
tutorial
: http://www.infosys.tuwien.ac.at/Research/Component/tutorial/prwmain.ht
m
STL Tutorial:
I have taken liberties with some of the types of function arguments -- for example
most of the integer arguments referred to in what follows actually have type size_type
which is typedef'ed to an appropriate basic type depending on the allocation model
being used. If you want to see the true signatures of the various functions discussed
have a look at the Working Paper or the header files.
There are a number of utility classes supplied with the STL. The only one of
importance to us is the pair class. This has the following definition:
};
If you don't want to remember which is which you could just use stl.h which includes
all the above (and all the other header files of the STL as well).
== comparison * * * *
< comparison * * * *
begin iterator * * * *
end iterator * * * *
[] element access/modification * *
If the following discussion leaves something unclear (and it will) you can always
write a small test program to investigate how some function or feature behaves.
23.4 Vectors
A vector is an array like container that improves on the C++ array types. In particular
it is not neccessary to know how big you want the vector to be when you declare it,
you can add new elements to the end of a vector using the push_back function. (In
fact the insert function allows you insert new elements at any position of the vector,
but this is a very inefficent operation -- if you need to do this often consider using a
list instead).
Constructing Vectors
vector is a class template so that when declaring a vector object you have to state the
type of the objects the vector is to contain. For example the following code fragment
vector<int> v1;
vector<string> v2;
vector<FiniteAutomaton> v3;
declares that v1 is a vector that holds integers, v2 a vector that holds strings and v3
holds objects of type FiniteAutomaton (presumably an user defined class type). These
declarations do not say anything about how large the vectors are to be
(implementations will use a default starting size) and you can grow them to as large as
you require.
which says that v4 is to be vector of characters that initially has room for 26
characters. There is also a way to initailise a vector's elements. The declaration
vector<float> v5(100,1.0);
says that v5 is a vector of 100 floating point numbers each of which has been
initialised to 1.0.
Once you have created a vector you can find out the current number of elements it
contains by using the size function. This function takes no arguments and returns an
integer (strictly a value of type size_type, but this gets converted to an integer) which
says how many elements there are in the vector. What will be printed out by the
following small program?
<vector-size.cc>=
#include <iostream.h>
#include <vector.h>
void main()
{
vector<int> v1;
vector<int> v2(10);
vector<int> v3(10,7);
To check on wether your vector is empty or not you can use the empty function. This
takes no arguments and returns a boolean value, true if the vector is empty, false if it
is not empty. What will be printed out by the following small program (true prints as 1
and false prints as 0)?
<vector-empty.cc>=
#include <iostream.h>
#include <vector.h>
void main()
{
vector<int> v1;
vector<int> v2(10);
vector<int> v3(10,7);
cout << "v1.empty() has value " << v1.empty() << endl;
cout << "v2.empty() has value " << v2.empty() << endl;
cout << "v3.empty() has value " << v3.empty() << endl;
}
You can access a vector's elements using operator[]. Thus, if you wanted to print out
all the elements in a vector you could use code like
vector<int> v;
// ...
for (int i=0; i<v.size(); i++)
cout << v[i];
(which is very similar to what you might write for a builtin array).
You can also use operator[] to set the values of the elements of a vector.
vector<int> v;
// ...
for (int i=0; i<v.size(); i++)
v[i] = 2*i;
The function front gives access to the first element of the vector.
vector<char> v(10,'a');
// ...
char ch = v.front();
The function back works the same as front but for the last element of the vector.
vector<char> v(10,'z');
// ...
char last = v.back();
v.back() = 'a';
<vector-access.cc>=
#include <vector.h>
#include <iostream.h>
void main()
{
vector<int> v1(5);
int x;
cout << "Enter 5 integers (seperated by spaces):" << endl;
for (int i=0; i<5; i++)
cin >> v1[i];
cout << "You entered:" << endl;
for (int i=0; i<5; i++)
cout << v1[i] << ' ';
cout << endl;
}
Along with operator[] as described above there are a number of other ways to change
or access the elements in a vector.
Note that insert and erase are expensive operations on vectors. If you use them a lot
then you should consider using the list data structure for which they are more
efficient.
<vector-mod.cc>=
#include <iostream.h>
#include <vector.h>
void main()
{
vector<int> v;
int a1[5];
for (int i=0; i<5; i++) a1[i] = 100;
In the above a vector v has been declared then initialised using push_back. Then some
elements have been trimmed off it's end using pop_back. Next an ordinary integer
array has been created and then some of its elements inserted into v using insert.
Finally erase has been used to remove elements from v. The functions used above take
arguments as follows.
push_back takes a single argument of the type of the elements held in the
vector.
pop_back takes no arguments. It is a mistake to use pop_back on an empty
vector.
insert has three forms:
o insert(pos, T& x) which will insert the single element x at position pos in
the vector.
o insert(pos, start, end) which inserts a sequence of elements from some
other container at position pos in the vector. The
o sequence of elements is identified as starting at the start element and
continuing to, but not including, the end element.
o insert(pos, int rep, T& x) inserts rep copies of x at position pos in the
vector.
As indicated in the code above the position pos should be the address of the element
to insert at, whilst the start and end arguments are likewise also addresses. (The true
story is that they are iterators -- see next subsection and following section).
erase has two forms (pos, start and end have the same types as for the insert
function):
o erase(pos) which will remove the element at position pos in the vector.
o insert(start,end) which will remove elements starting at postion start
upto, but not including, the element at position end.
Vector Iterators
The simple way to step through the elements of a vector v is as we have done above:
Another way is to use iterators. An iterator can be thought of as a pointer into the
container, incrementing the iterator allows you to step through the container. For
container types other than vectors iterators are the only way to step through the
container.
vector<T>::iterator i;
Such iterators are constructed and returned by the functions begin() and end(). You
can compare two iterators (of the same type) using == and !=, increment using ++ and
dereference using *. [In fact vector iterators allow more operations on them - see next
section for more information].
<vector-iterator.cc>=
#include <iostream.h>
#include <vector.h>
void main()
{
vector<int> v(10);
first is ``less'' than the second
int j = 1;
vector<int>::iterator i;
}
Note how *i can be used on the left-hand side of an assignment statement so as to
update the element pointed at by i, and on the right-hand side to access the current
value.
Comparing Vectors
You can compare two vectors using == and <. == will return true only if both vectors
have the same number of elements and all elements are equal. The < functions
performs a lexicographic comparison of the two vectors. This works by comparing the
vectors element by element. Suppose we are comparing v1 and v2 (that is v1 < v2?).
Set i=0. If v1[i] < v2[i] then return true, if v1[i] > v2[i] then return false, otherwise
increment i (that is move on to the next element). If the end of v1 is reached before v2
return true, otherwise return false. Lexicographic order is also known as dictionary
order. Some examples:
<vector-comp.cc>=
#include <vector.h>
#include <iostream.h>
void main()
{
vector<int> v1;
vector<int> v2;
for (int i=0; i<4; i++) v1.push_back(i+1);
for (int i=0; i<3; i++) v2.push_back(i+1);
cout << "v1 < v2 is: " << (v1<v2 ? "true" : "false") << endl;
}
The comparison operators <= and >= also work.
23.6 Lists
See the section STL References
23.7 Sets
The set container type allows an user to store and retrieve elements directly rather
than through an index into the container. The set container acts as a mathematical set
in that it holds only distinct elements. However unlike a mathematical set, elements in
a set container are held in (an user-supplied) order. In practise this is only a minor
restriction on treating a set container as an implementation of the mathematical set
abstract data type, and it allows for a much more efficent implementation than an
unordered approach.
Constructing Sets
Two template arguments are required to construct a set container -- the type of the
objects the set is to contain and a function object that can compare two elements of the
given type, that is:
set<T, Compare> s;
(The declaration set < T > s should also be possible -- it would use a default template
argument less < T > as the second argument, but many C++ compilers (including g+
+) cannot as yet cope with default template arguments.)
For simple types T we can use the function object less < T > ( without having to
worry about what a ``function object'' is), for example all the following are legal set
declarations.
(Note that the space between the two final >'s in the template is required - otherwise
the compiler will interpret >> as the right shift operator.) In each of these cases the
function object makes use of the operator < as defined for the the underlying type
(that is int, double, char and string).
The following code declares a set of integers, then adds some integers to the set using
the insert method and then prints out the set members by iterating through the set.
You will note that the set's contents are printed out in ascending order even though
they were added in no particular order.
<set-construct1.cc>=
#include <iostream.h>
#include <set.h>
void main()
{
set<int, less<int> > s;
set<int, less<int> >::iterator i;
s.insert(4);
s.insert(0);
s.insert(-9);
s.insert(7);
s.insert(-2);
s.insert(4);
s.insert(2);
Note that 4 is added twice but only turns up once on the list of elements -- which is
what one expects of a set.
One of the nifty features of C++ is the ability to overload operators, so that one can
have + mean whatever one likes for your newly designed class. One of the operators
C++ allows you to overload is the function call operator () and this allows you to
create classes whose instances can behave like functions in many ways. These are
function objects.
<function-object.cc>=
#include <iostream.h>
template<class T>
class square {
public:
T operator()(T x) { return x*x; }
};
// This can be used with any T for which * is defined.
void main()
{
// Create some function objects.
square<double> f1;
square<int> f2;
// Use them.
cout << 5.1^2 = << f1(5.1) << endl;
cout << 100^2 = << f2(100) << endl;
Function objects are used in a number of places in the STL. In particular they are used
when declaring sets and maps.
The function object required for these purposes, let's suppose it is called comp, must
satisfy the following requirements.
1. If comp(x,y) and comp(y,z) are true for objects x, y and z then comp(x,z) is also
true.
2. comp(x,x) is false for every object x.
If for any particular objects x and y, both comp(x,y) and comp(y,x) are false then x
and y are deemed to be equal.
This, in fact, is just the behaviour of the strictly-less-than relation (ie < ) on numbers.
The function object less < T > used above is defined in terms of a < operator for the
type T. It's definition can be thought of as follows.
template<class T>
struct less {
bool operator()(T x, T y) { return x<y; }
}
(The actual definition uses references, has appropriate const annotations and inherits
from a template class binary_function.)
This means that if the type T has operator < defined for it then you can use less < T >
as the comparator when declaring sets of T. You might still want to use a special
purpose comparator if the supplied < operator is not appropriate for your purposes.
Here is another example. This defines a simple class with a definition of operator <
and a function object that performs a different comparison. Note that the overloaded <
and () operators should be given const annotations so that the functions work correctly
with the STL.
<set-construct2.cc>=
#include <iostream.h>
#include <set.h>
// This class has two data members. The overloaded operator< compares
// such classes on the basis of the member f1.
class myClass {
private:
int f1;
char f2;
public:
myClass(int a, char b) : f1(a), f2(b) {}
int field1() const { return f1; }
char field2() const { return f2; }
bool operator<(myClass y) const
{ return (f1<y.field1()); }
};
void main()
{
set<myClass, less<myClass> > s1;
set<myClass, less<myClass> >::iterator i;
set<myClass, comp_myClass> s2;
set<myClass, comp_myClass>::iterator j;
s1.insert(myClass(1,'a'));
s2.insert(myClass(1,'a'));
s1.insert(myClass(1,'b'));
s2.insert(myClass(1,'b'));
s1.insert(myClass(2,'a'));
s2.insert(myClass(2,'a'));
The set s1 contains (1,a) and (2,a) as comparison is on the data member f1, so that
(1,a) and (1,b) are deemed the same element. The set s2 contains (1,a) and (1,b) as
comparison is on the data member f2, so that (1,a) and (2,a) are deemed the same
element.
A Printing Utility
The way we have printed out the sets in the previous examples is a little awkward so
the following header file containing a simple overloaded version ofoperator<< has
been written. It works fine for small sets with simple element types.
<printset.h>=
#ifndef _PRINTSET_H
#define _PRINTSET_H
#include <iostream.h>
#include <set.h>
return os;
}
#endif
The use here of << as an output routine for a set assumes that << has been defined for
the set elements, and uses this to print a comma delimited list of the set elements
wrapped in curly braces. It will be used without comment in the following examples.
You can determine if a set is empty or not by using the empty() method. You can find
out how many elements there are in a set by using the size() method. These methods
take no arguments, empty() returns true or false and size() returns an integer.
<set-size.cc>=
#include <iostream.h>
#include <set.h>
#include printset.h
void main()
{
set<int, less<int> > s;
s.insert(1);
s.insert(6);
s.insert(7);
s.insert(-7);
s.insert(5);
s.insert(2);
s.insert(1);
s.insert(6);
Two sets may be checked for equality by using ==. This equality test works by testing
in order the corresponding elements of each set for equality using T::operator==.
<set-equality.cc>=
#include <iostream.h>
#include <set.h>
#include printset.h
void main()
{
set<int, less<int> > s1, s2 ,s3;
It is also possible to compare two sets using <. The comparison s1 < s2 is true if the
set s1 is lexicographically less than the set s2, otherwise it is false.
The way to add elements to a set is to use the insert method (as we have done above).
The way to delete elements from a set is to use the erase method.
For a set holding elements of type T these methods come in following forms:
pair < iterator, bool> insert(T& x). This is the standard insert function. The
return value may be ignored or used to test if the insertion succeeded (that is
the element was not already in the set). If the insertion succeeded the
boolean component will be true and the iterator will point at the just inserted
element. If the element is already present the boolean component will be
false and the iterator will point at the element x already present.
iterator insert(iterator position, T& x). This version of the insert function
takes, in addition to the element to insert, an iterator stating where the insert
function should begin to search. The returned iterator points at the newly
inserted element, (or the already present element).
int erase(T& x). This version of the erase method takes an element to delete
and returns 1 if the element was present (and removes it) or 0 if the element
was not present.
void erase(iterator position). This version takes an iterator pointing at some
element in the set and removes that element.
void erase(iterator first, iterator last). This verion takes two iterators pointing
into the set and removes all the elements in the range [ first,last ] .
<set-add-delete.cc>=
#include <iostream.h>
#include <set.h>
#include printset.h
void main()
{
set<int, less<int> > s1;
Finding Elements
We mention two member functions that can be used to test if an element is present in
a set or not.
iterator find(T& x). This searches for the element x in the set. If x is found it
returns an iterator pointing at x otherwise it returns end().
int count(T& x). This returns 1 if it finds x in the set and 0 otherwise. (The
count function for multisets returns the number of copies of the element in
the set which may be more than 1. Hence, I guess, the name of the function.)
The use of find has been illustrated above. We could use count to write a simple
template based set membership function. (This should also provide a version that
takes a reference to the argument x.)
<setmember.h>=
#ifndef _SETMEMBER_H
#define _SETMEMBER_H
#include <set.h>
<set-membership.cc>=
#include <iostream.h>
#include <set.h>
#include printset.h
#include setmember.h
void main()
{
set<int, less<int> > s;
for (int i= 0; i<10; i++) s.insert(i);
cout << s = << s << endl;
cout << 1 is << (member(1,s) ? : not) << a member of s
<< endl;
cout << 10 is << (member(10,s) ? : not) << a member of s
<< endl;
}
The STL supplies as generic algorithms the set operations includes, union,
intersection, difference and symmetric diffference. To gain access to these functions
you need to include algo.h. (In what follows iter stands for an appropriate iterator).
This checks to see if the set represented by the range [f2,l2] is included in the
set [f1,l1]. It returns true if it is and false otherwise. So to check to see if one
set is included in another you would use
The includes function checks the truth of 3#3 ( that is of 4#4). This function
assumes that the sets are ordered using the comparison operator <. If some
other comparison operator has been used this needs to be passed to includes as
an extra (function object) argument after the other arguments.
The fact that the result argument is an output iterator means that you cannot use
set_union in the following, natural, fashion:
The reason is that begin() (also end()) when used with sets (or maps) returns a
(constant) input iterator. This type of iterator allows you to access elements of the set
for reading but not writing. (And this is a Good Thing since if you could assign to a
dereferenced iterator (as in (*i)= ...) then you could destroy the underlying order of
the set.)
The solution is to use an insert iterator based on the set type. This, basically, converts
an assignment (*i)=value (which is illegal) into a (legal) insertion s.insert(i,value)
(where s is the set object that the iterator i is pointing into). It is used as follows:
<set-theory.cc>=
#include <iostream.h>
#include <set.h>
#include <algo.h>
#include <iterator.h>
#include printset.h
void main()
{
typedef set<int, less<int> > intSet;
// Is s1 a subset of s2?
bool test = includes(s2.begin(),s2.end(),s1.begin(),s1.end());
cout << s1 subset of s2 is << (test ? true. : false.) << endl;
// Is s3 a subset of s1?
test = includes(s1.begin(),s1.end(),s3.begin(),s3.end());
cout << s3 subset of s1 is << (test ? true. : false.) << endl;
23.8 Maps
See the section STL References
Introduction
Multi threaded programming is becomming ever more popular. This section presents a
design for a C++ class that will encapsulate the threading mechanism. Certain aspects
of thread programming, like mutexes and semaphores are not discussed here. Also,
operating system calls to manipulate threads are shown in a generic form.
To understand threads one must think of several programs running at once. Imagine
further that all these programs have access to the same set of global variables and
function calls. Each of these programs would represent a thread of execution and is
thus called a thread. The important differentiation is that each thread does not have to
wait for any other thread to proceed. All the threads proceed simultaneously. To use a
metaphor, they are like runners in a race, no runner waits for another runner. They all
proceed at their own rate.
Why use threads you might ask. Well threads can often improve the performance of
an application and they do not incur significant overhead to implement. They
effectively give good bang for a buck. Imagine an image server program that must
service requests for images. The program gets a request for an image from another
program. It must then retieve the image from a database and send it to the program
that requested it. If the server were implemented in a single threaded approach, only
one program could request at a time. When it was busy retrieving an image and
sending it to a requestor, it could not service other requests. Of course one could still
implement such a system without using threads. It would be a challenge though.
Using threads, one can very naturally design a system to handle multiple requests. A
simple approach would be to create a thread for each request received. The main
thread would create this thread upon receipt of a request. The thread would then be
responsible for the conversation with the client program from that point on. After
retrieving the image, the thread would terminate itself. This would provide a smooth
system that would continue to service requests even though it was busy serviceing
other requests at the same time.
Basic Approach
The create a thread, you must specify a function that will become the entry point for
the thread. At the operating system level, this is a normal function. We have to do a
few tricks to wrap a C++ class around it because the entry function cannot be a
normal member function of a class. However, it can be a static member function of a
class. This is what we will use as the entry point. There is a gotcha here though. Static
member functions do not have access to the this pointer of a C++ object. They can
only access static data. Fortunately, there is way to do it. Thread entry point functions
take a void * as a parameter so that the caller can typecast any data and pass in to the
thread. We will use this to pass this to the static function. The static function will then
typecast the void * and use it to call a non static member function.
The Implementation
It should be mentioned that we are going to discuss a thread class with limited
functionality. It is possible to do more with threads than this class will allow.
class Thread
{
public:
Thread();
int Start(void * arg);
protected:
int Run(void * arg);
static void * EntryPoint(void*);
virtual void Setup();
virtual void Execute(void*);
void * Arg() const {return Arg_;}
void Arg(void* a){Arg_ = a;}
private:
THREADID ThreadId_;
void * Arg_;
};
Thread::Thread() {}
/*static */
void * Thread::EntryPoint(void * pthis)
{
Thread * pt = (Thread*)pthis;
pthis->Run( Arg() );
}
It is important to understand that we are wrapping a C++ object around a thread. Each
object will provide an interface to a single thread. The thread and the object are not
the same. The object can exist without a thread. In this implementation, the thread
does not actually exist until the Start function is called.
Notice that we store the user argument in the class. This is necessary because we need
a place to store it temporarily until the thread is started. The operating system thread
call allows us to pass an argument but we have used it to pass the this pointer. So we
store the real user argument in the class itself and when the execute function is called
it can get access to the argument.
int Start(void * arg); This function provides the means to create the thread and start
it going. The argument arg provides a way for user data to be passed into the thread.
Start() creates the thread by calling the operating system thread creation function.
int Run(void * arg); This is a protected function that should never be tampered with.
static void * EntryPoint(void * pthis); This function serves as the entry point to the
thread. It simply casts pthis to Thread * and
virtual void Setup(); This function is called after the thread has been created but
before Execute() is called. If you override this function, remember to call the parent
class Execute().
virtual void Execute(void *); You must override this function to provide your own
functionality.
To use the thread class, you derive a new class. you override the Execute() function
where you provide your own functionality. You may override the Setup() function to
do any start up duties before Execute is called. If you override Setup(), remember to
call the parent class Setup().
Conclusion
You can also find this document at the following mirrors sites -
http://www.caldera.com/LDP/HOWTO
http://www.linux.ucla.edu/LDP
http://www.cc.gatech.edu/linux/LDP
http://www.redhat.com/mirrors/LDP
Other mirror sites near you (network-address-wise) can be found
at http://www.linuxdoc.org/mirrors.html select a site and go to directory
/LDP/HOWTO/xxxxx-HOWTO.html
You can get this HOWTO document as a single file tar ball in HTML, DVI,
Postscript or SGML formats from
-ftp://www.linuxdoc.org/pub/Linux/docs/HOWTO/other-formats/ and http://
www.linuxdoc.org/docs.html#howto
Plain text format is
in: ftp://www.linuxdoc.org/pub/Linux/docs/HOWTO and http://www.linuxdoc
.org/docs.html#howto
Single HTML file format is in: http://www.linuxdoc.org/docs.html#howto
Single HTML file can be created with command (see man sgml2html) -
sgml2html -split 0 xxxxhowto.sgml
Translations to other languages like French, German, Spanish, Chinese,
Japanese are
in ftp://www.linuxdoc.org/pub/Linux/docs/HOWTO andhttp://www.linuxdoc.
org/docs.html#howto Any help from you to translate to other languages is
welcome.
The document is written using a tool called "SGML-Tools" which can be got from
- http://www.sgmltools.org Compiling the source you will get the following
commands like
Or you can use Ghostscript command ps2pdf. ps2pdf is a work-alike for nearly all the
functionality of Adobe's Acrobat Distiller product: it converts PostScript files to
Portable Document Format (PDF) files. ps2pdf is implemented as a very small
command script (batch file) that invokes Ghostscript, selecting a special "output
device" called pdfwrite. In order to use ps2pdf, the pdfwrite device must be included
in the makefile when Ghostscript was compiled; see the documentation on building
Ghostscript for details.
26.2 Convert Linuxdoc to Docbook format
This document is written in linuxdoc SGML format. The Docbook SGML format
supercedes the linuxdoc format and has lot more features than linuxdoc. The linuxdoc
is very simple and is easy to use. To convert linuxdoc SGML file to Docbook SGML
use the program ld2db.sh and some perl scripts. The ld2db output is not 100% clean
and you need to use the clean_ld2db.pl perl script. You may need to manually correct
few lines in the document.
The ld2db.sh is not 100% clean, you will get lots of errors when you run
And you may have to manually edit some of the minor errors after running the perl
script. For e.g. you may need to put closing tag < /Para> for each < Listitem>
Then use the tool HtmlToHlp. You can also use sgml2rtf and then use the RTF files for
generating winhelp files.
You can read postscript file using the program 'gv' (ghostview) or 'ghostscript'. The
ghostscript program is in ghostscript*.rpm package and gv program is in gv*.rpm
package in Redhat Linux which can be located through ControlPanel | Applications |
Graphics menu buttons. The gv program is much more user friendly than ghostscript.
Also ghostscript and gv are available on other platforms like OS/2, Windows 95 and
NT, you view this document even on those platforms.
Get ghostscript for Windows 95, OS/2, and for all OSes
from http://www.cs.wisc.edu/~ghost
You can read HTML format document using Netscape Navigator, Microsoft Internet
explorer, Redhat Baron Web browser or any of the 10 other web browsers.
You can read the latex, LyX output using LyX a X-Windows front end to latex.
Read the header file first and then see the example cpp program
o String.h http://www.angelfire.com/country/aldev0/cpphowto/String.h
o StringBuffer.h http://www.angelfire.com/country/aldev0/cpphowto/
StringBuffer.h
o StringTokenizer.h http://www.angelfire.com/country/aldev0/
cpphowto/StringTokenizer.h
o StringRW.h http://www.angelfire.com/country/aldev0/cpphowto/
StringRW.h
o string_multi.h http://www.angelfire.com/country/aldev0/cpphowto/
string_multi.h
o example_String.cpp http://www.angelfire.com/country/aldev0/
cpphowto/example_String.cpp
File manipulation class, only length() function is implemented..
o File.h http://www.angelfire.com/country/aldev0/cpphowto/File.h
o File.cpp http://www.angelfire.com/country/aldev0/cpphowto/File.cpp
The zap() implemented here ..
o my_malloc.h http://www.angelfire.com/country/aldev0/cpphowto/
my_malloc.h
o my_malloc.cpp http://www.angelfire.com/country/aldev0/
cpphowto/my_malloc.cpp
Implementation of string class...
o String.cpp http://www.angelfire.com/country/aldev0/cpphowto/
String.cpp
o StringTokenizer.cpp http://www.angelfire.com/country/aldev0/
cpphowto/StringTokenizer.cpp
o StringBuffer.cpp http://www.angelfire.com/country/aldev0/
cpphowto/StringBuffer.cpp
o StringRW.cpp http://www.angelfire.com/country/aldev0/cpphowto/
StringRW.cpp
Debug facilities ..
o debug.h http://www.angelfire.com/country/aldev0/cpphowto/debug.h
o debug.cpp http://www.angelfire.com/country/aldev0/cpphowto/
debug.cpp
o Makefile http://www.angelfire.com/country/aldev0/cpphowto/
Makefile
Sample java file for testing the functionalities of String class ..
o string.java http://www.angelfire.com/country/aldev0/cpphowto/
string.java