Home | History | Annotate | Line # | Download | only in common
emit.c revision 1.2
      1 /*	$NetBSD: emit.c,v 1.2 2002/01/21 19:49:51 tv 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 
     34 #include <sys/cdefs.h>
     35 #ifndef lint
     36 __RCSID("$NetBSD: emit.c,v 1.2 2002/01/21 19:49:51 tv Exp $");
     37 #endif
     38 
     39 #include <ctype.h>
     40 #include <stdio.h>
     41 #include <string.h>
     42 
     43 #include "lint.h"
     44 
     45 /* name and handle of output file */
     46 static	const	char *loname;
     47 static	FILE	*lout;
     48 
     49 /* output buffer data */
     50 ob_t	ob;
     51 
     52 static	void	outxbuf(void);
     53 
     54 
     55 /*
     56  * initialize output
     57  */
     58 void
     59 outopen(const char *name)
     60 {
     61 
     62 	loname = name;
     63 
     64 	/* Open output file */
     65 	if ((lout = fopen(name, "w")) == NULL)
     66 		err(1, "cannot open '%s'", name);
     67 
     68 	/* Create output buffer */
     69 	ob.o_len = 1024;
     70 	ob.o_end = (ob.o_buf = ob.o_nxt = xmalloc(ob.o_len)) + ob.o_len;
     71 }
     72 
     73 /*
     74  * flush output buffer and close file
     75  */
     76 void
     77 outclose(void)
     78 {
     79 
     80 	outclr();
     81 	if (fclose(lout) == EOF)
     82 		err(1, "cannot close '%s'", loname);
     83 }
     84 
     85 /*
     86  * resize output buffer
     87  */
     88 static void
     89 outxbuf(void)
     90 {
     91 	ptrdiff_t coffs;
     92 
     93 	coffs = ob.o_nxt - ob.o_buf;
     94 	ob.o_len *= 2;
     95 	ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len;
     96 	ob.o_nxt = ob.o_buf + coffs;
     97 }
     98 
     99 /*
    100  * reset output buffer
    101  * if it is not empty, it is flushed
    102  */
    103 void
    104 outclr(void)
    105 {
    106 	size_t	sz;
    107 
    108 	if (ob.o_buf != ob.o_nxt) {
    109 		outchar('\n');
    110 		sz = ob.o_nxt - ob.o_buf;
    111 		if (sz > ob.o_len)
    112 			errx(1, "internal error: outclr() 1");
    113 		if (fwrite(ob.o_buf, sz, 1, lout) != 1)
    114 			err(1, "cannot write to %s", loname);
    115 		ob.o_nxt = ob.o_buf;
    116 	}
    117 }
    118 
    119 /*
    120  * write a character to the output buffer
    121  */
    122 void
    123 outchar(int c)
    124 {
    125 
    126 	if (ob.o_nxt == ob.o_end)
    127 		outxbuf();
    128 	*ob.o_nxt++ = (char)c;
    129 }
    130 
    131 /*
    132  * write a character to the output buffer, qouted if necessary
    133  */
    134 void
    135 outqchar(int c)
    136 {
    137 
    138 	if (isprint(c) && c != '\\' && c != '"' && c != '\'') {
    139 		outchar(c);
    140 	} else {
    141 		outchar('\\');
    142 		switch (c) {
    143 		case '\\':
    144 			outchar('\\');
    145 			break;
    146 		case '"':
    147 			outchar('"');
    148 			break;
    149 		case '\'':
    150 			outchar('\'');
    151 			break;
    152 		case '\b':
    153 			outchar('b');
    154 			break;
    155 		case '\t':
    156 			outchar('t');
    157 			break;
    158 		case '\n':
    159 			outchar('n');
    160 			break;
    161 		case '\f':
    162 			outchar('f');
    163 			break;
    164 		case '\r':
    165 			outchar('r');
    166 			break;
    167 		case '\v':
    168 			outchar('v');
    169 			break;
    170 		case '\a':
    171 			outchar('a');
    172 			break;
    173 		default:
    174 			outchar((((u_int)c >> 6) & 07) + '0');
    175 			outchar((((u_int)c >> 3) & 07) + '0');
    176 			outchar((c & 07) + '0');
    177 			break;
    178 		}
    179 	}
    180 }
    181 
    182 /*
    183  * write a strint to the output buffer
    184  * the string must not contain any characters which
    185  * should be quoted
    186  */
    187 void
    188 outstrg(const char *s)
    189 {
    190 
    191 	while (*s != '\0') {
    192 		if (ob.o_nxt == ob.o_end)
    193 			outxbuf();
    194 		*ob.o_nxt++ = *s++;
    195 	}
    196 }
    197 
    198 /*
    199  * write an integer value to toe output buffer
    200  */
    201 void
    202 outint(int i)
    203 {
    204 
    205 	if ((ob.o_end - ob.o_nxt) < 3 * sizeof (int))
    206 		outxbuf();
    207 	ob.o_nxt += sprintf(ob.o_nxt, "%d", i);
    208 }
    209 
    210 /*
    211  * write the name of a symbol to the output buffer
    212  * the name is preceded by its length
    213  */
    214 void
    215 outname(const char *name)
    216 {
    217 
    218 	if (name == NULL)
    219 		errx(1, "internal error: outname() 1");
    220 	outint((int)strlen(name));
    221 	outstrg(name);
    222 }
    223 
    224 /*
    225  * write the name of the .c source
    226  */
    227 void
    228 outsrc(const char *name)
    229 {
    230 
    231 	outclr();
    232 	outchar('S');
    233 	outstrg(name);
    234 }
    235