root/trunk/contrib/extractor/libmpq/parser.cpp @ 177

Revision 177, 6.8 kB (checked in by yumileroy, 17 years ago)

[svn] * Avoid access to bag item prototype for getting bag size, use related item
update field instead as more fast source. source mangos.
* Further reduce of DB access in guild handlers.
* Multi-locale DBC extracting - source Foks

*** Devs not responsible if all your player items drop to the ground and get eaten by ants or rabbits.. or some kind of wierd ant-rabbits..

Original author: KingPin?
Date: 2008-11-06 08:20:26-06:00

Line 
1/*
2 *  parser.c -- functions used to parse list or config file.
3 *
4 *  Copyright (C) 2003 Maik Broemme <mbroemme@plusserver.de>
5 *
6 *  This program is free software; you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation; either version 2 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 *
20 *  $Id: parser.c,v 1.5 2004/02/12 00:47:53 mbroemme Exp $
21 */
22#define _CRT_SECURE_NO_DEPRECATE
23
24#include <stdlib.h>
25#include <stdio.h>
26#include <string.h>
27#include "mpq.h"
28#include "common.h"
29#include <ctype.h>
30
31/*
32 *  This function deletes the specified characters, but leaves
33 *  escape sequences unaffected. This means that " would be
34 *  deleted but \" would not.
35 */
36char *libmpq_conf_delete_char(char *buf, char *chars) {
37        static char *temp;
38        char ch;
39
40        temp = buf;
41
42        /* strip out special chars like " */
43        while (temp = strpbrk(temp, chars)) {
44                ch = temp[0];
45                memmove(&temp[0], &temp[1], strlen(temp));
46                if (ch == '\\') {
47                        temp++;
48                }
49        }
50
51        return buf;
52}
53
54/*
55 *  This function parses a line for the value to the given option. It
56 *  return 1 on success and the byte array or 0 and null.
57 */
58int libmpq_conf_parse_line(char *line, char *search_value, char *return_value, int size) {
59        int level = 0;
60        int found = 0;
61        int i = 0;
62        int pos = 0;
63
64        /* search value */
65        while (*(++line)) {
66
67                /* check for spaces */
68                if (!isspace(*line) && level == 1) {
69
70                        /* we found our value so break */
71                        found = 1;
72                        break;
73                }
74
75                /* check for '=' so the value follows as next parameter */
76                if (*line == '=' && level == 0) {
77                        level = 1;
78                }
79        }
80
81        /* now search for comment in this line */
82        for (i = 0; i < int(strlen(line)); i++) {
83                if (line[i] == '#') {
84                        pos = i - 1;
85                        break;
86                }
87        }
88
89        /* now set end of byte array behind value, but only if comment was found */
90        if (pos != 0) {
91                for (i = pos; i >= 0; i--) {
92                        if (line[i] != ' ' && line[i] != '\t') {
93                                line[i + 1] = '\0';
94                                break;
95                        }
96                }
97        }
98
99        /* now check if line has trailing spaces */
100        for (i = strlen(line); i >= 0; i--) {
101                if (line[i] != ' ' && line[i] != '\t') {
102                        line[i + 1] = '\0';
103                        break;
104                }
105        }
106
107        /* now check if value is quoted with "" and if there is a char behind. */
108        for (i = strlen(line); i >= 0; i--) {
109                if (line[i] == '"') {
110                        line[i + 1] = '\0';
111                        break;
112                }
113        }
114
115        /* return the values */
116        strncpy(return_value, line, size);
117        return found;
118}
119
120/*
121 *  This function returns the value for a given option in the
122 *  listdb or config file. On success it returns 1, otherwise 0.
123 */
124int libmpq_conf_get_value(FILE *fp, char *search_value, void *return_value, int type, int size) {
125        char buf[LIBMPQ_CONF_BUFSIZE];
126        int found = 0;
127        int result = LIBMPQ_TOOLS_SUCCESS;
128
129        while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) {
130                char *line;
131
132                buf[strlen(buf) - 1] = '\0';
133
134                /* skip whitespace */
135                for (line = buf; isspace(*line); line++) {
136                        continue;
137                }
138
139                /* skip empty line */
140                if (line[0] == '\0') {
141                        continue;
142                }
143
144                /* skip comments */
145                if (line[0] == '#') {
146                        continue;
147                }
148
149                /* process the line */
150                //if (!strncasecmp(line, search_value, strlen(search_value))) {
151        if (!strcmp(line, search_value)) {
152                        found = libmpq_conf_parse_line(line, search_value, line, LIBMPQ_CONF_BUFSIZE);
153                        if (found == 1) {
154                                libmpq_conf_delete_char(line, "\"\\");
155
156                                switch (type) {
157                                        case LIBMPQ_CONF_TYPE_INT:
158
159                                                /* if it is no valid number it is safe to return 0 */
160                                                *(int *)return_value = atoi(line);
161                                                break;
162                                        default:
163                                                strncpy((char *)return_value, line, size);
164                                                break;
165                                }
166
167                                /* value found, so rewind stream */
168                                break;
169                        }
170                }
171        }
172
173        /* if value was not found */
174        if (found == 0) {
175                switch (type) {
176                        case LIBMPQ_CONF_TYPE_INT:
177                                *(int *)return_value = 0;
178                                result = LIBMPQ_CONF_EVALUE_NOT_FOUND;
179                                break;
180                        default:
181                                strncpy((char *)return_value, "", size);
182                                result = LIBMPQ_CONF_EVALUE_NOT_FOUND;
183                                break;
184                }
185        }
186        fseek(fp, 0L, SEEK_SET);
187
188        return result;
189}
190
191/*
192 *  This function returns a pointer to a byte array, with all values
193 *  found in the config file. As second value it returns th number of
194 *  entries in the byte array. On success it returns 1, otherwise 0.
195 */
196int libmpq_conf_get_array(FILE *fp, char *search_value, char ***filelist, int *entries) {
197        char buf[LIBMPQ_CONF_BUFSIZE];
198        char temp[LIBMPQ_CONF_BUFSIZE];
199        int level = 0;
200        int array_start = 0;
201        int array_end = 0;
202        int fl_count;
203        int fl_size;
204        int found = 0;
205        int i = 0;
206
207        *entries = 0;
208
209        /* allocate memory for the file list */
210        (*filelist) = (char **)malloc(LIBMPQ_CONF_FL_INCREMENT * sizeof(char *));
211        fl_count = 0;
212        fl_size = LIBMPQ_CONF_FL_INCREMENT;
213
214        while (fgets(buf, LIBMPQ_CONF_BUFSIZE, fp) != NULL) {
215                char *line;
216
217                buf[strlen(buf) - 1] = '\0';
218
219                /* skip whitespace */
220                for (line = buf; isspace(*line); line++) {
221                        continue;
222                }
223
224                /* skip empty line */
225                if (line[0] == '\0') {
226                        continue;
227                }
228
229                /* skip comments */
230                if (line[0] == '#') {
231                        continue;
232                }
233
234                /* check for array end ) */
235                if (*line == ')') {
236                        array_end = 1;
237                        break;
238                }
239
240                /* process entries between () */
241                if (array_start == 1 && array_end == 0) {
242
243                        /* add dummy option to use with libmpq_conf_parse_line() */
244                        strncpy(temp, "MPQ_BUFFER = ", LIBMPQ_CONF_BUFSIZE);
245                        strncat(temp, line, LIBMPQ_CONF_BUFSIZE);
246                        found = libmpq_conf_parse_line(temp, "MPQ_BUFFER", temp, LIBMPQ_CONF_BUFSIZE);
247
248                        if (found == 1) {
249                                libmpq_conf_delete_char(temp, "\"\\");
250
251                                /* set the next filelist entry to a copy of the file */
252                                (*filelist)[fl_count++] = _strdup(temp);
253
254                                /* increase the array size */
255                                if (fl_count == fl_size) {
256                                        (*filelist) = (char **)realloc((*filelist), (fl_size + LIBMPQ_CONF_FL_INCREMENT) * sizeof(char *));
257                                        fl_size += LIBMPQ_CONF_FL_INCREMENT;
258                                }
259
260                                /* increase number of entries */
261                                (*entries)++;
262                        }
263                }
264
265                /* process the line and search array start */
266                //if (!strncasecmp(line, search_value, strlen(search_value))) {
267        if (!strcmp(line, search_value)) {
268
269                        /* search value */
270                        while (*(++line)) {
271
272                                /* check for array start ( */
273                                if (*line == '(' && level == 1) {
274
275                                        /* we found our value so break */
276                                        array_start = 1;
277                                        break;
278                                }
279
280                                /* check for '=' so the value follows as next parameter */
281                                if (*line == '=' && level == 0) {
282                                        level = 1;
283                                }
284                        }
285                }
286        }
287
288        /* we got all files, so rewind stream */
289        fseek(fp, 0L, SEEK_SET);
290
291        (*filelist)[fl_count] = NULL;
292
293        return found;
294}
Note: See TracBrowser for help on using the browser.