* ========== Copyright Header Begin ==========================================
* Hypervisor Software File: didepend.c
* Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
* - Do no alter or remove copyright notices
* - Redistribution and use of this software in source and binary forms, with
* or without modification, are permitted provided that the following
* - Redistribution of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* - Redistribution in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* Neither the name of Sun Microsystems, Inc. or the names of contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* This software is provided "AS IS," without a warranty of any kind.
* ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
* INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
* MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
* ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
* OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
* FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
* DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
* ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
* SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
* You acknowledge that this software is not designed, licensed or
* intended for use in the design, construction, operation or maintenance of
* ========== Copyright Header End ============================================
* id: @(#)didepend.c 1.12 04/04/22
* copyright: Copyright 1997-2004 Sun Microsystems, Inc. All Rights Reserved
* Use is subject to license terms.
fprintf(stderr
, "%s: [flag] sourcefile\n", progname
);
fprintf(stderr
, " -D <symbol> : define <symbol>\n");
fprintf(stderr
, " -U <symbol> : undefine <symbol>\n");
fprintf(stderr
, " -S : show symbols used\n");
fprintf(stderr
, " -s : print sources\n");
fprintf(stderr
, " -t : print targets\n");
fprintf(stderr
, " -d : print dependancies\n");
fprintf(stderr
, " -c : print code\n");
fprintf(stderr
, " -p : pedantic mode\n");
#define CAST(x) (retval) (x)
#define CMD_NULL_ARGS 0x00
#define CMD_OPT_ARGS 0x10
#define CMD_COMPAT_ONLY 0x40
retval (*fn
)(char *arg0
, char *line
);
retval
enable_cmds(char *line
, char *arg0
);
retval
disable_cmds(char *line
, char *arg0
);
retval
get_source_line(char *line
, char *arg0
);
retval
set_build_cmd(char *arg0
, char *line
);
retval
grab_depend_line(char *arg0
, char *line
);
retval
grab_target_line(char *arg0
, char *line
);
retval
grab_external_line(char *arg0
, char *line
);
retval
grab_source(char *arg0
, char *line
);
retval
comment_line(char *arg0
, char *line
);
retval
unexpected_token(char *arg0
, char *line
);
retval
get_execute_token(char *arg0
, char *line
);
retval
grab_next_file(char *arg0
, char *line
);
retval
set_code_file(char *arg0
, char *line
);
retval
set_build_flags(char *arg0
, char *line
);
retval
do_message(char *arg0
, char *line
);
retval
do_define(char *arg0
, char *line
);
retval
do_undef(char *arg0
, char *line
);
retval
do_ifdef(char *arg0
, char *line
);
retval
do_ifndef(char *arg0
, char *line
);
retval
do_else(char *arg0
, char *line
);
retval
do_endif(char *arg0
, char *line
);
#define COMPAT_NO_ARGS CMD_COMPAT|CMD_NULL_ARGS
#define COMPAT_OPT_ARGS CMD_COMPAT|CMD_OPT_ARGS
{ "version1", disable_cmds
, COMPAT_NO_ARGS
},
{ "version2", enable_cmds
, COMPAT_NO_ARGS
},
{ "build", set_build_cmd
, CMD_OPT_ARGS
| 1 },
{ "depend", grab_depend_line
, 1 },
{ "target", grab_target_line
, 2 },
{ "external", grab_external_line
, 1 },
{ "source{", grab_source
, CMD_OPT_ARGS
},
{ "}source", unexpected_token
, CMD_NULL_ARGS
},
{ "#", comment_line
, COMPAT_OPT_ARGS
},
{ "-", get_source_line
, CMD_COMPAT_ONLY
},
{ "include", grab_next_file
, 1 },
{ "codefile", set_code_file
, 1 },
{ "buildoptions", set_build_flags
, CMD_OPT_ARGS
| 1 },
{ "message", do_message
, CMD_OPT_ARGS
| 1 },
{ "#define", do_define
, 1 },
{ "#undef", do_undef
, 1 },
{ "#ifdef", do_ifdef
, CMD_IFDEF
| 1 },
{ "#ifndef", do_ifndef
, CMD_IFDEF
| 1 },
{ "#else", do_else
, CMD_IFDEF
| CMD_NULL_ARGS
},
{ "#endif", do_endif
, CMD_IFDEF
| CMD_NULL_ARGS
},
fprintf(stderr
, "%s:%d: Malloc failed\n", filename
, line_num
);
get_arg(char *line
, int which
, int *rpos
)
static char arg
[MAXLINE
];
if ((line
== NULL
) || (*line
== 0)) {
while ((which
-- >= 0) && (pos
< end
)) {
strip
= strspn(start
, tokens
);
len
= strcspn(start
, tokens
);
if ((pos
>= end
) && (which
>= 0)) {
strncpy(arg
, start
, len
);
lastarg
= get_arg(line
, argc
+1, NULL
);
automatic_message(char comment
)
printf("%c Warning this is a machine generated file\n", comment
);
printf("%c Changes made here will go away\n", comment
);
/* This is gross, but exists for Version1 compatability. */
"id: %" "Z%%" "M% %" "I% %" "E%\n"
"copyright: Copyright 1989-1997 Sun Microsystems, Inc. All Rights Reserved\n"
"\" /packages/SUNW,builtin-drivers\" find-device\n"
": do-fcode ( str$ -- )\n"
" 2dup 2>r execute-buffer\n"
get_line(char *line
, int from
)
argp
= get_arg(line
, from
, &pos
);
printf("rem_line: '%s'\n", (argp
? argp
: ""));
get_more_source(char *cmd
, char *line
)
printf("get_more_source('%s','%s')\n",
if (*backslash
== '\\') {
printf("%s\n", get_line(line
, 2));
return (CAST(get_more_source
));
return (CAST(get_execute_token
));
get_source_line(char *cmd
, char *line
)
char *arg0
, *argp
, *arg1
, *argn
;
printf("get_source_line('%s','%s')\n",
arg0
= arg1
= argn
= NULL
;
argp
= get_arg(line
, 0, NULL
);
if (argp
) arg0
= strdup(get_arg(line
, 0, NULL
));
argp
= get_arg(line
, 1, NULL
);
if (argp
) arg1
= strdup(argp
);
argp
= get_line(line
, 2);
get_more_source(cmd
, line
);
if (flags
& SOURCE_FLAG
) {
if (flags
& TARGET_FLAG
) {
if (flags
& DEPEND_FLAG
) {
printf("%s: %s\n\t%s %s %s\n\n",
return (CAST(get_more_source(cmd
, line
)));
enable_cmds(char *arg0
, char *line
)
return (CAST(get_execute_token
));
disable_cmds(char *arg0
, char *line
)
return (CAST(get_execute_token
));
set_build_cmd(char *arg0
, char *line
)
if (buildcmd
) free(buildcmd
);
sptr
= get_line(line
, 1);
if ((sptr
== NULL
) || ((sptr
!= NULL
) && (strlen(sptr
) == 0))) {
fprintf(stderr
, "%s:%d: Error, Missing argument\n",
return (CAST(get_execute_token
));
set_code_file(char *arg0
, char *line
)
if (codefile
) free(codefile
);
sptr
= get_line(line
, 1);
if ((sptr
== NULL
) || ((sptr
!= NULL
) && (strlen(sptr
) == 0))) {
fprintf(stderr
, "%s:%d: Error, Missing argument\n",
return (CAST(get_execute_token
));
grab_depend_line(char *arg0
, char *line
)
if (flags
& DEPEND_FLAG
) {
if (!once
++) automatic_message('#');
printf("\ninclude %s\n", get_arg(line
, 1, NULL
));
return (CAST(get_execute_token
));
grab_target_line(char *arg0
, char *line
)
char *cptr
, *dptr
, *source
, *target
, *diname
;
cptr
= get_arg(line
, 1, NULL
);
dptr
= strrchr(cptr
, '/');
diname
= get_arg(line
, 2, NULL
);
cptr
= strrchr(target
, '.');
if (flags
& TARGET_FLAG
) printf("%s.di ", target
);
if (flags
& SOURCE_FLAG
) printf("%s ", source
);
if (flags
& DEPEND_FLAG
) {
printf("\n%s.di: %s %s\n\t%s %s %s\n",
buildcmd
, source
, diname
);
return (CAST(get_execute_token
));
grab_external_line(char *arg0
, char *line
)
if (flags
& TARGET_FLAG
) printf("%s ", get_arg(line
, 1, NULL
));
return (CAST(get_execute_token
));
wait_source_end(char *arg0
, char *line
)
printf("wait_source_end('%s','%s')\n", arg0
, line
);
end
= (strcmp(arg0
, "}source") == 0);
if (flags
& DEPEND_FLAG
) {
if (!end
) printf("%s\n", line
);
return (CAST(wait_source_end
));
return (CAST(get_execute_token
));
grab_source(char *arg0
, char *line
)
static int start_code
= 0;
int codebase
, codeend
, codelen
;
retval (*fn
)(char *, char *);
char *lptr
= strdup(line
);
start
= (strcmp(arg0
, "source{") == 0);
if ((start
) && (start_code
++)) {
fprintf(stderr
, "%s:%d: Warning, unbalanced start{ tokens\n",
(void) get_arg(line
, 1, &codebase
);
args
= get_arg(lptr
, argcount
, &codeend
);
end
= (strcmp(args
, "}source") == 0);
if (!start
) codebase
= 0;
if (!end
) codeend
= strlen(line
);
codelen
= (codeend
-codebase
);
strncpy(lptr
, line
+ codebase
, codelen
);
if (start
&& !once
++) automatic_message('\\');
set_build_flags(char *arg0
, char *line
)
if (flags
& DEPEND_FLAG
) {
printf("\n%s", get_line(line
, 1));
return (CAST(get_execute_token
));
comment_line(char *arg0
, char *line
)
return (CAST(get_execute_token
));
do_message(char *arg0
, char *line
)
fprintf(stderr
, "%s:%d: %s\n",
filename
, line_num
, get_line(line
, 1));
return (CAST(get_execute_token
));
do_define(char *arg0
, char *line
)
define_symbol(get_arg(line
, 1, NULL
), FORTH_DEFINE
);
return (CAST(get_execute_token
));
do_undef(char *arg0
, char *line
)
define_symbol(get_arg(line
, 1, NULL
), FORTH_UNDEF
);
return (CAST(get_execute_token
));
#define defskip (def_state[defdepth] & DEF_SKIP)
static int def_state
[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
def_state_check(int state
, int flag
, char *msg
)
if ((state
& flag
) == 0) {
fprintf(stderr
, "%s:%d: Parse Error, %s\n",
filename
, line_num
, msg
);
if (defdepth
> MAX_DEF_DEPTH
) {
fprintf(stderr
, "%s:%d: too many Nested IFDEF's\n",
do_common_ifdef(char *arg0
, char *line
, int do_true
)
int state
= (DEF_ELSE
| DEF_ENDIF
);
def_state_check(1, 1, "");
state
|= def_state
[defdepth
++] & DEF_SKIP
;
def
= symbol_defined(get_arg(line
, 1, NULL
));
if ((do_true
&& !def
) || (!do_true
&& def
)) {
def_state
[defdepth
] = state
;
do_ifdef(char *arg0
, char *line
)
do_common_ifdef(arg0
, line
, 1);
return (CAST(get_execute_token
));
do_ifndef(char *arg0
, char *line
)
do_common_ifdef(arg0
, line
, 0);
return (CAST(get_execute_token
));
do_else(char *arg0
, char *line
)
def_state_check(def_state
[defdepth
], DEF_ELSE
, "Dangling #else");
def_state
[defdepth
] &= ~DEF_ELSE
;
def_state
[defdepth
] ^= DEF_SKIP
;
def_state
[defdepth
] |= def_state
[defdepth
-1] & DEF_SKIP
;
return (CAST(get_execute_token
));
do_endif(char *arg0
, char *line
)
def_state_check(def_state
[defdepth
], DEF_ENDIF
, "Dangling #endif");
def_state
[defdepth
--] &= ~DEF_ENDIF
;
return (CAST(get_execute_token
));
unexpected_token(char *arg0
, char *line
)
fprintf(stderr
, "%s:%d: bad token '%s'\n", filename
, line_num
, arg0
);
get_execute_token(char *token
, char *line
)
retval (*fn
)(char *p
, char *);
while (cptr
->name
!= NULL
) {
if (strcmp(cptr
->name
, token
) != 0) {
if (((flags
& COMPAT_MODE
) && !(cptr
->flags
& CMD_COMPAT
)) ||
(!(flags
& COMPAT_MODE
) && (cptr
->flags
& CMD_COMPAT_ONLY
)))
unexpected_token(token
, line
);
nargs
= cptr
->flags
& ~CMD_MASK
;
printf("[%d,%d] CMD: '%s' args = %d, argc = %d\n",
defdepth
, defskip
, token
, nargs
, argcount
);
if ((argcount
> nargs
) && (!(cptr
->flags
& CMD_OPT_ARGS
))) {
"%s:%d: Warning, extra arguments for '%s'\n",
filename
, line_num
, token
);
"%s:%d: Missing arguments for '%s'\n",
filename
, line_num
, token
);
if ((flags
& COMPAT_MODE
) && (fn
== unexpected_token
)) {
return (CAST(get_source_line(NULL
, line
)));
if (!(cptr
->flags
& CMD_IFDEF
) && defskip
) {
return (CAST((*fn
)(token
, line
)));
process_file(char *name
, int recurse
)
retval (*process
)(char *line
, char *arg
);
* This is a gross hack! I should have made this entire thing parameter
* driven, instead I chose to use globals :(
* So I need to save and restore them for this cruft to work.
if (flags
& DEPEND_FLAG
) printf("\n%s: %s\n", codefile
, name
);
} else if (flags
& DEPEND_FLAG
) {
if (comment
) printf("\n%c Included from %s\n", comment
, name
);
ifd
= fopen(filename
, "r");
fprintf(stderr
, "%s: unable to open: %s for reading",
process
= get_execute_token
;
line
= fgets(buffer
, MAXLINE
, ifd
);
cptr
= strchr(line
, '\n');
argcount
= count_args(line
);
cptr
= get_arg(line
, 0, NULL
);
if (cptr
) strcpy(cmd
, cptr
);
done
= (line
== NULL
) || feof(ifd
);
process
= (retval (*)()) process(cmd
, line
);
if (comment
) printf("\n%c back to %s\n", comment
, filename
);
grab_next_file(char *arg0
, char *line
)
cptr
= get_arg(line
, 1, NULL
);
if (flags
& DEPEND_FLAG
) {
printf("\n%s: %s\n", codefile
, cptr
);
return (CAST(get_execute_token
));
main(int argc
, char **argv
)
while ((c
= getopt(argc
, argv
, "D:U:SVstdcp")) != EOF
)
define_symbol(optarg
, CMD_DEFINE
);
define_symbol(optarg
, CMD_UNDEF
);
if (!flags
) flags
= SOURCE_FLAG
; else usage();
if (!flags
) flags
= TARGET_FLAG
; else usage();
if (!flags
) flags
= DEPEND_FLAG
; else usage();
if (!flags
) flags
= CODE_FLAG
; else usage();
(void) set_build_cmd(NULL
, "build\t${MAKEDI}");
(void) set_code_file(NULL
, "codefile\tbuiltin.fth");
process_file(srcfile
, 0);
finish_symbols(showsyms
);