Skip to content

Commit

Permalink
mamake: fix whitespace, fix a warning, add full backward compat
Browse files Browse the repository at this point in the history
src/cmd/INIT/mamake.c:

- delimiter() macro: Make whitespace check consistent with the rest
  by using isspace(). (re: abbd9ff, 6cc2f6a)

- Silence a warning that some GCC versions throw about strcpy into
  a region of size 1. This is due to the classic C89/C90 'struct
  hack' from before flexible arrays in structs were standardised:
  http://web.archive.org/web/20240108080600/c-faq.com/struct/structhack.html
  If we're compiling C99 or up, use flexible array struct members
  in Dict_item_t and View_t. In search(), the allocation of
  Dict_item_t items now needs to add a byte to strlen(name) because
  the flexible array is not counted in sizeof(Dict_item_t). Note
  that the allocation of View_t items in view() was already
  counting an extra byte, thus was wasting one until now. In
  C89/90, both will now waste a byte; not worth the effort to fix.

- rule(): Unless strict mode is on, make dependencies on source
  *.lic files (the removed proto(1) licence atrocities) optional by
  assigning the dontcare attribute. This was the only thing
  standing in the way of full backward compatibility with old
  Mamfiles. (re: 594f309)
  • Loading branch information
McDutchie committed Feb 18, 2024
1 parent b8e3d2a commit 2c37759
Showing 1 changed file with 34 additions and 4 deletions.
38 changes: 34 additions & 4 deletions src/cmd/INIT/mamake.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ static const char usage[] =
#include <string.h>
#endif

#define delimiter(c) ((c)==' '||(c)=='\t'||(c)=='\n'||(c)==';'||(c)=='('||(c)==')'||(c)=='`'||(c)=='|'||(c)=='&'||(c)=='=')
#define delimiter(c) (isspace(c)||(c)==';'||(c)=='('||(c)==')'||(c)=='`'||(c)=='|'||(c)=='&'||(c)=='=')

#define add(b,c) (((b)->nxt >= (b)->end) ? append(b, "") : NULL, *(b)->nxt++ = (c))
#define get(b) ((b)->nxt-(b)->buf)
Expand Down Expand Up @@ -216,7 +216,11 @@ typedef struct Dict_item_s /* dictionary item */
struct Dict_item_s* left; /* left child */
struct Dict_item_s* right; /* right child */
void* value; /* user defined value */
#if __STDC_VERSION__ >= 199901L
char name[]; /* 0 terminated name */
#else
char name[1];/* 0 terminated name */
#endif
} Dict_item_t;

typedef struct Dict_s /* dictionary handle */
Expand Down Expand Up @@ -254,7 +258,11 @@ typedef struct View_s /* viewpath level */
{
struct View_s* next; /* next level in viewpath */
int node; /* viewpath node path length */
#if __STDC_VERSION__ >= 199901L
char dir[]; /* viewpath level dir prefix */
#else
char dir[1]; /* viewpath level dir prefix */
#endif
} View_t;

static struct /* program state */
Expand Down Expand Up @@ -599,7 +607,7 @@ search(Dict_t* dict, char* name, void* value)
}
else if (value)
{
if (!(root = newof(0, Dict_item_t, 1, strlen(name))))
if (!(root = newof(0, Dict_item_t, 1, strlen(name) + 1)))
{
report(3, "out of memory [dictionary]", name, 0);
abort();
Expand Down Expand Up @@ -669,10 +677,18 @@ rule(char* name)

if (!(r = (Rule_t*)search(state.rules, name, NULL)))
{
int n;
if (!(r = newof(0, Rule_t, 1, 0)))
report(3, "out of memory [rule]", name, 0);
r->name = ((Dict_item_t*)search(state.rules, name, r))->name;
r->line = state.sp ? state.sp->line : 0;
/*
* Since ksh 93u+m removed proto(1) including the *.lic license
* atrocities, make those prerequisites optional. This allows
* testing code with old Mamfiles using the current build system.
*/
if (!state.strict && *name == '/' && (n = strlen(name)) > 4 && strcmp(name + n - 4, ".lic") == 0)
r->flags |= RULE_dontcare;
}
return r;
}
Expand Down Expand Up @@ -885,9 +901,13 @@ substitute(Buf_t* buf, char* s)
else if (*s == '}' && !--n)
break;
}

/* Special expansion syntax */

switch (c)
{
case '?':
/* ${variable?c?x?y?} */
q = cond(t - 1);
if (v)
{
Expand Down Expand Up @@ -921,6 +941,7 @@ substitute(Buf_t* buf, char* s)
break;
case '+':
case '-':
/* ${variable+x}, ${variable-x} */
if ((v == 0 || *v == 0) == (c == '-'))
{
c = *s;
Expand Down Expand Up @@ -1260,7 +1281,6 @@ run(Rule_t* r, char* s)
Rule_t* q;
char* t;
int c;
View_t* v;
int i;
int j;
int x;
Expand Down Expand Up @@ -1310,11 +1330,21 @@ run(Rule_t* r, char* s)
append(buf, t);
continue;
}
/*
* If the word matches the name of a non-generated prerequisite,
* replace it with its canonical path within the source directory.
*/
if ((q = (Rule_t*)search(state.rules, t, NULL)) && q->path && !(q->flags & RULE_generated))
append(buf, q->path);
else
{
append(buf, t);
/*
* Viewpathing for -I cc flags (include path directories):
* duplicate every '-Ipath' and '-I path', where 'path' is a relative
* pathname (i.e. not starting with '/'). The duplicate points to the
* corresponding canonical path in the source directory.
*/
if (*t == '-' && *(t + 1) == 'I' && (*(t + 2) || c))
{
if (*(t + 2))
Expand All @@ -1330,7 +1360,7 @@ run(Rule_t* r, char* s)
}
if (*(t + i) && *(t + i) != '/')
{
v = state.view;
View_t *v = state.view;
while (v = v->next)
{
add(buf, ' ');
Expand Down

0 comments on commit 2c37759

Please sign in to comment.