Updated Spanish translation
[anjuta-git-plugin.git] / plugins / valgrind / ldd.c
blob95f4eda03c5e160f45c74307a739f03a070f2a76
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Authors: Jeffrey Stedfast <fejj@ximian.com>
5 * Copyright 2003 Ximian, Inc. (www.ximian.com)
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
28 #include <glib.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <sys/types.h>
34 #include <unistd.h>
35 #include <fcntl.h>
36 #include <errno.h>
38 #include "ldd.h"
41 LddParser *
42 ldd_parser_new (int fd, LddSharedLibCallback shlib_cb, void *user_data)
44 LddParser *ldd;
46 ldd = g_new (LddParser, 1);
47 parser_init ((Parser *) ldd, fd);
49 ldd->linebuf = g_malloc (128);
50 ldd->lineptr = ldd->linebuf;
51 ldd->lineleft = 128;
53 ldd->shlib_cb = shlib_cb;
54 ldd->user_data = user_data;
56 return ldd;
60 void
61 ldd_parser_free (LddParser *ldd)
63 if (ldd == NULL)
64 return;
66 g_free (ldd->linebuf);
67 g_free (ldd);
71 void
72 ldd_shared_lib_free (LddSharedLib *shlib)
74 if (shlib == NULL)
75 return;
77 g_free (shlib->libname);
78 g_free (shlib->path);
79 g_free (shlib);
83 /* " libc.so.6 => /lib/libc.so.6 (0x40e50000)\n" */
85 static void
86 ldd_parse_linebuf (LddParser *ldd)
88 register unsigned char *inptr;
89 LddSharedLib *shlib;
90 char *inend;
92 shlib = g_new (LddSharedLib, 1);
94 inptr = ldd->linebuf;
95 while (*inptr == '\t' || *inptr == ' ')
96 inptr++;
98 shlib->libname = inptr;
99 while (*inptr && !(inptr[0] == ' ' && inptr[1] == '=' && inptr[2] == '>') && *inptr != '(')
100 inptr++;
102 shlib->libname = (unsigned char *)g_strndup ((char *)shlib->libname, inptr - shlib->libname);
104 if (!strncmp ((char *)inptr, " =>", 3))
105 inptr += 3;
107 while (*inptr == ' ' || *inptr == '\t')
108 inptr++;
110 shlib->path = inptr;
111 while (*inptr && *inptr != '(')
112 inptr++;
114 if (*inptr != '(') {
115 /* error - no address component; ignore */
116 g_free (shlib->libname);
117 g_free (shlib);
118 goto reset;
121 if (inptr == shlib->path) {
122 /* special case - no path component */
123 if (shlib->libname[0] != '/') {
124 /* unhandled */
125 g_free (shlib->libname);
126 g_free (shlib);
127 goto reset;
130 /* name is a path */
131 shlib->path = (unsigned char *)g_strdup ((char *)shlib->libname);
132 inptr++;
133 } else {
134 if (inptr[-1] == ' ')
135 inptr--;
136 shlib->path = (unsigned char *)g_strndup ((char *)shlib->path, inptr - shlib->path);
137 inptr += 2;
140 shlib->addr = strtoul ((const char *) inptr, &inend, 16);
142 ldd->shlib_cb (ldd, shlib, ldd->user_data);
144 reset:
146 ldd->lineleft += (ldd->lineptr - ldd->linebuf);
147 ldd->lineptr = ldd->linebuf;
151 #define ldd_backup_linebuf(ldd, start, len) G_STMT_START { \
152 if (ldd->lineleft <= len) { \
153 unsigned int llen, loff; \
155 llen = loff = ldd->lineptr - ldd->linebuf; \
156 llen = llen ? llen : 1; \
158 while (llen < (loff + len + 1)) \
159 llen <<= 1; \
161 ldd->linebuf = g_realloc (ldd->linebuf, llen); \
162 ldd->lineptr = ldd->linebuf + loff; \
163 ldd->lineleft = llen - loff; \
166 memcpy (ldd->lineptr, start, len); \
167 ldd->lineptr += len; \
168 ldd->lineleft -= len; \
169 } G_STMT_END
173 ldd_parser_step (LddParser *ldd)
175 register unsigned char *inptr;
176 unsigned char *start;
177 Parser *parser;
178 int ret;
180 parser = (Parser *) ldd;
182 if ((ret = parser_fill (parser)) == 0) {
183 return 0;
184 } else if (ret == -1) {
185 return -1;
188 start = inptr = parser->inptr;
189 *parser->inend = '\n';
191 while (inptr < parser->inend) {
192 while (*inptr != '\n')
193 inptr++;
195 if (inptr == parser->inend)
196 break;
198 *inptr++ = '\0';
199 ldd_backup_linebuf (ldd, start, inptr - start);
200 ldd_parse_linebuf (ldd);
201 start = inptr;
204 if (inptr > start)
205 ldd_backup_linebuf (ldd, start, inptr - start);
207 parser->inptr = inptr;
209 return 1;
214 ldd_parser_flush (LddParser *ldd)
216 Parser *parser = (Parser *) ldd;
218 if (parser->inptr < parser->inend)
219 return ldd_parser_step (ldd);
221 return 0;