From 4be25f4ced26b7ed12074463f2886287f5ab905b Mon Sep 17 00:00:00 2001 From: Brigitte Huynh Date: Mon, 20 Aug 2018 18:30:03 +0200 Subject: [PATCH 1/4] #119 Corrected the issues of the COM.PRES.Indent rule: - Awk command handling - Quotes and double quotes handling - Cases statements handling - Analysis failure on braces (issue due to [[) The following issues no longer occur although there was no specific correction for them. The overall modifications of the rule must have resolved them: - Comments handling - Forbidden increasing of identation not handled --- .../lex/COMPRESIndent.lex | 115 +++++++++++++-- .../COM/PRES/Indent/TestCOMPRESIndent.java | 8 +- .../shell/rules/COM/PRES/Indent/error.sh | 22 ++- .../shell/rules/COM/PRES/Indent/noError.sh | 135 +++++++++++++++++- 4 files changed, 255 insertions(+), 25 deletions(-) diff --git a/fr.cnes.analysis.tools.shell.rules/lex/COMPRESIndent.lex b/fr.cnes.analysis.tools.shell.rules/lex/COMPRESIndent.lex index 5914dc6e..187a774d 100755 --- a/fr.cnes.analysis.tools.shell.rules/lex/COMPRESIndent.lex +++ b/fr.cnes.analysis.tools.shell.rules/lex/COMPRESIndent.lex @@ -53,6 +53,11 @@ SPACETAB = {SPACE}|{TAB} VAR = [a-zA-Z][a-zA-Z0-9\_]* CONTINUEDLINE = \\ {SPACETAB}* \n +CASE_STMT = [^"\n""("" ""\r""\f""#"][^"\n""("]*\) + +CASE = "case" +ESAC = "esac" + BEGIN = "if" | "case" | "for" | "while" | "until" CONT = "do" | "then" END = "done" | "fi" | "esac" @@ -87,6 +92,13 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` Boolean indentationRequired = false; /* checkEnd is true when in CONSUME_LINE we are after a ";", requiring that ENDs should be taken into account */ Boolean checkEnd=false; + + /* firstInCase is true when the case statement is the first one of a case structure */ + Boolean firstInCase = false; + + /* decrementAtEnd is true when the body of the function is incremented, eg. when body is an if */ + /* with no { and is incremented compared to the function line */ + Boolean decrementAtEnd = false; private Stack functionStack = new Stack<>(); @@ -121,7 +133,7 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` indentationRequired = false; /* continue at same position */ } else { /* indentationRequired == false */ /* we are not at the beginning of a new indentation. The indentation should be the same as the last line */ - setError(location,"This line is not indented in comparison with the last one.", yyline+1); + setError(location,"This line should not be indented in comparison with the last one.", yyline+1); } } else { /* currentPos == value */ /* The indentation is what was expected */ @@ -158,7 +170,7 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` if (index >= 0) { int value = desiredPos.get(index); if (currentPos != value) - setError(location,"This line is not indented in comparison with the last one.", yyline+1); + setError(location,"This line is not aligned with its corresponding structure.", yyline+1); } } @@ -172,6 +184,10 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` /* we are in the main program: change location to main */ location = MAINPROGRAM; } + if (decrementAtEnd) { + if(desiredPos.size()>=1) {desiredPos.remove(desiredPos.size()-1);} + decrementAtEnd = false; + } }catch(EmptyStackException e){ final String errorMessage = e.getMessage(); throw new JFlexException(this.getClass().getName(), parsedFileName, @@ -223,6 +239,23 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` { ; {checkEnd=true;} {COMMENT_WORD} {checkEnd=false; yybegin(COMMENT);} + {IGNORE_STRING_D} {} + {STRING_D} {yybegin(STRING_DOUBLE);} + {IGNORE_STRING_S} {} + {STRING_S} {yybegin(STRING_SIMPLE);} + {ESAC} { + if(checkEnd && desiredPos.size()>=1) {desiredPos.remove(desiredPos.size()-1);} + if(!functionStack.empty()){ + if(functionStack.peek().isFinisher(yytext())){ + if(functionStack.peek().getStarterRepetition()>0) { + functionStack.peek().removeStarterRepetition(); + } else { + endLocation(); + } + } + } + firstInCase = false; + } {END} { if(checkEnd && desiredPos.size()>=1) {desiredPos.remove(desiredPos.size()-1);} if(!functionStack.empty()){ @@ -258,7 +291,9 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` { {COMMENT_WORD} {inTabs=false; yybegin(COMMENT);} - {STRING_D} {yybegin(STRING_DOUBLE);} + {IGNORE_STRING_D} {} + {STRING_D} {yybegin(STRING_DOUBLE);} + {IGNORE_STRING_S} {} {STRING_S} {yybegin(STRING_SIMPLE);} {FUNCTION} { inTabs=false; @@ -275,7 +310,7 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` desiredPos.add(currentPos+1); yybegin(BEGINFUNC); } - {BEGIN} { + {CASE} { if(!functionStack.empty()){ if(functionStack.peek().getFinisher().equals(Function.finisherOf(yytext()))){ functionStack.peek().addStarterRepetition(); @@ -285,15 +320,36 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` checkIndentation(); indentationRequired=true; desiredPos.add(currentPos+1); + /* Next case statement will be the first */ + firstInCase = true; yybegin(CONSUME_LINE); } + {BEGIN} { + if(!functionStack.empty()){ + if(functionStack.peek().getFinisher().equals(Function.finisherOf(yytext()))){ + functionStack.peek().addStarterRepetition(); + } + } + inTabs=false; + checkIndentation(); + indentationRequired=true; + desiredPos.add(currentPos+1); + yybegin(CONSUME_LINE); + } {CONT} | {ELSE} { inTabs=false; checkIndentationElse(); indentationRequired=true; yybegin(CONSUME_LINE); } - {END} { + {ESAC} { + inTabs=false; + if(desiredPos.size()>=1) {desiredPos.remove(desiredPos.size()-1);} + /* Another one to compensate for the added indentation of the previous case statement */ + if(desiredPos.size()>=1) {desiredPos.remove(desiredPos.size()-1);} + indentationRequired=false; + checkIndentation(); + firstInCase = false; if(!functionStack.empty()){ if(functionStack.peek().isFinisher(yytext())){ if(functionStack.peek().getStarterRepetition()>0) { @@ -303,10 +359,23 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` } } } + yybegin(CONSUME_LINE); + } + {END} { inTabs=false; - if(desiredPos.size()>=1) {desiredPos.remove(desiredPos.size()-1);} + if(desiredPos.size()>=1) { + desiredPos.remove(desiredPos.size()-1);} indentationRequired=false; checkIndentation(); + if(!functionStack.empty()){ + if(functionStack.peek().isFinisher(yytext())){ + if(functionStack.peek().getStarterRepetition()>0) { + functionStack.peek().removeStarterRepetition(); + } else { + endLocation(); + } + } + } yybegin(CONSUME_LINE); } {TAB} {pos=currentPos; currentPos+=yytext().length(); @@ -315,7 +384,7 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` inTabs=true; setError(location,"Tabulations are not allowed.", yyline+1); }} - {SPACE} {if(currentPos==0) {inTabs=true;}; currentPos+=yytext().length();} + {SPACE}+ {if(currentPos==0) {inTabs=true;}; currentPos+=yytext().length();} {VAR} {inTabs=false; checkIndentation(); yybegin(CONSUME_LINE);} {IGNORETEXT} {} \{ { @@ -328,6 +397,9 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` yybegin(CONSUME_LINE); } \} { + inTabs=false; + if(desiredPos.size()>=1) {desiredPos.remove(desiredPos.size()-1);} + checkIndentationNoChange(); if(!functionStack.empty()){ if(functionStack.peek().isFinisher(yytext())){ if(functionStack.peek().getStarterRepetition()>0) { @@ -337,17 +409,15 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` } } } - inTabs=false; - if(desiredPos.size()>=1) {desiredPos.remove(desiredPos.size()-1);} - checkIndentationNoChange(); yybegin(CONSUME_LINE); } - {FUNCSTART} { /* for the remaining beginnings not in START */ + {FUNCSTART} { /* for the remaining beginnings not in BEGIN */ if(!functionStack.empty()){ if(functionStack.peek().getFinisher().equals(Function.finisherOf(yytext()))){ functionStack.peek().addStarterRepetition(); } } + yybegin(CONSUME_LINE); } {FUNCEND} { /* for the remaining endings not in END */ if(!functionStack.empty()){ @@ -361,6 +431,19 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` } } \n {inTabs=false; currentPos=0;} + {CASE_STMT} { + inTabs=false; + if (!firstInCase) { + if(desiredPos.size()>=1) {desiredPos.remove(desiredPos.size()-1);} + checkIndentationNoChange(); + } else { + firstInCase = false; + checkIndentation(); + } + indentationRequired=true; + desiredPos.add(currentPos+1); + yybegin(CONSUME_LINE); + } . {inTabs=false; checkIndentation(); yybegin(CONSUME_LINE);} } @@ -375,6 +458,10 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` { \(\) {} + "\n"{SPACE}* { + currentPos = currentPos+yytext().length() -1; + decrementAtEnd = true; + } {BEGIN} { inTabs=false; checkIndentation(); @@ -410,7 +497,7 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` { {IGNORE_STRING_S} {} - {STRING_S} {yybegin(YYINITIAL);} + {STRING_S} {yybegin(CONSUME_LINE);} [^]|{SPACE} {} } @@ -420,12 +507,10 @@ IGNORETEXT = "<<" {SPACE}* "EOF" [^"<<"]* "EOF" | ` [^`]* ` { {IGNORE_STRING_D} {} - {STRING_D} {yybegin(YYINITIAL);} + {STRING_D} {yybegin(CONSUME_LINE);} [^]|{SPACE} {} } - - /************************/ /* ERROR STATE */ /************************/ diff --git a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/TestCOMPRESIndent.java b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/TestCOMPRESIndent.java index b08b7325..cca116ca 100755 --- a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/TestCOMPRESIndent.java +++ b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/TestCOMPRESIndent.java @@ -35,10 +35,10 @@ public class TestCOMPRESIndent { public final static String ERROR_FILE = "error.sh"; public final static String NO_ERROR_FILE = "noError.sh"; - public final static int[] LINES = { 18, 26, 45, 49, 59, 60, 64, 70, 78, 79 }; + public final static int[] LINES = { 18, 26, 45, 49, 59, 60, 64, 70, 78, 79, 92, 93, 94 }; public final static String[] LOCATIONS = { "ma_fonction_affine", "ma_fonction_affine", "affiche_resultat", "affiche_resultat", "MAIN PROGRAM", "MAIN PROGRAM", "MAIN PROGRAM", "MAIN PROGRAM", - "MAIN PROGRAM", "MAIN PROGRAM" }; + "MAIN PROGRAM", "MAIN PROGRAM", "ma_fonction_affine2", "ma_fonction_affine2", "ma_fonction_affine2" }; public final AbstractChecker rule = new COMPRESIndent(); /** @@ -76,8 +76,8 @@ public void testRunWithError() { for (final CheckResult value : list) { final Integer index = list.indexOf(value); final String location = value.getLocation(); - assertTrue("CheckResult " + index.toString() + " has wrong location : " + location + " should contain " - + LOCATIONS[index], location.contains(LOCATIONS[index])); + assertTrue("CheckResult " + index.toString() + " has wrong location : " + location + " should be " + + LOCATIONS[index], location.equals(LOCATIONS[index])); final int line = value.getLine(); assertEquals("CheckResult " + index.toString() + " is in wrong line : ", LINES[index], line); } diff --git a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/error.sh b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/error.sh index 8d714f43..1ce7d046 100755 --- a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/error.sh +++ b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/error.sh @@ -28,11 +28,11 @@ ma_fonction_affine () } + # ------------------------------------------------------------------------------------ # Definition d'une fonction qui affiche les resultats obtenus # ------------------------------------------------------------------------------------ -affiche_resultat () -{ +affiche_resultat () if [ $# -ne 2 ] then printf "Erreur grave dans affiche_resultat : nombre d'arguments incorrects\n" @@ -47,7 +47,7 @@ affiche_resultat () printf " ===>Erreur grave dans ma_fonction_affine : nombre d'arguments incorrects<===\n" fi fi -} + a_trouver=$(($RANDOM % 100)) @@ -79,4 +79,18 @@ else nbTarGbin=$(tar tvf ${FILETYPE}_${param: -4}.tar | grep gbin | wc -l) fi fi -fi \ No newline at end of file +fi + +function ma_fonction_affine2 () +{ + if [ $# -ne 3 ] + then + my_function=$code_error_nbargs + else + printf "Calling : p1=%s p2=%s p3=%s\n" $1 $2 $3 + # operation : y = ax + b + let y=$1*$2+$3 + printf "y=%s\n" $y + my_function=$y + fi +} diff --git a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/noError.sh b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/noError.sh index 106453b0..b6d2e6c4 100755 --- a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/noError.sh +++ b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/PRES/Indent/noError.sh @@ -5,6 +5,8 @@ echo "Fichier OK de TU" echo "La indentation du code source est bonne" echo "------------------------------------------" +[[ $? != 0 ]] && { echo >&2 the required \"message\" command is not in your PATH; exit 1; } + code_erreur_nbargs=-128 # Définition de la variable qui contiendra le code retour (en particulier pour les cas d'erreur avec valeurs negatives) @@ -55,7 +57,6 @@ ma_fonction_affine () # Definition d'une fonction qui affiche les resultats obtenus # ------------------------------------------------------------------------------------ affiche_resultat () -{ if [ $# -ne 2 ] then printf "Erreur grave dans affiche_resultat : nombre d'arguments incorrects\n" @@ -70,7 +71,6 @@ affiche_resultat () printf " ===>Erreur grave dans ma_fonction_affine : nombre d'arguments incorrects<===\n" fi fi -} a_trouver=$(($RANDOM % 100)) @@ -87,3 +87,134 @@ do done echo "bravo, le nombre etait en effet $a_trouver" +# - Traitement du fichier des mouvements, impression de chaque +# - mouvement avec son type et calcul du solde bancaire +cat mvts.txt | awk 'BEGIN { print "Start AWK command" } + /^A/ {print "A---", NR } + /^B/ {print "B---", NR } + /^C/ {print "C---", NR } + /^D/ {print "D---", NR } + /^E/ {print "E---", NR } + /^F/ {print "F---", NR } + /^![A-F]/ {print "Default---", NR } + END { print "End AWK command" }' + +echo +echo "String operations using \"expr \$string : \" construct" +echo "===================================================" +echo + +a=1234zipper5FLIPPER43231 + +echo "The string being operated upon is \"`expr "$a" : '\(.*\)'`\"." +# Escaped parentheses grouping operator. == == + +# *************************** +#+ Escaped parentheses +#+ match a substring +# *************************** + + +# If no escaped parentheses... +#+ then 'expr' converts the string operand to an integer. + +echo "Length of \"$a\" is `expr "$a" : '.*'`." # Length of string + +echo "Number of digits at the beginning of \"$a\" is `expr "$a" : '[0-9]*'`." + +# ------------------------------------------------------------------------- # + +echo + +echo "The digits at the beginning of \"$a\" are `expr "$a" : '\([0-9]*\)'`." +# == == +echo "The first 7 characters of \"$a\" are `expr "$a" : '\(.......\)'`." +# ===== == == +# Again, escaped parentheses force a substring match. +# +echo "The last 7 characters of \"$a\" are `expr "$a" : '.*\(.......\)'`." +# ==== end of string operator ^^ +# (actually means skip over one or more of any characters until specified +#+ substring) + +echo + + +INIT_TAB_AWK="" +# Parameter to initialize awk script. +count_case=0 +FILE_PARSE=$1 + +E_PARAMERR=65 + +usage() +{ + echo "Usage: letter-count.sh file letters" 2>&1 + # For example: ./letter-count2.sh filename.txt a b c + exit $E_PARAMERR # Not enough arguments passed to script. +} + +if [ ! -f "$1" ] ; then + echo "$1: No such file." 2>&1 + usage # Print usage message and exit. +fi + +if [ -z "$2" ] ; then + echo "$2: No letters specified." 2>&1 + usage +fi + +shift # Letters specified. +for letter in `echo $@` # For each one . . . +do + INIT_TAB_AWK="$INIT_TAB_AWK tab_search[${count_case}] = \"$letter\"; final_tab[${count_case}] = 0; " + # Pass as parameter to awk script below. + count_case=`expr $count_case + 1` +done + +# DEBUG: +# echo $INIT_TAB_AWK; + +cat $FILE_PARSE | +# Pipe the target file to the following awk script. + +# ---------------------------------------------------------------------------------- +# Earlier version of script used: +# awk -v tab_search=0 -v final_tab=0 -v tab=0 -v nb_letter=0 -v chara=0 -v chara2=0 \ + +awk \ +"BEGIN { $INIT_TAB_AWK } \ +{ split(\$0, tab, \"\"); \ +for (chara in tab) \ +{ for (chara2 in tab_search) \ +{ if (tab_search[chara2] == tab[chara]) { final_tab[chara2]++ } } } } \ +END { for (chara in final_tab) \ +{ print tab_search[chara] \" => \" final_tab[chara] } }" +# ---------------------------------------------------------------------------------- +# Nothing all that complicated, just . . . +#+ for-loops, if-tests, and a couple of specialized functions. + + +# ----------------------------------------------------------------------- +# Every file has an inode, a record that holds its physical address info. +# ----------------------------------------------------------------------- + +echo; echo -n "Are you absolutely sure you want to delete \"$1\" (y/n)? " +# The '-v' option to 'rm' also asks this. +read answer +case "$answer" in + [nN]) echo "Changed your mind, huh?" + exit $E_CHANGED_MIND + ;; + *) echo "Deleting file \"$1\".";; +esac + +awk ' +{nodecount()} # Execute the user-defined nodecount() for each row to update the node count +$0~//{ print } # Print the rows between "" +function nodecount() #Function definition for nodecount +{if($0~/clusternode name/){count+=1} +} +END{print "Node Count="count}' $1 #Print the count value in the END pattern which is executed once + + From 11805d9dc1386749f0d092398ade0930ab098942 Mon Sep 17 00:00:00 2001 From: Brigitte Huynh Date: Tue, 21 Aug 2018 18:37:21 +0200 Subject: [PATCH 2/4] #115 Added the COM.FLOW.FilePath, largely updating the old version using the COM.FLOW.FileExistence rule for recognizing file strings and adding file management commands. The tests files were updated accordingly. --- .../lex/COMFLOWFilePath.lex | 117 +++++++++++++++--- fr.cnes.analysis.tools.shell.rules/plugin.xml | 5 + .../FLOW/FilePath/TestCOMFLOWFilePath.java | 6 +- .../shell/rules/COM/FLOW/FilePath/error.sh | 25 +++- .../shell/rules/COM/FLOW/FilePath/noError.sh | 6 +- 5 files changed, 134 insertions(+), 25 deletions(-) diff --git a/fr.cnes.analysis.tools.shell.rules/lex/COMFLOWFilePath.lex b/fr.cnes.analysis.tools.shell.rules/lex/COMFLOWFilePath.lex index ffa81e21..980ce2b8 100755 --- a/fr.cnes.analysis.tools.shell.rules/lex/COMFLOWFilePath.lex +++ b/fr.cnes.analysis.tools.shell.rules/lex/COMFLOWFilePath.lex @@ -39,22 +39,57 @@ import fr.cnes.analysis.tools.analyzer.exception.JFlexException; %type List -%state COMMENT, NAMING, INITIALISATION +%state COMMENT, NAMING, FILE, STRING COMMENT_WORD = \# FUNCTION = "function" FUNCT = {FNAME}{SPACE}*[\(]{SPACE}*[\)] FNAME = [a-zA-Z0-9\.\!\-\_\@\?\+]+ -SPACE = [\ \r\t\f\space] -VAR = [a-zA-Z][a-zA-Z0-9\_]* - -POSERROR = {VAR}\= | \> | "cat" | "rm" | "more" -FILEEXT = \.[a-zA-Z][^\.]{0,5} +SPACE = [\ \r\t\f] +NAME = ([a-zA-Z\_][a-zA-Z0-9\_]*) +SHELL_VAR = ([0-9]+|[\-\@\?\#\!\_\*\$]) +EXPANDED_VAR = [\!]?{NAME}([\:]|(([\%]?[\%])|([\#]?[\#]))|([\:]?[\=\+\?\-]))({NAME}|[\[]{NAME}[\]])|([\#]{NAME}) +VAR = ({NAME}|([\$][\{]({NAME}|{SHELL_VAR}|{EXPANDED_VAR})[\}])|([\$]({NAME}|{SHELL_VAR}))) + +STRING = [\"]|[\'] +ESCAPE = [\\] +FILE_SEPARATOR = [\/]|[\\] + +FILECHAR = [a-zA-Z0-9\_\.\?\!\^\+\*\-\%\ยง] +FILEWORD = (([\.]?{FILE_SEPARATOR})|([\~]))?(({FILECHAR}+|{VAR}){FILE_SEPARATOR}?)+ +FILESTRING = (([\"]{SPACE}*{FILEWORD}{SPACE}*[\"])|([\']{SPACE}*{FILEWORD}{SPACE}*[\'])|{FILEWORD})+ + +FILEEXIST = "test" (\!)? {SPACE}+ {OPTION}{SPACE}+{FILESTRING}+ | \[ {SPACE}* (\!)? {SPACE}+ {OPTION}{SPACE}+{FILESTRING}+ {SPACE}+ \] + +OPTION = \- ("a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "k" | + "p" | "r" | "s" | "u" | "w" | "x" | "O" | "G" | "L" | + "N" | "S") + +COMMAND_END = [\n] | [\;] | [\|] | [\`] +COMMAND_NAME = "cat" | "tee" | "more" | "less" | "head" | "wc" | "sh" | "rm" +GREP_COMMAND = "grep"{SPACE}+(([\-][AB]{SPACE}+[0-9]+{SPACE}+)?|([\-]?[\-][a-zC-Z]+{SPACE}+)?)*([\-][\e]{SPACE}+)?[\^]?(([\"]([^\"]|([\\][\"]))*[\"])|([\']([^\']|([\\][\']))*[\'])|({FNAME}+|{VAR})+) +BASE_COMMAND = {COMMAND_NAME}{SPACE}+([\-]?[\-]({VAR}|{FNAME})+([\=]({VAR}|{FNAME})+)?{SPACE}*)*{SPACE}* +ASSIGN = {VAR}\={SPACE}*([\-]?[\-]({VAR}|{FNAME})+([\=]({VAR}|{FNAME})+)?{SPACE}*)*{SPACE}* +FILE_COMMAND = {GREP_COMMAND} | {BASE_COMMAND} | {ASSIGN} + +OPERATOR_RIGHT = [\>]|[\>][\&]|[\&][\>]|[\>][\>]|[\>][\>][\>] +OPERATOR_LEFT = [\<]|[\<][\&]|[\&][\<]|[\<][\<]|[\<][\<][\<] +OPERATOR_RL = [\<][\>] +RIGHT_FILE_REDIRECT = ({OPERATOR_RIGHT}|{OPERATOR_RL}){SPACE}*{FILESTRING} +LEFT_FILE_REDIRECT = {FILESTRING}{SPACE}*({OPERATOR_LEFT}|{OPERATOR_RL}) +REDIRECT_IGNORE = ([0-2]({OPERATOR_LEFT}|{OPERATOR_RL})) | (({OPERATOR_RIGHT}|{OPERATOR_RL})[0-2]) + +STRING_ESCAPED = [\\]{STRING} +IGNORE = {REDIRECT_IGNORE} | {STRING_ESCAPED} | ([\\][\#]) | "ssh" %{ String location = "MAIN PROGRAM"; private String parsedFileName; + private String stringBeginner = ""; + private boolean escapeNext = false; + + public COMFLOWFilePath() { } @@ -105,24 +140,76 @@ FILEEXT = \.[a-zA-Z][^\.]{0,5} /************************/ { - {COMMENT_WORD} {yybegin(COMMENT);} + {COMMENT_WORD} {if (!escapeNext) {yybegin(COMMENT);}} {FUNCTION} {yybegin(NAMING);} {FUNCT} {location = yytext().substring(0,yytext().length()-2).trim();} - {POSERROR} {yybegin(INITIALISATION);} - {VAR} {} /* Clause to match with words */ - [^] {} + {IGNORE} {} + {FILEEXIST} { + int index = yytext().indexOf('-'); + String subfile = yytext().substring(index); + String name = subfile.replaceAll("\"", "").replaceAll("\\{", "").replaceAll("\\}", "").replaceAll("]", "").split(" ")[1]; + setError(location,"It is forbidden to use a file name such as " + name + " directly.", yyline+1); + } + {LEFT_FILE_REDIRECT}|{RIGHT_FILE_REDIRECT} + { + String name = yytext().replaceAll("([\\s]|[\\>]|[\\\"]|[\\']|[\\<]|[\\&]|[\\{]|[\\}])+",""); + setError(location,"It is forbidden to use a file name such as " + name + " directly.", yyline+1); + } + {FILE_COMMAND} {yybegin(FILE);} + {STRING} { + stringBeginner=yytext(); + yybegin(STRING); + } + [^] {} } /************************/ -/* INITIALISATION STATE */ +/* FILE STATE */ /************************/ - + { - {FILEEXT} {setError(location,"It is not allowed to specify the file with this name. Use a variable instead.", yyline+1); yybegin(YYINITIAL);} - \n | \; {yybegin(YYINITIAL);} - . {} + {FILESTRING}+ { + String name = yytext().replaceAll("([\\\"]|[\\']|[\\{]|[\\}]|[\\[]|[\\]])+",""); + setError(location,"It is forbidden to use a file name such as " + name + " directly.", yyline+1); + escapeNext=false; + yybegin(YYINITIAL); + } + {COMMAND_END} {escapeNext=false; yybegin(YYINITIAL);} + {LEFT_FILE_REDIRECT}|{RIGHT_FILE_REDIRECT} + { + String name = yytext().replaceAll("([\\s]|[\\>]|[\\\"]|[\\']|[\\<]|[\\&]|[\\{]|[\\}])+",""); + setError(location,"It is forbidden to use a file name such as " + name + " directly.", yyline+1); + escapeNext=false; + yybegin(YYINITIAL); + } + . {} } +/************************/ +/* STRING STATE */ +/************************/ + + { + {ESCAPE} { + if(!escapeNext) + { + escapeNext=true; + } else + { + escapeNext=false; + } + } + {STRING} { + if(!escapeNext && yytext().equals(stringBeginner)) + { + yybegin(YYINITIAL); + } + escapeNext=false; + } + {COMMENT_WORD} {escapeNext=false;} + [^] {escapeNext=false;} + } + /************************/ /* ERROR STATE */ diff --git a/fr.cnes.analysis.tools.shell.rules/plugin.xml b/fr.cnes.analysis.tools.shell.rules/plugin.xml index 4c3acc95..3f4014d2 100755 --- a/fr.cnes.analysis.tools.shell.rules/plugin.xml +++ b/fr.cnes.analysis.tools.shell.rules/plugin.xml @@ -55,6 +55,11 @@ id="fr.cnes.analysis.tools.shell.rules.COMFLOWFileExistence" name="COM.FLOW.FileExistence" languageId="fr.cnes.analysis.tools.languages.shell"> + + $fichier +date > $fichier -if [ -f $fichier_texte ] || [ -f $fichier_texte_new ]; then - rm -f $fichier_texte - rm -f $fichier_texte_new +echo "test" > $dirbdtle/bd_objet/$n1/$n2/RCS.txt + +cat "${DATE_EXE}_${TYPE_ACTION}_${NIVEAU_SAUVEGARDE}_${MACHINE_S}.tar.gz" | Execute_Commande_C_Retour -d "cat - > ${TAPE_DEV_REP}/${DATE_EXE}_${TYPE_ACTION}_${NIVEAU_SAUVEGARDE}_${MACHINE_S}.tar.gz" + +echo "${nom_machine} ${nb_proc}" > "${elec_export}"/fcf/machines.txt + +wc -l l1.tmp | awk '{print $1}' | read nbobj +grep ^2 $fictle > l1.tmp + +date>$fichier + +if [ -e ${TAPE_DEV_REP}/${DATE_EXE}_${TYPE_ACTION}_${NIVEAU_SAUVEGARDE}_${MACHINE_S}.tar.gz ] ; then + cat "${DATE_EXE}_${TYPE_ACTION}_${NIVEAU_SAUVEGARDE}_${MACHINE_S}.tar.gz" | Execute_Commande_C_Retour -d "cat - > ${TAPE_DEV_REP}/${DATE_EXE}_${TYPE_ACTION}_${NIVEAU_SAUVEGARDE}_${MACHINE_S}.tar.gz" fi + +grep -v "P" $ficsynthese + +rm -f /tmp/results.$$ /tmp/results.end.$$ 2>/dev/null diff --git a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/FLOW/FilePath/noError.sh b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/FLOW/FilePath/noError.sh index b8bce307..10b5ed14 100755 --- a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/FLOW/FilePath/noError.sh +++ b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/FLOW/FilePath/noError.sh @@ -4,7 +4,7 @@ echo "COM.FLOW.FilePath" echo "Fichier OK de test" echo "------------------------------------------" -if [ -f $fichier_texte ] || [ -f $fichier_texte_new ]; then - rm -f $fichier_texte - rm -f $fichier_texte_new +if [[ -n $REP_FICH_CONF ]]; then + echo "Le répertoire contenant le fichier de configuration est : + $REP_FICH_CONF" fi From 6d2177995d49047b1f0573a41861d13acca0b1e4 Mon Sep 17 00:00:00 2001 From: Brigitte Huynh Date: Tue, 21 Aug 2018 19:05:27 +0200 Subject: [PATCH 3/4] #123 Added the SH.SYNC.Signals rule. No update of the existing rule nor its test files as it seems to be working correctly. --- fr.cnes.analysis.tools.shell.rules/plugin.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/fr.cnes.analysis.tools.shell.rules/plugin.xml b/fr.cnes.analysis.tools.shell.rules/plugin.xml index 3f4014d2..67956f84 100755 --- a/fr.cnes.analysis.tools.shell.rules/plugin.xml +++ b/fr.cnes.analysis.tools.shell.rules/plugin.xml @@ -215,6 +215,11 @@ id="fr.cnes.analysis.tools.shell.rules.SHREFExport" name="SH.Ref.Export" languageId="fr.cnes.analysis.tools.languages.shell"> + + From 78e792a8be305cad6a9db85df862849d3dbbaf68 Mon Sep 17 00:00:00 2001 From: Brigitte Huynh Date: Tue, 21 Aug 2018 23:17:36 +0200 Subject: [PATCH 4/4] #117 Corrected false positives of COM.INST.BoolNegation (outside tests) and updated test file accordingly --- .../lex/COMINSTBoolNegation.lex | 3 +++ .../tools/shell/rules/COM/INST/BoolNegation/noError.sh | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/fr.cnes.analysis.tools.shell.rules/lex/COMINSTBoolNegation.lex b/fr.cnes.analysis.tools.shell.rules/lex/COMINSTBoolNegation.lex index 196a77c9..1bf96c8b 100755 --- a/fr.cnes.analysis.tools.shell.rules/lex/COMINSTBoolNegation.lex +++ b/fr.cnes.analysis.tools.shell.rules/lex/COMINSTBoolNegation.lex @@ -51,6 +51,8 @@ FNAME = [a-zA-Z0-9\.\!\-\_\@\?\+]+ SPACE = [\ \r\t\f\space] VAR = [a-zA-Z][a-zA-Z0-9\_]* +IGNORE = \$\{[^\}"\n"]*\} | \$\([^\)"\n"]*\) + FUNCSTART = \{ | \( | \(\( | \[\[ | "if" | "case" | "select" | "for" | "while" | "until" FUNCEND = \} | \) | \)\) | \]\] | "fi" | "esac" | "done" @@ -150,6 +152,7 @@ OPER = \&\& | \|\| | \-"o" | \-"a" {STRING_S} {yybegin(STRING_SIMPLE);} {FUNCTION} {yybegin(NAMING);} {FUNCT} {location = yytext().substring(0,yytext().length()-2).trim(); yybegin(BEGINFUNC);} + {IGNORE} {} {NOT} {bracket=0; brace=0; parenth=0; yybegin(LOGICAL);} {FUNCSTART} { if(!functionStack.empty()){ diff --git a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/INST/BoolNegation/noError.sh b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/INST/BoolNegation/noError.sh index 7e1414b7..046ea52d 100755 --- a/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/INST/BoolNegation/noError.sh +++ b/tests/fr.cnes.analysis.tools.shell.rules.test/src/fr/cnes/analysis/tools/shell/rules/COM/INST/BoolNegation/noError.sh @@ -10,4 +10,9 @@ if [ ! $a -eq 0 ] && [ ! $a -eq 1 ] ; then echo "You entered a different number from 0 or 1" fi +if [ ! -r "$1" -o ! -f "$1" ] ; then + echo "This should be ok" +fi +debug ${!F}_${!L} "----------------> BEGIN: existsAndNotEmpty $item" +debug ${!F}_${!L} $(ls ${reportsDir})