|
|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T m
Length: 9390 (0x24ae)
Types: TextFile
Names: »misc.c«
└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
└─⟦42d463f8e⟧ »EurOpenD3/gnu/make/make-3.59.tar.Z«
└─⟦4f7e061fd⟧
└─⟦this⟧ »make-3.59/misc.c«
/* Copyright (C) 1988, 1989 Free Software Foundation, Inc.
This file is part of GNU Make.
GNU Make 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 1, or (at your option)
any later version.
GNU Make 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 GNU Make; see the file COPYING. If not, write to
the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "make.h"
#include "dep.h"
/* Compare strings *S1 and *S2.
Return negative if the first is less, positive if it is greater,
zero if they are equal. */
int
alpha_compare (s1, s2)
char **s1, **s2;
{
if (**s1 != **s2)
return **s1 - **s2;
return strcmp (*s1, *s2);
}
\f
/* Discard each backslash-newline combination from LINE.
Backslash-backslash-newline combinations become backslash-newlines.
This is done by copying the text at LINE into itself. */
void
collapse_continuations (line)
char *line;
{
register char *in, *out, *p;
register int backslash;
register unsigned int bs_write;
in = index (line, '\n');
if (in == 0)
return;
out = in;
if (out > line)
while (out[-1] == '\\')
--out;
while (*in != '\0')
{
/* BS_WRITE gets the number of quoted backslashes at
the end just before IN, and BACKSLASH gets nonzero
if the next character is quoted. */
backslash = 0;
bs_write = 0;
for (p = in - 1; p >= line && *p == '\\'; --p)
{
if (backslash)
++bs_write;
backslash = !backslash;
/* It should be impossible to go back this far without exiting,
but if we do, we can't get the right answer. */
if (in == out - 1)
abort ();
}
/* Output the appropriate number of backslashes. */
while (bs_write-- > 0)
*out++ = '\\';
/* Skip the newline. */
++in;
/* If the newline is quoted, discard following whitespace
and any preceding whitespace; leave just one space. */
if (backslash)
{
in = next_token (in);
while (out > line && (out[-1] == ' ' || out[-1] == '\t'))
--out;
*out++ = ' ';
}
else
/* If the newline isn't quoted, put it in the output. */
*out++ = '\n';
/* Now copy the following line to the output.
Stop when we find backslashes followed by a newline. */
while (*in != '\0')
if (*in == '\\')
{
p = in + 1;
while (*p == '\\')
++p;
if (*p == '\n')
{
in = p;
break;
}
while (in < p)
*out++ = *in++;
}
else
*out++ = *in++;
}
*out = '\0';
}
/* Remove comments, backslash-newline combinations and whitespace
following such combinations from LINE.
This is done by copying the text at LINE into itself. */
void
collapse_line (line)
char *line;
{
register char *p, *p2;
register int backslash;
register unsigned int bs_write;
/* Collapse backslash-newline continuations. */
collapse_continuations (line);
while (1)
{
p = index (line, '#');
if (p == 0)
break;
backslash = 0;
bs_write = 0;
for (p2 = p - 1; p2 > line && *p2 == '\\'; --p2)
{
if (backslash)
++bs_write;
backslash = !backslash;
}
if (!backslash)
{
/* Cut off the line at the #. */
*p = '\0';
break;
}
/* strcpy better copy left to right. */
line = p;
strcpy (p2 + 1 + bs_write, line);
}
}
\f
/* Print N spaces (used by DEBUGPR for target-depth). */
void
print_spaces (n)
register unsigned int n;
{
while (n-- > 0)
putchar (' ');
}
\f
/* Return a newly-allocated string whose contents
concatenate those of s1, s2, s3. */
char *
concat (s1, s2, s3)
register char *s1, *s2, *s3;
{
register unsigned int len1, len2, len3;
register char *result;
len1 = *s1 != '\0' ? strlen (s1) : 0;
len2 = *s2 != '\0' ? strlen (s2) : 0;
len3 = *s3 != '\0' ? strlen (s3) : 0;
result = (char *) xmalloc (len1 + len2 + len3 + 1);
if (*s1 != '\0')
bcopy (s1, result, len1);
if (*s2 != '\0')
bcopy (s2, result + len1, len2);
if (*s3 != '\0')
bcopy (s3, result + len1 + len2, len3);
*(result + len1 + len2 + len3) = '\0';
return result;
}
\f
/* Print an error message and exit. */
/* VARARGS1 */
void
fatal (s1, s2, s3, s4, s5, s6)
char *s1, *s2, *s3, *s4, *s5, *s6;
{
if (makelevel == 0)
fprintf (stderr, "%s: ", program);
else
fprintf (stderr, "%s[%u]: ", program, makelevel);
fprintf (stderr, s1, s2, s3, s4, s5, s6);
fputs (". Stop.\n", stderr);
die (1);
}
/* Print error message. `s1' is printf control string, `s2' is arg for it. */
/* VARARGS1 */
void
error (s1, s2, s3, s4, s5, s6)
char *s1, *s2, *s3, *s4, *s5, *s6;
{
if (makelevel == 0)
fprintf (stderr, "%s: ", program);
else
fprintf (stderr, "%s[%u]: ", program, makelevel);
fprintf (stderr, s1, s2, s3, s4, s5, s6);
putc ('\n', stderr);
fflush (stderr);
}
/* Print an error message from errno. */
void
perror_with_name (str, name)
char *str, *name;
{
extern int errno, sys_nerr;
extern char *sys_errlist[];
if (errno < sys_nerr)
error ("%s%s: %s", str, name, sys_errlist[errno]);
else
error ("%s%s: Unknown error %d", str, name, errno);
}
/* Print an error message from errno and exit. */
void
pfatal_with_name (name)
char *name;
{
extern int errno, sys_nerr;
extern char *sys_errlist[];
if (errno < sys_nerr)
fatal ("%s: %s", name, sys_errlist[errno]);
else
fatal ("%s: Unknown error %d", name, errno);
/* NOTREACHED */
}
\f
/* Like malloc but get fatal error if memory is exhausted. */
extern char *malloc (), *realloc ();
#undef xmalloc
#undef xrealloc
char *
xmalloc (size)
unsigned int size;
{
char *result = malloc (size);
if (result == 0)
fatal ("virtual memory exhausted");
return result;
}
char *
xrealloc (ptr, size)
char *ptr;
unsigned int size;
{
char *result = realloc (ptr, size);
if (result == 0)
fatal ("virtual memory exhausted");
return result;
}
char *
savestring (str, length)
char *str;
unsigned int length;
{
register char *out = (char *) xmalloc (length + 1);
if (length > 0)
bcopy (str, out, length);
out[length] = '\0';
return out;
}
\f
/* Search string BIG (length BLEN) for an occurrence of
string SMALL (length SLEN). Return a pointer to the
beginning of the first occurrence, or return nil if none found. */
char *
sindex (big, blen, small, slen)
char *big;
unsigned int blen;
char *small;
unsigned int slen;
{
register unsigned int b;
if (blen < 1)
blen = strlen (big);
if (slen < 1)
slen = strlen (small);
for (b = 0; b < blen; ++b)
if (big[b] == *small && !strncmp (&big[b + 1], small + 1, slen - 1))
return (&big[b]);
return 0;
}
/* Limited INDEX:
Search through the string STRING, which ends at LIMIT, for the character C.
Returns a pointer to the first occurrence, or nil if none is found.
Like INDEX except that the string searched ends where specified
instead of at the first null. */
char *
lindex (s, limit, c)
register char *s, *limit;
int c;
{
while (s < limit)
if (*s++ == c)
return s - 1;
return 0;
}
\f
/* Return the address of the first whitespace or null in the string S. */
char *
end_of_token (s)
char *s;
{
register char *p = s;
register int backslash = 0;
while (*p != '\0' && (backslash || (*p != ' ' && *p != '\t' && *p != '\f')))
{
if (*p++ == '\\')
{
backslash = !backslash;
while (*p == '\\')
{
backslash = !backslash;
++p;
}
}
else
backslash = 0;
}
return p;
}
/* Return the address of the first nonwhitespace or null in the string S. */
char *
next_token (s)
char *s;
{
register char *p = s;
while (*p == ' ' || *p == '\t' || *p == '\f')
++p;
return p;
}
/* Find the next token in PTR; return the address of it, and store the
length of the token into *LENGTHPTR if LENGTHPTR is not nil. */
char *
find_next_token (ptr, lengthptr)
char **ptr;
unsigned int *lengthptr;
{
char *p = next_token (*ptr);
char *end;
if (*p == '\0')
return 0;
*ptr = end = end_of_token (p);
if (lengthptr != 0)
*lengthptr = end - p;
return p;
}
\f
/* Copy a chain of `struct dep', making a new chain
with the same contents as the old one. */
struct dep *
copy_dep_chain (d)
register struct dep *d;
{
register struct dep *c;
struct dep *firstnew = 0;
struct dep *lastnew;
while (d != 0)
{
c = (struct dep *) xmalloc (sizeof (struct dep));
bcopy ((char *) d, (char *) c, sizeof (struct dep));
if (c->name != 0)
c->name = savestring (c->name, strlen (c->name));
c->next = 0;
if (firstnew == 0)
firstnew = lastnew = c;
else
lastnew = lastnew->next = c;
d = d->next;
}
return firstnew;
}
\f
#ifdef iAPX286
/* The losing compiler on this machine can't handle this macro. */
char *
dep_name (dep)
struct dep *dep;
{
return dep->name == 0 ? dep->file->name : dep->name;
}
#endif