1/* $NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $ */ 2 3/* 4 * Copyright (c) 1994, 1995 Jochen Pohl 5 * All Rights Reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by Jochen Pohl for 18 * The NetBSD Project. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 * 33 * $FreeBSD$ 34 */ 35 36#ifndef lint 37static char rcsid[] = "$NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $"; 38#endif 39 40#include <stdio.h> 41#include <string.h> 42#include <ctype.h> 43#include <err.h> 44 45#include "lint.h" 46 47/* name and handle of output file */ 48static const char *loname; 49static FILE *lout; 50 51/* output buffer data */ 52ob_t ob; 53 54static void outxbuf(void); 55 56 57/* 58 * initialize output 59 */ 60void 61outopen(name) 62 const char *name; 63{ 64 loname = name; 65 66 /* Ausgabedatei oeffnen */ 67 if ((lout = fopen(name, "w")) == NULL) 68 err(1, "cannot open '%s'", name); 69 70 /* Ausgabepuffer anlegen */ 71 ob.o_len = 1024; 72 ob.o_end = (ob.o_buf = ob.o_nxt = xmalloc(ob.o_len)) + ob.o_len; 73} 74 75/* 76 * flush output buffer and close file 77 */ 78void 79outclose() 80{ 81 outclr(); 82 if (fclose(lout) == EOF) 83 err(1, "cannot close '%s'", loname); 84} 85 86/* 87 * resize output buffer 88 */ 89static void 90outxbuf() 91{ 92 ptrdiff_t coffs; 93 94 coffs = ob.o_nxt - ob.o_buf; 95 ob.o_len *= 2; 96 ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len; 97 ob.o_nxt = ob.o_buf + coffs; 98} 99 100/* 101 * reset output buffer 102 * if it is not empty, it is flushed 103 */ 104void 105outclr() 106{ 107 size_t sz; 108 109 if (ob.o_buf != ob.o_nxt) { 110 outchar('\n'); 111 sz = ob.o_nxt - ob.o_buf; 112 if (sz > ob.o_len) 113 errx(1, "internal error: outclr() 1"); 114 if (fwrite(ob.o_buf, sz, 1, lout) != 1) 115 err(1, "cannot write to %s", loname); 116 ob.o_nxt = ob.o_buf; 117 } 118} 119 120/* 121 * write a character to the output buffer 122 */ 123void 124outchar(c) 125 int c; 126{ 127 if (ob.o_nxt == ob.o_end) 128 outxbuf(); 129 *ob.o_nxt++ = (char)c; 130} 131 132/* 133 * write a character to the output buffer, qouted if necessary 134 */ 135void 136outqchar(c) 137 int c; 138{ 139 if (isprint(c) && c != '\\' && c != '"' && c != '\'') { 140 outchar(c); 141 } else { 142 outchar('\\'); 143 switch (c) { 144 case '\\': 145 outchar('\\'); 146 break; 147 case '"': 148 outchar('"'); 149 break; 150 case '\'': 151 outchar('\''); 152 break; 153 case '\b': 154 outchar('b'); 155 break; 156 case '\t': 157 outchar('t'); 158 break; 159 case '\n': 160 outchar('n'); 161 break; 162 case '\f': 163 outchar('f'); 164 break; 165 case '\r': 166 outchar('r'); 167 break; 168#ifdef __STDC__ 169 case '\v': 170#else 171 case '\013': 172#endif 173 outchar('v'); 174 break; 175#ifdef __STDC__ 176 case '\a': 177#else 178 case '\007': 179#endif 180 outchar('a'); 181 break; 182 default: 183 outchar((((u_int)c >> 6) & 07) + '0'); 184 outchar((((u_int)c >> 3) & 07) + '0'); 185 outchar((c & 07) + '0'); 186 break; 187 } 188 } 189} 190 191/* 192 * write a strint to the output buffer 193 * the string must not contain any characters which 194 * should be quoted 195 */ 196void 197outstrg(s) 198 const char *s; 199{ 200 while (*s != '\0') { 201 if (ob.o_nxt == ob.o_end) 202 outxbuf(); 203 *ob.o_nxt++ = *s++; 204 } 205} 206 207/* 208 * write an integer value to toe output buffer 209 */ 210void 211outint(i) 212 int i; 213{ 214 if ((ob.o_end - ob.o_nxt) < 3 * sizeof (int)) 215 outxbuf(); 216 ob.o_nxt += sprintf(ob.o_nxt, "%d", i); 217} 218 219/* 220 * write the name of a symbol to the output buffer 221 * the name is preceded by its length 222 */ 223void 224outname(name) 225 const char *name; 226{ 227 if (name == NULL) 228 errx(1, "internal error: outname() 1"); 229 outint((int)strlen(name)); 230 outstrg(name); 231} 232 233/* 234 * write the name of the .c source 235 */ 236void 237outsrc(name) 238 const char *name; 239{ 240 outclr(); 241 outchar('S'); 242 outstrg(name); 243} 244