comparison keiko/util.c @ 0:bfdcc3820b32

Basis
author Mike Spivey <mike@cs.ox.ac.uk>
date Thu, 05 Oct 2017 08:04:15 +0100
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:bfdcc3820b32
1 /*
2 * util.c
3 *
4 * This file is part of the Oxford Oberon-2 compiler
5 * Copyright (c) 2006--2016 J. M. Spivey
6 * All rights reserved
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are met:
10 *
11 * 1. Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "config.h"
32 #include <stdio.h>
33 #include <stdarg.h>
34 #include <stdlib.h>
35 #include <ctype.h>
36 #include <string.h>
37 #include "obcommon.h"
38 #include "util.h"
39 #include <assert.h>
40
41 EXTERN int dflag;
42
43 char *prog_name;
44
45 void error(const char *msg, ...) {
46 va_list va;
47
48 va_start(va, msg);
49 fprintf(stderr, "%s: ", err_file);
50 vfprintf(stderr, msg, va);
51 va_end(va);
52 fprintf(stderr, "\n");
53
54 status = 1;
55 }
56
57 void panic(const char *msg, ...) {
58 va_list va;
59 mybool bug = FALSE;
60
61 if (*msg == '*') {
62 bug = TRUE; msg++;
63 }
64
65 fprintf(stderr, "%s: Fatal error -- ", progname);
66 va_start(va, msg);
67 vfprintf(stderr, msg, va);
68 va_end(va);
69 if (err_file != NULL)
70 fprintf(stderr, " in %s", err_file);
71 fprintf(stderr, "\n");
72 if (bug)
73 fprintf(stderr, "Please report bugs to %s or %s\n",
74 PACKAGE_TRACKER, PACKAGE_BUGREPORT);
75
76 exit(2);
77 }
78
79 /* must_alloc -- malloc or die */
80 void *must_alloc(int n, const char *why) {
81 void *p;
82 #ifdef DEBUG
83 if (dflag >= 2) printf("Allocating %s as %d", why, n);
84 #endif
85 p = malloc(n);
86 #ifdef DEBUG
87 if (dflag >= 2) printf(" at %p\n", p);
88 #endif
89 if (p == NULL) panic("couldn't allocate space for %s", why);
90 memset(p, 0, n);
91 return p;
92 }
93
94 /* must_strdup -- strdup or die */
95 char *must_strdup(const char *s) {
96 char *p = (char *) must_alloc(strlen(s)+1, s);
97 strcpy(p, s);
98 return p;
99 }
100
101 /* must_realloc -- realloc or (you guessed it) */
102 void *must_realloc(void *p, int n0, int n, const char *msg) {
103 #ifdef DEBUG
104 if (dflag >= 2) {
105 printf("Growing %s at %p from %d to %d\n", msg, p, n0, n);
106 fflush(stdout);
107 }
108 #endif
109 p = realloc(p, n);
110 if (p == NULL) panic("couldn't expand space for %s", msg);
111 memset(((char *) p) + n0, 0, n-n0);
112 return p;
113 }
114
115 void _buf_init(struct _growbuf *b, int size, int margin,
116 int elsize, const char *name) {
117 b->buf = must_alloc(size * elsize, name);
118 b->loc = 0;
119 b->size = size;
120 b->margin = margin;
121 b->elsize = elsize;
122 b->name = name;
123 }
124
125 void _buf_grow(struct _growbuf *b) {
126 if (b == NULL) panic("*uninitialized growbuf");
127
128 /* Ensure space for margin+1 items */
129 if (b->loc > b->size - b->margin) {
130 int size1 = max(b->size * GROW, b->loc + b->margin);
131 b->buf = must_realloc(b->buf, b->size * b->elsize,
132 size1 * b->elsize, b->name);
133 b->size = size1;
134 }
135 }
136
137 #define SIZE 10
138 #define PAGE 40000
139
140 void *pool_alloc(mempool *pool, int size) {
141 void *result;
142
143 assert(size < PAGE);
144
145 if (pool->p_alloc + size > pool->p_pool[pool->p_current] + PAGE) {
146 pool->p_current++;
147 if (pool->p_current >= pool->p_npools) {
148 if (pool->p_npools >= pool->p_size) {
149 pool->p_pool = (unsigned char **)
150 must_realloc(pool->p_pool,
151 pool->p_size * sizeof(void *),
152 2 * pool->p_size * sizeof(void *),
153 "pool table");
154 pool->p_size *= 2;
155 }
156 pool->p_pool[pool->p_npools++] =
157 (uchar *) must_alloc(PAGE, "pools");
158 }
159 pool->p_alloc = pool->p_pool[pool->p_current];
160 }
161
162 result = (void *) pool->p_alloc;
163 pool->p_alloc += size;
164 return result;
165 }
166
167 void pool_reset(mempool *pool) {
168 if (pool->p_pool == NULL) {
169 pool->p_pool = (unsigned char **)
170 must_alloc(SIZE * sizeof(void *), "pool table");
171 pool->p_pool[0] = (uchar *) must_alloc(PAGE, "pools");
172 pool->p_npools = 1; pool->p_size = SIZE;
173 }
174
175 pool->p_current = 0;
176 pool->p_alloc = pool->p_pool[0];
177 }
178
179
180 int split_line(char *line, char **words) {
181 int nwords = 0;
182 char *s;
183
184 s = line;
185 while (*s == ' ' || *s == '\t' || *s == '\r') s++;
186 if (*s == '\n' || *s == '!' || *s == '\0') return 0;
187
188 /* Set the words array */
189 while (1) {
190 while (*s == ' ' || *s == '\t' || *s == '\r') s++;
191 if (*s == '\n' || *s == '\0') break;
192 if (nwords == MAXWORDS) panic("too many words");
193 words[nwords++] = s;
194 while (! isspace((int) *s) && *s != '\0') s++;
195 if (*s == '\n' || *s == '\0') { *s = '\0'; break; }
196 *s++ = '\0';
197 }
198
199 return nwords;
200 }
201
202 /* squidge -- change Oberon-style name into C identifier */
203 char *squidge(char *name) {
204 static char buf[128];
205 char *t = buf;
206
207 for (char *s = name; *s != '\0'; s++)
208 *t++ = ((*s == '.' || *s == '%') ? '_' : *s);
209 *t = '\0';
210
211 return buf;
212 }