readtags(1) Universal Ctags readtags(1)

# [Name](#Name)

readtags - Find tag file entries matching specified names

# [SYNOPSIS](#SYNOPSIS)

```
readtags -h | --help
readtags (-H | --help-expression) (filter|sorter|formatter)
readtags -v | --version
readtags [OPTION]... ACTION
```

# [DESCRIPTION](#DESCRIPTION)

The **readtags** program filters, sorts and prints tag entries in a tags file. The basic filtering is done using **actions**, by which you can list all regular tags, pseudo tags or regular tags matching specific name. Then, further filtering, sorting, and formatting can be done using **post processors**, namely **filter expressions**, **sorter expressions**, and **formatter expressions**.

# [ACTIONS](#ACTIONS)

[**-l, --list**](#l)

List regular tags.

**\[-] NAME**

List regular tags matching NAME. "-" as NAME indicates arguments after this as NAME even if they start with -.

[**-D, --list-pseudo-tags**](#D)

List pseudo tags. You can use this option with **-Q** option to extract specified pseudo tags.

# [OPTIONS](#OPTIONS)

## [Controlling the Tags Reading Behavior](#Controlling_the_Tags_Reading_Behavior)

The behavior of reading tags can be controlled using these options:

[**-t TAGFILE, --tag-file TAGFILE**](#t)

Use specified tag file (default: "tags"). Giving "-" as TAGFILE indicates reading the tags file content from the standard input. "-" can make the command line simpler. However, it doesn't mean efficient; readtags stores the data to a temporary file and reads that file for taking the ACTION.

[**-s\[0|1|2\], --override-sort-detection METHOD**](#s_0_1_2_)

Override sort detection of tag file. METHOD: unsorted|sorted|foldcase

The NAME action will perform binary search on sorted (including "foldcase") tags files, which is much faster then on unsorted tags files.

## [Controlling the NAME Action Behavior](#Controlling_the_NAME_Action_Behavior)

The behavior of the NAME action can be controlled using these options:

[**-i, --icase-match**](#i)

Perform case-insensitive matching in the NAME action.

[**-p, --prefix-match**](#p)

Perform prefix matching in the NAME action.

## [Controlling the Output](#Controlling_the_Output)

By default, the output of readtags contains only the name, input and pattern field. The Output can be tweaked using these options:

[**-A, --absolute-input**](#A)

Do the same as **-C** option but use only absolute path form.

[**-C, --canonicalize-input**](#C)

Resolve '..' and '.' in input fields of regular tags. This produces a unique representation of the input path. This option works only with tags files having **!\_TAG\_PROC\_CWD** pseudo tag.

NOTE: The current implementation accepts only **!\_TAG\_PROC\_CWD** starting with **/**; a Windows directory name starting with a drive letter like **C:\\Somewhere** is not acceptable.

[**-d, --debug**](#d)

Turn on debugging output.

[**-E, --escape-output**](#E)

Escape characters like tabs in output as described in [tags(5)](/man/os/universal-ctags/tags.5).

[**-e, --extension-fields**](#e)

Include extension fields in output.

[**-n, --line-number**](#n)

Also include the line number field when **-e** option is give.

[**-P, --with-pseudo-tags**](#P)

List pseudo tags as if **-D** option is specified but continues processing without exiting. Even if you specify the **-Q** and **-P** options together, **-Q** affects only regular tags; it doesn't affect pseudo tags.

About the **-E** option: certain characters are escaped in a tags file, to make it machine-readable. e.g., ensuring no tabs character appear in fields other than the pattern field. By default, readtags translates them to make it human-readable, but when utilizing readtags output in a script or a client tool, **-E** option should be used. See [ctags-client-tools(7)](/man/os/universal-ctags/ctags-client-tools.7) for more discussion on this.

About printing input fields ({tagfile} in [tags(5)](/man/os/universal-ctags/tags.5)) with **-E** option: readtags always prints the input field literally (as it is in the tags file), and when ctags writes the tags file, the escaping rules are applied only when **TAG\_OUTPUT\_MODE** pseudo tag has "u-ctags" and **TAG\_OUTPUT\_FILESEP** has "slash" as values for their input fields, as explained in [ctags-client-tools(7)](/man/os/universal-ctags/ctags-client-tools.7).

## [Filtering, Sorting, and Formatting](#Filtering,_Sorting,_and_Formatting)

Further filtering, sorting, and formatting on the tags listed by actions are performed using:

[**-Q EXP, --filter EXP**](#Q)

Filter the tags listed by ACTION with EXP before printing.

[**-S EXP, --sorter EXP**](#S)

Sort the tags listed by ACTION with EXP before printing.

[**-F EXP, --formatter EXP**](#F)

Format the tags listed by ACTION with EXP when printing.

These are discussed in the EXPRESSION section.

## [Examples](#Examples)

•

List all tags in "/path/to/tags":

```
$ readtags -t /path/to/tags -l
```

•

List all tags in "tags" that start with "mymethod":

```
$ readtags -p - mymethod
```

•

List all tags matching "mymethod", case insensitively:

```
$ readtags -i - mymethod
```

•

List all tags start with "myvar", and printing all fields (i.e., the whole line):

```
$ readtags -p -ne - myvar
```

# [EXPRESSION](#EXPRESSION)

Scheme-style expressions are used for the **-Q**, **-S**, and **-F** options. For those who doesn't know Scheme or Lisp, just remember:

- A function call is wrapped in a pair of parenthesis. The first item in it is the function/operator name, the others are arguments.
- Function calls can be nested.
- Missing values and boolean false are represented by **#f**. **#t** and all other values are considered to be true.

So, **(+ 1 (+ 2 3))** means add 2 and 3 first, then add the result with 1. **(and "string" 1 #t)** means logical AND on **"string"**, **1** and **#t**, and the result is true since there is no **#f**.

## [Filtering](#Filtering)

The tag entries that make the filter expression produces true value are printed by readtags.

The basic operators for filtering are **eq?**, **prefix?**, **suffix?**, **substr?**, and **#/PATTERN/**. Language common fields can be accessed using variables starting with **$**, e.g., **$language** represents the language field. For example:

•

List all tags start with "myfunc" in Python code files:

```
$ readtags -p -Q '(eq? $language "Python")' - myfunc
```

**downcase** or **upcase** operators can be used to perform case-insensitive matching:

•

List all tags containing "my", case insensitively:

```
$ readtags -Q '(substr? (downcase $name) "my")' -l
```

We have logical operators like **and**, **or** and **not**. The value of a missing field is #f, so we could deal with missing fields:

•

List all tags containing "impl" in Python code files, but allow the **language:** field to be missing:

```
$ readtags -Q '(and (substr? $name "impl")\


                    (or (not $language)\


                        (eq? $language "Python")))' -l
```

**#/PATTERN/** is for the case when string predicates (**prefix?**, **suffix?**, and **substr?**) are not enough. You can use "Posix extended regular expression" as PATTERN.

•

List all tags inherits from the class "A":

```
$ readtags -Q '(#/(^|,) ?A(,|$)/ $inherits)' -l
```

Here **$inherits** is a comma-separated class list like "A,B,C", "P, A, Q", or just "A". Notice that this filter works on both situations where there's a space after each comma or there's not.

Case-insensitive matching can be performed by **#/PATTERN/i**:

•

List all tags inherits from the class "A" or "a":

```
$ readtags -Q '(#/(^|,) ?A(,|$)/i $inherits)' -l
```

To include "/" in a pattern, prefix **\\** to the "/".

NOTE: The above regular expression pattern for inspecting inheritances is just an example to show how to use **#/PATTERN/** expression. Tags file generators have no consensus about the format of **inherits:**, e.g., whether there should be a space after a comma. Even parsers in ctags have no consensus. Noticing the format of the **inherits:** field of specific languages is needed for such queries.

The expressions **#/PATTERN/** and **#/PATTERN/i** are for interactive use. Readtags also offers an alias **string-&gt;regexp**, so **#/PATTERN/** is equal to **(string-&gt;regexp "PATTERN")**, and **#/PATTERN/i** is equal to **(string-&gt;regexp "PATTERN" :case-fold #t)**. **string-&gt;regexp** doesn't need to prefix **\\** for including "/" in a pattern. **string-&gt;regexp** may simplify a client tool building an expression. See also [ctags-client-tools(7)](/man/os/universal-ctags/ctags-client-tools.7) for building expressions in your tool.

Let's now consider missing fields. The tags file may have tag entries that has no **inherits:** field. In that case **$inherits** is #f, and the regular expression matching raises an error, since string operators only work for strings. To avoid this problem:

•

Safely list all tags inherits from the class "A":

```
$ readtags -Q '(and $inherits (#/(^|,) ?A(,|$)/ $inherits))' -l
```

This makes sure **$inherits** is not missing first, then match it by regexp.

Sometimes you want to keep tags where the field *is* missing. For example, your want to exclude reference tags, which is marked by the **extras:** field, then you want to keep tags who doesn't have **extras:** field since they are also not reference tags. Here's how to do it:

•

List all tags but the reference tags:

```
$ readtags -Q '(or (not $extras) (#/(^|,) ?reference(,|$)/ $extras))' -l
```

Notice that **(not $extras)** produces **#t** when **$extras** is missing, so the whole **or** expression produces **#t**.

The combination of **ctags -o -** and **readtags -t -** is handy for inspecting a source file as far as the source file is enough short.

•

List all the large (&gt; 100 lines) functions in a file:

```
$ ctags -o - --fields=+neKz input.c \


  | ./readtags -t - -en \


               -Q '(and (eq? $kind "function") $end $line (> (- $end $line) 100))' \


               -l
```

•

List all the tags including line 80 in a file:

```
$ ctags -o - --fields=+neKz input.c \


  | readtags -t - -ne \


             -Q '(and $line


                      (or (eq? $line 80)


                          (and $end (< $line 80) (< 80 $end))))' \


    -l
```

Run "readtags -H filter" to know about all valid functions and variables.

## [Sorting](#Sorting)

When sorting, the sorter expression is evaluated on two tag entries to decide which should sort before the other one, until the order of all tag entries is decided.

In a sorter expression, **$** and **&** are used to access the fields in the two tag entries, and let's call them $-entry and &-entry. The sorter expression should have a value of -1, 0 or 1. The value -1 means the $-entry should be put above the &-entry, 1 means the contrary, and 0 makes their order in the output uncertain.

The core operator of sorting is **&lt;&gt;**. It's used to compare two strings or two numbers (numbers are for the **line:** or **end:** fields). In **(&lt;&gt; a b)**, if **a** &lt; **b**, the result is -1; **a** &gt; **b** produces 1, and **a** = **b** produces 0. Strings are compared using the **strcmp** function, see [strcmp(3)](/man/os/universal-ctags/strcmp.3).

For example, sort by names, and make those shorter or alphabetically smaller ones appear before the others:

```
$ readtags -S '(<> $name &name)' -l
```

This reads "If the tag name in the $-entry is smaller, it goes before the &-entry".

The **&lt;or&gt;** operator is used to chain multiple expressions until one returns -1 or 1. For example, sort by input file names, then line numbers if in the same file:

```
$ readtags -S '(<or> (<> $input &input) (<> $line &line))' -l
```

The **\*-** operator is used to flip the compare result. i.e., **(\*- (&lt;&gt; a b))** is the same as **(&lt;&gt; b a)**.

Filter expressions can be used in sorter expressions. The technique is use **if** to produce integers that can be compared based on the filter, like:

```
(<> (if filter-expr-on-$-entry -1 1)


    (if filter-expr-on-&-entry -1 1))
```

So if $-entry satisfies the filter, while &-entry doesn't, it's the same as **(&lt;&gt; -1 1)**, which produces **-1**.

For example, we want to put tags with "file" kind below other tags, then the sorter would look like:

```
(<> (if (eq? $kind "file") 1 -1)


    (if (eq? &kind "file") 1 -1))
```

A quick read tells us: If $-entry has "file" kind, and &-entry doesn't, the sorter becomes **(&lt;&gt; 1 -1)**, which produces **1**, so the $-entry is put below the &-entry, exactly what we want.

## [Formatting](#Formatting)

A formatter expression defines how readtags prints tag entries.

A formatter expression may produce a string, a boolean, an integer, or a list. Readtags prints the produced string, and integer as is. Readtags prints nothing for **#f**, and a newline for **#t**.

A list could contain any number of strings, booleans, integers, and/or lists. Readtags prints the elements of a list sequentially and recursively.

All the operators for filtering are also available in formatter expressions. In addition to the operators, **list** is available in formatter expressions. As the name shows, **list** is for making a list. **list** makes a list containing arguments passed to the operator. e.g., the following expression makes a list contains **1**, **#f**, and **"hello"**:

```
(list 1 #f "hello")
```

NOTE: Unlike real-Lisp, backquote constructs are not available.

To show some examples, the following tags file (**output.tags**) is assumed as input for readtags:

```
M    input.c 4;"     macro   file:
N    input.c 3;"     macro   file:
bar  input.c 11;"    f       typeref:typename:void   file:   signature:(char ** argv,int * r)
foo  input.c 6;"     f       typeref:typename:int    file:   signature:(int v)
main input.c 16;"    f       typeref:typename:int    signature:(int argc,char ** argv)
```

An example for printing only function names:

```
$ readtags -t output.tags -Q '(eq? $kind "function")' -F '(list $name #t)' -l
bar
foo
main
```

Doing the same only with a formatter expression:

```
$ readtags -t output.tags -F '(if (eq? $kind "function") (list $name #t) #f)' -l
bar
foo
main
```

Generating declarations for the functions:

```
$ readtags -t output.tags -F \


  '(if (eq? $kind "function")


      (list (if $file "static " #f) $typeref-name " " $name $signature ";" #t)


     #f)' -l
static void bar(char ** argv,int * r);
static int foo(int v);
int main(int argc,char ** argv);
```

## [Inspecting the Behavior of Expressions](#Inspecting_the_Behavior_of_Expressions)

The *print* operator can be used to print the value of an expression. For example:

```
$ readtags -Q '(print $name)' -l
```

prints the name of each tag entry before it. Since the return value of **print** is not #f, all the tag entries are printed. We could control this using the **begin** or **begin0** operator. **begin** returns the value of its last argument, and **begin0** returns the value of its first argument. For example:

```
$ readtags -Q '(begin0 #f (print (prefix? "ctags" "ct")))' -l
```

prints a bunch of "#t" (depending on how many lines are in the tags file), and the actual tag entries are not printed.

# [SEE ALSO](#SEE_ALSO)

See [tags(5)](/man/os/universal-ctags/tags.5) for the details of tags file format.

See [ctags-client-tools(7)](/man/os/universal-ctags/ctags-client-tools.7) for the tips writing a tool utilizing tags file.

The official Universal Ctags web site at:

&lt;https://ctags.io/&gt;

The git repository for the library used in readtags command:

&lt;https://github.com/universal-ctags/libreadtags&gt;

# [CREDITS](#CREDITS)

Universal Ctags project &lt;https://ctags.io/&gt;

Darren Hiebert &lt;&lt;dhiebert@users.sourceforge.net&gt;&gt; &lt;http://DarrenHiebert.com/&gt;

The readtags command and libreadtags maintained at Universal Ctags are derived from readtags.c and readtags.h developed at &lt;http://ctags.sourceforge.net&gt;.

6.2.1

---

Document: readtags(1) from universal-ctags 6.2.1-r1 (Chainguard OS)
Source: https://github.com/universal-ctags/ctags
