Add to git.
[dlife.git] / load.c
1 /* DLIFE Copyright (C) 2000 Richard W.M. Jones <rich@annexia.org>
2  * and other authors listed in the ``AUTHORS'' file.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17  *
18  * $Id: load.c,v 1.2 2002/04/05 16:47:12 rich Exp $
19  */
20
21 #include "config.h"
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "types.h"
28 #include "load.h"
29 #include "cell.h"
30 #include "soup.h"
31 #include "state.h"
32
33 struct cell *
34 load_cell (struct state *state, const char *filename)
35 {
36   FILE *fp;
37   int allocated = 0;
38   int len = 0;
39   char line[256];
40   byte_t *code = 0;
41   int n = 0, i, c = 0;
42   struct cell *cell;
43   struct soup_frag *frag;
44
45   fp = fopen (filename, "r");
46   if (fp == 0) { perror (filename); return 0; }
47
48   while (fgets (line, sizeof line, fp) != 0 && len < MAX_CELL_SIZE)
49     {
50       for (i = 0; i < strlen (line); ++i)
51         {
52           if (line[i] >= '0' && line[i] <= '9')
53             {
54               n *= 16;
55               n += line[i] - '0';
56               c++;
57             }
58           else if (line[i] >= 'a' && line[i] <= 'f')
59             {
60               n *= 16;
61               n += line[i] - 'a' + 10;
62               c++;
63             }
64           else if (line[i] >= 'A' && line[i] <= 'F')
65             {
66               n *= 16;
67               n += line[i] - 'A' + 10;
68               c++;
69             }
70           if (c == 2)
71             {
72               if (allocated - len <= 0)
73                 {
74                   code = realloc (code, allocated += 256);
75                   if (code == 0) { perror ("realloc"); abort (); }
76                 }
77               code[len++] = n;
78               n = c = 0;
79             }
80         }
81     }
82
83   if (c != 0)
84     {
85       fprintf (stderr, "%s: error in input file\n", filename);
86       fclose (fp);
87       free (code);
88       return 0;
89     }
90
91   fclose (fp);
92
93   /* Refuse any cells which are too small or too large. */
94   if (len < MIN_CELL_SIZE || len > MAX_CELL_SIZE)
95     {
96       fprintf (stderr, "%s: cell is too small or too large (len = %d)\n",
97                filename, len);
98       free (code);
99       return 0;
100     }
101
102   /* Allocate soup fragment. */
103   frag = soup_frag_malloc (state, 0, len);
104   if (frag == 0) { free (code); return 0; }
105
106   /* Allocate cell. */
107   cell = cell_malloc (state, 0, frag);
108   if (cell == 0) { free (code); return 0; }
109
110   /* Populate cell. */
111   for (i = 0; i < len; ++i)
112     set_soup (state, cell->frag, code[i], i);
113   free (code);
114
115   return cell;
116 }