Files
Cody Boone Ferguson 92139c55d7 Move 199[1-3]/ant and 2015/howe alt code
The unobfuscated code, which was put in deobfuscated/, has been turned
into alt code. In one case the already existing alt code was made alt2
and the unobfuscated code was alt. In the case of the ones with two C
files there, the one that did not require modification (to compile in
modern systems) were used as those are original.

In a few cases these changes suggested additional files: a test suite
Makefile for the alt code, a try.alt.sh script and maybe some other
things besides.

The bug status was updated for 2015/howe with a known bug: in particular
the test scripts do not work (at least not completely).

In the manifest all references (except for a file name that has not been
renamed - at least not yet) of 'deobfuscated' to 'unobfuscated': a minor
detail that might not matter much but it sounds ever so slightly better
(maybe). These other entries that had an entry_text change were
1995/garry and 2020/endoh2. Rebuilt .entry.json and index.html files for
this (and in the case of the moved code the index.html files also had to
be changed for that in addition to the Makefiles).
2024-07-07 09:53:56 -07:00

243 lines
5.0 KiB
C

/*
* am.c Anthony's Make
*
* Public Domain 1992 by Anthony Howe. All rights released.
*
*
* SYNOPSIS
*
* am <makefile> [target]
*
*
* REFERENCES
*
* [Mil87] Webb Miller, "A Software Tools Sampler", Prentic Hall, 87
* ISBN 0-13-822305-X, chaper 2
*
* [POSIX] POSIX.2 draft 11.2 MAKE
*/
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#ifndef RULES
#define RULES 500
#endif
#define next(p, i) (p += i, p += strspn(p, white), i = strcspn(p, white))
char *buf, line[BUFSIZ];
char *tar[RULES], *dep[RULES], *cmd[RULES], white[] = "\n\t ";
time_t mtime();
int target();
void update();
/*
* Return the modification time for file.
* If file does not exist then return zero.
*/
time_t
mtime(f)
char *f;
{
int j, x;
size_t i = 0;
struct stat s;
next(f, i);
x = f[i];
f[i] = '\0';
j = stat(f, &s);
f[i] = x;
return (j < 0 ? 0 : s.st_mtime);
}
/*
* Find first occurence of target f. All subsequent occurences
* are ignored. Return the rule number, zero (0) is the empty
* rule and indicates no target found.
*/
int
target(f)
char *f;
{
char *q;
size_t i = 0, j, k = 1;
next(f, i);
while ((q = tar[k]) != NULL) {
j = 0;
while (next(q, j) != 0) {
if (i == j && strncmp(f, q, i) == 0)
return (k);
}
++k;
}
return (0);
}
/*
* Try to update a file's dependencies, then the file itself.
* If the file does not exist, has no dependencies, and no
* known commands, then exit with an error.
*/
void
update(f)
char *f;
{
time_t t = mtime(f);
size_t i = 0, j = t == 0, k = target(f);
char *p = dep[k], *q = cmd[k];
if (next(p, i) == 0 && q != NULL && *q != '\t' && j) {
fprintf(stderr, "am: Don't know how to make '%s'.\n", f);
exit(1);
}
/* Try and update all out-of-date dependencies first. */
while (0 < i) {
update(p);
if (t < mtime(p))
j = 1;
next(p, i);
}
if (j && q != NULL && *q == '\t') {
/* Some systems do not record a file's modification times
* with enough precision. This sleep() guarantees that
* each file has a unique modification time.
*/
sleep(1);
while (*q++ == '\t') {
i = j = 1;
while (0 < strspn(q, "-+@")) {
if (*q == '@')
/* Be silent. */
i = 0;
if (*q++ == '-')
/* Ignore errors. */
j = 0;
}
if (i)
puts(q);
if (system(q) != 0 && j) {
fprintf(stderr, "am: Error making '%s'\n", f);
exit(1);
}
q += strlen(q) + 1;
}
cmd[k] = NULL;
}
}
int
main(argc, argv)
int argc;
char **argv;
{
FILE *f;
struct stat s;
size_t i, j, k;
char *m, *n, *p, *q, *r;
if (argc < 2) {
fprintf(stderr, "usage: am <makefile> [target]\n");
return (2);
}
if (stat(*++argv, &s) != 0 || (f = fopen(*argv, "r")) == NULL)
return (3);
/* Allocate room for expanded target rules. */
q = buf = malloc(2*s.st_size);
if (buf == NULL)
return (4);
/* Facts:
*
* o When a C program starts, all uninitialized data will be
* zero or NULL.
*
* o line[] contains the current makefile line and r points
* into line[]. line <= r < line + BUFSIZ
*
* o p points to the start of text copied from line[].
* q points to the next free storage location.
* buf <= p <= q <= buf + s.st_size;
*
* o m points to start of a temporarily stored macro definition.
*
* o i is the number of rules stored. 0 < i < RULES
*
* o When a C program terminates, all open files are closed and
* any allocated memory is freed.
*/
i = 1;
k = 0;
m = NULL;
/* The empty rule. */
*tar = *dep = *cmd = "";
while ((r = fgets(line, BUFSIZ, f)) != NULL) {
if (RULES <= i) {
fprintf(stderr,
"am: Number of target-rules exceeds %d.\n",
RULES
);
return (1);
}
if (k) {
*q++ = ' ';
r += strspn(r, white);
} else {
/* If a target list was saved and we've terminated
* the dependency list, then line[] may be the first
* command in the target recipe.
*/
if (tar[i] != NULL)
cmd[i++] = q;
if (m != NULL && putenv(m))
fprintf(stderr,
"am: No more environment space.\n");
m = NULL;
/* Skip comment or blank lines. */
if (*line == '#' || *line == '\n')
continue;
p = q;
}
while (!(k = *r == '\\' && r[1] == '\n') && *r != '\0') {
if (*r == '$') {
if (r[1] == '(') {
n = r+2;
r += strcspn(r, ")");
*r++ = '\0';
n = getenv(n);
if (n != NULL)
q = strcpy(q, n) + strlen(n);
continue;
}
if (*r == r[1])
++r;
}
if (*r == '=' && *line != '\t' && m == NULL) {
*q = '\0';
m = p;
j = 0;
q = next(m, j) + m;
*q++ = *r;
j = 1;
if (next(r, j) == 0)
*q++ = '\0';
continue;
}
if (*r == ':') {
tar[i] = p;
*r = '\0';
dep[i] = q+1;
}
if (*r == '\n')
*r = '\0';
*q++ = *r++;
}
}
fclose(f);
update(2 < argc ? *++argv : tar[1]);
return (0);
}