diff --git a/Units/parser-robot.r/keyword-started-from-varref.d/args.ctags b/Units/parser-robot.r/keyword-started-from-varref.d/args.ctags new file mode 100644 index 0000000000..5ee5f79f70 --- /dev/null +++ b/Units/parser-robot.r/keyword-started-from-varref.d/args.ctags @@ -0,0 +1 @@ +--sort=no diff --git a/Units/parser-robot.r/keyword-started-from-varref.d/expected.tags b/Units/parser-robot.r/keyword-started-from-varref.d/expected.tags new file mode 100644 index 0000000000..04a01ca332 --- /dev/null +++ b/Units/parser-robot.r/keyword-started-from-varref.d/expected.tags @@ -0,0 +1,33 @@ +myvar input.robot /^${myvar} variable_value$/;" v +My Regular Keyword input.robot /^My Regular Keyword$/;" k +My_Regular_Keyword input.robot /^My Regular Keyword$/;" k +${embedded arg} Starting Single input.robot /^${embedded arg} Starting Single$/;" k +${embedded_arg}_Starting_Single input.robot /^${embedded arg} Starting Single$/;" k +${e} Starting Single Letter input.robot /^${e} Starting Single Letter$/;" k +${e}_Starting_Single_Letter input.robot /^${e} Starting Single Letter$/;" k +${embedded arg:value1|value2} Starting Single With Regex input.robot /^${embedded arg:value1|value2} Starting Single With Regex$/;" k +${embedded_arg:value1|value2}_Starting_Single_With_Regex input.robot /^${embedded arg:value1|value2} Starting Single With Regex$/;" k +${embedded arg1} Starting ${embedded arg2} Multiple input.robot /^${embedded arg1} Starting ${embedded arg2} Multiple$/;" k +${embedded_arg1}_Starting_${embedded_arg2}_Multiple input.robot /^${embedded arg1} Starting ${embedded arg2} Multiple$/;" k +${embedded arg1} Starting ${embedded arg2:value1|value2} Multiple With Regex input.robot /^${embedded arg1} Starting ${embedded arg2:value1|value2} Multiple With Regex$/;" k +${embedded_arg1}_Starting_${embedded_arg2:value1|value2}_Multiple_With_Regex input.robot /^${embedded arg1} Starting ${embedded arg2:value1|value2} Multiple With Regex$/;" k +${embedded arg1} Starting And ${embedded arg2} Ending ${embedded arg3} input.robot /^${embedded arg1} Starting And ${embedded arg2} Ending ${embedded arg3}$/;" k +${embedded_arg1}_Starting_And_${embedded_arg2}_Ending_${embedded_arg3} input.robot /^${embedded arg1} Starting And ${embedded arg2} Ending ${embedded arg3}$/;" k +Middle ${embedded arg} Single Arguments input.robot /^Middle ${embedded arg} Single Arguments$/;" k +Middle_${embedded_arg}_Single_Arguments input.robot /^Middle ${embedded arg} Single Arguments$/;" k +Middle ${embedded arg1} Multiple ${embedded arg2} Arguments input.robot /^Middle ${embedded arg1} Multiple ${embedded arg2} Arguments$/;" k +Middle_${embedded_arg1}_Multiple_${embedded_arg2}_Arguments input.robot /^Middle ${embedded arg1} Multiple ${embedded arg2} Arguments$/;" k +Middle ${embedded arg:value1|value2} Single Arguments With Regex input.robot /^Middle ${embedded arg:value1|value2} Single Arguments With Regex$/;" k +Middle_${embedded_arg:value1|value2}_Single_Arguments_With_Regex input.robot /^Middle ${embedded arg:value1|value2} Single Arguments With Regex$/;" k +Middle ${e} Single Letter Arguments input.robot /^Middle ${e} Single Letter Arguments$/;" k +Middle_${e}_Single_Letter_Arguments input.robot /^Middle ${e} Single Letter Arguments$/;" k +Ending Single ${embedded arg} input.robot /^Ending Single ${embedded arg}$/;" k +Ending_Single_${embedded_arg} input.robot /^Ending Single ${embedded arg}$/;" k +Ending Multiple ${embedded arg1} And ${embedded arg2} input.robot /^Ending Multiple ${embedded arg1} And ${embedded arg2}$/;" k +Ending_Multiple_${embedded_arg1}_And_${embedded_arg2} input.robot /^Ending Multiple ${embedded arg1} And ${embedded arg2}$/;" k +My Keyword_with_underscore-and-dashes input.robot /^My Keyword_with_underscore-and-dashes$/;" k +My Keyword with underscore-and-dashes input.robot /^My Keyword_with_underscore-and-dashes$/;" k +My Keyword_With $ dollar sign input.robot /^My Keyword_With $ dollar sign$/;" k +My Keyword With $ dollar sign input.robot /^My Keyword_With $ dollar sign$/;" k +My Test With Template1 input.robot /^My Test With Template1 My Kw 1 My Kw 2$/;" t +My_Test_With_Template1 input.robot /^My Test With Template1 My Kw 1 My Kw 2$/;" t diff --git a/Units/parser-robot.r/keyword-started-from-varref.d/input.robot b/Units/parser-robot.r/keyword-started-from-varref.d/input.robot new file mode 100644 index 0000000000..90ffcc55b6 --- /dev/null +++ b/Units/parser-robot.r/keyword-started-from-varref.d/input.robot @@ -0,0 +1,58 @@ +# +# This test input is taken from #1572 opened by @mMontu. +# +*** Variables *** + +${myvar} variable_value + +*** Keywords *** + +My Regular Keyword + Sleep 5s + +${embedded arg} Starting Single + No Operation + +${e} Starting Single Letter + No Operation + + +${embedded arg:value1|value2} Starting Single With Regex + No Operation + +${embedded arg1} Starting ${embedded arg2} Multiple + No Operation + +${embedded arg1} Starting ${embedded arg2:value1|value2} Multiple With Regex + No Operation + +${embedded arg1} Starting And ${embedded arg2} Ending ${embedded arg3} + No Operation + +Middle ${embedded arg} Single Arguments + No Operation + +Middle ${embedded arg1} Multiple ${embedded arg2} Arguments + No Operation + +Middle ${embedded arg:value1|value2} Single Arguments With Regex + No Operation + +Middle ${e} Single Letter Arguments + No Operation + +Ending Single ${embedded arg} + No Operation + +Ending Multiple ${embedded arg1} And ${embedded arg2} + No Operation + +My Keyword_with_underscore-and-dashes + No Operation + +My Keyword_With $ dollar sign + No Operation + +*** Test Cases *** + +My Test With Template1 My Kw 1 My Kw 2 diff --git a/main/lregex.c b/main/lregex.c index cbe8d94444..43d944b25a 100644 --- a/main/lregex.c +++ b/main/lregex.c @@ -1116,7 +1116,7 @@ static void matchTagPattern (struct lregexControlBlock *lcb, vStringDelete (name); } -static void matchCallbackPattern ( +static bool matchCallbackPattern ( const vString* const line, const regexPattern* const patbuf, const regmatch_t* const pmatch) { @@ -1134,7 +1134,7 @@ static void matchCallbackPattern ( if (pmatch [i].rm_so != -1) count = i + 1; } - patbuf->u.callback.function (vStringValue (line), matches, count, + return patbuf->u.callback.function (vStringValue (line), matches, count, patbuf->u.callback.userData); } @@ -1159,7 +1159,7 @@ static bool matchRegexPattern (struct lregexControlBlock *lcb, if (patbuf->type == PTRN_TAG) matchTagPattern (lcb, vStringValue (line), patbuf, pmatch, 0); else if (patbuf->type == PTRN_CALLBACK) - matchCallbackPattern (line, patbuf, pmatch); + result = matchCallbackPattern (line, patbuf, pmatch); else { Assert ("invalid pattern type" == NULL); diff --git a/main/lregex.h b/main/lregex.h index 351bed77b8..1aa956964e 100644 --- a/main/lregex.h +++ b/main/lregex.h @@ -37,7 +37,10 @@ enum regexParserType { REG_PARSER_MULTI_TABLE, }; -typedef void (*regexCallback) (const char *line, const regexMatch *matches, unsigned int count, +/* Return value is referred when {exclusive} is also specified. + The input line is consumed when "{exclusive}" is specified and + the value returned from the callback function is true. */ +typedef bool (*regexCallback) (const char *line, const regexMatch *matches, unsigned int count, void *userData); struct lregexControlBlock; diff --git a/parsers/cobol.c b/parsers/cobol.c index a72990e4c5..b895d475a5 100644 --- a/parsers/cobol.c +++ b/parsers/cobol.c @@ -91,23 +91,25 @@ static void cobol_make_tag_maybe (const char *line, } } -static void make_tag_for_data_maybe (const char *line, +static bool make_tag_for_data_maybe (const char *line, const regexMatch *matches, unsigned int count, void *data) { cobol_make_tag_maybe (line, matches, count, *(langType *)data, 1, K_DATA); + return true; } -static void make_tag_for_paragraph_maybe (const char *line, +static bool make_tag_for_paragraph_maybe (const char *line, const regexMatch *matches, unsigned int count, void *data) { cobol_make_tag_maybe (line, matches, count, *(langType *)data, 1, K_PARAGRAPH); + return true; } -static void make_tag_for_copied_in_sourcefile (const char *line, +static bool make_tag_for_copied_in_sourcefile (const char *line, const regexMatch *matches, unsigned int count, void *data CTAGS_ATTR_UNUSED) @@ -120,6 +122,7 @@ static void make_tag_for_copied_in_sourcefile (const char *line, makeSimpleRefTag (name, CobolKinds, K_SOURCEFILE, COBOL_SOURCEFILE_COPIED); vStringDelete (name); } + return true; } static void initializeCobolParser (langType language) diff --git a/parsers/robot.c b/parsers/robot.c index 262bf58d7e..989733ad11 100644 --- a/parsers/robot.c +++ b/parsers/robot.c @@ -71,7 +71,7 @@ static bool whitespaceSwap (vString *const s) return changed; } -static void changeSection (const char *const line, const regexMatch *const matches, +static bool changeSection (const char *const line, const regexMatch *const matches, const unsigned int count CTAGS_ATTR_UNUSED, void *data CTAGS_ATTR_UNUSED) { const char * const matchedSection = line + matches[1].start; @@ -88,6 +88,7 @@ static void changeSection (const char *const line, const regexMatch *const match { section = K_VARIABLE; } + return true; } static void makeSimpleXTag (const vString* const name, kindDefinition* const kinds, const int kind, @@ -100,7 +101,7 @@ static void makeSimpleXTag (const vString* const name, kindDefinition* const kin makeTagEntry (&e); } -static void tagKeywordsAndTestCases (const char *const line, const regexMatch *const matches, +static bool tagKeywordsAndTestCases (const char *const line, const regexMatch *const matches, const unsigned int count, void *data CTAGS_ATTR_UNUSED) { if (count > 1 && ( section == K_KEYWORD || section == K_TESTCASE) ) @@ -113,10 +114,12 @@ static void tagKeywordsAndTestCases (const char *const line, const regexMatch *c makeSimpleXTag (name, RobotKinds, section, RobotXtags[X_WHITESPACE_SWAPPED].xtype); vStringDelete (name); + return true; } + return false; } -static void tagVariables (const char *const line, const regexMatch *const matches, +static bool tagVariables (const char *const line, const regexMatch *const matches, const unsigned int count, void *data CTAGS_ATTR_UNUSED) { if (count > 1 && section == K_VARIABLE) @@ -129,15 +132,21 @@ static void tagVariables (const char *const line, const regexMatch *const matche makeSimpleXTag (name, RobotKinds, K_VARIABLE, RobotXtags[X_WHITESPACE_SWAPPED].xtype); vStringDelete (name); + return true; } + return false; } static void initialize (const langType language) { addLanguageCallbackRegex (language, "^\\*+ *([^* ].+[^* ]) *\\*+$", "{exclusive}", changeSection, NULL, NULL); - addLanguageCallbackRegex (language, "(^[A-Za-z0-9]+([${}' _][-${}A-Za-z0-9]+)*)", - "{exclusive}", tagKeywordsAndTestCases, NULL, NULL); + + addLanguageCallbackRegex ( + language, + "(^([A-Za-z0-9]+|\\$\\{[_A-Za-z0-9][' _A-Za-z0-9]*(:([^}]|\\\\|.{0})+)*\\})([${}' _]([-_$A-Za-z0-9]+|\\{[_A-Za-z0-9][' _A-Za-z0-9]*(:([^}]|\\\\|.{0})+)*\\})+)*)", + "{exclusive}", tagKeywordsAndTestCases, NULL, NULL); + addLanguageCallbackRegex (language, "^[$@]\\{([_A-Za-z0-9][' _A-Za-z0-9]+)\\} [ ]*.+", "{exclusive}", tagVariables, NULL, NULL); } diff --git a/parsers/rpmspec.c b/parsers/rpmspec.c index 1dfbb06f95..6706967c3d 100644 --- a/parsers/rpmspec.c +++ b/parsers/rpmspec.c @@ -76,7 +76,7 @@ static bool is_line_continued(const char *line) || ((len >= 2) && (line[len - 1] == '\n') && (line[len - 2] == '\\')))? true: false; } -static void found_macro_cb (const char *line, +static bool found_macro_cb (const char *line, const regexMatch *matches, unsigned int count, void *uesrData) @@ -117,9 +117,10 @@ static void found_macro_cb (const char *line, if (signature) vStringDelete (signature); } + return true; } -static void found_tag_cb (const char *line, +static bool found_tag_cb (const char *line, const regexMatch *matches, unsigned int count, void *userData) @@ -142,9 +143,10 @@ static void found_tag_cb (const char *line, } vStringDelete (name); } + return true; } -static void found_package_cb (const char *line, +static bool found_package_cb (const char *line, const regexMatch *matches, unsigned int count, void *userData) @@ -160,6 +162,7 @@ static void found_package_cb (const char *line, makeTagEntry (&tag); vStringDelete (name); } + return true; } static void initializeRpmSpecParser (langType language) diff --git a/parsers/yacc.c b/parsers/yacc.c index 79808aad22..c09b4fa3c4 100644 --- a/parsers/yacc.c +++ b/parsers/yacc.c @@ -34,7 +34,7 @@ struct cStart { unsigned long source; }; -static void change_section (const char *line CTAGS_ATTR_UNUSED, +static bool change_section (const char *line CTAGS_ATTR_UNUSED, const regexMatch *matches CTAGS_ATTR_UNUSED, unsigned int count CTAGS_ATTR_UNUSED, void *data CTAGS_ATTR_UNUSED) @@ -69,9 +69,10 @@ static void change_section (const char *line CTAGS_ATTR_UNUSED, makePromise ("C", c_start, 0, c_end, endCharOffset, c_source_start); } + return true; } -static void enter_c_prologue (const char *line CTAGS_ATTR_UNUSED, +static bool enter_c_prologue (const char *line CTAGS_ATTR_UNUSED, const regexMatch *matches CTAGS_ATTR_UNUSED, unsigned int count CTAGS_ATTR_UNUSED, void *data) @@ -82,9 +83,10 @@ static void enter_c_prologue (const char *line CTAGS_ATTR_UNUSED, readLineFromInputFile (); cstart->input = getInputLineNumber (); cstart->source = getSourceLineNumber (); + return true; } -static void leave_c_prologue (const char *line CTAGS_ATTR_UNUSED, +static bool leave_c_prologue (const char *line CTAGS_ATTR_UNUSED, const regexMatch *matches CTAGS_ATTR_UNUSED, unsigned int count CTAGS_ATTR_UNUSED, void *data) @@ -95,9 +97,11 @@ static void leave_c_prologue (const char *line CTAGS_ATTR_UNUSED, c_end = getInputLineNumber (); makePromise ("C", cstart->input, 0, c_end, 0, cstart->source); memset (cstart, 0, sizeof (*cstart)); + + return true; } -static void enter_union (const char *line CTAGS_ATTR_UNUSED, +static bool enter_union (const char *line CTAGS_ATTR_UNUSED, const regexMatch *matches CTAGS_ATTR_UNUSED, unsigned int count CTAGS_ATTR_UNUSED, void *data) @@ -110,9 +114,10 @@ static void enter_union (const char *line CTAGS_ATTR_UNUSED, cstart->input = getInputLineNumber (); cstart->source = getInputLineNumber (); } + return true; } -static void leave_union (const char *line CTAGS_ATTR_UNUSED, +static bool leave_union (const char *line CTAGS_ATTR_UNUSED, const regexMatch *matches CTAGS_ATTR_UNUSED, unsigned int count CTAGS_ATTR_UNUSED, void *data) @@ -132,6 +137,7 @@ static void leave_union (const char *line CTAGS_ATTR_UNUSED, memset (cstart, 0, sizeof (*cstart)); in_union = false; } + return true; } static void initializeYaccParser (langType language)