#include <stdio.h>
#include <stdlib.h>
//Structure containing a Data part & a
//Link part to the next node in the List
struct Node
{
int Data;
struct Node *Next;
}*Head;
// Counting number of elements in the List
int length()
{
struct Node *cur_ptr;
int count=0;
cur_ptr=Head;
while(cur_ptr != NULL)
{
cur_ptr=cur_ptr->Next;
count++;
}
return(count);
}
// Deleting a node from List depending upon the data in the node.
int delNodeData(int num)
{
struct Node *prev_ptr, *cur_ptr;
cur_ptr=Head;
while(cur_ptr != NULL)
{
if(cur_ptr->Data == num)
{
if(cur_ptr==Head)
{
Head=cur_ptr->Next;
free(cur_ptr);
return 0;
}
else
{
prev_ptr->Next=cur_ptr->Next;
free(cur_ptr);
return 0;
}
}
else
{
prev_ptr=cur_ptr;
cur_ptr=cur_ptr->Next;
}
}
printf("\nElement %d is not found in the List", num);
return 1;
}
// Deleting a node from List depending upon the location in the list.
int delNodeLoc(int loc)
{
struct Node *prev_ptr, *cur_ptr;
int i;
cur_ptr=Head;
if(loc > (length()) || loc <= 0)
{
printf("\nDeletion of Node at given location is not possible\n ");
}
else
{
// If the location is starting of the list
if (loc == 1)
{
Head=cur_ptr->Next;
free(cur_ptr);
return 0;
}
else
{
for(i=1;i<loc;i++)
{
prev_ptr=cur_ptr;
cur_ptr=cur_ptr->Next;
}
prev_ptr->Next=cur_ptr->Next;
free(cur_ptr);
}
}
return 1;
}
//Adding a Node at the end of the list
void addEnd(int num)
{
struct Node *temp1, *temp2;
temp1=(struct Node *)malloc(sizeof(struct Node));
temp1->Data=num;
// Copying the Head location into another node.
temp2=Head;
if(Head == NULL)
{
// If List is empty we create First Node.
Head=temp1;
Head->Next=NULL;
}
else
{
// Traverse down to end of the list.
while(temp2->Next != NULL)
temp2=temp2->Next;
// Append at the end of the list.
temp1->Next=NULL;
temp2->Next=temp1;
}
}
// Adding a Node at the Beginning of the List
void addBeg(int num)
{
struct Node *temp;
temp=(struct Node *)malloc(sizeof(struct Node));
temp->Data = num;
if (Head == NULL)
{
//List is Empty
Head=temp;
Head->Next=NULL;
}
else
{
temp->Next=Head;
Head=temp;
}
}
// Adding a new Node at specified position
void addAt(int num, int loc)
{
int i;
struct Node *temp, *prev_ptr, *cur_ptr;
cur_ptr=Head;
if(loc > (length()+1) || loc <= 0)
{
printf("\nInsertion at given location is not possible\n ");
}
else
{
// If the location is starting of the list
if (loc == 1)
{
addBeg(num);
}
else
{
for(i=1;i<loc;i++)
{
prev_ptr=cur_ptr;
cur_ptr=cur_ptr->Next;
}
temp=(struct Node *)malloc(sizeof(struct Node));
temp->Data=num;
prev_ptr->Next=temp;
temp->Next=cur_ptr;
}
}
}
// Displaying list contents
void display()
{
struct Node *cur_ptr;
cur_ptr=Head;
if(cur_ptr==NULL)
{
printf("\nList is Empty");
}
else
{
printf("\nElements in the List: ");
//traverse the entire linked list
while(cur_ptr!=NULL)
{
printf(" -> %d ",cur_ptr->Data);
cur_ptr=cur_ptr->Next;
}
printf("\n");
}
}
//Reversesing a Linked List
void reverse()
{
struct Node *prev_ptr, *cur_ptr, *temp;
cur_ptr=Head;
prev_ptr=NULL;
while(cur_ptr != NULL)
{
temp=prev_ptr;
prev_ptr=cur_ptr;
cur_ptr=cur_ptr->Next;
prev_ptr->Next=temp;
}
Head=prev_ptr;
}
int main(int argc, char *argv[])
{
int i=0;
//Set HEAD as NULL
Head=NULL;
while(1)
{
printf("\n####################################################\n");
printf("MAIN MENU\n");
printf("####################################################\n");
printf(" \nInsert a number \n1. At the Beginning");
printf(" \n2. At the End");
printf(" \n3. At a Particular Location in the List");
printf(" \n\n4. Print the Elements in the List");
printf(" \n5. Print number of elements in the List");
printf(" \n6. Reverse the linked List");
printf(" \n\nDelete a Node in the List");
printf(" \n7. Delete a node based on Value");
printf(" \n8. Delete a node based on Location\n");
printf(" \n\n9. Exit\n");
printf(" \nChoose Option: ");
scanf("%d",&i);
switch(i)
{
case 1:
{
int num;
printf(" \nEnter a Number to insert in the List: ");
scanf("%d",&num);
addBeg(num);
display();
break;
}
case 2:
{
int num;
printf(" \nEnter the Number to insert: ");
scanf("%d",&num);
addEnd(num);
display();
break;
}
case 3:
{
int num, loc;
printf("\nEnter the Number to insert: ");
scanf("%d",&num);
printf("\nEnter the location Number in List at which \
the Number is inserted: ");
scanf("%d",&loc);
addAt(num,loc);
display();
break;
}
case 4:
{
display();
break;
}
case 5:
{
display();
printf(" \nTotal number of nodes in the List: %d",length());
break;
}
case 6:
{
reverse();
display();
break;
}
case 7:
{
int num;
printf(" \nEnter the number to be deleted from List: ");
scanf("%d",&num);
delNodeData(num);
display();
break;
}
case 8:
{
int num;
printf(" \nEnter the location of the node to \
be deleted from List: ");
scanf("%d",&num);
delNodeLoc(num);
display();
break;
}
case 9:
{
struct Node *temp;
while(Head!=NULL)
{
temp = Head->Next;
free(Head);
Head=temp;
}
exit(0);
}
default:
{
printf("\nWrong Option choosen");
}
}/* end if switch */
}/* end of while */
}/* end of main */
4.24.2010
Singly Linked List in C
Check Implementation of Singly Linked List for theoretical explanation regarding implementation of singly linked lists.
3.27.2010
Fedora 12 on HP Pavilion dv6340eu
Atlast the day has come, LINUX running on my laptop(pre-loaded with M$ VISTA). Time for celebrations.
So I decided to drop a post on how the journey took place towards installing and using LINUX in my laptop. Initially I faced a serious problem, which LINUX flavour to use ... UBUNTU or FEDORA (sorry these are only my preferred flavours for long time). I got UBUNTU successfully running on my old desktop, on my sister's latest desktop and some more desktops of friends. I got FEDORA running successfully on my SERVER and other desktops. I never tried or used LINUX flavours on a LAPTOP (as I see communities filled with posts saying problems with LINUX on their laptops) so I have to choose one ...
Atlast I decided to go with FEDORA 12 .. not sure why I dumped UBUNTU over FEDORA ... but since I am comfortable with FEDORA as I work more with FEDORA .. and FEDORA 12 got many new open-source technologies and pre-packed with latest kernel in the market (Hmm I agree that a UBUNTU release is 6 months older to a FEDORA release). But still I love UBUNTU :)
Laptop Specs
HP Pavilion dv6340eu (2007 European model)
AMD Turion 64 X2 processor,
1GB RAM (really insane),
NVIDIA GEOFORCE 7200M graphics card,
BROADCOM wireless chipset and other HP stuff.
Off the Road ... M$ VISTA
Boot up and complete M$ VISTA loading takes around 10 to 15 minutes (low RAM might be the cause) until then don't even think of opening any other application it will mess up. Sometimes I use a NOKIA mobile to connect to WIRELESS GPRS INTERNET of AIRTEL and it requires PC-SUITE software from NOKIA. Apart from this inorder to protect myself from viruses and online threats I need a third party security application(s) like ANTIVIRUS, FIREWALL (resource hogs on 1GB RAM machine running M$ VISTA). Even in idle state more than 60% of the RAM is always busy and processor(s) utilization is always more than 50%. I faced strange problems on M$ VISTA with External harddisks .. when I use "safely remove hardware" option and then disconnect the hardware it always pop up message saying some information might be lost ... eventhough I wait for sometime to disconnect them?? and it really messed up my external storage devices many times.
Back to the Road ...
I decided to go with a 32 bit FEDORA OS installation ... after seeing many problems reported with 64 bit OS when compared to 32 bit OS. Downloaded a LIVECD and installed FEDORA 12 in dual boot without any hiccups ... that's a plain install no magic spells or hacking cheats used :). Voilla great its really simple on my laptop.
Automatic reboot of laptop once the installation is complete and booted in FEDORA12 ... Wow it just took less than 2 minutes to boot up completely ... RAM and CPU usage has been drastically reduced.
I connected my NOKIA mobile to laptop and it is detected automatically. I created a new wireless broadband connection under my subscriber AIRTEL and it simply connected like a charm. Damn who needs NOKIA PC-SUITE crap for connecting to internet. I am not using any of the fancy COMPIZ stuff and simply using the NOUVEAU drivers for my graphic cards. My wirelan connection is also working like a charm no drivers from HP or any third party stuff.
Problems in Journey ..
Small usage problems with openoffice ... as my brain is corrupted with M$ OFFICE. Eventhough LIVE CD is downloaded recently it has got many security updates and patches (around 412 I guess .. of 300MB) to be downloaded from internet ... I wonder why don't they update the FEDORA build atleast once in a month with latest patches :(. Livecd doesn't have any compilers for C, C++, Java and so on and they have to be updated from internet :(. Fedora by default has music/movie players but none of them have any codecs to play a normal MP3 file (hmm licensing problems)...
Seems there are some problems with power management .. as my laptop makes me feel as if it is burning ... My harddisk temperature is at 60'c and processor cores are above 65'c eventhough internal fans are running at full speed.
After all the problems and happiness I decided to drop this post in BLOGGER from a LINUX machine ... my FIRST one. Now my laptop proudly carry the logo of FEDORA on its chest.
Update 1: Do check Fedora 12 common bugs before you install Fedora 12 on your machine - https://fedoraproject.org/wiki/Common_F12_bugs
Update 2: Integrated Webcam is still not working .. looking for workarounds.
Update 3: Do not use Nvidia Proprietary drivers replacing NOUVEAU drivers. Atleast I am seeing a system crash after update. Raised a bug at https://bugzilla.redhat.com/show_bug.cgi?id=594439 and waiting for the real reason behind the crash and any workarounds.
Hmm ... haven't found any solution until now ... Only solution available is REINSTALL OS again ... stupid workaround. Why should I stuck with FEDORA 12 which seems to be crappy .. UBUNTU 10.04 with 5 years of support here I come.
Update 4:BYE BYE FEDORA 12 .... I am really disappointed by the support and help provided by Fedora Community.
So I decided to drop a post on how the journey took place towards installing and using LINUX in my laptop. Initially I faced a serious problem, which LINUX flavour to use ... UBUNTU or FEDORA (sorry these are only my preferred flavours for long time). I got UBUNTU successfully running on my old desktop, on my sister's latest desktop and some more desktops of friends. I got FEDORA running successfully on my SERVER and other desktops. I never tried or used LINUX flavours on a LAPTOP (as I see communities filled with posts saying problems with LINUX on their laptops) so I have to choose one ...
Atlast I decided to go with FEDORA 12 .. not sure why I dumped UBUNTU over FEDORA ... but since I am comfortable with FEDORA as I work more with FEDORA .. and FEDORA 12 got many new open-source technologies and pre-packed with latest kernel in the market (Hmm I agree that a UBUNTU release is 6 months older to a FEDORA release). But still I love UBUNTU :)
Laptop Specs
HP Pavilion dv6340eu (2007 European model)
AMD Turion 64 X2 processor,
1GB RAM (really insane),
NVIDIA GEOFORCE 7200M graphics card,
BROADCOM wireless chipset and other HP stuff.
Off the Road ... M$ VISTA
Boot up and complete M$ VISTA loading takes around 10 to 15 minutes (low RAM might be the cause) until then don't even think of opening any other application it will mess up. Sometimes I use a NOKIA mobile to connect to WIRELESS GPRS INTERNET of AIRTEL and it requires PC-SUITE software from NOKIA. Apart from this inorder to protect myself from viruses and online threats I need a third party security application(s) like ANTIVIRUS, FIREWALL (resource hogs on 1GB RAM machine running M$ VISTA). Even in idle state more than 60% of the RAM is always busy and processor(s) utilization is always more than 50%. I faced strange problems on M$ VISTA with External harddisks .. when I use "safely remove hardware" option and then disconnect the hardware it always pop up message saying some information might be lost ... eventhough I wait for sometime to disconnect them?? and it really messed up my external storage devices many times.
Back to the Road ...
I decided to go with a 32 bit FEDORA OS installation ... after seeing many problems reported with 64 bit OS when compared to 32 bit OS. Downloaded a LIVECD and installed FEDORA 12 in dual boot without any hiccups ... that's a plain install no magic spells or hacking cheats used :). Voilla great its really simple on my laptop.
Automatic reboot of laptop once the installation is complete and booted in FEDORA12 ... Wow it just took less than 2 minutes to boot up completely ... RAM and CPU usage has been drastically reduced.
I connected my NOKIA mobile to laptop and it is detected automatically. I created a new wireless broadband connection under my subscriber AIRTEL and it simply connected like a charm. Damn who needs NOKIA PC-SUITE crap for connecting to internet. I am not using any of the fancy COMPIZ stuff and simply using the NOUVEAU drivers for my graphic cards. My wirelan connection is also working like a charm no drivers from HP or any third party stuff.
Problems in Journey ..
Small usage problems with openoffice ... as my brain is corrupted with M$ OFFICE. Eventhough LIVE CD is downloaded recently it has got many security updates and patches (around 412 I guess .. of 300MB) to be downloaded from internet ... I wonder why don't they update the FEDORA build atleast once in a month with latest patches :(. Livecd doesn't have any compilers for C, C++, Java and so on and they have to be updated from internet :(. Fedora by default has music/movie players but none of them have any codecs to play a normal MP3 file (hmm licensing problems)...
Seems there are some problems with power management .. as my laptop makes me feel as if it is burning ... My harddisk temperature is at 60'c and processor cores are above 65'c eventhough internal fans are running at full speed.
Update 1: Do check Fedora 12 common bugs before you install Fedora 12 on your machine - https://fedoraproject.org/wiki/Common_F12_bugs
Update 2: Integrated Webcam is still not working .. looking for workarounds.
Update 3: Do not use Nvidia Proprietary drivers replacing NOUVEAU drivers. Atleast I am seeing a system crash after update. Raised a bug at https://bugzilla.redhat.com/show_bug.cgi?id=594439 and waiting for the real reason behind the crash and any workarounds.
Hmm ... haven't found any solution until now ... Only solution available is REINSTALL OS again ... stupid workaround. Why should I stuck with FEDORA 12 which seems to be crappy .. UBUNTU 10.04 with 5 years of support here I come.
Update 4:BYE BYE FEDORA 12 .... I am really disappointed by the support and help provided by Fedora Community.
1.04.2010
iptables - Rate-limit incoming connections
Using "recent" match option in iptables we can match recent connections, and perform simple throttling operation on incoming connections i.e. we can create simple firewall rules which will deny access from remote clients who attempt to connect "too many" times.
"recent" dynamically creates a list of IP addresses and then match against that list. The functionality of "recent" match option is simple, a list of IP addresses are created dynamically, which can be used in the future to test connection attempts against.
rate limiting is conceptually different from bandwidth throttling/limiting; a bandwidth-throttled connection will queue packets and limit the rate at which they are transmitted/received. Rate limiting will not do this; when you use rate limiting on, for example, incoming TCP connection attempts to your identd, and connections exceeding the specified limit will be denied; there is no queueing of packets.
NOTE: CONFIG_IP_NF_MATCH_RECENT flag should be enabled in Linux Kernel to use "recent" option.
Following 2 rules will limit incoming connections to destination port 22 not more than 3 in a minute and more than that will be dropped:
iptables -I INPUT -p tcp --dport 22 -m state --state NEW \
-m recent --set
iptables -I INPUT -p tcp --dport 22 -m state --state NEW \
-m recent --update --seconds 60 --hitcount 3 -j DROP
"--state NEW" – To make sure that only new connections are managed."--set" flag will make sure that the IP address of the host which initiated the connection will be added to the "recent list", where it can be tested and used again in the future i.e. in our second rule.
The second rule is where the actual magic happens.
"—update" flag tests whether the source IP address is in the list of recent connections, in our case each new tcp connection to destination port 22 will be in the list because we used the "--set" flag to add it in the preceeding rule.
"--seconds" flag is used to make sure that the source IP address is only going to match if the last connection was within the timeframe given.
"--hitcount" flag matches only if the given count of connection attempts is greater than or equal to the number given.
The second rule will DROP an incoming connection if:
- The IP address which initiated the connection has previously been added to the list and
- The IP address has sent a packet in the past 60 seconds and
- The IP address has sent more than 3 packets in total.
iptables -I INPUT -p icmp --icmp-type echo-request \ -m recent --set iptables -I INPUT -p icmp --icmp-type echo-request \ -m recent --update --seconds 60 --hitcount 30 -j DROPIn above rules we dont use "--state NEW" since it is not needed in rate limiting number of ICMP echo requests.
NOTE: In the above rules we are trying to automatically limit number of connections from each user. So it is something like 3 attempts from each user in 1 minute.
What if we want to limit number of certain packets from all users ? Then "limit" match option comes to rescue.
"limit" option specifies the maximum average number of matches to allow per second. We can specify time intervals in the format /second, /minute, /hour, or /day, or you can use abbreviations so that 3/second is the same as 3/s.
NOTE: CONFIG_IP_NF_MATCH_LIMIT flag should be enabled in Linux Kernel to use "limit" option.
Let us see how to limit number of ICMP echo requests not more than 3 per second and drop rest of them.
iptables -I INPUT -p icmp --icmp-type echo-request \ -m limit !--limit 3/s -j ACCEPTWhen tuned correctly, this feature allows us to filter unusually high volumes of traffic that characterize denial of service (DOS) attacks and Internet worms.
But take care: When tuned incorrectly, this feature does the opposite: Helping any attacker in denial of service attacks. Instead of having to initiate enough connections to bring the whole server down, it then may be sufficient to just start enough connections to activate the firewall rules.
References:
1. Debian Administration
2. man iptables
1.01.2010
Creating and using static libraries in Linux
Static libraries are simply a collection of ordinary object files.
For more information on shared libraries checkout - Creating and using shared libraries in Linux
Static libraries conventionally end with the ".a" suffix. They are useful for developers to link to their library, but don't want to give the library source code. Theoretically code in static ELF libraries that is linked into an executable should run slightly faster (by 1-5%) than a shared library or a dynamically loaded library, but in practice this rarely seems to be the case due to other confounding factors.
We use following source code files for this post.
calc_mean.c
First we have to create object file for calc_mean.c
Compiling main program and linking with static library
We have already created a static library libmean.a and now let us use the static library by invoking it as part of the compilation and linking process when creating a program executable. Incase of gcc we use following flags to create static library
For more information on shared libraries checkout - Creating and using shared libraries in Linux
Static libraries conventionally end with the ".a" suffix. They are useful for developers to link to their library, but don't want to give the library source code. Theoretically code in static ELF libraries that is linked into an executable should run slightly faster (by 1-5%) than a shared library or a dynamically loaded library, but in practice this rarely seems to be the case due to other confounding factors.
We use following source code files for this post.
calc_mean.c
double mean(double a, double b) { return (a+b) / 2; }calc_mean.h
double mean(double, double);main.c - We are including our static library in this application.
#include <stdio.h> #include "calc_mean.h" int main(int argc, char* argv[]) { double v1, v2, m; v1 = 5.2; v2 = 7.9; m = mean(v1, v2); printf("The mean of %3.2f and %3.2f is %3.2f\n", v1, v2, m); return 0; }Creating the static library
First we have to create object file for calc_mean.c
gcc -c calc_mean.c -o calc_mean.oThen, using archiver (ar) we produce a static library (named libmean.a) out of the object file calc_mean.o.
ar rcs libmean.a calc_mean.oNOTE: A static library must start with the three letters 'lib' and have the suffix '.a'.
Compiling main program and linking with static library
We have already created a static library libmean.a and now let us use the static library by invoking it as part of the compilation and linking process when creating a program executable. Incase of gcc we use following flags to create static library
- -llibrary searches for the library named library at the time of linking. Linker searches and processes libraries and object files in the order they are specified. Thus, ‘foo.o -lz bar.o’ searches library ‘z’ after file foo.o but before bar.o. If bar.o refers to functions in ‘z’, those functions may not be loaded. The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.
- -L(path-to-the-library) Specifies the path in which the library file can be found. We can use -L. inorder to point to the current directory and -L/home/tmp to point to /home/tmp directory.
- -static On systems that support dynamic linking, this prevents linking with the shared libraries.
gcc -static main.c -L. -lmean -o mainNow run the executable program 'main'
$./main
12.16.2009
ctags - vim with steroids
Basically C/C++ projects have thousands of lines of code divided into hundreds in some cases thousands of files. Inorder to access various function definitions within the sourcecode repository effectively using a VIM editor there is a great need for using addons like ctags which provides easy code go through.
Eventhough there are many effective GUI based code editors like eclipse e.t.c I prefer to use VIM editor as my primary code editor. I am not much into GUI funda so still prefer basic editor like VIM.
1. Installing ctags package
Almost all the linux flavours with 2.6.X kernel might have ctags installed by default. If not download the appropriate .deb or rpm file. Sorry I am not dealing with installing of ctags as I havent came across this stage as I am using FEDORA 9.
2. Generating ctags on your source code.
We have to generate a file named 'tags' for all the source code files, use the following command:
But VIM searching many places for tags files is not really robust enough as it may get a bit slow. It's better to generate one big tags file offcourse it takes more time to create a single tags files for whole project. Just give the following command to recursively add all files in your project.
Now we can simply include this single tags files as shown below
We have 3 different ways to use ctags in VIM editor.
From Shell:
We can invoke directly the file or the files containing the definition for a particular function from shell.
OR
VIM command line:
We can invoke from VIM commandline (in command mode) the definition of a function.
OR
By cursor position:
This option is more user-friendly as we use a key combination instead of giving commands.
History
To display the list of tags that we have traversed in past give the following command.
Divide and Conquer
As we saw already 'ctrl + ]' replaces the file in the current window with the one containing the new function. But suppose if we want to see not only the old function but also the new one?
We can split the window using the ":split" command followed by the ":tag" command.
VIM supports tag name completion. Start typing the tag name (i.e. function name) and then hit TAB key and name completion will be done automatically if there is a tag name.
You are editing a C program and wonder if a variable is declared as "int" or "unsigned". A quick way to find this is with the "[I" command. Suppose the cursor is on the word "column" then type
but also in all included files (and files included in them, etc.). The result
looks like this:
searched. In most cases this results in the right declaration to be found.
Also when the tags file is out of date. Also when you don't have tags for the
included files.
However, a few things must be right for "[I" to do its work. First of all,
the 'include' option must specify how a file is included. The default value
works for C and C++. For other languages you will have to change it.
Reference:
ctags documentation
Eventhough there are many effective GUI based code editors like eclipse e.t.c I prefer to use VIM editor as my primary code editor. I am not much into GUI funda so still prefer basic editor like VIM.
1. Installing ctags package
Almost all the linux flavours with 2.6.X kernel might have ctags installed by default. If not download the appropriate .deb or rpm file. Sorry I am not dealing with installing of ctags as I havent came across this stage as I am using FEDORA 9.
2. Generating ctags on your source code.
We have to generate a file named 'tags' for all the source code files, use the following command:
ctags *.c *.hWhen we have many files in many directories then we have to create a tags file in each of the directories. But VIM will only be able to jump to tags within the same directory. To find more tags files, we have to set the 'tags' option in VIM to include all the relevant tags files. Just set the following command in ~/.vimrc file.
:set tags=./tags,./../tags,./*/tagsThis finds a tags file in the same directory as the current file, one directory level higher and in all subdirectories.
But VIM searching many places for tags files is not really robust enough as it may get a bit slow. It's better to generate one big tags file offcourse it takes more time to create a single tags files for whole project. Just give the following command to recursively add all files in your project.
$ cd /proj-R is to recursively go across all the directories, and a ‘tags’ file will be created including all the files in the sub-directories also.
$ ctags -R *
Now we can simply include this single tags files as shown below
:set tags=~/proj/tags3. Start using ctags with VIM editor
We have 3 different ways to use ctags in VIM editor.
From Shell:
We can invoke directly the file or the files containing the definition for a particular function from shell.
vi -t function_nameThis will find the correct file or list of files having function_name definition.
OR
VIM command line:
We can invoke from VIM commandline (in command mode) the definition of a function.
:tag function_nameThis will jump automatically from the current file to the file containing the function_name definition.
or
:ta function_name
OR
By cursor position:
This option is more user-friendly as we use a key combination instead of giving commands.
ctrl + ]Place the cursor on the first character of the function name and press ctrl-]. This will jump to the file containing the definition of function_name.
ctrl + tThis command will jump back to previous location.
ctrl + iTo travel forward through the tag history.
ctrl + oTo travel backward through the tag history.
History
To display the list of tags that we have traversed in past give the following command.
:tagsShows tag stack (history).
Divide and Conquer
As we saw already 'ctrl + ]' replaces the file in the current window with the one containing the new function. But suppose if we want to see not only the old function but also the new one?
We can split the window using the ":split" command followed by the ":tag" command.
:stag function_nameCursor command for above feature is
ctrl + w + ]Auto Complete
VIM supports tag name completion. Start typing the tag name (i.e. function name) and then hit TAB key and name completion will be done automatically if there is a tag name.
:tag start-of-tag-name_TABJump to a tag name found by a search.
:tag /search-stringWhen multiple entries exist in the tags file, such as a function declaration in a header file and a function definition (the function itself), the operator can choose by issuing this command. The user will be presented with all the references to the function and the user will be prompted to enter the number associated with the appropriate one.
:tselect function-nameJumps to next matching tag.
:tnextJump to previous matching tag.
or
:tn
:tpreviousJump to first matching tag.
or
:tp
:tfirstJump to last matching tag.
or
:tf
or
:trewindor:tr
:tlastFinding global identifiers
or
:tl
You are editing a C program and wonder if a variable is declared as "int" or "unsigned". A quick way to find this is with the "[I" command. Suppose the cursor is on the word "column" then type
[ + shiftkey + iVim will list the matching lines it can find. Not only in the current file,
but also in all included files (and files included in them, etc.). The result
looks like this:
The advantage over using tags or the preview window is that included files are
structs.h
1: 29 unsigned column; /* column number */
searched. In most cases this results in the right declaration to be found.
Also when the tags file is out of date. Also when you don't have tags for the
included files.
However, a few things must be right for "[I" to do its work. First of all,
the 'include' option must specify how a file is included. The default value
works for C and C++. For other languages you will have to change it.
Reference:
ctags documentation
Subscribe to:
Posts
(
Atom
)