|
|
researchv9-SUN3(old)
static char ID[] = "@(#) util.c: 1.5 5/27/83";
#include "system.h"
#include <stdio.h>
#include <signal.h>
#include "structs.h"
#include "extrns.h"
#include "sgs.h"
#include "sgsmacros.h"
#define INT int
#define BUSY 1
#define testbusy(p) ((INT)(p)&BUSY)
/*eject*/
ACTITEM *
dfnscngrp(type, bondaddr, align, block)
int type;
ADDRESS *bondaddr, *align, *block;
{
/*
* Build a AIDFNSCN/AIDFNGRP action item
*/
ACTITEM *p;
p = (ACTITEM *) myalloc(sizeof(ACTITEM));
p->dfnscn.aiinflnm = curfilnm;
p->dfnscn.aiinlnno = lineno;
p->dfnscn.aitype = type;
p->dfnscn.aibndadr = -1L;
p->dfnscn.aialign = 0L;
p->dfnscn.aiblock = 0L;
if ( bondaddr != NULL ) { /* there is a bond */
p->dfnscn.aibndadr = *bondaddr;
}
if (align != NULL) { /* there is alignment */
p->dfnscn.aialign = *align;
chkpower2(p->dfnscn.aialign);
}
if (block) {
p->dfnscn.aiblock = *block;
chkpower2(*block);
}
return(p);
}
/*eject*/
chkpower2(n)
long n;
{
/*
* Determine if 'n' is a power of two
*/
long c;
for( c = n; c > 2; c >>= 1 )
if( (c % 2) == 1 ) {
lderror(0, lineno, curfilnm, "%.1lx is not a power of 2", n );
break;
}
}
/*eject*/
char *
zero(ptr, cnt)
char *ptr;
int cnt;
{
/*
* Zero "cnt" bytes starting at the address "ptr".
* Return "ptr".
*/
register char *p, *w;
if( cnt > 0 ) {
if( ((short) (p = ptr)) & 1 ) {
*p++ = '\0';
--cnt;
}
w = p + (cnt & (~1));
while (p < w) {
*((short *) p) = 0;
p += sizeof(short);
}
if (cnt & 1)
*p = '\0';
}
return( ptr );
}
/*eject*/
zerofile(fildes,bptr,bsiz)
FILE *fildes; /* write opened file */
unsigned *bptr; /* zero filled buffer */
int bsiz; /* size of buffer */
{
long file_end;
OUTSECT *osptr;
/*
* Insure that fildes is zero filled up to the point
* of symbol table origin, or up to the last section if the symbol
* table is stripped. Under TS, we simply seek to the point
* and write one unsigned. Under RT or DMERT we must write 0's
* throughout the entire space.
*/
#if PAGING
if (Fflag || !sflag)
#else
if (!sflag)
#endif
file_end = symtborg - 4;
else
{
file_end = 0L;
for (osptr = (OUTSECT *) outsclst.head; osptr; osptr = osptr->osnext)
file_end = max( file_end, osptr->oshdr.s_scnptr );
}
#if RT
rewind(fildes);
while ( file_end > ftell(fildes) )
fwrite( (char*) bptr, bsiz, 1, fildes);
#else
fseek(fildes, file_end, 0);
fwrite( (char *) bptr, sizeof(long), 1, fildes);
#endif
rewind(fildes); /* leave everythiing as we found it */
return;
}
/*eject*/
char *
sname(s)
char *s;
{
/*
* Returns pointer to "simple" name of path name; that is,
* pointer to first character after last '/'. If no slashes,
* returns pointer to first char of arg.
*
* If the string ends in a slash:
* 1. replace the terminating slash with '\0'
* 2. return a pointer to the first character after the last
* '/', or the first character in the string
*/
register char *p;
p = s;
while( *p )
if(*p++ == '/')
if( *p == '\0' ) {
*(p-1) = '\0';
break;
}
else
s = p;
return(s);
}
/*eject*/
char *
myalloc(nbytes)
int nbytes;
{
/*
* Allocate "nbytes" of memory, and exit from ld
* upon failure.
*/
register char *mem;
extern char *calloc();
if( (mem = calloc(1,nbytes)) == NULL ) {
lderror(0,0,NULL, "memory allocation failure on %d-byte 'calloc' call",
nbytes);
lderror(2,0,NULL, "%s run is too large and complex", SGS );
}
allocspc += (long) nbytes;
maxalloc = max(maxalloc,allocspc);
return(mem);
}
stoi(p)
char *p;
{
/*
* Given a string of digits, perhaps beginning with "0" or "0x",
* convert to an integer
*
* Return 0x8000 on any type of error
*/
register int base, num;
register char limit;
num = 0;
if (*p == '0') {
if (*++p == 'x' || *p == 'X') { /* string is hex */
for (p++; *p; p++) {
num <<= 4;
if (*p >= '0' && *p <= '9')
num += *p - '0';
else if (*p >= 'a' && *p <= 'f')
num += *p - 'a' + 10;
else if (*p >= 'A' && *p <= 'F')
num += *p - 'A' + 10;
else return(0x8000);
}
return (num);
}
else {
base = 8;
limit = '7';
}
}
else {
base = 10;
limit = '9';
}
for ( ; *p; p++)
if( (*p >= '0') && (*p <= limit) )
num = num * base + *p - '0';
else
return(0x8000);
return(num);
}
/*eject*/
copybyts(src,dest,len)
char *src, *dest;
int len;
{
/*
* Copy len bytes from src to dest
*/
while( len-- > 0 )
*dest++ = *src++;
}
/*eject*/
/*VARARGS*/
lderror(lvl, ln,fln,strng, a1,a2,a3,a4,a5,a6,a7,a8,a9,aa)
int lvl; /* error severity level */
int ln; /* line in ifile containing the error */
char *fln; /* name of the ifile containing the error */
char *strng; /* error message format */
int a1,a2,a3,a4,a5, /* error message format arguments */
a6,a7,a8,a9,aa;
{
/*
* Prepend a filename and a line number to an error message.
* used for printing all parsing-related errors.
*/
errlev = (errlev < lvl ) ? lvl : errlev;
if( Sflag && (lvl != 2) )
return;
fprintf(stderr, "%sld", SGS);
if (fln != NULL)
fprintf(stderr, " %s", sname(fln));
if ( ln > 0 )
fprintf(stderr, " %d", ln) ;
switch(lvl) {
case 0:
fprintf(stderr, " warning: ");
break;
case 2:
fprintf(stderr, " fatal: ");
break;
default:
fprintf(stderr, ": ");
break;
}
fprintf(stderr, strng, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa);
fprintf(stderr, "\n");
fflush(stderr);
if(lvl > 1)
ldexit();
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.