diff options
| author | Fabrice Nicol | 2021-06-17 19:59:52 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2021-06-18 14:18:34 +0300 |
| commit | 0ffcf7479c49ad5e0f9f675124c7cf741197aedd (patch) | |
| tree | 4a630b074ae5485677a23fe764f613fb16c582f3 /lib-src | |
| parent | bc44763b8342ee9e1bf43ffb202c73fee5ba0bf6 (diff) | |
| download | emacs-0ffcf7479c49ad5e0f9f675124c7cf741197aedd.tar.gz emacs-0ffcf7479c49ad5e0f9f675124c7cf741197aedd.zip | |
Fix Mercury support, notably qualified procedures.
Correct the previous fix (did not correctly handle qualified types).
Also fix the following issues:
- remove module name (+ dot) from tags, as prefixing module name is
often inconsistent in code and may cause tags to be too specific.
- now tag 0-arity predicates and functions (':- func foo_14.')
- now tag one-word declarations (':- interface.')
* lib-src/etags.c (mercury_pr): Pass the correct NAME and NAMELEN
arguments to 'make_tag'.
(mercury_decl): Return more information about the declaration or
definition it finds. This allows mercury_pr to be smarter.
(Bug#47408)
Diffstat (limited to 'lib-src')
| -rw-r--r-- | lib-src/etags.c | 126 |
1 files changed, 83 insertions, 43 deletions
diff --git a/lib-src/etags.c b/lib-src/etags.c index 9f20e44caf4..bd57ede2f37 100644 --- a/lib-src/etags.c +++ b/lib-src/etags.c | |||
| @@ -6081,10 +6081,10 @@ prolog_atom (char *s, size_t pos) | |||
| 6081 | pos++; | 6081 | pos++; |
| 6082 | if (s[pos] != '\'') | 6082 | if (s[pos] != '\'') |
| 6083 | break; | 6083 | break; |
| 6084 | pos++; /* A double quote */ | 6084 | pos++; /* A double quote */ |
| 6085 | } | 6085 | } |
| 6086 | else if (s[pos] == '\0') | 6086 | else if (s[pos] == '\0') |
| 6087 | /* Multiline quoted atoms are ignored. */ | 6087 | /* Multiline quoted atoms are ignored. */ |
| 6088 | return 0; | 6088 | return 0; |
| 6089 | else if (s[pos] == '\\') | 6089 | else if (s[pos] == '\\') |
| 6090 | { | 6090 | { |
| @@ -6119,6 +6119,13 @@ static void mercury_skip_comment (linebuffer *, FILE *); | |||
| 6119 | static bool is_mercury_type = false; | 6119 | static bool is_mercury_type = false; |
| 6120 | static bool is_mercury_quantifier = false; | 6120 | static bool is_mercury_quantifier = false; |
| 6121 | static bool is_mercury_declaration = false; | 6121 | static bool is_mercury_declaration = false; |
| 6122 | typedef struct | ||
| 6123 | { | ||
| 6124 | size_t pos; /* Position reached in parsing tag name. */ | ||
| 6125 | size_t namelength; /* Length of tag name */ | ||
| 6126 | size_t totlength; /* Total length of parsed tag: this field is currently | ||
| 6127 | reserved for control and debugging. */ | ||
| 6128 | } mercury_pos_t; | ||
| 6122 | 6129 | ||
| 6123 | /* | 6130 | /* |
| 6124 | * Objective-C and Mercury have identical file extension .m. | 6131 | * Objective-C and Mercury have identical file extension .m. |
| @@ -6374,10 +6381,12 @@ static const char *Mercury_decl_tags[] = {"type", "solver type", "pred", | |||
| 6374 | "initialise", "finalise", "mutable", "module", "interface", "implementation", | 6381 | "initialise", "finalise", "mutable", "module", "interface", "implementation", |
| 6375 | "import_module", "use_module", "include_module", "end_module", "some", "all"}; | 6382 | "import_module", "use_module", "include_module", "end_module", "some", "all"}; |
| 6376 | 6383 | ||
| 6377 | static size_t | 6384 | static mercury_pos_t |
| 6378 | mercury_decl (char *s, size_t pos) | 6385 | mercury_decl (char *s, size_t pos) |
| 6379 | { | 6386 | { |
| 6380 | if (s == NULL) return 0; | 6387 | mercury_pos_t null_pos = {0, 0, 0}; |
| 6388 | |||
| 6389 | if (s == NULL) return null_pos; | ||
| 6381 | 6390 | ||
| 6382 | size_t origpos; | 6391 | size_t origpos; |
| 6383 | origpos = pos; | 6392 | origpos = pos; |
| @@ -6398,7 +6407,8 @@ mercury_decl (char *s, size_t pos) | |||
| 6398 | if (is_mercury_quantifier) | 6407 | if (is_mercury_quantifier) |
| 6399 | { | 6408 | { |
| 6400 | if (strcmp (buf, "pred") != 0 && strcmp (buf, "func") != 0) /* Bad syntax. */ | 6409 | if (strcmp (buf, "pred") != 0 && strcmp (buf, "func") != 0) /* Bad syntax. */ |
| 6401 | return 0; | 6410 | return null_pos; |
| 6411 | |||
| 6402 | is_mercury_quantifier = false; /* Reset to base value. */ | 6412 | is_mercury_quantifier = false; /* Reset to base value. */ |
| 6403 | found_decl_tag = true; | 6413 | found_decl_tag = true; |
| 6404 | } | 6414 | } |
| @@ -6418,7 +6428,7 @@ mercury_decl (char *s, size_t pos) | |||
| 6418 | is_mercury_quantifier = true; | 6428 | is_mercury_quantifier = true; |
| 6419 | } | 6429 | } |
| 6420 | 6430 | ||
| 6421 | break; /* Found declaration tag of rank j. */ | 6431 | break; /* Found declaration tag of rank j. */ |
| 6422 | } | 6432 | } |
| 6423 | else | 6433 | else |
| 6424 | /* 'solver type' has a blank in the middle, | 6434 | /* 'solver type' has a blank in the middle, |
| @@ -6461,24 +6471,36 @@ mercury_decl (char *s, size_t pos) | |||
| 6461 | if (found_decl_tag) | 6471 | if (found_decl_tag) |
| 6462 | pos = skip_spaces (s + pos) - s; /* Skip len blanks again. */ | 6472 | pos = skip_spaces (s + pos) - s; /* Skip len blanks again. */ |
| 6463 | else | 6473 | else |
| 6464 | return 0; | 6474 | return null_pos; |
| 6465 | } | 6475 | } |
| 6466 | 6476 | ||
| 6467 | /* From now on it is the same as for Prolog except for module dots. */ | 6477 | /* From now on it is the same as for Prolog except for module dots. */ |
| 6468 | 6478 | ||
| 6479 | size_t start_of_name = pos; | ||
| 6480 | |||
| 6469 | if (c_islower (s[pos]) || s[pos] == '_' ) | 6481 | if (c_islower (s[pos]) || s[pos] == '_' ) |
| 6470 | { | 6482 | { |
| 6471 | /* The name is unquoted. | 6483 | /* The name is unquoted. |
| 6472 | Do not confuse module dots with end-of-declaration dots. */ | 6484 | Do not confuse module dots with end-of-declaration dots. */ |
| 6485 | int module_dot_pos = 0; | ||
| 6473 | 6486 | ||
| 6474 | while (c_isalnum (s[pos]) | 6487 | while (c_isalnum (s[pos]) |
| 6475 | || s[pos] == '_' | 6488 | || s[pos] == '_' |
| 6476 | || (s[pos] == '.' /* A module dot. */ | 6489 | || (s[pos] == '.' /* A module dot. */ |
| 6477 | && s + pos + 1 != NULL | 6490 | && s + pos + 1 != NULL |
| 6478 | && (c_isalnum (s[pos + 1]) || s[pos + 1] == '_'))) | 6491 | && (c_isalnum (s[pos + 1]) || s[pos + 1] == '_') |
| 6492 | && (module_dot_pos = pos))) /* Record module dot position. | ||
| 6493 | Erase module from name. */ | ||
| 6479 | ++pos; | 6494 | ++pos; |
| 6480 | 6495 | ||
| 6481 | return pos - origpos; | 6496 | if (module_dot_pos) |
| 6497 | { | ||
| 6498 | start_of_name = module_dot_pos + 2; | ||
| 6499 | ++pos; | ||
| 6500 | } | ||
| 6501 | |||
| 6502 | mercury_pos_t position = {pos, pos - start_of_name + 1, pos - origpos}; | ||
| 6503 | return position; | ||
| 6482 | } | 6504 | } |
| 6483 | else if (s[pos] == '\'') | 6505 | else if (s[pos] == '\'') |
| 6484 | { | 6506 | { |
| @@ -6493,28 +6515,37 @@ mercury_decl (char *s, size_t pos) | |||
| 6493 | ++pos; /* A double quote. */ | 6515 | ++pos; /* A double quote. */ |
| 6494 | } | 6516 | } |
| 6495 | else if (s[pos] == '\0') /* Multiline quoted atoms are ignored. */ | 6517 | else if (s[pos] == '\0') /* Multiline quoted atoms are ignored. */ |
| 6496 | return 0; | 6518 | return null_pos; |
| 6497 | else if (s[pos] == '\\') | 6519 | else if (s[pos] == '\\') |
| 6498 | { | 6520 | { |
| 6499 | if (s[pos+1] == '\0') | 6521 | if (s[pos+1] == '\0') |
| 6500 | return 0; | 6522 | return null_pos; |
| 6501 | pos += 2; | 6523 | pos += 2; |
| 6502 | } | 6524 | } |
| 6503 | else | 6525 | else |
| 6504 | ++pos; | 6526 | ++pos; |
| 6505 | } | 6527 | } |
| 6506 | return pos - origpos; | 6528 | |
| 6529 | mercury_pos_t position = {pos, pos - start_of_name + 1, pos - origpos}; | ||
| 6530 | return position; | ||
| 6507 | } | 6531 | } |
| 6508 | else if (is_mercury_quantifier && s[pos] == '[') /* :- some [T] pred/func. */ | 6532 | else if (is_mercury_quantifier && s[pos] == '[') /* :- some [T] pred/func. */ |
| 6509 | { | 6533 | { |
| 6510 | for (++pos; s + pos != NULL && s[pos] != ']'; ++pos) {} | 6534 | for (++pos; s + pos != NULL && s[pos] != ']'; ++pos) {} |
| 6511 | if (s + pos == NULL) return 0; | 6535 | if (s + pos == NULL) return null_pos; |
| 6512 | ++pos; | 6536 | ++pos; |
| 6513 | pos = skip_spaces (s + pos) - s; | 6537 | pos = skip_spaces (s + pos) - s; |
| 6514 | return mercury_decl (s, pos) + pos - origpos; | 6538 | mercury_pos_t position = mercury_decl (s, pos); |
| 6539 | position.totlength += pos - origpos; | ||
| 6540 | return position; | ||
| 6541 | } | ||
| 6542 | else if (s[pos] == '.') /* as in ':- interface.' */ | ||
| 6543 | { | ||
| 6544 | mercury_pos_t position = {pos, pos - origpos + 1, pos - origpos}; | ||
| 6545 | return position; | ||
| 6515 | } | 6546 | } |
| 6516 | else | 6547 | else |
| 6517 | return 0; | 6548 | return null_pos; |
| 6518 | } | 6549 | } |
| 6519 | 6550 | ||
| 6520 | static ptrdiff_t | 6551 | static ptrdiff_t |
| @@ -6523,6 +6554,7 @@ mercury_pr (char *s, char *last, ptrdiff_t lastlen) | |||
| 6523 | size_t len0 = 0; | 6554 | size_t len0 = 0; |
| 6524 | is_mercury_type = false; | 6555 | is_mercury_type = false; |
| 6525 | is_mercury_quantifier = false; | 6556 | is_mercury_quantifier = false; |
| 6557 | bool stop_at_rule = false; | ||
| 6526 | 6558 | ||
| 6527 | if (is_mercury_declaration) | 6559 | if (is_mercury_declaration) |
| 6528 | { | 6560 | { |
| @@ -6530,38 +6562,46 @@ mercury_pr (char *s, char *last, ptrdiff_t lastlen) | |||
| 6530 | len0 = skip_spaces (s + 2) - s; | 6562 | len0 = skip_spaces (s + 2) - s; |
| 6531 | } | 6563 | } |
| 6532 | 6564 | ||
| 6533 | size_t len = mercury_decl (s, len0); | 6565 | mercury_pos_t position = mercury_decl (s, len0); |
| 6534 | if (len == 0) return 0; | 6566 | size_t pos = position.pos; |
| 6535 | len += len0; | 6567 | int offset = 0; /* may be < 0 */ |
| 6536 | 6568 | if (pos == 0) return 0; | |
| 6537 | if (( (s[len] == '.' /* This is a statement dot, not a module dot. */ | 6569 | |
| 6538 | || (s[len] == '(' && (len += 1)) | 6570 | /* Skip white space for: |
| 6539 | || (s[len] == ':' /* Stopping in case of a rule. */ | 6571 | a. rules in definitions before :- |
| 6540 | && s[len + 1] == '-' | 6572 | b. 0-arity predicates with inlined modes. |
| 6541 | && (len += 2))) | 6573 | c. possibly multiline type definitions */ |
| 6542 | && (lastlen != len || memcmp (s, last, len) != 0) | 6574 | |
| 6575 | while (c_isspace (s[pos])) { ++pos; ++offset; } | ||
| 6576 | |||
| 6577 | if (( ((s[pos] == '.' && (pos += 1)) /* case 1 | ||
| 6578 | This is a statement dot, | ||
| 6579 | not a module dot. */ | ||
| 6580 | || c_isalnum(s[pos]) /* 0-arity procedures */ | ||
| 6581 | || (s[pos] == '(' && (pos += 1)) /* case 2: arity > 0 */ | ||
| 6582 | || ((s[pos] == ':') /* case 3: rules */ | ||
| 6583 | && s[pos + 1] == '-' && (stop_at_rule = true))) | ||
| 6584 | && (lastlen != pos || memcmp (s, last, pos) != 0) | ||
| 6543 | ) | 6585 | ) |
| 6544 | /* Types are often declared on several lines so keeping just | 6586 | /* Types are often declared on several lines so keeping just |
| 6545 | the first line. */ | 6587 | the first line. */ |
| 6546 | || is_mercury_type) | 6588 | |
| 6589 | || is_mercury_type) /* When types are implemented. */ | ||
| 6547 | { | 6590 | { |
| 6548 | char *name = skip_non_spaces (s + len0); | 6591 | size_t namelength = position.namelength; |
| 6549 | size_t namelen; | 6592 | if (stop_at_rule && offset) --offset; |
| 6550 | if (name >= s + len) | 6593 | |
| 6551 | { | 6594 | /* Left-trim type definitions. */ |
| 6552 | name = s; | 6595 | |
| 6553 | namelen = len; | 6596 | while (pos > namelength + offset |
| 6554 | } | 6597 | && c_isspace (s[pos - namelength - offset])) |
| 6555 | else | 6598 | --offset; |
| 6556 | { | 6599 | |
| 6557 | name = skip_spaces (name); | 6600 | /* There is no need to correct namelength or call notinname. */ |
| 6558 | namelen = len - (name - s); | 6601 | |
| 6559 | } | 6602 | make_tag (s + pos - namelength - offset, namelength - 1, true, |
| 6560 | /* Remove trailing non-name characters. */ | 6603 | s, pos - offset - 1, lineno, linecharno); |
| 6561 | while (namelen > 0 && notinname (name[namelen - 1])) | 6604 | return pos; |
| 6562 | namelen--; | ||
| 6563 | make_tag (name, namelen, true, s, len, lineno, linecharno); | ||
| 6564 | return len; | ||
| 6565 | } | 6605 | } |
| 6566 | 6606 | ||
| 6567 | return 0; | 6607 | return 0; |