support for c99 style and gnu style structure and union named initializers.
This commit is contained in:
parent
2a0b34371c
commit
66cab14e3e
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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)) ||
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user