Set up current working directory on File->Open
[gscope.git] / id-utils.c
blobcbd9ebbd24cbefb5aaa429aee69b62697973ddcf
1 /*
2 * (c) 2010 Cyrill Gorcunov, gorcunov@gmail.com
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or (at
7 * your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
18 * iu-utils backend
21 #include <unistd.h>
22 #include <stdio.h>
23 #include <stddef.h>
24 #include <stdlib.h>
25 #include <stdarg.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <limits.h>
29 #include <sys/param.h>
30 #include <sys/types.h>
32 #include "id-utils.h"
33 #include "backend-proto.h"
34 #include "util.h"
36 struct idutils_query_result {
37 struct list_head list;
38 void *data_copy;
39 struct backend_proto_item item;
42 static struct idutils_query_result *idutils_parse(char *name, char *str, unsigned long key)
44 char *func, *file, *line, *text, *data_copy;
45 struct idutils_query_result *r = NULL;
47 if (!str || !str[0])
48 goto err;
50 data_copy = xstrdup(str);
52 func = skip_spaces(name);
53 file = skip_spaces(strtok(data_copy, ":"));
54 line = skip_spaces(strtok(NULL, ":"));
55 text = skip_spaces(strtok(NULL, "\r\n"));
57 if (!func || !file || !line || !text) {
58 free(data_copy);
59 goto err;
62 r = xzalloc(sizeof(*r));
64 r->data_copy = data_copy;
65 r->item.key = key;
66 r->item.func = xstrdup(func);
67 r->item.file = file;
68 r->item.line = atoi(line);
69 r->item.text = text;
71 INIT_LIST_HEAD(&r->list);
73 err:
74 return r;
77 static void idutils_query_free(struct list_head *head)
79 struct idutils_query_result *r, *n;
81 list_for_each_entry_safe(r, n, head, list) {
82 free(r->item.func);
83 free(r->data_copy);
84 free(r);
88 #define MAX_CMDLINE 256
89 static const char idutils_cmd[] = "gid ";
90 static const char rebuild_cmd[] = "mkid ";
92 static struct list_head *idutils_query(struct backend_proto_query_params *backend_params)
94 char cmd_buf[MAX_CMDLINE] = { 0 };
95 char read_buf[1024];
96 struct idutils_query_result *r;
97 struct list_head *head = NULL;
98 unsigned long key = 0;
99 FILE *pipe;
101 if (!backend_params->u.idutils.name ||
102 !*backend_params->u.idutils.name)
103 return NULL;
105 #define strlcat_buf(str) strlcat(cmd_buf, str, sizeof(cmd_buf))
106 strlcat_buf(idutils_cmd);
107 strlcat_buf(backend_params->u.idutils.name);
108 #undef strlcat_buf
110 head = xalloc(sizeof(*head));
111 INIT_LIST_HEAD(head);
113 pipe = popen(cmd_buf, "r");
114 if (!pipe) {
115 warning("Can't open pipe for : %s", idutils_cmd);
116 free(head), head = NULL;
117 goto err;
121 * We assume the output line will not exceed the buffer
122 * otherwise the parsing would not be strictly correct
124 while (fgets(read_buf, sizeof(read_buf), pipe)) {
125 r = idutils_parse(backend_params->u.idutils.name, read_buf, key++);
126 if (r)
127 list_add(&r->list, head);
129 if (pclose(pipe))
130 warning("Closing pipe for parsing '%s' failed",
131 backend_params->u.idutils.name);
133 err:
134 return head;
137 static struct idutils_query_result *idutils_lookup_key(struct list_head *head, unsigned long key)
139 struct idutils_query_result *t;
140 list_for_each_entry(t, head, list) {
141 if (t->item.key == key)
142 return t;
144 return NULL;
147 static int idutils_backend_proto_lookup(struct list_head *head, struct backend_proto_item *item, unsigned long key)
149 struct idutils_query_result *t = idutils_lookup_key(head, key);
150 if (!t)
151 return -1;
152 memcpy(item, &t->item, sizeof(*item));
153 return 0;
156 static int idutils_backend_proto_get(struct list_head *entry, struct backend_proto_item *item)
158 struct idutils_query_result *t = container_of(entry, struct idutils_query_result, list);
159 memcpy(item, &t->item, sizeof(*item));
160 return 0;
163 static void idutils_backend_proto_destory(struct list_head *entry)
165 struct idutils_query_result *t = container_of(entry, struct idutils_query_result, list);
166 idutils_query_free(&t->list);
167 free(t);
170 static void idutils_backend_proto_refresh(void)
172 FILE *pipe;
174 pipe = popen(rebuild_cmd, "r");
175 if (!pipe) {
176 warning("Can't open pipe for : %s", rebuild_cmd);
177 return;
180 if (pclose(pipe))
181 warning("Closing pipe for parsing '%s' failed",
182 rebuild_cmd);
185 void init_id_utils_backend_proto(void)
187 static struct backend_proto proto = {
188 .protocol_name = "id-utils",
189 .protocol = BACKEND_PROTO_ID_UTILS,
190 .backend_proto_query = idutils_query,
191 .backend_proto_get = idutils_backend_proto_get,
192 .backend_proto_lookup = idutils_backend_proto_lookup,
193 .backend_proto_destory = idutils_backend_proto_destory,
194 .backend_proto_refresh = idutils_backend_proto_refresh,
197 backend_proto_register(&proto);