/****************************************************************************** * Copyright (c) 2000-2019 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 ******************************************************************************/ /////////////////////////////////////////////////////////////////////////////// // // File: TCCTemplate_Functions.ttcn // Description: TCC Useful Functions: Template Functions // Rev: R36B // Prodnr: CNL 113 472 // /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// // Module: TCCTemplate_Functions // // Purpose: // This module supports template handling // Originally for TitanSIM R2 needs it for substituting substrings in a // charstring template. // // Module Parameters: // - // // Module depends on: // - // // Current Owner: // Zsolt Szalai (EZSOSZA) // // Last Review Date: // - // // Comments: // Intruduction of ? regexp like behavior like \(x)? in our own pattern // couses many troubles, like with the current templatefunc signature it // can be impossible to determine the parameters(using 2 ? pattern) and // lookup may need much more and complicated additions or rewrite that // we may want at that time; // /////////////////////////////////////////////////////////////////////////////// module TCCTemplate_Functions { // import from TCCConversion_Functions all; import from TCCFileIO_Functions all; modulepar{ charstring TCCTemplate_opentoken := "$("; charstring TCCTemplate_closetoken := ")"; } type function templatefunc(in charstringList pl_params) runs on self return charstring; type record TCCSubstitution { charstring patt, charstring string, templatefunc func optional } type record of TCCSubstitution TCCSubstitutionList; type record of charstring charstringList; group PublicFunctions{ /////////////////////////////////////////////////////////////////////////////// // Function: f_Template_substitutetemplate // // Purpose: // Makes the substitutions according to the dictonary given // // Parameters: // pl_dict - *in* *TCCSubstitutionList* - dictionary // pl_string - *in* *charstring* - string to substitute in // // Return Value: // charstring - substituted string // // Errors: // - // // Detailed description: // - // /////////////////////////////////////////////////////////////////////////////// function f_Template_substitutetemplate(in TCCSubstitutionList pl_dict, in charstring pl_string) return charstring{ var charstring ret := pl_string; //log("original template:",ret,"\n"); // heuristic implementation ///////////////////////////////////////////////////////////////////////// // searches for every pattern /* for (var integer i := 0; i<sizeof(pl_dict); i:=i+1){ if (ispresent(pl_dict[i].func)){ var charstring matched := regexp(ret, "*(" & pl_dict[i].patt & ")*",0);//f_Template_searchpattern(ret, pl_dict[i].patt); if (matched != ""){ ret := f_Template_substituteall(ret, matched, pl_dict[i].func.apply(matched, pl_dict[i].patt)); } } else { ret := f_Template_substituteall(ret, pl_dict[i].patt, pl_dict[i].string); } } return ret;*/ //heuristic implementation end///////////////////////////////////////////// var charstring t_open := TCCTemplate_opentoken; var charstring t_close := TCCTemplate_closetoken; // fast implentation ////////////////////////////////////////////////////////////////////////// for (var integer i:=0; i<lengthof(ret);i:=i+1){ if (ret[i] == t_open[0]) { // maybe its a variable in template? if (substr(ret,i,lengthof(t_open)) == t_open){ // it is a variable opening string var integer tokenstart := i; // log("tokenstart:",tokenstart,"\n"); i := i + lengthof(t_open); while(ret[i] != t_close[0] and i<lengthof(ret)){ i:=i+1; } if (i<lengthof(ret)){ if (substr(ret,i,lengthof(t_close)) == t_close){ i := i + lengthof(t_close); var charstring variable := substr(ret, tokenstart+lengthof(t_open), i-tokenstart-lengthof(t_open)-lengthof(t_close)); //log("Variable found: ", variable,"\n"); var charstringList params := {}; var integer recindex := f_Template_lookup(pl_dict, variable, params); if (recindex != -1){ // substitution var charstring pvalue := ""; if(ispresent(pl_dict[recindex].func)){ pvalue := pl_dict[recindex].func.apply(params); } else{ pvalue := pl_dict[recindex].string; } ret := substr(ret,0,tokenstart) & pvalue & substr(ret, i, lengthof(ret)-i); //log("New template: ", ret, "\n"); i := tokenstart; } else { i := tokenstart; } } } else { log("No closing string in a variable!\n"); } } // not a variable opening string, nothing to do } // not a variable in template, nothing to do } return ret; // fast implentation end ///////////////////////////////////////////////// } /////////////////////////////////////////////////////////////////////////////// // Function: f_Template_subsfiletemplate // // Purpose: // Makes the substitutions in the content of the given file, // according to the dictonary // // Parameters: // pl_dict - *in* *TCCSubstitutionList* - dictionary // pl_file - *in* *charstring* - name of the file containing the template // // Return Value: // charstring - substituted string // // Errors: // From FIO - in this case "" returns // // Detailed description: // - // /////////////////////////////////////////////////////////////////////////////// function f_Template_subsfiletemplate(in TCCSubstitutionList pl_dict, in charstring pl_file) return charstring{ var integer fd := f_FIO_open_rdonly(pl_file); if (fd == -1){ return ""; } var integer len := f_FIO_seek_end(fd); var charstring content; if (f_FIO_seek_home(fd) != 0){ return "" } if (f_FIO_read_text(fd, content, len) == -1){ if (f_FIO_close(fd) == -1){log("Error while closing file!");} return ""; } if (f_FIO_close(fd) == -1){log("Error while closing file!");} return f_Template_substitutetemplate(pl_dict, content); } } group PrivateFunctions{ function f_Template_getparams(in charstring matched, in charstring patt) return charstringList { var integer pc := 0; var charstringList params:={}; for (var integer i:=0;i<lengthof(patt);i:=i+1){ if (patt[i]=="(" and i!=0 and patt[i-1]!="#" and patt[i-1]!="\\"){pc:=pc+1;} } for (var integer i:=0;i<pc;i:=i+1){ params[sizeof(params)] := regexp(matched, patt, i); } return params; } function f_Template_lookup(in TCCSubstitutionList pl_dict, in charstring pl_var, out charstringList pl_params) return integer{ pl_params:={}; for (var integer i:=0; i<sizeof(pl_dict);i:=i+1){ // simple search if(pl_dict[i].patt == pl_var){ return i; } } for (var integer i:=0; i<sizeof(pl_dict);i:=i+1){ // regexp like search var integer j := 0; var integer k := 0; while (j<lengthof(pl_dict[i].patt) and k<lengthof(pl_var)){ while(j<lengthof(pl_dict[i].patt) and k<lengthof(pl_var) and pl_dict[i].patt[j] == pl_var[k]){ j := j + 1; k := k + 1; } if (j<lengthof(pl_dict[i].patt) and pl_dict[i].patt[j]=="\\" and j+1<lengthof(pl_dict[i].patt) and pl_dict[i].patt[j+1]=="w" and j+2<lengthof(pl_dict[i].patt)){ // we have found an escape, parameter begins j := j + 2; var integer paramstart := k; while (k<lengthof(pl_var) and pl_var[k] != pl_dict[i].patt[j]) {k := k + 1;} var charstring parameter := substr(pl_var,paramstart, k - paramstart); pl_params[sizeof(pl_params)] := parameter; } else { if (j==lengthof(pl_dict[i].patt) and k==lengthof(pl_var)){ return i; } else { // that is not the proper pattern; j := lengthof(pl_dict[i].patt); } } } } return -1; } } }