Completed the cmd_add implementation
[vimicxx.git] / src / ctags_db.cc
blobc82ff7153ecbb3c02bb444be2415789e7c458957
1 /*******************************************************************************
2 ********************************************************************************
4 Copyright (c) 2008 Ahmed S. Badran
6 Licensed under the FreeBSD License (see LICENSE)
8 Filename: ctags_db.cc
9 Description: Implementation.
10 Created: 09/17/2008 11:01:30 PM PDT
11 Author: Ahmed S. Badran (Ahmed B.), ahmed.badran@gmail.com
13 ********************************************************************************
14 *******************************************************************************/
15 #include "ctags_db.h"
16 #include "tree_builder.h"
17 #include "fs_item.h"
18 #include <cstring>
19 #include <unistd.h>
20 #include <sys/types.h>
21 #include <sys/wait.h>
22 #include <cstdlib>
23 using namespace std;
25 ctags_db::ctags_db (const string& prj_, const string& prj_path_, const
26 string& prj_cache_, const string& prj_flist_, const
27 string& prj_ctags_db_, const vector<string>&
28 extensions_):
29 prj(prj_), prj_path(prj_path_), prj_cache(prj_cache_),
30 prj_flist(prj_flist_), prj_ctags_db(prj_ctags_db_),
31 extension_list(extensions_)
35 bool
36 ctags_db::create ()
38 tree_builder* builder = tree_builder::get_instance();
39 const fs_item* tree = builder->build(prj_path, extension_list,
40 &file_list);
41 FILE* tmp;
42 if ((tmp = fopen(prj_flist.c_str(), "w")) == 0) {
43 perror("fopen");
44 return false;
46 for (int i = 0; i < file_list.size(); ++i) {
47 fprintf(tmp, "%s\n", file_list[i].c_str());
49 fclose(tmp);
50 return build_db(prj_flist, prj_ctags_db);
53 bool
54 ctags_db::add_file (const string& new_file)
56 FILE* tmp;
57 if ((tmp = fopen(prj_flist.c_str(), "a+")) == 0) {
58 perror("fopen");
59 return false;
61 fprintf(tmp, "%s\n", new_file.c_str());
62 fclose(tmp);
63 return build_db(prj_flist, prj_ctags_db);
66 bool
67 ctags_db::remove_file(const string& old_file)
69 FILE *tmp1, *tmp2;
70 if ((tmp1 = fopen(prj_flist.c_str(), "r")) == 0) {
71 perror("fopen");
72 return false;
74 string tmpfile = prj_cache;
75 tmpfile += "/tmp.txt";
76 if ((tmp1 = fopen(tmpfile.c_str(), "w")) == 0) {
77 perror("fopen");
78 return false;
81 const unsigned MAX = 2048;
82 char* buf = (char*) malloc(sizeof(char) * MAX);
83 if (! buf) {
84 perror("malloc");
85 return false;
87 memset(buf, 0, sizeof(char) * MAX);
88 size_t n = MAX;
89 while (getline(&buf, &n, tmp1)) {
90 if (strcmp(buf, old_file.c_str()) == 0) {
91 continue;
93 fprintf(tmp2, "%s", buf);
96 fclose(tmp1);
97 fclose(tmp2);
98 free(buf);
99 if (rename(tmpfile.c_str(), prj_flist.c_str()) != 0) {
100 perror("rename");
101 return false;
103 return build_db(prj_flist, prj_ctags_db);
106 bool
107 ctags_db::update ()
109 return build_db(prj_flist, prj_ctags_db);
112 bool
113 ctags_db::build_db (const string& flist_file, const string& db_file) const
115 vector<string> args;
116 string tmp;
117 args.push_back("--c++-kinds=+p");
118 args.push_back("--fields=+iaS");
119 args.push_back("--extra=+q");
120 args.push_back("-f");
121 //tmp += db_file;
122 args.push_back(db_file);
123 //tmp = "-L";
124 args.push_back("-L");
125 //tmp += flist_file;
126 args.push_back(flist_file);
127 return invoke_ctags(args);
130 bool
131 ctags_db::invoke_ctags (const vector<string>& args) const
133 char* const * argv = build_argv(args);
134 pid_t pid = 0;
135 if ((pid = fork()) == -1) {
136 perror("fork");
137 } else if (pid != 0) {
138 int status;
139 waitpid(pid, &status, 0);
140 if (WEXITSTATUS(status) != 0) {
141 return false;
142 } else {
143 return true;
145 } else if (execvp("ctags", argv) == -1 ) {
146 perror("execvp");
147 _exit(1);
149 return false;
152 char**
153 ctags_db::build_argv (const vector<string>& args) const
155 char** argv;
156 argv = new char*[args.size() + 2];
157 bzero(argv, (args.size() + 2) * sizeof(char*));
158 argv[0] = strdup("ctags");
159 for (int i = 0; i < args.size(); ++i) {
160 argv[i + 1] = strdup(args[i].c_str());
162 return argv;
165 ctags_db::~ctags_db ()