Commit feade998 authored by Elemer Lelik's avatar Elemer Lelik
Browse files

Sync with 5.4.3

parent 2b4bcb7a
......@@ -256,7 +256,7 @@ extern int add_include_file(const std::string& filename)
expstring_t currdirname, dirname, filenamepart, basedir;
currdirname = get_dir_from_path(get_cfg_preproc_current_file().c_str());
dirname = get_dir_from_path(filename.c_str());
basedir = get_absolute_dir(dirname, currdirname);
basedir = get_absolute_dir(dirname, currdirname, 1);
Free(currdirname);
Free(dirname);
filenamepart = get_file_from_path(filename.c_str());
......@@ -294,7 +294,7 @@ extern int preproc_parse_file(const char *filename, string_chain_t **filenames,
config_preproc_defines=string_map_new();
{
expstring_t dirname=get_dir_from_path(filename);
expstring_t basedir=get_absolute_dir(dirname, NULL);
expstring_t basedir=get_absolute_dir(dirname, NULL, 1);
expstring_t filenamepart=get_file_from_path(filename);
Free(dirname);
if (basedir == NULL) {
......
......@@ -129,7 +129,7 @@ expstring_t compose_path_name(const char *dir_name,
} else return mcopystr(file_name);
}
expstring_t get_absolute_dir(const char *dir_name, const char *base_dir)
expstring_t get_absolute_dir(const char *dir_name, const char *base_dir, const int with_error)
{
expstring_t ret_val;
/* save the working directory */
......@@ -142,12 +142,18 @@ expstring_t get_absolute_dir(const char *dir_name, const char *base_dir)
return NULL;
}
}
if (dir_name != NULL && set_working_dir(dir_name)) {
if (dir_name != NULL && with_error && set_working_dir(dir_name)) {
/* there was an error: go back to initial_dir */
set_working_dir(initial_dir);
Free(initial_dir);
return NULL;
}
if (dir_name != NULL && !with_error && chdir(dir_name)) {
//No error sign
errno = 0;
Free(initial_dir);
return NULL;
}
ret_val = get_working_dir();
/* restore the working directory */
set_working_dir(initial_dir);
......@@ -174,9 +180,9 @@ expstring_t get_relative_dir(const char *dir_name, const char *base_dir)
{
expstring_t ret_val = NULL;
/* canonize dir_name and the base directory */
expstring_t canonized_dir_name = get_absolute_dir(dir_name, base_dir);
expstring_t canonized_dir_name = get_absolute_dir(dir_name, base_dir, 1);
expstring_t canonized_base_dir = base_dir != NULL ?
get_absolute_dir(base_dir, NULL) : get_working_dir();
get_absolute_dir(base_dir, NULL, 1) : get_working_dir();
size_t i, last_slash = 0;
if (canonized_dir_name == NULL || canonized_base_dir == NULL) {
/* an error occurred */
......
......@@ -68,8 +68,10 @@ extern expstring_t compose_path_name(const char *dir_name,
* (i.e. symlinks in it are resolved). NULL pointer returned in case of error.
* The string returned shall be deallocated by the caller using \a Free().
* Note: The working directory of the current process might change during the
* function call, but it is restored before the function returns. */
extern expstring_t get_absolute_dir(const char *dir_name, const char *base_dir);
* function call, but it is restored before the function returns.
* If the with_error is true, then it won't sign error when set_working_dir
* is called.*/
extern expstring_t get_absolute_dir(const char *dir_name, const char *base_dir, const int with_error);
/** Converts \a dir_name to a relative path name based on \a working_dir. If
* \a working_dir is NULL the current working directory of the process is used.
......
......@@ -11,7 +11,7 @@
/* Version numbers */
#define TTCN3_MAJOR 5
#define TTCN3_MINOR 4
#define TTCN3_PATCHLEVEL 2
#define TTCN3_PATCHLEVEL 3
//#define TTCN3_BUILDNUMBER 0
/* The aggregated version number must be set manually since some stupid
......@@ -22,7 +22,7 @@
* TTCN3_VERSION = TTCN3_MAJOR * 1000000 + TTCN3_MINOR * 10000 +
* TTCN3_PATCHLEVEL * 100 + TTCN3_BUILDNUMBER
*/
#define TTCN3_VERSION 50402
#define TTCN3_VERSION 50403
/* A monotonically increasing version number.
* An official release is deemed to have the highest possible build number (99)
......
......@@ -1610,6 +1610,9 @@ namespace Common {
case T_SET_T:
case T_ANYTYPE:
break;
case T_COMPONENT:
ref->error("Referencing fields of a component is not allowed");
return 0;
default:
ref->error("Invalid field reference `%s': type `%s' "
"does not have fields", id.get_dispname().c_str(),
......@@ -2777,11 +2780,14 @@ namespace Common {
comp_type->jsonattrib->metainfo_unbound = true;
}
}
else if (NULL == parent || (T_SEQ_T != parent->typetype &&
T_SET_T != parent->typetype)) {
// only allowed if it's a field of a record/set
else if (T_SEQOF != get_type_refd_last()->typetype &&
T_SETOF != get_type_refd_last()->typetype &&
T_ARRAY != get_type_refd_last()->typetype &&
(NULL == parent || (T_SEQ_T != parent->typetype &&
T_SET_T != parent->typetype))) {
// only allowed if it's an array type or a field of a record/set
error("Invalid attribute 'metainfo for unbound', requires record, set, "
"or field of a record or set");
"record of, set of, array or field of a record or set");
}
}
}
......
......@@ -395,6 +395,7 @@ void Type::parse_attributes()
case T_SEQ_T:
case T_SET_T:
case T_ANYTYPE:
case T_ARRAY:
if(rawattrib==NULL) {rawattrib= new RawAST; new_raw=true;}
if(textattrib==NULL){textattrib= new TextAST; new_text=true;}
if(xerattrib==NULL) {xerattrib = new XerAttributes; new_xer = true;}
......@@ -459,7 +460,8 @@ void Type::parse_attributes()
// This should be bool, but gcc 4.1.2-sol8 generates incorrect code
// with -O2 :(
const int se_of = (typetype == T_SEQOF || typetype == T_SETOF);
const int se_of = (typetype == T_SEQOF || typetype == T_SETOF ||
typetype == T_ARRAY);
const size_t nof_comps = se_of ? 1 : get_nof_comps();
// Distribute the attributes with qualifiers to the components.
......@@ -4070,6 +4072,9 @@ bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
alt_type->chk_this_value_ref(alt_value);
self_ref |= alt_type->chk_this_value(alt_value, lhs, expected_value,
incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
if (alt_value->get_valuetype() == Value::V_NOTUSED) {
value->set_valuetype(Value::V_NOTUSED);
}
break;}
default:
value->error("%s value was expected for type `%s'",
......@@ -4159,6 +4164,7 @@ bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_
CompField *last_cf = 0;
size_t next_index = 0;
size_t seq_index = 0;
bool is_empty = n_type_comps > 0; // don't do this check if the record type has no fields
for (size_t v_i = 0; v_i < n_value_comps; v_i++, seq_index++) {
NamedValue *nv = value->get_se_comp_byIndex(v_i);
const Identifier& value_id = nv->get_name();
......@@ -4226,8 +4232,16 @@ bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_
type->chk_this_value_ref(comp_value);
self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
if (comp_value->get_valuetype() != Value::V_NOTUSED) {
is_empty = false;
}
}
if (is_empty) {
// all of the record's fields are unused (-), set the record to unused
// to avoid unnecessary code generation
value->set_valuetype(Value::V_NOTUSED);
}
if (!incomplete_allowed || implicit_omit) {
else if (!incomplete_allowed || implicit_omit) {
for (size_t i = 0; i < n_type_comps; i++) {
const Identifier& id = get_comp_byIndex(i)->get_name();
if (!comp_map.has_key(id.get_name())) {
......@@ -4251,6 +4265,7 @@ bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_
map<string, NamedValue> comp_map;
size_t n_type_comps = get_nof_comps();
size_t n_value_comps = value->get_nof_comps();
bool is_empty = n_type_comps > 0; // don't do this check if the set type has no fields
for(size_t v_i = 0; v_i < n_value_comps; v_i++) {
NamedValue *nv = value->get_se_comp_byIndex(v_i);
const Identifier& value_id = nv->get_name();
......@@ -4282,8 +4297,16 @@ bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_
type->chk_this_value_ref(comp_value);
self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
if (comp_value->get_valuetype() != Value::V_NOTUSED) {
is_empty = false;
}
}
if (is_empty) {
// all of the set's fields are unused (-), set the set to unused to avoid
// unnecessary code generation
value->set_valuetype(Value::V_NOTUSED);
}
if (!incomplete_allowed || implicit_omit) {
else if (!incomplete_allowed || implicit_omit) {
for (size_t i = 0; i < n_type_comps; i++) {
const Identifier& id = get_comp_byIndex(i)->get_name();
if(!comp_map.has_key(id.get_name())) {
......@@ -5460,7 +5483,7 @@ bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
t_comp->set_my_governor(this);
chk_this_template_ref(t_comp);
self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
omit_in_value_list ? OMIT_ALLOWED : OMIT_NOT_ALLOWED,
omit_in_value_list ? allow_omit : OMIT_NOT_ALLOWED,
ANY_OR_OMIT_ALLOWED, sub_chk, implicit_omit, lhs);
if(temptype==Ttcn::Template::COMPLEMENTED_LIST &&
t_comp->get_template_refd_last()->get_templatetype() ==
......
......@@ -2467,6 +2467,9 @@ namespace Common {
u.val_Real = i_mant * pow(static_cast<double>(i_base),
static_cast<double>(i_exp));
break; }
case V_NOTUSED:
clean_up();
break;
default:
FATAL_ERROR("Value::set_valuetype()");
} // switch
......@@ -2535,6 +2538,15 @@ namespace Common {
FATAL_ERROR("Value::set_valuetype()");
}
break;
case V_SET:
case V_CHOICE:
if (p_valuetype == V_NOTUSED) {
clean_up();
}
else {
FATAL_ERROR("Value::set_valuetype()");
}
break;
case V_TTCN3_NULL:
switch (p_valuetype) {
case V_DEFAULT_NULL:
......@@ -5927,8 +5939,8 @@ error:
if (!governor) {
string str;
ti->append_stringRepr( str);
ti->error("Cannot determine the argument type of %s in the`%s' operation.\n"
"If type is known, use valuof(<type>: %s) as argument.",
ti->error("Cannot determine the argument type of %s in the `%s' operation.\n"
"If type is known, use valueof(<type>: %s) as argument.",
str.c_str(), get_opname(), str.c_str());
set_valuetype(V_ERROR);
}
......@@ -11097,6 +11109,9 @@ error:
FATAL_ERROR("Value::generate_code_init()");
}
break;
case V_NOTUSED:
// unbound value, don't generate anything
break;
default:
FATAL_ERROR("Value::generate_code_init()");
}
......@@ -11672,8 +11687,7 @@ error:
expr->expr=mputstr(expr->expr, ".is_bound()");
break;
case OPTYPE_ISPRESENT:
expr->expr=mputprintf(expr->expr, ".is_present(%s)",
omit_in_value_list ? "TRUE" : "");
expr->expr=mputprintf(expr->expr, ".is_present()");
break;
case OPTYPE_SIZEOF:
expr->expr=mputstr(expr->expr, ".size_of()");
......@@ -12878,6 +12892,9 @@ error:
FATAL_ERROR("Value::has_single_expr()");
case V_INT:
return u.val_Int->is_native_fit();
case V_NOTUSED:
// should only happen when generating code for an unbound record/set value
return false;
default:
// other value types (literal values) do not need temporary reference
return true;
......
......@@ -66,7 +66,6 @@ namespace Common {
/** value type */
enum valuetype_t {
V_ERROR, /**< erroneous */
V_NULL, /**< NULL (for ASN.1 NULL type, also in TTCN-3) */
......
......@@ -3,7 +3,7 @@
compiler \- TTCN-3 and ASN.1 to C++ translator
.SH SYNOPSIS
.B compiler
.RB "[\| " \-abcdfgijlLMpqrRsStuwxXyY " \|]"
.RB "[\| " \-abcdEfgijlLMpqrRsStuwxXyY " \|]"
.RB "[\| " \-V
.IR " verb_level" " \|]"
.RB "[\| " \-K
......@@ -81,6 +81,10 @@ fields with DEFAULT values as
.I omit
in TTCN-3.
.TP
.B \-E
Instructs the variant attribute parser to display warnings instead of errors
for unrecognized/erroneous attributes.
.TP
.B \-f
Forces the compiler to
.I overwrite
......
......@@ -53,7 +53,7 @@ void def_encdec(const char *p_classname,
"int XER_encode(const XERdescriptor_t&, TTCN_Buffer&, unsigned int, int, "
"embed_values_enc_struct_t*) const;\n"
"int XER_decode(const XERdescriptor_t&, XmlReaderWrap&, unsigned int, "
"embed_values_dec_struct_t*);\n"
"unsigned int, embed_values_dec_struct_t*);\n"
"static boolean can_start(const char *name, const char *uri, "
"XERdescriptor_t const& xd, unsigned int);\n"
"%s"
......@@ -217,7 +217,7 @@ void def_encdec(const char *p_classname,
" for (int rd_ok=reader.Read(); rd_ok==1; rd_ok=reader.Read()) {\n"
" if (reader.NodeType() == XML_READER_TYPE_ELEMENT) break;\n"
" }\n"
" XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, 0);\n"
" XER_decode(*(p_td.xer), reader, XER_coding | XER_TOPLEVEL, XER_NONE, 0);\n"
" size_t bytes = reader.ByteConsumed();\n"
" p_buf.set_pos(bytes);\n"
" break;}\n"
......
......@@ -677,7 +677,7 @@ void defEnumClass(const enum_def *edef, output_struct *output)
"// written by %s in " __FILE__ " at %d\n"
#endif
"int %s::XER_decode(const XERdescriptor_t& p_td, XmlReaderWrap& p_reader,"
" unsigned int p_flavor, embed_values_dec_struct_t*)\n"
" unsigned int p_flavor, unsigned int /*p_flavor2*/, embed_values_dec_struct_t*)\n"
"{\n"
" int rd_ok = 1, type;\n"
......
......@@ -71,7 +71,8 @@ boolean generate_skeleton = FALSE, force_overwrite = FALSE,
use_runtime_2 = FALSE, gcc_compat = FALSE, asn1_xer = FALSE,
check_subtype = TRUE, suppress_context = FALSE, display_up_to_date = FALSE,
implicit_json_encoding = FALSE, json_refs_for_all_types = TRUE,
force_gen_seof = FALSE, omit_in_value_list = FALSE;
force_gen_seof = FALSE, omit_in_value_list = FALSE,
warnings_for_bad_variants = FALSE;
// Default code splitting mode is set to 'no splitting'.
CodeGenHelper::split_type code_splitting_mode = CodeGenHelper::SPLIT_NONE;
......@@ -224,7 +225,7 @@ char *canonize_input_file(const char *path_name)
break;
}
char *dir_name = get_dir_from_path(path_name);
char *abs_dir = get_absolute_dir(dir_name, NULL);
char *abs_dir = get_absolute_dir(dir_name, NULL, true);
Free(dir_name);
char *file_name = get_file_from_path(path_name);
char *ret_val = compose_path_name(abs_dir, file_name);
......@@ -360,7 +361,7 @@ static boolean is_valid_asn1_filename(const char* file_name)
static void usage()
{
fprintf(stderr, "\n"
"usage: %s [-abcdfgijlLOpqrRsStuwxXyY] [-K file] [-z file] [-V verb_level]\n"
"usage: %s [-abcdEfgijlLOpqrRsStuwxXyY] [-K file] [-z file] [-V verb_level]\n"
" [-o dir] [-U none|type] [-P modulename.top_level_pdu_name] [-Q number] ...\n"
" [-T] module.ttcn [-A] module.asn ...\n"
" or %s -v\n"
......@@ -371,6 +372,7 @@ static void usage()
" -b: disable BER encoder/decoder functions\n"
" -c: write out checksums in case of error\n"
" -d: treat default fields as omit\n"
" -E: display only warnings for unrecognized encoding variants\n"
" -f: force overwriting of output files\n"
" -g: emulate GCC error/warning message format\n"
" -i: use only line numbers in error/warning messages\n"
......@@ -455,7 +457,8 @@ int main(int argc, char *argv[])
dflag = false, Xflag = false, Rflag = false, gflag = false, aflag = false,
s0flag = false, Cflag = false, yflag = false, Uflag = false, Qflag = false,
Sflag = false, Kflag = false, jflag = false, zflag = false, Fflag = false,
Mflag = false, errflag = false, print_usage = false, ttcn2json = false;
Mflag = false, Eflag = false, errflag = false, print_usage = false,
ttcn2json = false;
CodeGenHelper cgh;
......@@ -547,7 +550,7 @@ int main(int argc, char *argv[])
if (!ttcn2json) {
for ( ; ; ) {
int c = getopt(argc, argv, "aA:C:K:LP:T:V:bcdfFgilMo:YpqQ:rRs0StuU:vwxXjyz:-");
int c = getopt(argc, argv, "aA:bcC:dEfFgijK:lLMo:pP:qQ:rRsStT:uU:vV:wxXyYz:0-");
if (c == -1) break;
switch (c) {
case 'a':
......@@ -714,6 +717,10 @@ int main(int argc, char *argv[])
SET_FLAG(M);
omit_in_value_list = TRUE;
break;
case 'E':
SET_FLAG(E);
warnings_for_bad_variants = TRUE;
break;
case 'Q': {
long max_errs;
......@@ -758,7 +765,7 @@ int main(int argc, char *argv[])
if (Aflag || Lflag || Pflag || Tflag || Vflag || Yflag ||
bflag || fflag || iflag || lflag || oflag || pflag || qflag ||
rflag || sflag || tflag || uflag || wflag || xflag || Xflag || Rflag ||
Uflag || yflag || Kflag || jflag || zflag || Fflag || Mflag) {
Uflag || yflag || Kflag || jflag || zflag || Fflag || Mflag || Eflag) {
errflag = true;
print_usage = true;
}
......
......@@ -36,7 +36,7 @@ extern boolean generate_skeleton, force_overwrite, include_line_info,
output_only_linenum, default_as_optional, use_runtime_2, gcc_compat, asn1_xer,
check_subtype, suppress_context, enable_set_bound_out_param, display_up_to_date,
implicit_json_encoding, json_refs_for_all_types, force_gen_seof,
omit_in_value_list;
omit_in_value_list, warnings_for_bad_variants;
extern const char *expected_platform;
......
......@@ -238,6 +238,8 @@ struct makefile_struct {
boolean suppresswarnings;
boolean outparamboundness;
boolean omit_in_value_list;
boolean warnings_for_bad_variants;
boolean disable_predef_ext_folder;
struct string_list* solspeclibraries; /* not owned */
struct string_list* sol8speclibraries; /* not owned */
struct string_list* linuxspeclibraries; /* not owned */
......@@ -301,6 +303,7 @@ static void init_makefile_struct(struct makefile_struct *makefile)
makefile->prep_defines = NULL;
makefile->outparamboundness = FALSE;
makefile->omit_in_value_list = FALSE;
makefile->warnings_for_bad_variants = FALSE;
makefile->solspeclibraries = NULL;
makefile->sol8speclibraries = NULL;
makefile->linuxspeclibraries = NULL;
......@@ -518,7 +521,7 @@ static char *get_dir_name(const char *path_name, const char *working_dir)
{
char *dir_name = get_dir_from_path(path_name);
if (dir_name != NULL) {
char *absolute_dir = get_absolute_dir(dir_name, working_dir);
char *absolute_dir = get_absolute_dir(dir_name, working_dir, TRUE);
Free(dir_name);
if (absolute_dir == NULL || working_dir == NULL) {
/* an error occurred */
......@@ -1975,13 +1978,13 @@ static void print_makefile(struct makefile_struct *makefile)
"AR = ar\n"
"ARFLAGS = \n\n"
"# Flags for the TTCN-3 and ASN.1 compiler:\n"
"COMPILER_FLAGS =%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n\n"
"COMPILER_FLAGS =%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n\n"
"# Execution mode: (either ttcn3 or ttcn3-parallel)\n"
"TTCN3_LIB = ttcn3%s%s%s\n\n"
#ifdef LICENSE
"# The path of your OpenSSL installation:\n"
"# If you do not have your own one, leave it unchanged.\n"
"OPENSSL_DIR = $(TTCN3_DIR)\n\n"
"%sOPENSSL_DIR = $(TTCN3_DIR)\n\n"
#endif
"# The path of your libxml2 installation:\n"
"# If you do not have your own one, leave it unchanged.\n"
......@@ -2012,12 +2015,16 @@ static void print_makefile(struct makefile_struct *makefile)
(makefile->suppresswarnings ? " -w" : ""),
(makefile->outparamboundness ? " -Y" : ""),
(makefile->omit_in_value_list ? " -M" : ""),
(makefile->warnings_for_bad_variants ? " -E" : ""),
(makefile->tcov_file_name ? makefile->tcov_file_name : ""),
(makefile->profiled_file_list ? " -z $(PROFILED_FILE_LIST)" : ""),
/* end of COMPILER FLAGS */
(makefile->use_runtime_2 ? "-rt2" : ""), /* TTCN3_LIB */
(makefile->single_mode ? "" : "-parallel"),
(makefile->dynamic ? "-dynamic": "")
#ifdef LICENSE
,(makefile->disable_predef_ext_folder ? "# " : "")
#endif
);
if (!makefile->gnu_make) {
fputs("# Note: you can set any directory except ./archive\n", fp);
......@@ -3719,8 +3726,8 @@ static void generate_makefile(size_t n_arguments, char *arguments[],
const char* cxxcompiler, const char* optlevel, const char* optflags, boolean disableber, boolean disableraw, boolean disabletext,
boolean disablexer, boolean disablejson, boolean forcexerinasn, boolean defaultasomit, boolean gccmsgformat,
boolean linenumbersonlymsg, boolean includesourceinfo, boolean addsourcelineinfo, boolean suppresswarnings,
boolean outparamboundness, boolean omit_in_value_list, struct string_list* solspeclibraries, struct string_list* sol8speclibraries,
struct string_list* linuxspeclibraries, struct string_list* freebsdspeclibraries,
boolean outparamboundness, boolean omit_in_value_list, boolean warnings_for_bad_variants, boolean disable_predef_ext_folder, struct string_list* solspeclibraries,
struct string_list* sol8speclibraries, struct string_list* linuxspeclibraries, struct string_list* freebsdspeclibraries,
struct string_list* win32speclibraries, const char* ttcn3preprocessor, struct string_list* linkerlibraries,
struct string_list* additionalObjects, struct string_list* linkerlibsearchpath, char* generatorCommandOutput,
struct string2_list* target_placement_list)
......@@ -3770,6 +3777,8 @@ static void generate_makefile(size_t n_arguments, char *arguments[],
makefile.suppresswarnings = suppresswarnings;
makefile.outparamboundness = outparamboundness;
makefile.omit_in_value_list = omit_in_value_list;
makefile.warnings_for_bad_variants = warnings_for_bad_variants;
makefile.disable_predef_ext_folder = disable_predef_ext_folder;
makefile.solspeclibraries = solspeclibraries;
makefile.sol8speclibraries = sol8speclibraries;
makefile.linuxspeclibraries = linuxspeclibraries;
......@@ -3904,7 +3913,7 @@ static void generate_makefile(size_t n_arguments, char *arguments[],
static void usage(void)
{
fprintf(stderr, "\n"
"usage: %s [-abc" C_flag "dDfFglLmMprRstTVwWXZ] [-K file] [-z file ] [-P dir]"
"usage: %s [-abc" C_flag "dDEfFglLmMprRstTVwWXZ] [-K file] [-z file ] [-P dir]"
" [-U none|type] [-e ets_name] [-o dir|file]\n"
" [-t project_descriptor.tpd [-b buildconfig]]\n"
" [-O file] ... module_name ... testport_name ...\n"
......@@ -3918,8 +3927,10 @@ static void usage(void)
#endif
" -d: dump the data used for Makefile generation\n"
" -e ets_name: name of the target executable\n"
" -E: display only warnings for unrecognized encoding variants\n"
" -f: force overwriting of the output Makefile\n"
" -g: generate Makefile for use with GNU make\n"
" -I path: Add path to the search paths when using TPD files\n"
" -K file: enable selective code coverage\n"
" -l: use dynamic linking\n"
" -L: create makefile with library archive as the default target\n"
......@@ -3992,7 +4003,7 @@ int main(int argc, char *argv[])
gfflag = FALSE, lnflag = FALSE, isflag = FALSE, asflag = FALSE,
swflag = FALSE, Vflag = FALSE, Dflag = FALSE, Wflag = FALSE,
djflag = FALSE, Zflag = FALSE, Hflag = FALSE, Mflag = FALSE,
zflag = FALSE;
diflag = FALSE, zflag = FALSE, Eflag = FALSE;
boolean error_flag = FALSE;
char *output_file = NULL;
char *ets_name = NULL;
......@@ -4003,6 +4014,8 @@ int main(int argc, char *argv[])
const char *tpd_file_name = NULL;
const char *tpd_build_config = NULL;
const char *tcov_file_name = NULL;
size_t n_search_paths = 0;
const char **search_paths = NULL;
struct string_list* profiled_file_list = NULL;
const char *profiled_file_list_zflag = NULL;
const char *file_list_path = NULL;
......@@ -4047,7 +4060,7 @@ int main(int argc, char *argv[])
}
for ( ; ; ) {
int c = getopt(argc, argv, "O:ab:c" C_flag "dDe:fFgK:o:lLmMpP:rRst:TU:vVwWXYz:ZH");
int c = getopt(argc, argv, "O:ab:c" C_flag "dDe:EfFgI:K:o:lLmMpP:rRst:TU:vVwWXYz:ZH");
if (c == -1) break;
switch (c) {
case 'O':
......@@ -4056,6 +4069,12 @@ int main(int argc, char *argv[])
Realloc(other_files, n_other_files * sizeof(*other_files));
other_files[n_other_files - 1] = optarg;
break;
case 'I':
n_search_paths++;
search_paths = (const char**)
Realloc(search_paths, n_search_paths * sizeof(*search_paths));
search_paths[n_search_paths - 1] = optarg;
break;
case 'a':
SET_FLAG(a);
break;
......@@ -4085,6 +4104,9 @@ int main(int argc, char *argv[])
SET_FLAG(e);
ets_name = optarg;
break;
case 'E':
SET_FLAG(E);
break;
case 'f':
SET_FLAG(f);
break;
......@@ -4189,7 +4211,7 @@ int main(int argc, char *argv[])
if ( aflag || bflag || cflag || Cflag || dflag || eflag || fflag || Fflag || gflag
|| mflag || oflag || lflag || pflag || Pflag || rflag || Rflag || sflag
|| tflag || Tflag || Vflag || wflag || Xflag || Kflag || Dflag || Wflag || Yflag
|| Zflag || Hflag || Mflag || zflag || n_other_files > 0)
|| Zflag || Hflag || Mflag || zflag || Eflag || n_other_files > 0 || n_search_paths > 0)
error_flag = TRUE;
}
......@@ -4239,6 +4261,30 @@ int main(int argc, char *argv[])
error_flag = TRUE;
}
if (n_search_paths > 0 && !tflag) {
ERROR("Using the '-I' option requires use of the '-t' option.");
error_flag = TRUE;
}
for (size_t i = 0; i < n_search_paths; i++) {
boolean is_abs_path =
#if defined WIN32 && defined MINGW
/* On native Windows the absolute path name shall begin with
* a drive letter, colon and backslash */
(((search_paths[i][0] < 'A' || search_paths[i][0] > 'Z') &&
(search_paths[i][0] < 'a' || search_paths[i][0] > 'z')) ||
search_paths[i][1] != ':' || search_paths[i][2] != '\\');
#else
/* On UNIX-like systems the absolute path name shall begin with
* a slash */
search_paths[i][0] != '/';
#endif
if (is_abs_path) {
ERROR("The path after the -I flag must be an absolute path.");
error_flag = TRUE;
}
}
if (error_flag) {
usage();
return EXIT_FAILURE;
......@@ -4351,9 +4397,9 @@ int main(int argc, char *argv[])
&Rflag, &lflag, &mflag, &Pflag, &Lflag, rflag, Fflag, Tflag, output_file, &abs_work_dir, sub_project_dirs, program_name, prj_graph_fp,
create_symlink_list,ttcn3_prep_includes, ttcn3_prep_defines,ttcn3_prep_undefines, prep_includes, prep_defines, prep_undefines, &csflag,
&quflag, &dsflag, &cxxcompiler, &optlevel, &optflags, &dbflag, &drflag, &dtflag, &dxflag, &djflag, &fxflag, &doflag, &gfflag, &lnflag, &isflag,
&asflag, &swflag, &Yflag, &Mflag, solspeclibraries, sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, &ttcn3prep,
&asflag, &swflag, &Yflag, &Mflag, &Eflag, &diflag, solspeclibraries, sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, &ttcn3prep,
linkerlibraries, additionalObjects, linkerlibsearchpath, Vflag, Dflag, &Zflag, &Hflag,
&generatorCommandOutput, target_placement_list, Wflag, run_command_list, required_configs, &profiled_file_list);
&generatorCommandOutput, target_placement_list, Wflag, run_command_list, required_configs, &profiled_file_list, search_paths, n_search_paths);
Free(abs_work_dir);
if (prj_graph_fp) {
......@@ -4390,7 +4436,7 @@ int main(int argc, char *argv[])
Rflag, lflag, mflag, Cflag, code_splitting_mode, tcov_file_name, profiled_file_list,
Lflag, Zflag, Hflag, rflag ? sub_project_dirs : NULL, ttcn3_prep_includes,
ttcn3_prep_defines, ttcn3_prep_undefines, prep_includes, prep_defines, prep_undefines, csflag, quflag, dsflag, cxxcompiler, optlevel, optflags, dbflag,
drflag, dtflag, dxflag, djflag, fxflag, doflag, gfflag, lnflag, isflag, asflag, swflag, Yflag, Mflag, solspeclibraries,
drflag, dtflag, dxflag, djflag, fxflag, doflag, gfflag, lnflag, isflag, asflag, swflag, Yflag, Mflag, Eflag, diflag, solspeclibraries,
sol8speclibraries, linuxspeclibraries, freebsdspeclibraries, win32speclibraries, ttcn3prep, linkerlibraries, additionalObjects,
linkerlibsearchpath, generatorCommandOutput, target_placement_list);
}
......@@ -4412,6 +4458,8 @@ int main(int argc, char *argv[])
free_string_list(linkerlibsearchpath);
free_string_list(profiled_file_list);
Free(search_paths);
Free(generatorCommandOutput);