universal-ctags / ctags

A maintained ctags implementation
https://ctags.io
GNU General Public License v2.0
6.57k stars 628 forks source link

TOML: reporting wrong patterns when the parser runs as a sub parser #4114

Open masatake opened 4 days ago

masatake commented 4 days ago
[yamato@dev64 ~]$ cat /tmp/input.toml 
cat /tmp/input.toml 
[g]
  a = "/"
[m]
  b = ""
[yamato@dev64 ~]$ ~/bin/ctags --options=NONE --quiet --sort=no --fields=+ne --extras=+g -o - /tmp/input.toml 
~/bin/ctags --options=NONE --quiet --sort=no --fields=+ne --extras=+g -o - /tmp/input.toml 
ctags: Notice: No options will be read from files or environment
g   /tmp/input.toml /^[g]$/;"   t   line:1  end:2
a   /tmp/input.toml /^  a = "\/"$/;"    K   line:2  table:g
m   /tmp/input.toml /^[m]$/;"   t   line:3  end:4
b   /tmp/input.toml /^  b = ""$/;"  K   line:4  table:m

It works fine. However, if the TOML code is embedded in a Markdown file, the patterns become incorrect.

[yamato@dev64 ~]$ cat /tmp/input.md 
cat /tmp/input.md 
```toml
[g]
  a = "/"
[m]
  b = ""
```
[yamato@dev64 ~]$ ~/bin/ctags --options=NONE --quiet --sort=no --fields=+ne --extras=+g -o - /tmp/input.md
~/bin/ctags --options=NONE --quiet --sort=no --fields=+ne --extras=+g -o - /tmp/input.md
ctags: Notice: No options will be read from files or environment
g   /tmp/input.md   /^[g]$/;"   t   line:1  end:2
a   /tmp/input.md   /^[g]$/;"   K   line:1  table:g
m   /tmp/input.md   /^"$/;" t   line:3  end:5
b   /tmp/input.md   /^"$/;" K   line:3  table:m

I expected the following code fixs this:

diff --git a/main/read.c b/main/read.c
index 67586051d..8ac90d440 100644
--- a/main/read.c
+++ b/main/read.c
@@ -386,6 +386,14 @@ static int compoundPosForOffset (const void* oft, const void *p)
        return 1;
 }

+extern unsigned long getInputLineNumberForFileOffsetRela(long offset_rela)
+{
+   long offset_abs = offset_rela + File.nestedInputStreamInfo.startCharOffset + File.filePosition.offset;
+
+   fprintf(stderr, ">>>>> %ld\n", offset_abs);
+   return getInputLineNumberForFileOffset (offset_abs);
+}
+
@ -94,12 +97,14 @@ static void tableKeyStart (struct parserCtx *auxil, bool isArrayTable, long offs
 static void tableKeyEnd (struct parserCtx *auxil)
 {
    tagEntryInfo e;
-   unsigned long lineNumber = getInputLineNumberForFileOffset(auxil->keyOffset);
+   unsigned long lineNumber = getInputLineNumberForFileOffsetRela(auxil->keyOffset);
    MIOPos filePosition = getInputFilePositionForLine (lineNumber);

    vString *vname = makeVStringFromKeyQueue (auxil->keyQueue);
    const char *name = vStringValue (vname);

+   fprintf(stderr, ">>>%s %ld\n", name, auxil->keyOffset);
+
    initTagEntry (&e, name, auxil->isArrayTable? TOML_K_ARRAYTABLE: TOML_K_TABLE);
    e.lineNumber = lineNumber;
    e.filePosition = filePosition;
@@ -142,7 +147,7 @@ static void keyvalStart (struct parserCtx *auxil, long offset)
 static void keyvalKeyEnd (struct parserCtx *auxil)
 {
    tagEntryInfo e;
-   unsigned long lineNumber = getInputLineNumberForFileOffset(auxil->keyOffset);
+   unsigned long lineNumber = getInputLineNumberForFileOffsetRela(auxil->keyOffset);
    MIOPos filePosition = getInputFilePositionForLine (lineNumber);

    vString *vname = makeVStringFromKeyQueue (auxil->keyQueue);

However, it didn't.

The original input reproducing the issue:

# /

## NAME

**[METRICS]**
: Section to enable and configure a metrics

**[PLUGINS]**
: The plugins section contains configuration options exposed from installed plugins.

## EXAMPLE

```toml
[grpc]
  address = "/run/containerd/containerd.sock"
[metrics]
  address = ""
  grpc_histogram = false

[cgroup]
  path = ""

[plugins]
  [plugins."io.containerd.monitor.v1.cgroups"]
    no_prometheus = false
```
masatake commented 4 days ago

This may happen only when running a PEG-based parser as a guest.