NetBSD/usr.bin/sed/utils.c

360 lines
5.9 KiB
C

/* Functions from hack's utils library.
Copyright (C) 1989-1991 Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* These routines were written as part of a library (by hack), but since most
people don't have the library, here they are. */
#ifdef __STDC__
#define VOID void
#else
#define VOID char
#endif
#include <stdio.h>
#if defined(USG) || defined(STDC_HEADERS)
#include <string.h>
#define bcopy(src, dst, len) memcpy((dst), (src), (len))
#else
#endif
#if defined(STDC_HEADERS)
#include <stdlib.h>
#else
VOID *malloc();
VOID *realloc();
#endif
VOID *ck_malloc();
char *myname;
#ifdef __STDC__
#include <stdarg.h>
/* Print an error message and exit */
void
panic(char *str, ...)
{
va_list iggy;
fprintf(stderr,"%s: ",myname);
va_start(iggy,str);
#ifdef NO_VFPRINTF
_doprnt(str,&iggy,stderr);
#else
vfprintf(stderr,str,iggy);
#endif
va_end(iggy);
putc('\n',stderr);
exit(4);
}
#else
#include <varargs.h>
void
panic(str,va_alist)
char *str;
va_dcl
{
va_list iggy;
fprintf(stderr,"%s: ",myname);
va_start(iggy);
#ifdef NO_VFPRINTF
_doprnt(str,&iggy,stderr);
#else
vfprintf(stderr,str,iggy);
#endif
va_end(iggy);
putc('\n',stderr);
exit(4);
}
#endif
/* Store information about files opened with ck_fopen
so that error messages from ck_fread, etc can print the
name of the file that had the error */
#define N_FILE 32
struct id {
FILE *fp;
char *name;
};
static struct id __id_s[N_FILE];
/* Internal routine to get a filename from __id_s */
char *
__fp_name(fp)
FILE *fp;
{
int n;
for(n=0;n<N_FILE;n++) {
if(__id_s[n].fp==fp)
return __id_s[n].name;
}
return "{Unknown file pointer}";
}
/* Panic on failing fopen */
FILE *
ck_fopen(name,mode)
char *name;
char *mode;
{
FILE *ret;
int n;
ret=fopen(name,mode);
if(ret==(FILE *)0)
panic("Couldn't open file %s",name);
for(n=0;n<N_FILE;n++) {
if(ret==__id_s[n].fp) {
free((VOID *)__id_s[n].name);
__id_s[n].name=(char *)ck_malloc(strlen(name)+1);
strcpy(__id_s[n].name,name);
break;
}
}
if(n==N_FILE) {
for(n=0;n<N_FILE;n++)
if(__id_s[n].fp==(FILE *)0)
break;
if(n==N_FILE)
panic("Internal error: too many files open");
__id_s[n].fp=ret;
__id_s[n].name=(char *)ck_malloc(strlen(name)+1);
strcpy(__id_s[n].name,name);
}
return ret;
}
/* Panic on failing fwrite */
void
ck_fwrite(ptr,size,nmemb,stream)
char *ptr;
int size,nmemb;
FILE *stream;
{
if(fwrite(ptr,size,nmemb,stream)!=nmemb)
panic("couldn't write %d items to %s",nmemb,__fp_name(stream));
}
/* Panic on failing fclose */
void
ck_fclose(stream)
FILE *stream;
{
if(fclose(stream)==EOF)
panic("Couldn't close %s",__fp_name(stream));
}
/* Panic on failing malloc */
VOID *
ck_malloc(size)
int size;
{
VOID *ret;
if(!size)
size++;
ret=malloc(size);
if(ret==(VOID *)0)
panic("Couldn't allocate memory");
return ret;
}
/* Panic on failing realloc */
VOID *
ck_realloc(ptr,size)
VOID *ptr;
int size;
{
VOID *ret;
ret=realloc(ptr,size);
if(ret==(VOID *)0)
panic("Couldn't re-allocate memory");
return ret;
}
/* Return a malloc()'d copy of a string */
char *
ck_strdup(str)
char *str;
{
char *ret;
ret=(char *)ck_malloc(strlen(str)+2);
strcpy(ret,str);
return ret;
}
#if !defined(USG) && !defined(STDC_HEADERS)
/*
* memchr - search for a byte
*
*/
VOID *
memchr(s, ucharwanted, size)
VOID *s;
int ucharwanted;
int size;
{
register char *scan;
register n;
register uc;
scan = (char *)s;
uc = (ucharwanted&0xFF);
for (n = size; n > 0; n--)
if (((*scan)&0xFF) == uc)
return((VOID *)scan);
else
scan++;
return 0;
}
#endif
#if !defined(STDC_HEADERS)
/*
* memmove - copy bytes, being careful about overlap.
*/
VOID *
memmove(dst, src, size)
VOID *dst;
VOID *src;
int size;
{
register char *d;
register char *s;
register int n;
if (size <= 0)
return(dst);
s = (char *)src;
d = (char *)dst;
if (s <= d && s + (size-1) >= d) {
/* Overlap, must copy right-to-left. */
s += size-1;
d += size-1;
for (n = size; n > 0; n--)
*d-- = *s--;
} else
for (n = size; n > 0; n--)
*d++ = *s++;
return(dst);
}
#endif
/* Implement a variable sized buffer of 'stuff'. We don't know what it is,
nor do we care, as long as it doesn't mind being aligned by malloc. */
struct buffer {
int allocated;
int length;
char *b;
};
#define MIN_ALLOCATE 50
VOID *
init_buffer()
{
struct buffer *b;
b=(struct buffer *)ck_malloc(sizeof(struct buffer));
b->allocated=MIN_ALLOCATE;
b->b=(char *)ck_malloc(MIN_ALLOCATE);
b->length=0;
return (VOID *)b;
}
void
flush_buffer(bb)
VOID *bb;
{
struct buffer *b;
b=(struct buffer *)bb;
free(b->b);
b->b=0;
b->allocated=0;
b->length=0;
free(b);
}
int
size_buffer(b)
VOID *b;
{
struct buffer *bb;
bb=(struct buffer *)b;
return bb->length;
}
void
add_buffer(bb,p,n)
VOID *bb;
char *p;
int n;
{
struct buffer *b;
b=(struct buffer *)bb;
if(b->length+n>b->allocated) {
b->allocated*=2;
b->b=(char *)ck_realloc(b->b,b->allocated);
}
bcopy(p,b->b+b->length,n);
b->length+=n;
}
void
add1_buffer(bb,ch)
VOID *bb;
int ch;
{
struct buffer *b;
b=(struct buffer *)bb;
if(b->length+1>b->allocated) {
b->allocated*=2;
b->b=(char *)ck_realloc(b->b,b->allocated);
}
b->b[b->length]=ch;
b->length++;
}
char *
get_buffer(bb)
VOID *bb;
{
struct buffer *b;
b=(struct buffer *)bb;
return b->b;
}