diff --git a/common/config_preproc_la.l b/common/config_preproc_la.l index 7cad633a5ec6515fa65f9274f6010648d8f7b336..0e885e613239cece4727789337ebaaf3d6aa645e 100644 --- a/common/config_preproc_la.l +++ b/common/config_preproc_la.l @@ -288,6 +288,9 @@ MACRO_REFERENCE_INT \$"{"{WS}{TTCN3IDENTIFIER}{WS}(","{WS}integer{WS})?"}" BEGIN(SC_define_structured); return LCurly; } + +"*" { return MultiplyOp; } + } /* SC_define */ <SC_define_structured> diff --git a/common/config_preproc_p.y b/common/config_preproc_p.y index c3face154952e5dbb0366d6f6cbe355cd99f0acb..672cab75838a10bd990da628df5419f997c18461 100644 --- a/common/config_preproc_p.y +++ b/common/config_preproc_p.y @@ -59,10 +59,15 @@ static char* decode_secret_message(char* encoded); char* str_val; int last_literal; } macro_val; /* 0 or 1 */ + struct { + char* str; + double num; + } multiplication; } %token <str_val> FillerStuff "whitespace, newline or comment" %token AssignmentChar ":= or =" +%token MultiplyOp "*" %token LCurly "{" %token RCurly "}" %token <str_val> FString "sequence of characters" @@ -78,6 +83,7 @@ static char* decode_secret_message(char* encoded); %type <str_val> StructuredValue %type <str_val> StructuredValueList %type <str_val> MacroRhs +%type <multiplication> Multiplication %destructor { Free($$); } FillerStuff @@ -97,6 +103,9 @@ MacroRhs MacroAssignmentValueList MacroAssignmentValue +%destructor { Free($$.str); } +Multiplication + %% DefineSections: @@ -124,6 +133,10 @@ MacroRhs: StructuredDefinition { $$ = $1; } +| + Multiplication { + $$ = $1.str; +} ; StructuredDefinition: @@ -250,6 +263,38 @@ FillerStuffConcat: } ; +Multiplication: + MacroAssignmentValue MultiplyOp MacroAssignmentValue { + char* ptr = NULL; + double num1 = strtod($1.str_val, &ptr); + if (ptr == NULL || *ptr != '\0') { + preproc_error_flag = 1; + config_preproc_error("First operand of multiplication is not a number: %s", $1.str_val); + } + double num2 = strtod($3.str_val, &ptr); + if (ptr == NULL || *ptr != '\0') { + preproc_error_flag = 1; + config_preproc_error("Second operand of multiplication is not a number: %s", $3.str_val); + } + Free($1.str_val); + Free($3.str_val); + $$.num = num1 * num2; + $$.str = mprintf("%lf", $$.num); + } +| Multiplication MultiplyOp MacroAssignmentValue { + char* ptr = NULL; + double num2 = strtod($3.str_val, &ptr); + if (ptr == NULL || *ptr != '\0') { + preproc_error_flag = 1; + config_preproc_error("Second operand of multiplication is not a number: %s", $3.str_val); + } + Free($1.str); + Free($3.str_val); + $$.num = $1.num * num2; + $$.str = mprintf("%lf", $$.num); + } +; + %% /* BISON error reporting function */ diff --git a/regression_test/cfgFile/define/Makefile b/regression_test/cfgFile/define/Makefile index ed00fe350057ddd31790c5d01dbcfa1792bf9d03..d5bd245b12d7e8ee00e3c72378a85451ca6e19d2 100644 --- a/regression_test/cfgFile/define/Makefile +++ b/regression_test/cfgFile/define/Makefile @@ -15,7 +15,7 @@ include $(TOPDIR)/Makefile.regression unexport ABS_SRC unexport SRCDIR -DIRS := macro_reference structured +DIRS := macro_reference structured expressions # List of fake targets: .PHONY: all dep clean run $(DIRS) $(addsuffix /, $(DIRS)) profile diff --git a/regression_test/cfgFile/define/expressions/.gitignore b/regression_test/cfgFile/define/expressions/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d2055f0075b7603fec2794f6e39b8ae33aa38239 --- /dev/null +++ b/regression_test/cfgFile/define/expressions/.gitignore @@ -0,0 +1,2 @@ +dir_single_mode +dir_parallel_mode diff --git a/regression_test/cfgFile/define/expressions/Makefile b/regression_test/cfgFile/define/expressions/Makefile new file mode 100644 index 0000000000000000000000000000000000000000..02e9997db770946e8aa711165542f4e42d8ae543 --- /dev/null +++ b/regression_test/cfgFile/define/expressions/Makefile @@ -0,0 +1,69 @@ +############################################################################## +# Copyright (c) 2000-2021 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################## +TOPDIR := ../../../ +include $(TOPDIR)/Makefile.regression + +MAKE_PROG := $(MAKE) + +TTCN_FILE := expressions.ttcn +CFG := expressions.cfg + +FILES := $(TTCN_FILE) $(CFG) +RUNNABLE := $(TTCN_FILE:.ttcn=) + +DIR_SINGLE := dir_single_mode +DIR_PARALLEL := dir_parallel_mode +GENERATED_DIRS := $(DIR_SINGLE) $(DIR_PARALLEL) + +COVERAGE_FLAG := +ifeq ($(COVERAGE), yes) + COVERAGE_FLAG += -C +endif + +ifdef DYN +ifeq ($(PLATFORM), WIN32) + export PATH:=$(PATH):$(TTCN3_DIR)/lib:$(ABS_SRC)/$(DIR_SINGLE):$(ABS_SRC)/$(DIR_PARALLEL): +else + export LD_LIBRARY_PATH:=$(LD_LIBRARY_PATH):$(ABS_SRC)/$(DIR_SINGLE):$(ABS_SRC)/$(DIR_PARALLEL): +endif +endif + +# List of fake targets: +.PHONY: all clean run run_single run_parallel runall + +all: $(GENERATED_DIRS) + +$(DIR_SINGLE): + mkdir $@ + cd $@ && for file in $(FILES); do ln -s ../$$file || exit; done + cd $@ && $(TTCN3_DIR)/bin/ttcn3_makefilegen $(COVERAGE_FLAG) $(SPLIT_FLAG) $(RT2_FLAG) -s ./* && $(MAKE_PROG) 'CXXFLAGS=$(CXXFLAGS)' 'LDFLAGS=$(LDFLAGS)' + +$(DIR_PARALLEL): + mkdir $@ + cd $@ && for file in $(FILES); do ln -s ../$$file || exit; done + cd $@ && $(TTCN3_DIR)/bin/ttcn3_makefilegen $(COVERAGE_FLAG) $(SPLIT_FLAG) $(RT2_FLAG) ./* && $(MAKE_PROG) 'CXXFLAGS=$(CXXFLAGS)' 'LDFLAGS=$(LDFLAGS)' + +run: $(GENERATED_DIRS) + cd $(DIR_SINGLE) && ./$(RUNNABLE) $(CFG) + cd $(DIR_PARALLEL) && $(TTCN3_DIR)/bin/ttcn3_start $(RUNNABLE) $(CFG) + +# To run all tests, possibly in parallel +run_single: $(DIR_SINGLE) + cd $(DIR_SINGLE) && ./$(RUNNABLE) $(CFG) +run_parallel: $(DIR_PARALLEL) + cd $(DIR_PARALLEL) && $(TTCN3_DIR)/bin/ttcn3_start $(RUNNABLE) $(CFG) +runall: run_single run_parallel + +clean distclean: + rm -rf $(GENERATED_DIRS) + + diff --git a/regression_test/cfgFile/define/expressions/expressions.cfg b/regression_test/cfgFile/define/expressions/expressions.cfg new file mode 100644 index 0000000000000000000000000000000000000000..f24ef29b0041d4f6dd4157df422861955816802b --- /dev/null +++ b/regression_test/cfgFile/define/expressions/expressions.cfg @@ -0,0 +1,33 @@ +############################################################################### +# Copyright (c) 2000-2021 Ericsson Telecom AB +# All rights reserved. This program and the accompanying materials +# are made available under the terms of the Eclipse Public License v2.0 +# which accompanies this distribution, and is available at +# https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html +# +# Contributors: +# Baranyi, Botond +# +############################################################################### + +[DEFINE] + +DEF_1 := 10.0 +DEF_2 := + 2.0 +DEF_3 := 1.5 + +MUL_1 := ${DEF_1}*${DEF_2} +MUL_2 := ${DEF_1}*${DEF_2}*${DEF_3} +MUL_3 := ${DEF_1}*3*${DEF_2}*${DEF_3} +MUL_4 := ${DEF_1}*-1.0e2*${DEF_2}*${DEF_3} + +[MODULE_PARAMETERS] + +mul1 := ${MUL_1, float} +mul2 := ${MUL_2, float} +mul3 := ${MUL_3, float} +mul4 := ${MUL_4, float} + +[EXECUTE] +expressions.control diff --git a/regression_test/cfgFile/define/expressions/expressions.ttcn b/regression_test/cfgFile/define/expressions/expressions.ttcn new file mode 100644 index 0000000000000000000000000000000000000000..44474726c3866782938169bbebc39007a082fc62 --- /dev/null +++ b/regression_test/cfgFile/define/expressions/expressions.ttcn @@ -0,0 +1,42 @@ +/****************************************************************************** + * Copyright (c) 2000-2021 Ericsson Telecom AB + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v2.0 + * which accompanies this distribution, and is available at + * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html + * + * Contributors: + * Baranyi, Botond + * + ******************************************************************************/ +module expressions { + +modulepar float mul1; +modulepar float mul2; +modulepar float mul3; +modulepar float mul4; + +type component CT {} + +testcase tc_multiply() runs on CT { + if (mul1 != 20.0) { + setverdict(fail, "mul1: ", mul1); + } + if (mul2 != 30.0) { + setverdict(fail, "mul2: ", mul1); + } + if (mul3 != 90.0) { + setverdict(fail, "mul3: ", mul1); + } + if (mul4 != -3000.0) { + setverdict(fail, "mul4: ", mul1); + } + setverdict(pass); +} + + +control { + execute(tc_multiply()); +} + +}