support for c99 style and gnu style structure and union named initializers.

This commit is contained in:
christos 2002-10-21 21:14:51 +00:00
parent 2a0b34371c
commit 66cab14e3e
6 changed files with 170 additions and 19 deletions

View File

@ -1,5 +1,5 @@
%{
/* $NetBSD: cgram.y,v 1.25 2002/09/13 14:59:24 christos Exp $ */
/* $NetBSD: cgram.y,v 1.26 2002/10/21 21:14:51 christos Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@ -35,7 +35,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: cgram.y,v 1.25 2002/09/13 14:59:24 christos Exp $");
__RCSID("$NetBSD: cgram.y,v 1.26 2002/10/21 21:14:51 christos Exp $");
#endif
#include <stdlib.h>
@ -1120,6 +1120,7 @@ init_expr:
expr %prec T_COMMA {
mkinit($1);
}
| init_by_name init_expr %prec T_COMMA
| init_lbrace init_expr_list init_rbrace
| init_lbrace init_expr_list T_COMMA init_rbrace
| error
@ -1130,6 +1131,19 @@ init_expr_list:
| init_expr_list T_COMMA init_expr
;
init_by_name:
point T_NAME T_ASSIGN {
if (!Sflag)
warning(313);
memberpush($2);
}
| T_NAME T_COLON {
gnuism(315);
memberpush($1);
}
;
init_lbrace:
T_LBRACE {
initlbr();
@ -1619,6 +1633,13 @@ point_or_arrow:
}
;
point:
T_STROP {
if ($1 != POINT)
error(249);
}
;
identifier:
T_NAME {
$$ = $1;

View File

@ -1,4 +1,4 @@
/* $NetBSD: err.c,v 1.19 2002/09/13 14:59:24 christos Exp $ */
/* $NetBSD: err.c,v 1.20 2002/10/21 21:14:51 christos Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@ -33,7 +33,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: err.c,v 1.19 2002/09/13 14:59:24 christos Exp $");
__RCSID("$NetBSD: err.c,v 1.20 2002/10/21 21:14:51 christos Exp $");
#endif
#include <sys/types.h>
@ -368,6 +368,9 @@ const char *msgs[] = {
"symbol renaming can't be used on function arguments", /* 310 */
"symbol renaming can't be used on automatic variables", /* 311 */
"%s C does not support // comments", /* 312 */
"struct or union member name in initializer is a C9X feature",/* 313 */
"%s is not a structure or a union", /* 314 */
"GCC style struct or union member name in initializer", /* 315 */
};
/*
@ -457,8 +460,8 @@ lerror(const char *file, int line, const char *msg, ...)
va_start(ap, msg);
fn = lbasename(curr_pos.p_file);
(void)fprintf(stderr, "%s(%d): lint error: %s, %d", fn, curr_pos.p_line,
file, line);
(void)fprintf(stderr, "%s(%d): lint error: %s, %d: ",
fn, curr_pos.p_line, file, line);
(void)vfprintf(stderr, msg, ap);
(void)fprintf(stderr, "\n");
va_end(ap);

View File

@ -1,4 +1,4 @@
/* $NetBSD: externs1.h,v 1.15 2002/09/13 14:59:24 christos Exp $ */
/* $NetBSD: externs1.h,v 1.16 2002/10/21 21:14:52 christos Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@ -50,6 +50,7 @@ extern int vflag;
extern int yflag;
extern int wflag;
extern int zflag;
extern int Sflag;
extern void norecover(void);
@ -273,6 +274,7 @@ extern void prepinit(void);
extern void initrbr(void);
extern void initlbr(void);
extern void mkinit(tnode_t *);
extern void memberpush(sbuf_t *);
/*
* emit.c

View File

@ -1,4 +1,4 @@
/* $NetBSD: init.c,v 1.11 2002/09/13 14:59:24 christos Exp $ */
/* $NetBSD: init.c,v 1.12 2002/10/21 21:14:52 christos Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@ -33,7 +33,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: init.c,v 1.11 2002/09/13 14:59:24 christos Exp $");
__RCSID("$NetBSD: init.c,v 1.12 2002/10/21 21:14:52 christos Exp $");
#endif
#include <stdlib.h>
@ -53,6 +53,15 @@ sym_t *initsym;
/* Points to the top element of the initialisation stack. */
istk_t *initstk;
typedef struct namlist {
const char *n_name;
struct namlist *n_prev;
struct namlist *n_next;
} namlist_t;
/* Points to a c9x named member; */
namlist_t *namedmem = NULL;
static void popi2(void);
static void popinit(int);
@ -60,6 +69,53 @@ static void pushinit(void);
static void testinit(void);
static void nextinit(int);
static int strginit(tnode_t *);
static void memberpop(void);
#ifndef DEBUG
#define DPRINTF(a)
#else
#define DPRINTF(a) printf a
#endif
void
memberpush(sb)
sbuf_t *sb;
{
namlist_t *nam = xcalloc(1, sizeof (namlist_t));
nam->n_name = sb->sb_name;
DPRINTF(("memberpush = %s\n", nam->n_name));
if (namedmem == NULL) {
nam->n_prev = nam->n_next = nam;
namedmem = nam;
} else {
namedmem->n_prev->n_next = nam;
nam->n_prev = namedmem->n_prev;
nam->n_next = namedmem;
namedmem->n_prev = nam;
}
#if 0
nam->n_next = namedmem;
namedmem = nam;
#endif
}
static void
memberpop()
{
DPRINTF(("memberpop = %s\n", namedmem->n_name));
if (namedmem->n_next == namedmem) {
free(namedmem);
namedmem = NULL;
} else {
namlist_t *nam = namedmem;
namedmem = namedmem->n_next;
free(nam);
}
#if 0
namedmem = namedmem->n_next;
free(nam);
#endif
}
/*
@ -96,6 +152,9 @@ prepinit(void)
static void
popi2(void)
{
#ifdef DEBUG
char buf[64];
#endif
istk_t *istk;
sym_t *m;
@ -110,11 +169,30 @@ popi2(void)
if (istk->i_cnt < 0)
LERROR("popi2()");
if (istk->i_cnt >= 0 && namedmem != NULL) {
DPRINTF(("popi2(): %d %s %s\n", istk->i_cnt,
tyname(buf, sizeof(buf), istk->i_type), namedmem->n_name));
for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
if (m->s_field && m->s_name == unnamed)
continue;
if (strcmp(m->s_name, namedmem->n_name) == 0) {
istk->i_subt = m->s_type;
istk->i_cnt++;
memberpop();
return;
}
}
error(101, namedmem->n_name);
memberpop();
istk->i_namedmem = 1;
return;
}
/*
* If the removed element was a structure member, we must go
* to the next structure member.
*/
if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT) {
if (istk->i_cnt > 0 && istk->i_type->t_tspec == STRUCT &&
!istk->i_namedmem) {
do {
m = istk->i_mem = istk->i_mem->s_nxt;
if (m == NULL)
@ -127,6 +205,7 @@ popi2(void)
static void
popinit(int brace)
{
DPRINTF(("popinit(%d)\n", brace));
if (brace) {
/*
@ -153,6 +232,9 @@ popinit(int brace)
static void
pushinit(void)
{
#ifdef DEBUG
char buf[64];
#endif
istk_t *istk;
int cnt;
sym_t *m;
@ -161,6 +243,8 @@ pushinit(void)
/* Extend an incomplete array type by one element */
if (istk->i_cnt == 0) {
DPRINTF(("pushinit(extend) %s\n", tyname(buf, sizeof(buf),
istk->i_type)));
/*
* Inside of other aggregate types must not be an incomplete
* type.
@ -186,8 +270,10 @@ pushinit(void)
if (initstk->i_type->t_tspec == FUNC)
LERROR("pushinit()");
again:
istk = initstk;
DPRINTF(("pushinit(%s)\n", tyname(buf, sizeof(buf), istk->i_type)));
switch (istk->i_type->t_tspec) {
case ARRAY:
if (incompl(istk->i_type) && istk->i_nxt->i_nxt != NULL) {
@ -213,14 +299,37 @@ pushinit(void)
return;
}
cnt = 0;
DPRINTF(("2. member lookup %s\n",
tyname(buf, sizeof(buf), istk->i_type)));
for (m = istk->i_type->t_str->memb; m != NULL; m = m->s_nxt) {
if (m->s_field && m->s_name == unnamed)
continue;
if (namedmem != NULL) {
DPRINTF(("pushinit():[member:%s, looking:%s]\n",
m->s_name, namedmem->n_name));
if (strcmp(m->s_name, namedmem->n_name) == 0) {
cnt++;
break;
} else
continue;
}
if (++cnt == 1) {
istk->i_mem = m;
istk->i_subt = m->s_type;
}
}
if (namedmem != NULL) {
istk->i_namedmem = 1;
if (m == NULL) {
error(101, namedmem->n_name);
initerr = 1;
} else {
istk->i_mem = m;
istk->i_subt = m->s_type;
}
memberpop();
cnt = istk->i_type->t_tspec == STRUCT ? 2 : 1;
}
if (cnt == 0) {
/* cannot init. struct/union with no named member */
error(179);
@ -230,6 +339,12 @@ pushinit(void)
istk->i_cnt = istk->i_type->t_tspec == STRUCT ? cnt : 1;
break;
default:
if (namedmem) {
DPRINTF(("pushinit(): pop\n"));
free(istk);
initstk = initstk->i_nxt;
goto again;
}
istk->i_cnt = 1;
break;
}
@ -246,7 +361,7 @@ testinit(void)
* If a closing brace is expected we have at least one initializer
* too much.
*/
if (istk->i_cnt == 0 && !istk->i_nolimit) {
if (istk->i_cnt == 0 && !istk->i_nolimit && !istk->i_namedmem) {
switch (istk->i_type->t_tspec) {
case ARRAY:
/* too many array initializers */
@ -269,7 +384,9 @@ testinit(void)
static void
nextinit(int brace)
{
char buf[64];
DPRINTF(("nextinit(%d)\n", brace));
if (!brace) {
if (initstk->i_type == NULL &&
!issclt(initstk->i_subt->t_tspec)) {
@ -291,7 +408,7 @@ nextinit(int brace)
if (initstk->i_type != NULL &&
issclt(initstk->i_type->t_tspec)) {
/* invalid initializer */
error(176);
error(176, tyname(buf, sizeof(buf), initstk->i_type));
initerr = 1;
}
if (!initerr)
@ -345,7 +462,11 @@ mkinit(tnode_t *tn)
tnode_t *ln;
struct mbl *tmem;
scl_t sc;
#ifdef DEBUG
char buf[64];
#endif
DPRINTF(("mkinit(%s)\n", tyname(buf, sizeof(buf), tn->tn_type)));
if (initerr || tn == NULL)
goto end;
@ -387,7 +508,7 @@ mkinit(tnode_t *tn)
goto end;
initstk->i_cnt--;
DPRINTF(("mkinit() cnt=%d\n", initstk->i_cnt));
/* Create a temporary node for the left side. */
ln = tgetblk(sizeof (tnode_t));
ln->tn_op = NAME;
@ -465,7 +586,7 @@ strginit(tnode_t *tn)
* Check if we have an array type which can be initialized by
* the string.
*/
if (istk->i_subt->t_tspec == ARRAY) {
if (istk->i_subt != NULL && istk->i_subt->t_tspec == ARRAY) {
t = istk->i_subt->t_subt->t_tspec;
if (!((strg->st_tspec == CHAR &&
(t == CHAR || t == UCHAR || t == SCHAR)) ||

View File

@ -1,4 +1,4 @@
/* $NetBSD: lint1.h,v 1.14 2002/09/13 14:59:25 christos Exp $ */
/* $NetBSD: lint1.h,v 1.15 2002/10/21 21:14:53 christos Exp $ */
/*
* Copyright (c) 1996 Christopher G. Demetriou. All Rights Reserved.
@ -345,6 +345,7 @@ typedef struct istk {
type_t *i_subt; /* type of next level */
u_int i_brace : 1; /* need } for pop */
u_int i_nolimit : 1; /* incomplete array type */
u_int i_namedmem : 1; /* has c9x named members */
sym_t *i_mem; /* next structure member */
int i_cnt; /* # of remaining elements */
struct istk *i_nxt; /* previous level */

View File

@ -1,4 +1,4 @@
/* $NetBSD: main1.c,v 1.12 2002/01/31 19:33:50 tv Exp $ */
/* $NetBSD: main1.c,v 1.13 2002/10/21 21:14:53 christos Exp $ */
/*
* Copyright (c) 1994, 1995 Jochen Pohl
@ -33,7 +33,7 @@
#include <sys/cdefs.h>
#if defined(__RCSID) && !defined(lint)
__RCSID("$NetBSD: main1.c,v 1.12 2002/01/31 19:33:50 tv Exp $");
__RCSID("$NetBSD: main1.c,v 1.13 2002/10/21 21:14:53 christos Exp $");
#endif
#include <sys/types.h>
@ -99,6 +99,8 @@ int sflag;
/* Traditional C mode. */
int tflag;
/* Enable C9X extensions */
int Sflag;
/*
* Complain about functions and external variables used and not defined,
* or defined and not used.
@ -126,7 +128,7 @@ main(int argc, char *argv[])
setprogname(argv[0]);
ERR_ZERO(&msgset);
while ((c = getopt(argc, argv, "abcdeghmprstuvwyzFX:")) != -1) {
while ((c = getopt(argc, argv, "abcdeghmprstuvwyzFSX:")) != -1) {
switch (c) {
case 'a': aflag++; break;
case 'b': bflag = 1; break;
@ -139,6 +141,7 @@ main(int argc, char *argv[])
case 'p': pflag = 1; break;
case 'r': rflag = 1; break;
case 's': sflag = 1; break;
case 'S': Sflag = 1; break;
case 't': tflag = 1; break;
case 'u': uflag = 0; break;
case 'w': wflag = 1; break;
@ -209,7 +212,7 @@ static void
usage(void)
{
(void)fprintf(stderr,
"Usage: %s [-abcdeghmprstuvwyzF] [-X <id>[,<id>]... src dest\n",
"Usage: %s [-abcdeghmprstuvwyzFS] [-X <id>[,<id>]... src dest\n",
getprogname());
exit(1);
}