#include <signal.h>
#ifdef vms
# include <types.h>
# include <stat.h>
# include <stsdef.h>
# include <descrip.h>
#else
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
#endif
#include <frontend.h>
#include <astp.h>
#include <astp_dmp.h>
#include <checker.h>
#include <command.h>
#include <errors.h>
#include <files.h>
#include <getflags.h>
#include <propagat.h>
#include <y_tab.h>
#include <message.h>
#define CONFIG_SUFFIX ".acf"
#ifndef VMS
#include <errno.h>
#define PCLOSE(stream) \
{ \
char buf[256]; \
\
while (fgets(buf, sizeof(buf), stream) != NULL) ; \
}
#endif
extern int yyparse(
void
);
extern void acf_cleanup(
void
);
extern void acf_init(
boolean *cmd_opt_arr,
void **cmd_val_arr,
char *acf_file
);
#ifdef GNU_LEX_YACC
int yylineno;
int acf_yylineno;
int acf_yynerrs;
int yynerrs;
#endif
static boolean *saved_cmd_opt;
static void **saved_cmd_val;
typedef struct FE_import_file_n_t {
struct FE_import_file_n_t * next;
STRTAB_str_t imported_fn_id;
STRTAB_str_t imported_full_fn_id;
} FE_import_file_n_t;
static FE_import_file_n_t * imported_file_list = NULL;
extern boolean ASTP_parsing_main_idl;
LEX_YACC_EXTERNS;
static void FE_init(void)
{
saved_cmd_opt = NULL;
saved_cmd_val = NULL;
KEYWORDS_init();
NAMETABLE_init();
AST_init();
}
#if defined(CPP)
static void cpp
(
char *cpp_cmd,
char *cpp_opt,
char *file_name,
char *dst_file_name,
char **def_strings,
char **undef_strings,
char **idir_list,
FILE **cpp_output
)
{
#ifdef VMS
boolean paren_flag;
char dir[max_string_len], name[max_string_len], type[max_string_len];
char expanded_file_name[max_string_len];
int system_status;
#endif
char cmd[max_string_len];
cmd[0] = '\0';
strcpy(cmd, cpp_cmd);
strcat(cmd, " ");
#ifdef VMS
strcat(cmd, "/PREPROCESS=");
strcat(cmd, dst_file_name);
strcat(cmd, " ");
#endif
strcat(cmd, cpp_opt);
strcat(cmd, " ");
#ifndef VMS
strcat(cmd, file_name);
#else
FILE_parse(file_name, dir, name, type);
FILE_form_filespec(name, dir, type, (char *)NULL, expanded_file_name);
strcat(cmd, expanded_file_name);
#endif
#ifdef VMS
if (*def_strings)
{
paren_flag = TRUE;
strcat(cmd, " /DEFINE=(");
}
else
paren_flag = FALSE;
#endif
while (*def_strings)
{
#ifndef VMS
strcat(cmd, " -D");
#endif
strcat(cmd, *def_strings++);
#ifdef VMS
strcat(cmd, ",");
#endif
}
#ifdef VMS
if (paren_flag)
cmd[strlen(cmd)-1] = ')';
#endif
#ifdef VMS
if (*undef_strings)
{
paren_flag = TRUE;
strcat(cmd, " /UNDEFINE=(");
}
else
paren_flag = FALSE;
#endif
while (*undef_strings)
{
#ifndef VMS
strcat(cmd, " -U");
#endif
strcat(cmd, *undef_strings++);
#ifdef VMS
strcat(cmd, ",");
#endif
}
#ifdef VMS
if (paren_flag)
cmd[strlen(cmd)-1] = ')';
#endif
if (strcmp(cpp_cmd, CMD_def_cpp_cmd) == 0)
{
#ifdef VMS
if (*idir_list)
{
paren_flag = TRUE;
strcat(cmd, " /INCLUDE_DIRECTORY=(");
}
else
paren_flag = FALSE;
#endif
while (*idir_list)
{
#ifndef VMS
strcat(cmd, " -I");
#endif
strcat(cmd, *idir_list++);
#ifdef VMS
strcat(cmd, ",");
#endif
}
#ifdef VMS
if (paren_flag)
cmd[strlen(cmd)-1] = ')';
#endif
}
if (saved_cmd_opt[opt_verbose])
message_print(NIDL_RUNCPP,cmd);
#ifdef VMS
{
$DESCRIPTOR(vcmd, cmd);
vcmd.dsc$w_length = strlen(cmd);
system_status = LIB$SPAWN(&vcmd);
if (($VMS_STATUS_SEVERITY(system_status) == STS$K_ERROR) ||
($VMS_STATUS_SEVERITY(system_status) == STS$K_SEVERE))
{
idl_error_list_t errvec[2];
errvec[0].msg_id = NIDL_INVOKECPP;
errvec[1].msg_id = NIDL_SYSERRMSG;
errvec[1].arg1 = strerror(EVMSERR,system_status);
error_list(2, errvec, TRUE);
}
}
FILE_open(dst_file_name, cpp_output);
#endif
#ifndef VMS
if ((*cpp_output = popen(cmd, "r")) == 0)
error(NIDL_INVOKECPP);
#endif
}
#endif
static boolean parse_acf
(
boolean *cmd_opt,
void **cmd_val,
char *acf_file
)
{
extern int acf_yyparse(
void
);
extern FILE *acf_yyin;
extern int acf_yylineno;
extern int acf_yynerrs;
#ifndef GNU_LEX_YACC
extern int acf_yyprevious;
#endif
extern char acf_yytext[];
FILE **yyin_sp;
int *yylineno_sp;
int *yynerrs_sp;
char *yytext_sp;
char temp_path_name[max_string_len];
if (cmd_opt[opt_verbose])
message_print(NIDL_PROCESSACF, acf_file);
if (cmd_opt[opt_confirm])
return true;
yylineno = 1;
#ifndef GNU_LEX_YACC
yyprevious = (int)'\n';
yysptr= yysbuf;
#endif
acf_yylineno = 1;
#ifndef GNU_LEX_YACC
acf_yyprevious = (int)'\n';
#endif
yyin_sp = yyin_p;
yylineno_sp = yylineno_p;
yynerrs_sp = yynerrs_p;
yytext_sp = yytext_p;
yyin_p = &acf_yyin;
yylineno_p = &acf_yylineno;
yynerrs_p = &acf_yynerrs;
yytext_p = acf_yytext;
acf_init(cmd_opt, cmd_val, acf_file);
#if defined(CPP)
if (cmd_opt[opt_cpp])
{
#ifdef VMS
char temp_file_name[max_string_len];
ASSERTION(max_string_len > L_tmpnam);
FILE_parse(acf_file, (char *)NULL, temp_file_name, (char *)NULL);
FILE_form_filespec(temp_file_name, "sys$scratch:", ".acf$tmp",
(char *)NULL, temp_path_name);
#else
temp_path_name[0] = '\0';
#endif
cpp((char *)cmd_val[opt_cpp],
(char *)cmd_val[opt_cpp_opt],
acf_file,
temp_path_name,
(char **)cmd_val[opt_cpp_def],
(char **)cmd_val[opt_cpp_undef],
(char **)cmd_val[opt_idir],
&acf_yyin);
}
else
#endif
FILE_open(acf_file, &acf_yyin);
#ifdef GNU_LEX_YACC
acf_yynerrs = 0;
#endif
if (acf_yyparse() != 0 && acf_yynerrs == 0)
log_error(acf_yylineno, NIDL_COMPABORT);
acf_cleanup();
#ifndef VMS
if (cmd_opt[opt_cpp])
PCLOSE(acf_yyin)
else
fclose(acf_yyin);
#endif
#ifdef VMS
fclose(acf_yyin);
if (cmd_opt[opt_cpp])
delete(temp_path_name);
#endif
yyin_p = yyin_sp;
yylineno_p = yylineno_sp;
yynerrs_p = yynerrs_sp;
yytext_p = yytext_sp;
if (acf_yynerrs != 0)
return false;
return true;
}
static boolean already_imported
(
STRTAB_str_t import_path_id
)
{
char new_import_full_fn[max_string_len];
STRTAB_str_t new_import_full_fn_id;
STRTAB_str_t new_import_fn_id;
char base_file_name[max_string_len];
char base_file_ext[max_string_len];
struct stat stat_buf;
FE_import_file_n_t * imported_file;
char ** idir_list;
boolean alr_imp;
char * file_name;
STRTAB_str_to_string (import_path_id, &file_name);
idir_list = (char **)saved_cmd_val[opt_idir];
if (!FILE_lookup(file_name, idir_list, &stat_buf, new_import_full_fn))
return false;
new_import_full_fn_id = STRTAB_add_string(new_import_full_fn);
if (!FILE_parse(new_import_full_fn, NULL, base_file_name, base_file_ext))
return false;
strncat(base_file_name, base_file_ext, max_string_len);
new_import_fn_id = STRTAB_add_string(base_file_name);
alr_imp = false;
imported_file = imported_file_list;
while ((imported_file != NULL) && (!alr_imp))
{
if (new_import_fn_id == imported_file->imported_fn_id)
{
alr_imp = true;
}
imported_file = imported_file -> next;
}
if (!alr_imp)
{
imported_file = (FE_import_file_n_t *) MALLOC (sizeof(FE_import_file_n_t));
imported_file -> imported_fn_id = new_import_fn_id;
imported_file -> imported_full_fn_id = new_import_full_fn_id;
imported_file -> next = imported_file_list;
imported_file_list = imported_file;
}
return alr_imp;
}
static boolean parse
(
boolean *cmd_opt,
void **cmd_val,
STRTAB_str_t idl_sid,
boolean idir_valid,
AST_interface_n_t **int_p
)
{
extern FILE *yyin;
extern int yylineno;
extern char yytext[];
char *sf;
char full_path_name[max_string_len];
char temp_path_name[max_string_len];
STRTAB_str_t full_pn_id;
char **idir_list;
char file_dir[max_string_len];
boolean file_dir_is_cwd;
char file_name[max_string_len];
char acf_file[max_string_len];
char full_acf_name[max_string_len];
boolean acf_exists;
struct stat stat_buf;
int i = 0;
if (saved_cmd_opt == NULL)
saved_cmd_opt = cmd_opt;
if (saved_cmd_val == NULL)
saved_cmd_val = cmd_val;
if (idir_valid)
idir_list = (char **)cmd_val[opt_idir];
else
idir_list = (char **)NULL;
if (idl_sid == STRTAB_NULL_STR)
full_path_name[0] = '\0';
else
{
STRTAB_str_to_string(idl_sid, &sf);
if (!FILE_lookup(sf, idir_list, &stat_buf, full_path_name))
{
error(NIDL_FILENOTFND, sf);
return false;
}
}
if (cmd_opt[opt_verbose] && !ASTP_parsing_main_idl)
message_print(NIDL_IMPORTIDL, full_path_name);
#if defined(CPP)
if (cmd_opt[opt_cpp])
{
#ifdef VMS
char temp_file_name[max_string_len];
ASSERTION(max_string_len > L_tmpnam);
FILE_parse(full_path_name, (char *)NULL, temp_file_name, (char *)NULL);
FILE_form_filespec(temp_file_name, "sys$scratch:", ".idl$tmp",
(char *)NULL, temp_path_name);
#else
temp_path_name[0] = '\0';
#endif
cpp((char *)cmd_val[opt_cpp],
(char *)cmd_val[opt_cpp_opt],
full_path_name,
temp_path_name,
(char **)cmd_val[opt_cpp_def],
(char **)cmd_val[opt_cpp_undef],
(char **)cmd_val[opt_idir],
&yyin);
}
else
#endif
if (full_path_name[0] == '\0')
yyin = stdin;
else
FILE_open(full_path_name, &yyin);
set_name_for_errors((full_path_name[0] == '\0') ? "stdin" : full_path_name);
yylineno = 1;
#ifndef GNU_LEX_YACC
yyprevious = (int)'\n';
yysptr= yysbuf;
#endif
yyin_p = &yyin;
yylineno_p = &yylineno;
yynerrs_p = &yynerrs;
yytext_p = yytext;
#ifdef GNU_LEX_YACC
yynerrs = 0;
#endif
if (yyparse() != 0 && error_count == 0)
log_error(yylineno, NIDL_COMPABORT);
*int_p = the_interface;
#ifndef VMS
if (cmd_opt[opt_cpp])
PCLOSE(yyin)
else
fclose(yyin);
#endif
#ifdef VMS
fclose(yyin);
if (cmd_opt[opt_cpp])
delete(temp_path_name);
#endif
if (error_count != 0)
return false;
if (the_interface != NULL)
{
full_pn_id = STRTAB_add_string(full_path_name);
the_interface->fe_info->file = full_pn_id;
}
else
{
if (ASTP_parsing_main_idl) return false;
}
if (!FILE_parse(full_path_name, file_dir, file_name, (char *)NULL))
return false;
if (!FILE_form_filespec(file_name, (char *)NULL, CONFIG_SUFFIX,
(char *)NULL, acf_file))
return false;
#ifdef UNIX
if (strcmp(file_name, acf_file) == 0)
strcat(acf_file, CONFIG_SUFFIX);
#endif
idir_list = (char **)cmd_val[opt_idir];
file_dir_is_cwd = FILE_is_cwd(file_dir);
if (!file_dir_is_cwd)
{
for (i = 0 ; idir_list[i] != NULL ; i++)
;
idir_list[i] = file_dir;
idir_list[i+1] = NULL;
}
acf_exists = FILE_lookup(acf_file, idir_list, &stat_buf, full_acf_name);
#ifdef VMS
if (!acf_exists)
{
if (!FILE_form_filespec((char *)NULL, (char *)NULL, CONFIG_SUFFIX,
full_path_name, acf_file))
return false;
acf_exists = FILE_lookup(acf_file, (char **)NULL, &stat_buf,
full_acf_name);
}
#endif
if (!file_dir_is_cwd)
idir_list[i] = NULL;
if (!acf_exists)
return true;
if (!parse_acf(cmd_opt, cmd_val, full_acf_name))
return false;
return true;
}
AST_interface_n_t *FE_parse_import
(
STRTAB_str_t new_input
)
{
LEX_YACC_STATE_BUFFER(saved_state);
boolean saved_ASTP_parsing_main_idl;
char saved_current_file[ PATH_MAX ];
STRTAB_str_t saved_error_file_name_id;
AST_interface_n_t *int_p;
int saved_interface_pointer_class;
AST_interface_n_t *saved_interface;
if (already_imported (new_input))
return (AST_interface_n_t *)NULL;
SAVE_LEX_YACC_STATE(saved_state);
saved_ASTP_parsing_main_idl = ASTP_parsing_main_idl;
inq_name_for_errors(saved_current_file);
saved_error_file_name_id = error_file_name_id;
saved_interface = the_interface;
saved_interface_pointer_class = interface_pointer_class;
the_interface = NULL;
interface_pointer_class = 0;
ASTP_parsing_main_idl = false;
parse(saved_cmd_opt, saved_cmd_val, new_input, true, &int_p);
the_interface = saved_interface;
interface_pointer_class = saved_interface_pointer_class;
RESTORE_LEX_YACC_STATE(saved_state);
ASTP_parsing_main_idl = saved_ASTP_parsing_main_idl;
set_name_for_errors(saved_current_file);
error_file_name_id = saved_error_file_name_id;
return int_p;
}
static boolean parse_idl
(
boolean *cmd_opt,
void **cmd_val,
STRTAB_str_t idl_sid,
AST_interface_n_t **int_p
)
{
boolean status;
FE_import_file_n_t *imported_file;
char *file_name;
char imported_fn[max_string_len];
struct stat stat_buf;
char file_name_part[max_string_len];
char file_type_part[max_string_len];
boolean name_warning = false;
if (idl_sid != STRTAB_NULL_STR)
{
STRTAB_str_to_string(idl_sid, &file_name);
FILE_parse(file_name, NULL, file_name_part, file_type_part);
strcat(file_name_part, file_type_part);
if (!strcmp(file_name_part,"iovector.idl")) name_warning = true;
else if (!strcmp(file_name_part,"lbase.idl")) name_warning = true;
else if (!strcmp(file_name_part,"nbase.idl")) name_warning = true;
else if (!strcmp(file_name_part,"ncastat.idl")) name_warning = true;
else if (!strcmp(file_name_part,"ndrold.idl")) name_warning = true;
else if (!strcmp(file_name_part,"rpc.idl")) name_warning = true;
else if (!strcmp(file_name_part,"rpcsts.idl")) name_warning = true;
else if (!strcmp(file_name_part,"rpctypes.idl")) name_warning = true;
else if (!strcmp(file_name_part,"twr.idl")) name_warning = true;
else if (!strcmp(file_name_part,"uuid.idl")) name_warning = true;
if (name_warning)
message_print(NIDL_SYSIDLNAME,file_name);
if (FILE_lookup(file_name, (char **)NULL, &stat_buf, imported_fn))
{
imported_file = (FE_import_file_n_t *)
MALLOC(sizeof(FE_import_file_n_t));
imported_file->imported_fn_id = STRTAB_add_string(file_name_part);
imported_file->imported_full_fn_id = STRTAB_add_string(imported_fn);
imported_file->next = imported_file_list;
imported_file_list = imported_file;
}
}
*int_p = NULL;
status = parse(cmd_opt, cmd_val, idl_sid, false, int_p);
if (*int_p == NULL)
status = false;
return status;
}
boolean FE_main
(
boolean *cmd_opt,
void **cmd_val,
STRTAB_str_t idl_sid,
AST_interface_n_t **int_p
)
{
boolean status;
FE_init();
status = parse_idl(cmd_opt, cmd_val, idl_sid, int_p);
#ifdef DUMPERS
if (cmd_opt[opt_dump_nametbl])
NAMETABLE_dump_tab();
#endif
#ifdef DUMPERS
if (cmd_opt[opt_dump_ast])
AST_dump_interface(*int_p);
#endif
if (status && !cmd_opt[opt_confirm])
status = PROP_main(cmd_opt, cmd_val, *int_p);
if (status)
{
if (!cmd_opt[opt_confirm])
status = CHECKER_main(cmd_opt, cmd_val, *int_p);
}
else
message_print(NIDL_NOSEMCHECK);
#ifdef DUMPERS
if (cmd_opt[opt_dump_ast_after])
AST_dump_interface(*int_p);
#endif
set_name_for_errors(NULL);
return status;
}