~ubuntu-branches/debian/stretch/libxr/stretch

« back to all changes in this revision

Viewing changes to xdl-compiler/parser-lib.c

  • Committer: Bazaar Package Importer
  • Author(s): Fabien Boucher
  • Date: 2009-10-14 00:52:51 UTC
  • Revision ID: james.westby@ubuntu.com-20091014005251-epx05xv5ef9188q0
Tags: upstream-1.0
ImportĀ upstreamĀ versionĀ 1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
 * Copyright 2006-2008 Ondrej Jirman <ondrej.jirman@zonio.net>
 
3
 * 
 
4
 * This file is part of libxr.
 
5
 *
 
6
 * Libxr is free software: you can redistribute it and/or modify it under the
 
7
 * terms of the GNU Lesser General Public License as published by the Free
 
8
 * Software Foundation, either version 2 of the License, or (at your option) any
 
9
 * later version.
 
10
 *
 
11
 * Libxr is distributed in the hope that it will be useful, but WITHOUT ANY
 
12
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 
13
 * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
 
14
 * details.
 
15
 *
 
16
 * You should have received a copy of the GNU Lesser General Public License
 
17
 * along with libxr.  If not, see <http://www.gnu.org/licenses/>.
 
18
 */
 
19
 
 
20
#include "parser-lib.h"
 
21
 
 
22
/* stream api */
 
23
 
 
24
stream* stream_new_from_string(const char* str)
 
25
{
 
26
  if (str == NULL)
 
27
    return NULL;
 
28
  stream* s = g_new0(stream, 1);
 
29
  s->buffer = g_strdup(str);
 
30
  s->length = strlen(str);
 
31
  return s;
 
32
}
 
33
 
 
34
void stream_advance(stream* s, int length)
 
35
{
 
36
  int i;
 
37
 
 
38
  for (i = 0; i < length && s->index < s->length; i++, s->index++)
 
39
  {
 
40
    s->col++;
 
41
    if (s->buffer[s->index] == '\n')
 
42
    {
 
43
      s->col = 0;
 
44
      s->line++;
 
45
    }
 
46
  }
 
47
}
 
48
 
 
49
/* tokenizer api */
 
50
 
 
51
token *token_new(stream* s, int type, int length)
 
52
{
 
53
  int i;
 
54
  token *t = g_new0(token, 1);
 
55
 
 
56
  t->type = type;
 
57
  t->text = g_strndup(s->buffer + s->index, length);
 
58
  t->length = length;
 
59
  t->sline = t->eline = s->line;
 
60
  t->scol = t->ecol = s->col;
 
61
  for (i = 0; i < length; i++)
 
62
  {
 
63
    t->ecol++;
 
64
    if (t->text[i] == '\n')
 
65
    {
 
66
      t->ecol = 0;
 
67
      t->eline++;
 
68
    }
 
69
  }
 
70
  stream_advance(s, length);
 
71
  return t;
 
72
}
 
73
 
 
74
void token_free(token * t)
 
75
{
 
76
  if (t == NULL)
 
77
    return;
 
78
  g_free(t->text);
 
79
  g_free(t);
 
80
}
 
81
 
 
82
/* parser api */
 
83
 
 
84
static int __parse(parser_context* ctx, 
 
85
            parser parser_cb, 
 
86
            parser_alloc parser_alloc_cb, 
 
87
            parser_free parser_free_cb,
 
88
            lexer lexer_cb)
 
89
{
 
90
  void* parser;
 
91
  token* t;
 
92
  stream* s = ctx->stream;
 
93
  int retval = -1;
 
94
 
 
95
  if (ctx == NULL || ctx->error != NULL || ctx->stream == NULL)
 
96
    return -1;
 
97
 
 
98
  parser = parser_alloc_cb((void *(*)(size_t))g_malloc);
 
99
  while ((t = lexer_cb(s)) != NULL)
 
100
  {
 
101
    if (t->type == TK_UNKNOWN)
 
102
    {
 
103
      ctx->error = g_strdup_printf("Unknown token '%s' at line %d char %d\n", t->text, t->sline, t->scol);
 
104
      token_free(t);
 
105
      goto err;
 
106
    }
 
107
    else if (t->type == TK_EOF)
 
108
    {
 
109
      token_free(t);
 
110
      parser_cb(parser, 0, NULL, ctx);
 
111
      break;
 
112
    }
 
113
 
 
114
    parser_cb(parser, t->type, t, ctx);
 
115
    if (ctx->error)
 
116
      goto err;
 
117
  }
 
118
 
 
119
  retval = 0;
 
120
 err:
 
121
  parser_free_cb(parser, g_free);
 
122
  return retval;
 
123
}
 
124
 
 
125
void* __parse_string(const char* str, 
 
126
                     GError** err,
 
127
                     parser parser_cb, 
 
128
                     parser_alloc parser_alloc_cb, 
 
129
                     parser_free parser_free_cb,
 
130
                     lexer lexer_cb)
 
131
{
 
132
  parser_context* ctx = g_new0(parser_context, 1);
 
133
 
 
134
  ctx->stream = stream_new_from_string(str);
 
135
  if (ctx->stream == NULL)
 
136
  {
 
137
    g_free(ctx);
 
138
    g_set_error(err, 0, 1, "Stream can't be created!");
 
139
    return NULL;
 
140
  }
 
141
 
 
142
  __parse(ctx, parser_cb, parser_alloc_cb, parser_free_cb, lexer_cb);
 
143
  if (ctx->error)
 
144
  {
 
145
    g_set_error(err, 0, 1, "%s", ctx->error);
 
146
    return NULL;
 
147
  }
 
148
 
 
149
  void* data = ctx->data;
 
150
  g_free(ctx);
 
151
  return data;
 
152
}
 
153
 
 
154
void* __parse_file(const char* path, 
 
155
                   GError** err,
 
156
                   parser parser_cb, 
 
157
                   parser_alloc parser_alloc_cb, 
 
158
                   parser_free parser_free_cb,
 
159
                   lexer lexer_cb)
 
160
{
 
161
  char* buffer;
 
162
  if (!g_file_get_contents(path, &buffer, NULL, err))
 
163
    return NULL;
 
164
  return __parse_string(buffer, err, parser_cb, parser_alloc_cb, parser_free_cb, lexer_cb);
 
165
}