From 585b16b0daec4f0f3a6e396692560cdb678774d6 Mon Sep 17 00:00:00 2001 From: Colomban Wendling Date: Sat, 20 Apr 2019 10:54:27 +0200 Subject: [PATCH] COBOL: Import new upstream candidate parser This fixes support for COBOL symbols after the recent breakage of regex parsers, as well as introducing additional features and bug fixes. Also import some of the tests. https://github.com/universal-ctags/ctags/pull/2076 Part of #2119. --- ctags/parsers/cobol.c | 520 ++++++++++++++++++- src/symbols.c | 2 + src/tagmanager/tm_parser.c | 3 + tests/ctags/Makefile.am | 8 +- tests/ctags/cobol/helloworld.cbl | 14 + tests/ctags/cobol/helloworld.cbl.tags | 11 + tests/ctags/cobol/helloworld2.cbl | 19 + tests/ctags/cobol/helloworld2.cbl.tags | 11 + tests/ctags/cobol/levels.cbl | 27 + tests/ctags/cobol/levels.cbl.tags | 22 + tests/ctags/cobol/quoted-program-id.cbl | 7 + tests/ctags/cobol/quoted-program-id.cbl.tags | 5 + tests/ctags/{ => cobol}/simple.cbl | 0 tests/ctags/cobol/simple.cbl.tags | 22 + tests/ctags/simple.cbl.tags | 19 - 15 files changed, 645 insertions(+), 45 deletions(-) create mode 100644 tests/ctags/cobol/helloworld.cbl create mode 100644 tests/ctags/cobol/helloworld.cbl.tags create mode 100644 tests/ctags/cobol/helloworld2.cbl create mode 100644 tests/ctags/cobol/helloworld2.cbl.tags create mode 100644 tests/ctags/cobol/levels.cbl create mode 100644 tests/ctags/cobol/levels.cbl.tags create mode 100644 tests/ctags/cobol/quoted-program-id.cbl create mode 100644 tests/ctags/cobol/quoted-program-id.cbl.tags rename tests/ctags/{ => cobol}/simple.cbl (100%) create mode 100644 tests/ctags/cobol/simple.cbl.tags delete mode 100644 tests/ctags/simple.cbl.tags diff --git a/ctags/parsers/cobol.c b/ctags/parsers/cobol.c index 1ccc557e..69108a63 100644 --- a/ctags/parsers/cobol.c +++ b/ctags/parsers/cobol.c @@ -8,42 +8,516 @@ * files. */ +/* Some references: + * - https://www.cs.vu.nl/grammarware/browsable/cobol/ + * - https://www.cs.vu.nl/grammarware/browsable/vs-cobol-ii/ + * - https://open-cobol.sourceforge.io/guides/grammar.pdf + * - http://mapage.noos.fr/~bpinon/a_cobol_parser.htm + * - https://en.wikipedia.org/wiki/COBOL + */ + /* * INCLUDE FILES */ #include "general.h" /* must always come first */ +#include "debug.h" +#include "entry.h" +#include "keyword.h" +#include "nestlevel.h" #include "parse.h" +#include "read.h" #include "routines.h" -static tagRegexTable cobolTagRegexTable[] = { - {"^[ \t]*[0-9]+[ \t]+([A-Z0-9][A-Z0-9-]*)[ \t]+(" - "BLANK|OCCURS|IS|JUST|PIC|REDEFINES|RENAMES|SIGN|SYNC|USAGE|VALUE" - ")", "\\1", - "d,data,data items", "i", NULL}, - {"^[ \t]*[FSR]D[ \t]+([A-Z0-9][A-Z0-9-]*)\\.", "\\1", - "f,file,file descriptions (FD, SD, RD)", "i", NULL}, - {"^[ \t]*[0-9]+[ \t]+([A-Z0-9][A-Z0-9-]*)\\.", "\\1", - "g,group,group items", "i", NULL}, - {"^[ \t]*([A-Z0-9][A-Z0-9-]*)\\.", "\\1", - "p,paragraph,paragraphs", "i", NULL}, - {"^[ \t]*PROGRAM-ID\\.[ \t]+([A-Z0-9][A-Z0-9-]*)\\.", "\\1", - "P,program,program ids", "i", NULL}, - {"^[ \t]*([A-Z0-9][A-Z0-9-]*)[ \t]+SECTION\\.", "\\1", - "s,section,sections", "i", NULL}, +typedef enum { + K_FILE, + K_GROUP, + K_PROGRAM, + K_SECTION, + K_DIVISION, + K_PARAGRAPH, + K_DATA, + K_SOURCEFILE, +} cobolKind; + +typedef enum { + COBOL_SOURCEFILE_COPIED, +} cobolSourcefileRole; + +static roleDefinition CobolSourcefileRoles [] = { + { true, "copied", "copied in source file" }, }; -/* -* FUNCTION DEFINITIONS -*/ +static kindDefinition CobolKinds[] = { + { true, 'f', "fd", "file descriptions (FD, SD, RD)" }, + { true, 'g', "group", "group items" }, + { true, 'P', "program", "program ids" }, + { true, 's', "section", "sections" }, + { true, 'D', "division", "divisions" }, + { true, 'p', "paragraph", "paragraphs" }, + { true, 'd', "data", "data items" }, + { true, 'S', "sourcefile", "source code file", + .referenceOnly = true, ATTACH_ROLES(CobolSourcefileRoles)}, +}; + +static langType Lang_cobol; + +enum { + KEYWORD_FD, + KEYWORD_SD, + KEYWORD_RD, + KEYWORD_SECTION, + KEYWORD_DIVISION, + KEYWORD_CONTINUE, + KEYWORD_END_EXEC, + KEYWORD_FILLER, + KEYWORD_BLANK, + KEYWORD_OCCURS, + KEYWORD_IS, + KEYWORD_JUST, + KEYWORD_PIC, + KEYWORD_REDEFINES, + KEYWORD_RENAMES, + KEYWORD_SIGN, + KEYWORD_SYNC, + KEYWORD_USAGE, + KEYWORD_VALUE, + KEYWORD_PROGRAM_ID, + KEYWORD_EXIT, + KEYWORD_COPY, +}; + +static const keywordTable cobolKeywordTable[] = { +#define DEFINE_KEYWORD(n) { #n, KEYWORD_##n } + DEFINE_KEYWORD (FD), + DEFINE_KEYWORD (SD), + DEFINE_KEYWORD (RD), + DEFINE_KEYWORD (SECTION), + DEFINE_KEYWORD (DIVISION), + DEFINE_KEYWORD (CONTINUE), + { "END-EXEC", KEYWORD_END_EXEC }, + DEFINE_KEYWORD (EXIT), + DEFINE_KEYWORD (FILLER), + DEFINE_KEYWORD (BLANK), + DEFINE_KEYWORD (OCCURS), + DEFINE_KEYWORD (IS), + DEFINE_KEYWORD (JUST), + DEFINE_KEYWORD (PIC), + { "PICTURE", KEYWORD_PIC }, + DEFINE_KEYWORD (REDEFINES), + DEFINE_KEYWORD (RENAMES), + DEFINE_KEYWORD (SIGN), + DEFINE_KEYWORD (SYNC), + DEFINE_KEYWORD (USAGE), + DEFINE_KEYWORD (VALUE), + { "VALUES", KEYWORD_VALUE }, + { "PROGRAM-ID", KEYWORD_PROGRAM_ID }, + DEFINE_KEYWORD (COPY), +}; + +#define INDICATOR_COLUMN 7 +#define PROGRAM_NAME_AREA_COLUMN 73 + +#define isIdentifierChar(c) (isalnum(c) || (c) == '-') +#define isQuote(c) ((c) == '\'' || (c) == '"') + +typedef enum { + /* Fixed: program starts at column 8, ends at column 72 */ + FORMAT_FIXED = 0x1, + /* Free: program starts at column 1, no specific end */ + FORMAT_FREE = 0x2, + /* Variable: program starts at column 8, no specific end */ + FORMAT_VARIABLE = FORMAT_FIXED | FORMAT_FREE +} CobolFormat; + +static struct { + vString *line; + unsigned long int lineNumber; + MIOPos filePosition; + const char *nextLine; + CobolFormat format; +} CblInputState; + +static void cblppInit (const CobolFormat format) +{ + CblInputState.line = vStringNew (); + CblInputState.lineNumber = 0; + CblInputState.nextLine = NULL; + CblInputState.format = format; +} + +static void cblppDeinit (void) +{ + vStringDelete (CblInputState.line); +} + +static const char *cblppGetColumn (const char *line, + const unsigned int column) +{ + unsigned int col = 0; + + for (; *line; line++) + { + col += (*line == '\t') ? 8 : 1; + if (col >= column) + return line; + } + + return NULL; +} + +static void cblppAppendLine (vString *buffer, + const char *line) +{ + if (CblInputState.format & FORMAT_FIXED) + { + const char *indicator = cblppGetColumn (line, INDICATOR_COLUMN); + + if (indicator && *indicator && *indicator != '*' && *indicator != '/') + { + const char *lineStart = indicator + 1; + const char *lineEnd = cblppGetColumn (line, PROGRAM_NAME_AREA_COLUMN); + + if (*indicator == '-') + { + vStringStripTrailing (buffer); + while (isspace (*lineStart)) + lineStart++; + } + + if (CblInputState.format == FORMAT_FIXED) + vStringNCatS (buffer, lineStart, lineEnd - lineStart); + else + vStringCatS (buffer, lineStart); + } + } + else if (line[0] != '*' && line[0] != '/') + vStringCatS (buffer, line); +} + +/* TODO: skip *> comments */ +static const char *cblppGetLine (void) +{ + const char *line; + + if (CblInputState.nextLine) + { + line = CblInputState.nextLine; + CblInputState.nextLine = NULL; + } + else + line = (const char *) readLineFromInputFile (); + + CblInputState.lineNumber = getInputLineNumber (); + CblInputState.filePosition = getInputFilePosition (); + + if (!line) + return NULL; + + vStringClear (CblInputState.line); + cblppAppendLine (CblInputState.line, line); + + /* check for continuation lines */ + if (CblInputState.format & FORMAT_FIXED) + { + while (true) + { + const char *indicator; + line = (const char *) readLineFromInputFile (); + if (! line) + break; + indicator = cblppGetColumn (line, INDICATOR_COLUMN); + if (indicator && *indicator == '-') + cblppAppendLine (CblInputState.line, line); + else + break; + } + + CblInputState.nextLine = line; + } + + return vStringValue (CblInputState.line); +} + +static void initCOBOLRefTagEntry (tagEntryInfo *e, const char *name, + const cobolKind kind, const int role) +{ + initRefTagEntry (e, name, kind, role); + e->lineNumber = CblInputState.lineNumber; + e->filePosition = CblInputState.filePosition; +} + +static void initCOBOLTagEntry (tagEntryInfo *e, const char *name, const cobolKind kind) +{ + initCOBOLRefTagEntry (e, name, kind, ROLE_INDEX_DEFINITION); +} + +static int makeCOBOLRefTag (const char *name, const cobolKind kind, const int role) +{ + if (CobolKinds[kind].enabled) + { + tagEntryInfo e; + + initCOBOLRefTagEntry (&e, name, kind, role); + + return makeTagEntry (&e); + } + + return CORK_NIL; +} + +static int makeCOBOLTag (const char *name, const cobolKind kind) +{ + return makeCOBOLRefTag (name, kind, ROLE_INDEX_DEFINITION); +} + +#define CBL_NL(nl) (*((unsigned int *) (nestingLevelGetUserData (nl)))) + +static NestingLevel *popNestingLevelsToLevelNumber (NestingLevels *levels, const unsigned int levelNumber) +{ + NestingLevel *nl; + + while (true) + { + nl = nestingLevelsGetCurrent (levels); + if (! nl || CBL_NL (nl) < levelNumber) + break; + nestingLevelsPop (levels); + } + + return nl; +} + +static bool isNumeric (const char *nptr, unsigned long int *num) +{ + char *endptr; + unsigned long int v; + + v = strtoul (nptr, &endptr, 10); + if (nptr != endptr && *endptr == 0) + { + if (num) + *num = v; + return true; + } + return false; +} + +static void findCOBOLTags (const CobolFormat format) +{ + NestingLevels *levels; + const char *line; + + cblppInit (format); + + levels = nestingLevelsNew (sizeof (unsigned int)); + + while ((line = cblppGetLine ()) != NULL) + { + char word[64]; + int keyword; + unsigned long int levelNumber; + +#define READ_WHILE(word, cond) \ + do { \ + unsigned int i; \ + for (i = 0; i < (ARRAY_SIZE (word) - 1) && *line && (cond); line++) \ + word[i++] = *line; \ + word[i] = 0; \ + } while (0) +#define READ_LITERAL(word) \ + do { \ + const char READ_LITERAL__q = isQuote (*line) ? *line++ : 0; \ + READ_WHILE (word, (READ_LITERAL__q && READ_LITERAL__q != *line) || \ + isIdentifierChar (*line)); \ + if (READ_LITERAL__q && READ_LITERAL__q == *line) \ + line++; \ + keyword = lookupCaseKeyword (word, Lang_cobol); \ + } while (0) +#define READ_WORD(word, keyword) \ + do { \ + READ_WHILE (word, isIdentifierChar (*line)); \ + keyword = lookupCaseKeyword (word, Lang_cobol); \ + } while (0) +#define READ_KEYWORD(keyword) \ + do { \ + char READ_KEYWORD__word[64]; \ + READ_WORD (READ_KEYWORD__word, keyword); \ + } while (0) +#define SKIP_SPACES() do { while (isspace (*line)) line++; } while (0) + + SKIP_SPACES (); + READ_WORD (word, keyword); + SKIP_SPACES (); + + switch (keyword) + { + case KEYWORD_FD: + case KEYWORD_SD: + case KEYWORD_RD: + READ_WORD (word, keyword); + SKIP_SPACES (); + if (*word && *line == '.') + makeCOBOLTag (word, K_FILE); + break; + + case KEYWORD_PROGRAM_ID: + if (*line == '.') + { + line++; + SKIP_SPACES (); + } + READ_LITERAL (word); + if (*word) + makeCOBOLTag (word, K_PROGRAM); + break; + + case KEYWORD_COPY: + READ_WORD (word, keyword); // FIXME: also allow LITERAL + if (*word) + makeCOBOLRefTag (word, K_SOURCEFILE, COBOL_SOURCEFILE_COPIED); + break; + + case KEYWORD_CONTINUE: + case KEYWORD_END_EXEC: + case KEYWORD_EXIT: + case KEYWORD_FILLER: + /* nothing, just ignore those in following cases */; + break; + + default: + if (isNumeric (word, &levelNumber)) + { + READ_WORD (word, keyword); + SKIP_SPACES (); + + if (*word && keyword != KEYWORD_FILLER) + { + int kind = KIND_GHOST_INDEX; + + if (*line == '.') + kind = K_GROUP; + else + { + int keyword2; + + READ_KEYWORD (keyword2); + switch (keyword2) + { + case KEYWORD_BLANK: + case KEYWORD_OCCURS: + case KEYWORD_IS: + case KEYWORD_JUST: + case KEYWORD_PIC: + case KEYWORD_REDEFINES: + case KEYWORD_RENAMES: + case KEYWORD_SIGN: + case KEYWORD_SYNC: + case KEYWORD_USAGE: + case KEYWORD_VALUE: + kind = K_DATA; + } + } + + if (kind != KIND_GHOST_INDEX) + { + NestingLevel *nl; + tagEntryInfo entry; + int r; + unsigned int nestingLevelNumber; + + /* for nesting purposes, level 77 is identical to 1, + * and 66 to 2 */ + switch (levelNumber) + { + default: nestingLevelNumber = levelNumber; break; + case 77: nestingLevelNumber = 1; break; + case 66: nestingLevelNumber = 2; break; + } + + nl = popNestingLevelsToLevelNumber (levels, nestingLevelNumber); + initCOBOLTagEntry (&entry, word, kind); + if (nl && CBL_NL (nl) < nestingLevelNumber) + entry.extensionFields.scopeIndex = nl->corkIndex; + r = makeTagEntry (&entry); + if (levelNumber < 50 /* exclude special levels */) + { + nl = nestingLevelsPush (levels, r); + CBL_NL (nl) = levelNumber; + } + } + } + } + else if (*word && *line == '.') + makeCOBOLTag (word, K_PARAGRAPH); + else + { + int keyword2; + + READ_KEYWORD (keyword2); + SKIP_SPACES (); + + if (keyword2 == KEYWORD_DIVISION && *line == '.') + makeCOBOLTag (word, K_DIVISION); + else if (keyword2 == KEYWORD_SECTION && *line == '.') + makeCOBOLTag (word, K_SECTION); + } + } + } + + nestingLevelsFree (levels); + cblppDeinit (); +} + +static void findCOBOLFixedTags (void) +{ + findCOBOLTags (FORMAT_FIXED); +} + +static void findCOBOLFreeTags (void) +{ + findCOBOLTags (FORMAT_FREE); +} + +static void findCOBOLVariableTags (void) +{ + findCOBOLTags (FORMAT_VARIABLE); +} + +static void initializeCobolParser (langType language) +{ + Lang_cobol = language; +} + +static parserDefinition* commonCobolParserDefinition (const char *name, + simpleParser parser) +{ + parserDefinition* def = parserNew (name); + def->initialize = initializeCobolParser; + def->parser = parser; + def->kindTable = CobolKinds; + def->kindCount = ARRAY_SIZE(CobolKinds); + def->keywordTable = cobolKeywordTable; + def->keywordCount = ARRAY_SIZE(cobolKeywordTable); + def->useCork = true; + return def; +} extern parserDefinition* CobolParser (void) { static const char *const extensions [] = { - "cbl", "cob", "cpy", "CBL", "COB", NULL }; - parserDefinition* def = parserNew ("Cobol"); + "cbl", "cob", "CBL", "COB", NULL }; + parserDefinition* def = commonCobolParserDefinition ("Cobol", + findCOBOLFixedTags); def->extensions = extensions; - def->tagRegexTable = cobolTagRegexTable; - def->tagRegexCount = ARRAY_SIZE (cobolTagRegexTable); - def->method = METHOD_NOT_CRAFTED|METHOD_REGEX; return def; } + +extern parserDefinition* CobolFreeParser (void) +{ + return commonCobolParserDefinition ("CobolFree", findCOBOLFreeTags); +} + +extern parserDefinition* CobolVariableParser (void) +{ + return commonCobolParserDefinition ("CobolVariable", findCOBOLVariableTags); +} diff --git a/src/symbols.c b/src/symbols.c index bed454d3..c250c7ce 100644 --- a/src/symbols.c +++ b/src/symbols.c @@ -490,10 +490,12 @@ static void add_top_level_items(GeanyDocument *doc) tag_list_add_groups(tag_store, &tv_iters.tag_class, _("Program"), ICON_CLASS, &tv_iters.tag_function, _("File"), ICON_METHOD, + &tv_iters.tag_interface, _("Divisions"), ICON_NAMESPACE, &tv_iters.tag_namespace, _("Sections"), ICON_NAMESPACE, &tv_iters.tag_macro, _("Paragraph"), ICON_OTHER, &tv_iters.tag_struct, _("Group"), ICON_STRUCT, &tv_iters.tag_variable, _("Data"), ICON_VAR, + &tv_iters.tag_externvar, _("Copies"), ICON_NAMESPACE, NULL); break; case GEANY_FILETYPES_CONF: diff --git a/src/tagmanager/tm_parser.c b/src/tagmanager/tm_parser.c index e5564ffa..d7d4d95f 100644 --- a/src/tagmanager/tm_parser.c +++ b/src/tagmanager/tm_parser.c @@ -423,11 +423,13 @@ static TMParserMapEntry map_R[] = { static TMParserMapEntry map_COBOL[] = { {'d', tm_tag_variable_t}, + {'D', tm_tag_interface_t}, {'f', tm_tag_function_t}, {'g', tm_tag_struct_t}, {'p', tm_tag_macro_t}, {'P', tm_tag_class_t}, {'s', tm_tag_namespace_t}, + {'S', tm_tag_externvar_t}, }; static TMParserMapEntry map_OBJC[] = { @@ -768,6 +770,7 @@ gboolean tm_parser_has_full_context(TMParserType lang) case TM_PARSER_C: case TM_PARSER_CPP: case TM_PARSER_CSHARP: + case TM_PARSER_COBOL: case TM_PARSER_D: case TM_PARSER_FERITE: case TM_PARSER_GLSL: diff --git a/tests/ctags/Makefile.am b/tests/ctags/Makefile.am index a934b517..6e2a96cc 100644 --- a/tests/ctags/Makefile.am +++ b/tests/ctags/Makefile.am @@ -1,9 +1,6 @@ dist_check_SCRIPTS = runner.sh -# Disabled tests: -# simple.cbl - NULL = test_sources = \ 1795612.js \ @@ -117,6 +114,11 @@ test_sources = \ case_sensitivity.php \ char-selector.f90 \ classes.php \ + cobol/helloworld.cbl \ + cobol/helloworld2.cbl \ + cobol/levels.cbl \ + cobol/quoted-program-id.cbl \ + cobol/simple.cbl \ common.f \ complex-return.js \ continuation.f90 \ diff --git a/tests/ctags/cobol/helloworld.cbl b/tests/ctags/cobol/helloworld.cbl new file mode 100644 index 00000000..63bbf6dd --- /dev/null +++ b/tests/ctags/cobol/helloworld.cbl @@ -0,0 +1,14 @@ + 00000* VALIDATION OF BASE COBOL INSTALL 00050000 + 01000 IDENTIFICATION DIVISION. 00060000 + 01100 PROGRAM-ID. 'HELLO'. 00070000 + 02000 ENVIRONMENT DIVISION. 00080000 + 02100 CONFIGURATION SECTION. 00090000 + 02110 SOURCE-COMPUTER. GNULINUX. 00100000 + 02120 OBJECT-COMPUTER. HERCULES. 00110000 + 02200 SPECIAL-NAMES. 00120000 + 02210 CONSOLE IS CONSL. 00130000 + 03000 DATA DIVISION. 00140000 + 04000 PROCEDURE DIVISION. 00150000 + 04100 00-MAIN. 00160000 + 04110 DISPLAY 'HELLO, WORLD' UPON CONSL. 00170000 + 04900 STOP RUN. 00180000 diff --git a/tests/ctags/cobol/helloworld.cbl.tags b/tests/ctags/cobol/helloworld.cbl.tags new file mode 100644 index 00000000..3dfafb5e --- /dev/null +++ b/tests/ctags/cobol/helloworld.cbl.tags @@ -0,0 +1,11 @@ +# format=tagmanager +00-MAINÌ65536Ö0 +CONFIGURATIONÌ256Ö0 +DATAÌ32Ö0 +ENVIRONMENTÌ32Ö0 +HELLOÌ1Ö0 +IDENTIFICATIONÌ32Ö0 +OBJECT-COMPUTERÌ65536Ö0 +PROCEDUREÌ32Ö0 +SOURCE-COMPUTERÌ65536Ö0 +SPECIAL-NAMESÌ65536Ö0 diff --git a/tests/ctags/cobol/helloworld2.cbl b/tests/ctags/cobol/helloworld2.cbl new file mode 100644 index 00000000..4b2a734e --- /dev/null +++ b/tests/ctags/cobol/helloworld2.cbl @@ -0,0 +1,19 @@ + 00000* VALIDATION OF BASE COBOL INSTALL + IDENTIFICATION DIVISION. + 01100 PROGRAM-ID. 'HELLO WORLD'. + 02000 ENVIRONMENT DIV + -ISION. + 02100 CONFIGURATION SECTION. + 02110 SOURCE-COMPUTER. GNULINUX. + 02120 OBJECT-COMPUTER. HERCULES. + 02200 SPECIAL + --NAMES. + 02210 CONSOLE IS CONSL. + 03000 DATA DIVISION. + 04000 PROCEDUR + - E DIVISION. + 04100 00-MAIN. + 04110 DISPLAY + 'HELLO, WORLD' + UPON CONSL. + 04900 STOP RUN. diff --git a/tests/ctags/cobol/helloworld2.cbl.tags b/tests/ctags/cobol/helloworld2.cbl.tags new file mode 100644 index 00000000..6eee0a09 --- /dev/null +++ b/tests/ctags/cobol/helloworld2.cbl.tags @@ -0,0 +1,11 @@ +# format=tagmanager +00-MAINÌ65536Ö0 +CONFIGURATIONÌ256Ö0 +DATAÌ32Ö0 +ENVIRONMENTÌ32Ö0 +HELLO WORLDÌ1Ö0 +IDENTIFICATIONÌ32Ö0 +OBJECT-COMPUTERÌ65536Ö0 +PROCEDUREÌ32Ö0 +SOURCE-COMPUTERÌ65536Ö0 +SPECIAL-NAMESÌ65536Ö0 diff --git a/tests/ctags/cobol/levels.cbl b/tests/ctags/cobol/levels.cbl new file mode 100644 index 00000000..90042e09 --- /dev/null +++ b/tests/ctags/cobol/levels.cbl @@ -0,0 +1,27 @@ + IDENTIFICATION DIVISION. + PROGRAM-ID. Test-Items. + + DATA DIVISION. + WORKING-STORAGE SECTION. + 01 RECORD1. + 05 ITEM1 PIC X(1). + 05 ITEM2 PIC A(1). + 88 ODD VALUES 1, 3, 5, 7, 9. + 88 EVEN VALUES 2, 4, 6, 8. + 05 ITEM3 PIC X(6). + 66 RDITEM4 RENAMES ITEM1 THRU ITEM2. + 66 RDITEM5 RENAMES ITEM1 THROUGH ITEM3. + 77 STDLN1 PIC A(4). + 01 REC2. + 02 G1. + 05 ITEM1 PICTURE X(10). + 05 ITEM2 PIC X(10). + 66 OTHERNAME1 RENAMES ITEM1 IN REC2. + 66 OTHERNAME2 RENAMES G1. + + PROCEDURE DIVISION. + MAIN-PROCEDURE. + DISPLAY "Hello world". + DISPLAY OTHERNAME2. + STOP RUN. + END PROGRAM Test-Items. diff --git a/tests/ctags/cobol/levels.cbl.tags b/tests/ctags/cobol/levels.cbl.tags new file mode 100644 index 00000000..566e2329 --- /dev/null +++ b/tests/ctags/cobol/levels.cbl.tags @@ -0,0 +1,22 @@ +# format=tagmanager +DATAÌ32Ö0 +EVENÌ16384ÎRECORD1.ITEM2Ö0 +G1Ì2048ÎREC2Ö0 +IDENTIFICATIONÌ32Ö0 +ITEM1Ì16384ÎREC2.G1Ö0 +ITEM1Ì16384ÎRECORD1Ö0 +ITEM2Ì16384ÎREC2.G1Ö0 +ITEM2Ì16384ÎRECORD1Ö0 +ITEM3Ì16384ÎRECORD1Ö0 +MAIN-PROCEDUREÌ65536Ö0 +ODDÌ16384ÎRECORD1.ITEM2Ö0 +OTHERNAME1Ì16384ÎREC2Ö0 +OTHERNAME2Ì16384ÎREC2Ö0 +PROCEDUREÌ32Ö0 +RDITEM4Ì16384ÎRECORD1Ö0 +RDITEM5Ì16384ÎRECORD1Ö0 +REC2Ì2048Ö0 +RECORD1Ì2048Ö0 +STDLN1Ì16384Ö0 +Test-ItemsÌ1Ö0 +WORKING-STORAGEÌ256Ö0 diff --git a/tests/ctags/cobol/quoted-program-id.cbl b/tests/ctags/cobol/quoted-program-id.cbl new file mode 100644 index 00000000..10fbefe5 --- /dev/null +++ b/tests/ctags/cobol/quoted-program-id.cbl @@ -0,0 +1,7 @@ + IDENTIFICATION DIVISION. + PROGRAM-ID. 'Test program name'. + PROCEDURE DIVISION. + MAIN. + DISPLAY 'This is a test program'. + STOP RUN. + END PROGRAM 'Test program name'. diff --git a/tests/ctags/cobol/quoted-program-id.cbl.tags b/tests/ctags/cobol/quoted-program-id.cbl.tags new file mode 100644 index 00000000..31c4af14 --- /dev/null +++ b/tests/ctags/cobol/quoted-program-id.cbl.tags @@ -0,0 +1,5 @@ +# format=tagmanager +IDENTIFICATIONÌ32Ö0 +MAINÌ65536Ö0 +PROCEDUREÌ32Ö0 +Test program nameÌ1Ö0 diff --git a/tests/ctags/simple.cbl b/tests/ctags/cobol/simple.cbl similarity index 100% rename from tests/ctags/simple.cbl rename to tests/ctags/cobol/simple.cbl diff --git a/tests/ctags/cobol/simple.cbl.tags b/tests/ctags/cobol/simple.cbl.tags new file mode 100644 index 00000000..6066e881 --- /dev/null +++ b/tests/ctags/cobol/simple.cbl.tags @@ -0,0 +1,22 @@ +# format=tagmanager +AUTHORÌ65536Ö0 +BeginÌ65536Ö0 +DATAÌ32Ö0 +DW-DAYS-IN-MONTHÌ16384ÎGroup-Name.Data-Item1.DW-DAYS-IN-MONTHSÖ0 +DW-DAYS-IN-MONTHSÌ16384ÎGroup-Name.Data-Item1Ö0 +Data-Item1Ì16384ÎGroup-NameÖ0 +ENVIRONMENTÌ32Ö0 +FILEÌ256Ö0 +FILE-CONTROLÌ65536Ö0 +File-Data-ItemÌ16384ÎFile-Group-NameÖ0 +File-Group-NameÌ2048Ö0 +File-NameÌ16Ö0 +Group-NameÌ2048Ö0 +IDENTIFICATIONÌ32Ö0 +INPUT-OUPUTÌ256Ö0 +PROCEDUREÌ32Ö0 +Program-NameÌ1Ö0 +SH-WORK-MMDDYYYYÌ16384ÎGroup-Name.Data-Item1Ö0 +SH-WORK-MMDDYYYY-2Ì16384ÎGroup-Name.Data-Item1Ö0 +Subprogram-NameÌ65536Ö0 +WORKING-STORAGEÌ256Ö0 diff --git a/tests/ctags/simple.cbl.tags b/tests/ctags/simple.cbl.tags deleted file mode 100644 index 07ce90d8..00000000 --- a/tests/ctags/simple.cbl.tags +++ /dev/null @@ -1,19 +0,0 @@ -# format=tagmanager -AUTHORÌ65536Ö0 -BeginÌ65536Ö0 -DW-DAYS-IN-MONTHÌ16384Ö0 -DW-DAYS-IN-MONTHSÌ16384Ö0 -Data-Item1Ì16384Ö0 -FILEÌ256Ö0 -FILE-CONTROLÌ65536Ö0 -File-Data-ItemÌ16384Ö0 -File-Group-NameÌ2048Ö0 -File-NameÌ16Ö0 -Group-NameÌ2048Ö0 -INPUT-OUPUTÌ256Ö0 -PROGRAM-IDÌ65536Ö0 -Program-NameÌ1Ö0 -SH-WORK-MMDDYYYYÌ16384Ö0 -SH-WORK-MMDDYYYY-2Ì16384Ö0 -Subprogram-NameÌ65536Ö0 -WORKING-STORAGEÌ256Ö0