~ubuntu-branches/ubuntu/hardy/orbital-eunuchs-sniper/hardy

« back to all changes in this revision

Viewing changes to src/sexpr/sexp.c

  • Committer: Bazaar Package Importer
  • Author(s): Kees Cook
  • Date: 2007-05-29 09:32:48 UTC
  • mfrom: (1.1.1 upstream) (2.1.2 gutsy)
  • Revision ID: james.westby@ubuntu.com-20070529093248-laj1bsm2dffohdf9
Tags: 1.30+svn20070601-1
Fix broken "upstream" rule to generate correctly versioned orig.tar.gz
to avoid native package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
This software and ancillary information (herein called "SOFTWARE")
 
3
called Supermon is made available under the terms described
 
4
here.  The SOFTWARE has been approved for release with associated
 
5
LA-CC Number LA-CC 99-51.
 
6
 
 
7
Unless otherwise indicated, this SOFTWARE has been authored by an
 
8
employee or employees of the University of California, operator of the
 
9
Los Alamos National Laboratory under Contract No.  W-7405-ENG-36 with
 
10
the U.S. Department of Energy.  The U.S. Government has rights to use,
 
11
reproduce, and distribute this SOFTWARE, and to allow others to do so.
 
12
The public may copy, distribute, prepare derivative works and publicly
 
13
display this SOFTWARE without charge, provided that this Notice and
 
14
any statement of authorship are reproduced on all copies.  Neither the
 
15
Government nor the University makes any warranty, express or implied,
 
16
or assumes any liability or responsibility for the use of this
 
17
SOFTWARE.
 
18
 
 
19
If SOFTWARE is modified to produce derivative works, such modified
 
20
SOFTWARE should be clearly marked, so as not to confuse it with the
 
21
version available from LANL.
 
22
**/
 
23
/** NOTICE: This software is licensed under the GNU Public License, which
 
24
    is included as LICENSE_GPL in this source distribution. **/
 
25
/** NOTE: This library is part of the supermon project, hence the name
 
26
          supermon above. **/
 
27
/***
 
28
 * Matt's smaller s-expression parsing library
 
29
 *
 
30
 * Written by Matt Sottile (matt@lanl.gov), January 2002.
 
31
 ***/
 
32
 
 
33
#include <assert.h>
 
34
#include <stdio.h>
 
35
#include <stdlib.h>
 
36
#include <string.h>
 
37
#include "sexp.h"
 
38
#include "faststack.h"
 
39
 
 
40
/**
 
41
 * Recursively walk an s-expression and free it.
 
42
 */
 
43
void
 
44
destroy_sexp (sexp_t * s)
 
45
{
 
46
  if (s == NULL) {
 
47
    return;
 
48
  }
 
49
 
 
50
  if (s->ty == SEXP_LIST)
 
51
    destroy_sexp (s->list);
 
52
 
 
53
  if (s->ty == SEXP_VALUE && s->val != NULL)
 
54
    free(s->val);
 
55
 
 
56
  destroy_sexp (s->next);
 
57
 
 
58
  sexp_t_deallocate(s);
 
59
}
 
60
 
 
61
/**
 
62
 * Iterative method to walk sx and turn it back into the string
 
63
 * representation of the s-expression.  Fills the buffer.
 
64
 */
 
65
int
 
66
print_sexp (char *buf, int size, sexp_t * sx)
 
67
{
 
68
  int retval;
 
69
  char *b = buf, *tc;
 
70
  int left = size;
 
71
  int depth = 0;
 
72
  faststack_t *stack;
 
73
  stack_lvl_t *top;
 
74
  sexp_t *tdata;
 
75
  sexp_t *fakehead;
 
76
 
 
77
  if (sx == NULL) {
 
78
    fprintf(stderr,"print_sexp: s-expression is null.\n");
 
79
    return -1;
 
80
  }
 
81
 
 
82
  /*fakehead = (sexp_t *)malloc(sizeof(sexp_t));*/
 
83
  fakehead = sexp_t_allocate();
 
84
  assert(fakehead!=NULL);
 
85
 
 
86
  /* duplicate the head to prevent going down a sx->next path
 
87
     that we don't really want to see. */
 
88
  fakehead->list = sx->list;
 
89
  fakehead->ty = sx->ty;
 
90
  fakehead->next = NULL; /* this is the important part of fakehead */
 
91
  fakehead->aty = sx->aty;
 
92
  if (fakehead->ty == SEXP_VALUE) {
 
93
    assert(sx->val != NULL);
 
94
    fakehead->val = (char *)malloc(sizeof(char)*sx->val_used);
 
95
    assert(fakehead->val != NULL);
 
96
    fakehead->val_used = fakehead->val_allocated = sx->val_used;
 
97
    strcpy(fakehead->val,sx->val);
 
98
  }
 
99
 
 
100
  if (size < 1)
 
101
    {
 
102
      fprintf (stderr,
 
103
               "Warning: print_sexp not provided sufficient space.\n");
 
104
      return -1;
 
105
    }
 
106
 
 
107
  stack = make_stack ();
 
108
 
 
109
  push (stack, fakehead);
 
110
 
 
111
  while (stack->top != NULL)
 
112
    {
 
113
      top = stack->top;
 
114
      tdata = (sexp_t *) top->data;
 
115
 
 
116
      if (tdata == NULL)
 
117
        {
 
118
          pop (stack);
 
119
 
 
120
          if (depth > 0)
 
121
            {
 
122
              b[0] = ')';
 
123
              b++;
 
124
              left--;
 
125
              depth--;
 
126
              if (left == 0)
 
127
                {
 
128
                  fprintf (stderr,
 
129
                           "Warning: print_sexp out of buffer space.\n");
 
130
                  break;
 
131
                }
 
132
            }
 
133
 
 
134
          if (stack->top == NULL)
 
135
            break;
 
136
 
 
137
          top = stack->top;
 
138
          top->data = ((sexp_t *) top->data)->next;
 
139
          if (top->data != NULL)
 
140
            {
 
141
              b[0] = ' ';
 
142
              b++;
 
143
              left--;
 
144
              if (left == 0)
 
145
                {
 
146
                  fprintf (stderr,
 
147
                           "Warning: print_sexp out of buffer space.\n");
 
148
                  break;
 
149
                }
 
150
            }
 
151
        }
 
152
      else if (tdata->ty == SEXP_VALUE)
 
153
        {
 
154
          if (tdata->aty == SEXP_DQUOTE)
 
155
            {
 
156
              b[0] = '\"';
 
157
              b++;
 
158
              left--;
 
159
            }
 
160
          else if (tdata->aty == SEXP_SQUOTE)
 
161
            {
 
162
              b[0] = '\'';
 
163
              b++;
 
164
              left--;
 
165
            }
 
166
 
 
167
          assert(tdata->val != NULL);
 
168
          tc = tdata->val;
 
169
          /* copy value into string */
 
170
          while (tc[0] != 0 && left > 0)
 
171
            {
 
172
              /* escape characters that need escaping. */
 
173
              /*              if (tc[0] == '\"' || tc[0] == '\'' ||
 
174
                  tc[0] == '\\' || ((tc[0] == '(' ||
 
175
                                     tc[0] == ')') &&
 
176
                                    tdata->aty != SEXP_DQUOTE))
 
177
                      {
 
178
                b[0] = '\\';
 
179
                b++;
 
180
                left--;
 
181
                if (left == 0) break;
 
182
                }*/
 
183
 
 
184
              b[0] = tc[0];
 
185
              b++;
 
186
              tc++;
 
187
              left--;
 
188
              if (left == 0)
 
189
                break;
 
190
            }
 
191
 
 
192
          if (tdata->aty == SEXP_DQUOTE && left > 0)
 
193
            {
 
194
              b[0] = '\"';
 
195
              b++;
 
196
              left--;
 
197
            }
 
198
 
 
199
          if (left < 0)
 
200
            left = 0;
 
201
          if (left == 0)
 
202
            {
 
203
              fprintf (stderr, "Warning: print_sexp out of buffer space.\n");
 
204
              break;
 
205
            }
 
206
 
 
207
          top->data = ((sexp_t *) top->data)->next;
 
208
 
 
209
          if (top->data != NULL)
 
210
            {
 
211
              b[0] = ' ';
 
212
              b++;
 
213
              left--;
 
214
              if (left == 0)
 
215
                {
 
216
                  fprintf (stderr,
 
217
                           "Warning: print_sexp out of buffer space.\n");
 
218
                  break;
 
219
                }
 
220
            }
 
221
        }
 
222
      else if (tdata->ty == SEXP_LIST)
 
223
        {
 
224
          depth++;
 
225
          b[0] = '(';
 
226
          b++;
 
227
          left--;
 
228
          if (left == 0)
 
229
            {
 
230
              fprintf (stderr, "Warning: print_sexp out of buffer space.\n");
 
231
              break;
 
232
            }
 
233
 
 
234
          push (stack, tdata->list);
 
235
        }
 
236
      else
 
237
        {
 
238
          fprintf (stderr, "ERROR: Unknown type in sexp_t.\n");
 
239
          fflush (stderr);
 
240
          return -1;
 
241
        }
 
242
 
 
243
    }
 
244
  while (depth != 0)
 
245
    {
 
246
      b[0] = ')';
 
247
      b++;
 
248
      left--;
 
249
      depth--;
 
250
      if (left == 0)
 
251
        {
 
252
          fprintf (stderr, "Warning: print_sexp out of buffer space.\n");
 
253
          break;
 
254
        }
 
255
    }
 
256
 
 
257
  if (left != 0) {
 
258
    b[0] = 0;
 
259
    retval = (size-left);
 
260
  } else {
 
261
    b--;
 
262
    b[0] = 0;
 
263
    retval = -1;
 
264
  }
 
265
 
 
266
  destroy_stack (stack);
 
267
  sexp_t_deallocate(fakehead);
 
268
 
 
269
  return retval;
 
270
}