emit.c revision 165628
112099Sjoerg/* $NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $ */ 212099Sjoerg 312099Sjoerg/* 412099Sjoerg * Copyright (c) 1994, 1995 Jochen Pohl 512099Sjoerg * All Rights Reserved. 612099Sjoerg * 712099Sjoerg * Redistribution and use in source and binary forms, with or without 812099Sjoerg * modification, are permitted provided that the following conditions 912099Sjoerg * are met: 1012099Sjoerg * 1. Redistributions of source code must retain the above copyright 1112099Sjoerg * notice, this list of conditions and the following disclaimer. 1212099Sjoerg * 2. Redistributions in binary form must reproduce the above copyright 1312099Sjoerg * notice, this list of conditions and the following disclaimer in the 1412099Sjoerg * documentation and/or other materials provided with the distribution. 1512099Sjoerg * 3. All advertising materials mentioning features or use of this software 1612099Sjoerg * must display the following acknowledgement: 1712099Sjoerg * This product includes software developed by Jochen Pohl for 1812099Sjoerg * The NetBSD Project. 1912099Sjoerg * 4. The name of the author may not be used to endorse or promote products 2012099Sjoerg * derived from this software without specific prior written permission. 2112099Sjoerg * 2212099Sjoerg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2312099Sjoerg * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2412099Sjoerg * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2512099Sjoerg * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2612099Sjoerg * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2712099Sjoerg * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2812099Sjoerg * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2912099Sjoerg * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3012099Sjoerg * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 3112099Sjoerg * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3292922Simp * 3392922Simp * $FreeBSD: head/usr.bin/xlint/lint1/emit.c 165628 2006-12-29 13:08:46Z yar $ 3412099Sjoerg */ 3512099Sjoerg 3612099Sjoerg#ifndef lint 3712099Sjoergstatic char rcsid[] = "$NetBSD: emit.c,v 1.2 1995/07/03 21:24:00 cgd Exp $"; 3812099Sjoerg#endif 3912099Sjoerg 4012099Sjoerg#include <stdio.h> 4112099Sjoerg#include <string.h> 4212099Sjoerg#include <ctype.h> 4312099Sjoerg#include <err.h> 4412099Sjoerg 4512099Sjoerg#include "lint.h" 4612099Sjoerg 4712099Sjoerg/* name and handle of output file */ 4812099Sjoergstatic const char *loname; 4912099Sjoergstatic FILE *lout; 5012099Sjoerg 5112099Sjoerg/* output buffer data */ 5212099Sjoergob_t ob; 5312099Sjoerg 5492922Simpstatic void outxbuf(void); 5512099Sjoerg 5612099Sjoerg 5712099Sjoerg/* 5812099Sjoerg * initialize output 5912099Sjoerg */ 6012099Sjoergvoid 6112099Sjoergoutopen(name) 6212099Sjoerg const char *name; 6312099Sjoerg{ 6412099Sjoerg loname = name; 6512099Sjoerg 6612099Sjoerg /* Ausgabedatei oeffnen */ 6712099Sjoerg if ((lout = fopen(name, "w")) == NULL) 6812099Sjoerg err(1, "cannot open '%s'", name); 6912099Sjoerg 7012099Sjoerg /* Ausgabepuffer anlegen */ 7112099Sjoerg ob.o_len = 1024; 7212099Sjoerg ob.o_end = (ob.o_buf = ob.o_nxt = xmalloc(ob.o_len)) + ob.o_len; 7312099Sjoerg} 7412099Sjoerg 7512099Sjoerg/* 7612099Sjoerg * flush output buffer and close file 7712099Sjoerg */ 7812099Sjoergvoid 7912099Sjoergoutclose() 8012099Sjoerg{ 8112099Sjoerg outclr(); 8212099Sjoerg if (fclose(lout) == EOF) 8312099Sjoerg err(1, "cannot close '%s'", loname); 8412099Sjoerg} 8512099Sjoerg 8612099Sjoerg/* 8712099Sjoerg * resize output buffer 8812099Sjoerg */ 8912099Sjoergstatic void 9012099Sjoergoutxbuf() 9112099Sjoerg{ 9212099Sjoerg ptrdiff_t coffs; 9312099Sjoerg 9412099Sjoerg coffs = ob.o_nxt - ob.o_buf; 9512099Sjoerg ob.o_len *= 2; 9612099Sjoerg ob.o_end = (ob.o_buf = xrealloc(ob.o_buf, ob.o_len)) + ob.o_len; 9712099Sjoerg ob.o_nxt = ob.o_buf + coffs; 9812099Sjoerg} 9912099Sjoerg 10012099Sjoerg/* 10112099Sjoerg * reset output buffer 10212099Sjoerg * if it is not empty, it is flushed 10312099Sjoerg */ 10412099Sjoergvoid 10512099Sjoergoutclr() 10612099Sjoerg{ 10712099Sjoerg size_t sz; 10812099Sjoerg 10912099Sjoerg if (ob.o_buf != ob.o_nxt) { 11012099Sjoerg outchar('\n'); 11112099Sjoerg sz = ob.o_nxt - ob.o_buf; 11212099Sjoerg if (sz > ob.o_len) 11312099Sjoerg errx(1, "internal error: outclr() 1"); 11412099Sjoerg if (fwrite(ob.o_buf, sz, 1, lout) != 1) 11512099Sjoerg err(1, "cannot write to %s", loname); 11612099Sjoerg ob.o_nxt = ob.o_buf; 11712099Sjoerg } 11812099Sjoerg} 11912099Sjoerg 12012099Sjoerg/* 12112099Sjoerg * write a character to the output buffer 12212099Sjoerg */ 12312099Sjoergvoid 12412099Sjoergoutchar(c) 12512099Sjoerg int c; 12612099Sjoerg{ 12712099Sjoerg if (ob.o_nxt == ob.o_end) 12812099Sjoerg outxbuf(); 12912099Sjoerg *ob.o_nxt++ = (char)c; 13012099Sjoerg} 13112099Sjoerg 13212099Sjoerg/* 13312099Sjoerg * write a character to the output buffer, qouted if necessary 13412099Sjoerg */ 13512099Sjoergvoid 13612099Sjoergoutqchar(c) 13712099Sjoerg int c; 13812099Sjoerg{ 13912099Sjoerg if (isprint(c) && c != '\\' && c != '"' && c != '\'') { 14012099Sjoerg outchar(c); 14112099Sjoerg } else { 14212099Sjoerg outchar('\\'); 14312099Sjoerg switch (c) { 14412099Sjoerg case '\\': 14512099Sjoerg outchar('\\'); 14612099Sjoerg break; 14712099Sjoerg case '"': 14812099Sjoerg outchar('"'); 14912099Sjoerg break; 15012099Sjoerg case '\'': 15112099Sjoerg outchar('\''); 15212099Sjoerg break; 15312099Sjoerg case '\b': 15412099Sjoerg outchar('b'); 15512099Sjoerg break; 15612099Sjoerg case '\t': 15712099Sjoerg outchar('t'); 15812099Sjoerg break; 15912099Sjoerg case '\n': 16012099Sjoerg outchar('n'); 16112099Sjoerg break; 16212099Sjoerg case '\f': 16312099Sjoerg outchar('f'); 16412099Sjoerg break; 16512099Sjoerg case '\r': 16612099Sjoerg outchar('r'); 16712099Sjoerg break; 16812099Sjoerg#ifdef __STDC__ 16912099Sjoerg case '\v': 17012099Sjoerg#else 17112099Sjoerg case '\013': 17212099Sjoerg#endif 17312099Sjoerg outchar('v'); 17412099Sjoerg break; 17512099Sjoerg#ifdef __STDC__ 17612099Sjoerg case '\a': 17712099Sjoerg#else 17812099Sjoerg case '\007': 17912099Sjoerg#endif 18012099Sjoerg outchar('a'); 18112099Sjoerg break; 18212099Sjoerg default: 18312099Sjoerg outchar((((u_int)c >> 6) & 07) + '0'); 18412099Sjoerg outchar((((u_int)c >> 3) & 07) + '0'); 18512099Sjoerg outchar((c & 07) + '0'); 18612099Sjoerg break; 18712099Sjoerg } 18812099Sjoerg } 18912099Sjoerg} 19012099Sjoerg 19112099Sjoerg/* 19212099Sjoerg * write a strint to the output buffer 19312099Sjoerg * the string must not contain any characters which 19412099Sjoerg * should be quoted 19512099Sjoerg */ 19612099Sjoergvoid 19712099Sjoergoutstrg(s) 19812099Sjoerg const char *s; 19912099Sjoerg{ 20012099Sjoerg while (*s != '\0') { 20112099Sjoerg if (ob.o_nxt == ob.o_end) 20212099Sjoerg outxbuf(); 20312099Sjoerg *ob.o_nxt++ = *s++; 20412099Sjoerg } 20512099Sjoerg} 20612099Sjoerg 20712099Sjoerg/* 20812099Sjoerg * write an integer value to toe output buffer 20912099Sjoerg */ 21012099Sjoergvoid 21112099Sjoergoutint(i) 21212099Sjoerg int i; 21312099Sjoerg{ 21412099Sjoerg if ((ob.o_end - ob.o_nxt) < 3 * sizeof (int)) 21512099Sjoerg outxbuf(); 21612099Sjoerg ob.o_nxt += sprintf(ob.o_nxt, "%d", i); 21712099Sjoerg} 21812099Sjoerg 21912099Sjoerg/* 22012099Sjoerg * write the name of a symbol to the output buffer 221165628Syar * the name is preceded by its length 22212099Sjoerg */ 22312099Sjoergvoid 22412099Sjoergoutname(name) 22512099Sjoerg const char *name; 22612099Sjoerg{ 22712099Sjoerg if (name == NULL) 22812099Sjoerg errx(1, "internal error: outname() 1"); 22912099Sjoerg outint((int)strlen(name)); 23012099Sjoerg outstrg(name); 23112099Sjoerg} 23212099Sjoerg 23312099Sjoerg/* 23412099Sjoerg * write the name of the .c source 23512099Sjoerg */ 23612099Sjoergvoid 23712099Sjoergoutsrc(name) 23812099Sjoerg const char *name; 23912099Sjoerg{ 24012099Sjoerg outclr(); 24112099Sjoerg outchar('S'); 24212099Sjoerg outstrg(name); 24312099Sjoerg} 244