Skip to content

[WIP] main: oneshot mode, reading source file contents from stdin#4407

Draft
masatake wants to merge 13 commits intouniversal-ctags:masterfrom
masatake:oneshot
Draft

[WIP] main: oneshot mode, reading source file contents from stdin#4407
masatake wants to merge 13 commits intouniversal-ctags:masterfrom
masatake:oneshot

Conversation

@masatake
Copy link
Copy Markdown
Member

@masatake masatake commented Mar 27, 2026

$ echo 'int v; int main(void) {return 0;}'  | ./ctags --oneshot=a.c -x --sort=yes -o -
main             function      1 a.c              int v; int main(void) {return 0;}
v                variable      1 a.c              int v; int main(void) {return 0;}
$ echo 'int v; int main(void) {return 0;}'  | ./ctags --oneshot=a.c -x --sort=no  -o -
v                variable      1 a.c              int v; int main(void) {return 0;}
main             function      1 a.c              int v; int main(void) {return 0;}
$ echo 'int v; int main(void) {return 0;}'  | ./ctags --oneshot=a.c -x --sort=no --output-format=json -o -
{"_type": "tag", "name": "v", "path": "a.c", "pattern": "/^int v; int main(void) {return 0;}$/", "typeref": "typename:int", "kind": "variable"}
{"_type": "tag", "name": "main", "path": "a.c", "pattern": "/^int v; int main(void) {return 0;}$/", "typeref": "typename:int", "kind": "function"}
$ echo 'int v; int main(void) {return 0;}'  | ./ctags --oneshot-limit=6  --oneshot=a.c -x --sort=no --output-format=xref
ctags: Warning: input read from stdin exceeds the limit: name: a.c, size: 6
v                variable      1 a.c              int v;

TODO:

  • merge V: enable stack usage guard #4387 first
  • write about --oneshot-limit to ctags.1
  • add more test cases
  • implement JSON based error report
  • update --help message for --_interactive

@masatake masatake force-pushed the oneshot branch 4 times, most recently from 5592e4a to 6a3c05f Compare March 27, 2026 06:10
@masatake
Copy link
Copy Markdown
Member Author

I must merge #4387.

@masatake masatake requested a review from Copilot March 27, 2026 06:46
@masatake masatake marked this pull request as draft March 27, 2026 06:50
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new “oneshot” execution mode so ctags can read a single source file’s contents from stdin while still treating it as a named file for language detection and output paths (optionally with a size limit), and wires this into interactive/sandbox behavior and Windows build files.

Changes:

  • Add --oneshot=<filename> and --oneshot-limit=<bytes> to read source contents from stdin and emit tags to stdout.
  • Introduce interactiveOneshot() main loop and adjust sorting/sandbox interactions (including forcing internal sort in sandbox oneshot).
  • Add a writer init hook (used by the JSON writer) and update Windows project generation inputs/outputs plus documentation and a basic regression test.

Reviewed changes

Copilot reviewed 21 out of 22 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
win32/ctags_vs2013.vcxproj.filters Includes main/seccomp.c and main/interactive_p.h in the VS filters list.
win32/ctags_vs2013.vcxproj Adds main/seccomp.c and main/interactive_p.h to the VS project build inputs.
win32/GNUmakefile Stops excluding main/seccomp.c and main/interactive_p.h from generated VS project lists.
man/ctags.1.rst.in Documents --oneshot=<filename> (template man page).
main/writer_p.h Adds a tagWriter.init callback hook.
main/writer.c Calls writer->init() from setTagWriter() when provided.
main/writer-json.c Adds JSON writer init to pre-seed hashing before seccomp sandboxing.
main/sort_p.h Adjusts header guards so internal sort API is always declared.
main/sort.c Makes internal sort code always compiled; improves safety around mio_file_get_fp().
main/parse.c Updates filter-vs-interactive checks to use the new interactive bitmask flags and adjusts closeTagFile() call.
main/options_p.h Changes Option.interactive from enum states to a bitmask of interactive flags.
main/options.h Removes inSandbox() declaration from the public header.
main/options.c Implements oneshot option parsing, oneshot input limit, updated interactive parsing, and sandbox/sort checks.
main/main.c Adds interactiveOneshot() loop to read stdin into a memory MIO and parse it as a named file; refactors sandbox prep.
main/interactive_p.h Extends interactive args with fname and limit; declares interactiveOneshot().
main/entry_p.h Updates closeTagFile() signature to accept a “force internal sort” flag.
main/entry.c Updates sandbox detection and adds forceUseInternalSort plumbing into tag sorting/closing.
docs/news/HEAD.rst Announces the new --oneshot=<filename> option.
docs/man/ctags.1.rst Documents --oneshot=<filename> (generated man page).
Tmain/oneshot.d/stdout-expected.txt Expected output for the new oneshot regression test.
Tmain/oneshot.d/stderr-expected.txt Placeholder expected stderr for oneshot tests.
Tmain/oneshot.d/run.sh New test script covering oneshot sorting and -x output.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +224 to +229
``--oneshot=<filename>``
Makes ctags behave as a filter, reading source
file contents from standard input and printing their tags to
standard output. When this option is enabled, the options ``-L``,
``-f``, ``-o``, and ``--totals`` are ignored.

Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The man page documents --oneshot, but the newly introduced --oneshot-limit=<bytes> option is not described here. Consider adding a short paragraph in this section explaining the limit behavior (including that 0 disables the limit and the default is 32MB).

Copilot uses AI. Check for mistakes.
Comment on lines +499 to +513
MIO *mio = mio_new_memory (NULL, 0, eRealloc, eFreeNoNullCheck);
int c;
size_t r = 0;
while ((c = getchar()) != EOF)
{
r++;
if (iargs->limit != 0 && r > iargs->limit)
{
error (WARNING, "input read from stdin exceeds the limit: name: %s, size: %lu",
iargs->fname,
(unsigned long) iargs->limit);
break;
}
mio_putc (mio, c);
}
Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading stdin one byte at a time via getchar() + mio_putc() adds avoidable overhead, especially with the default 32MB limit. Consider buffered reads (e.g., fread() into a stack buffer and mio_write()), while still enforcing iargs->limit.

Copilot uses AI. Check for mistakes.
Comment on lines +224 to +229
``--oneshot=<filename>``
Makes @CTAGS_NAME_EXECUTABLE@ behave as a filter, reading source
file contents from standard input and printing their tags to
standard output. When this option is enabled, the options ``-L``,
``-f``, ``-o``, and ``--totals`` are ignored.

Copy link

Copilot AI Mar 27, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The template man page documents --oneshot, but the newly added --oneshot-limit=<bytes> option isn’t described in this section. Please add a short description here so generated man pages include it.

Copilot uses AI. Check for mistakes.
masatake added 11 commits March 28, 2026 01:47
Sort process requires more varietry of system calls.

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
…get_fp

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
…ansson API

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
…writer's init method

Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
@masatake masatake force-pushed the oneshot branch 2 times, most recently from 6c3badd to 1403a1f Compare March 27, 2026 20:27
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Signed-off-by: Masatake YAMATO <yamato@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants