\input texinfo @c -*-texinfo-*- @c %**start of header @setfilename ctlseqs.info @include version.texi @settitle ctlseqs @value{VERSION} Manual @c %**end of header @copying This manual is for ctlseqs, a helper library for control sequences. Copyright @copyright{} 2021 CismonX @quotation Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. @end quotation @end copying @titlepage @title ctlseqs @subtitle Helper Library for Control Sequences, version @value{VERSION} @author CismonX @page @vskip 0pt plus 1filll @insertcopying @end titlepage @summarycontents @contents @ifnottex @node Top @top ctlseqs This manual is for ctlseqs, a helper library for control sequences. Permission is granted to copy, distribute and/or modify this document under the terms of the @pxref{GNU Free Documentation License}, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, with no Front-Cover Texts, and with no Back-Cover Texts. ctlseqs is free software. You can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. @end ifnottex @menu * Overview:: Brief overview of ctlseqs. * Helper Macros:: Helper macros provided by ctlseqs. * Control Sequence Matching:: Using ctlseqs for matching control sequences. * Control Sequence Reading:: Using ctlseqs for reading control sequences. * Tips:: Tips & hints for using ctlseqs. * Example Programs:: Example programs using ctlseqs. Appendices * API Reference:: C API reference for ctlseqs. * GNU Free Documentation License:: Copying conditions of this manual. @end menu @node Overview @chapter Overview of ctlseqs The name ``ctlseqs'' is an abbreviation of ``control sequences'', as defined in section 5.4 of ECMA-48. As the name suggests, this library focuses on handling control sequences. However, it only cares about the bit combinations, while the actual meaning and implementation of a control sequence is up to the user. The C API provided by ctlseqs is composed of three major parts: The helper macros, the control sequence matcher, and the control sequence reader. Any of them can be used separatedly or combined, after including the header file @code{ctlseqs.h} in a source file. @menu * Contributing:: Contributing to ctlseqs. * Use Scenarios:: When to use ctlseqs. @end menu @node Contributing @section Contributing We welcome any form of contribution to ctlseqs (as well as this manual), including bug reports, patches, etc. As ctlseqs is primarily @url{https://sv.gnu.org/p/ctlseqs, hosted on Savannah}, it is recommended to contribute using the bug tracker and patch manager. Sending an email to @email{bug-report@@cismon.net} is also a viable option. @cindex Checklist for bug reports An effective bug report should contain enough information to reproduce the bug, which may contain: @itemize @bullet @item The version number of ctlseqs involved. @item A minimal code snippet to reproduce the bug. @item Expected and actual behaviour of the program. @item A core file for the crashed program. @item Name of the operating system and hardware. @end itemize @cindex Checklist for patch submission Before you submit a patch for ctlseqs, it is recommended to: @itemize @bullet @item Follow the existing coding style. @item Discuss with the community about new features or breaking changes. @item Write test cases, documentation and changelogs for your code. @end itemize @node Use Scenarios @section Use Scenarios of ctlseqs Control sequences, as well as other control functions, were once commonly used in computer terminals. Terminals exchange control information with the host regarding colors, font styles, cursor position, etc., using control functions embedded in normal text. Such physical terminals are no longer used today, however, popular ones like DEC VT100 are widely emulated by modern terminal emulators. The primary purpose of the ctlseqs library is to provide developers with a set of simple and easy-to-use API for handling control functions, when working on terminal emulators and text-based programs. However, while there is no de facto standard, control functions used in terminals are largely vendor-specific, and terminal emulators like to add their own private controls. That makes ctlseqs not suitable for writing text-based programs which intend to be portable. Instead of raw control codes, the developer should stick to ncurses or terminfo. @cindex List of common use cases of ctlseqs There are still cases when dealing with raw escape sequences is inevitable, and ctlseqs may come in handy: @itemize @bullet @item Development of text-based programs which rely heavily on special control sequences, which is not supported by libraries like ncurses. @item Implementing a terminal emulator. @item Experimenting or debugging the features of text-based programs or terminal emulators. @end itemize @node Helper Macros @chapter Helper Macros A helper macro in ctlseqs is a C preprocessor macro representing a control function, which expands to a C string literal. @cindex List of control function types in ctlseqs helper macros The control function can be one of the following three types: @itemize @bullet @item Elements from the C0 or C1 set. @item Control Sequences. @item Other control functions (such as device control functions). @end itemize Name of a helper macro is the function name with @code{CTLSEQS_} as prefix. For a control function other than elements from the C0 or C1 set, the corresponding helper macro is a function-like macro which may or may not take arguments. Control sequences listed in the helper macros are primarily exerpted from @url{https://invisible-island.net/xterm/ctlseqs/ctlseqs.html, XTerm's manual}, which may differ across implementations. As ctlseqs does not currently support 8-bit controls, 2-character 7-bit codes from the C1 set are used instead of their 1-character 8-bit representation. For example, @code{CTLSEQS_CSI} expands to @code{"\x1b["}. @cindex Helper macro usage example The following code snippet is an example usage of helper macros: @example printf(CTLSEQS_BEL); printf(CTLSEQS_XTVERSION()); printf(CTLSEQS_CUP("%d", "%d"), 3, 4); @end example Rememeber that the standard output stream is line buffered within a terminal. Either @code{fflush(stdout)} after printing, or disable output buffering with @code{setvbuf(stdout, NULL, _IONBF, 0)}. @node Control Sequence Matching @chapter Control Sequence Matching Given a character string, checking whether it matches a control sequence is quite trivial, with only the standard C library: @example char const *str /* = ... */; int row, col; if (0 == strcmp(str, CTLSEQS_XTVERSION())) @{ // ... @} else if (2 == sscanf(str, CTLSEQS_CUP("%d", "%d"), &row, &col)) @{ // ... @} else /* ... */ @end example However, as the number of possible matches grows, this naive implementation becomes less efficient and harder to maintain. Such problems can be easily solved by using the control sequence matcher provided by ctlseqs. The @code{struct ctlseqs_matcher *} is a pointer to an opaque type which represents an instance of control sequence matcher. Before using, the matcher should be initialized with @code{ctlseqs_matcher_init}. After using, it should be deallocated with @code{ctlseqs_matcher_free}. @cindex Control sequence matcher initialization example @example struct ctlseqs_matcher *matcher = ctlseqs_matcher_init(); // ... ctlseqs_matcher_free(matcher); @end example On rare occurences when ctlseqs fail to allocate enough memory, function @code{ctlseqs_matcher_init} may return @code{NULL}. However, it is okay to pass null pointers to @code{ctlseqs_matcher_free}, which in turn does nothing. @menu * Matcher Configuration:: Configuring a control sequence matcher * Matching String:: Matching a string with control sequence matcher @end menu @node Matcher Configuration @section Matcher Configuration Matcher configuration consists of two parts: the number of matching patterns, and the patterns themselves. Invoke function @code{ctlseqs_matcher_config} to configure a matcher. @cindex Control sequence matcher configuration example @example struct ctlseqs_matcher *matcher /* = ... */; char const *patterns[] = @{ // ... @}; struct ctlseqs_matcher_options options = @{ .patterns = patterns, .npatterns = sizeof(patterns) / sizeof(char const *), @}; int result = ctlseqs_matcher_config(matcher, &options); // ... @end example Each invocation of @code{ctlseqs_matcher_config} on the same matcher overwrites the data generated from the last invocation. Upon success, the function returns @code{CTLSEQS_OK}. If the function fails to allocate enough memory, returns @code{CTLSEQS_NOMEM}. If the @code{patterns} field in @code{struct ctlseqs_matcher_options} is invalid, function behaviour is undefined. See @ref{Patterns} for details. @menu * Patterns:: Supported control squence pattern formats @end menu @node Patterns @subsection Patterns The @code{patterns} field in @code{struct ctlseqs_matcher_options} is an array of NUL-terminated strings which indicates the desired patterns of control functions for the current matcher. @cindex Control functions supported by the matcher The following types of control functions are recognizable by the matcher: @itemize @bullet @item Control sequences: @code{CSI [param...] [intmd...] final} @item C1 functions with command string: @code{(APC|DCS|OSC|PM) [cmdstr] ST} @item Single shifts: @code{(SS2|SS3) ch} @item SOS function: @code{SOS [chrstr] ST} @end itemize According to ECMA-48, CSI parameter bytes are of range @code{0x30} to @code{0x3f}, intermediate bytes @code{0x20} to @code{0x2f}, and final byte @code{0x40} to @code{0x7e}. Command string consists of printable characters and characters of range @code{0x08} and @code{0x0e}. Character string can be any bit combination which does not represent @code{SOS} or @code{ST}. A supported control function, either verbatim or combined with placeholders, can be specified as a valid pattern. The terminating @code{NUL} character does not count into the pattern. @cindex List of supported placeholders A placeholder can only take place in the @code{param}, @code{intmd}, @code{cmdstr} or @code{chrstr} fields, and can be one of the following values: @itemize @bullet @item @code{CTLSEQS_PH_NUM}: A single unsigned integer. @item @code{CTLSEQS_PH_NUMS}: An unsigned integer indicating the number of extracted values, followed by unsigned integers of that many. @item @code{CTLSEQS_PH_STR}: An unsigned integer indicating the number of characters of the extracted string, followed by a string of printable characters. @item @code{CTLSEQS_PH_CMDSTR}: An unsigned integer indicating the number of characters of the extracted string, followed by a string containing only printable characters and characters of range @code{0x08} to @code{0x0d}. @item @code{CTLSEQS_PH_CSI_PARAM}: An unsigned integer indicating the number of characters of the extracted string, followed by a string of CSI parameter bytes. @item @code{CTLSEQS_PH_CSI_INTMD}: An unsigned integer indicating the number of characters of the extracted string, followed by a string of CSI intermediate bytes. @item @code{CTLSEQS_PH_HEXNUM}: A single unsigned integer, which is the integer value of extracted hexadecimal string. @item @code{CTLSEQS_PH_CHRSTR}: An unsigned integer indicating the number of characters of the extracted string, followed by a string of any bit combination which does not represent @code{SOS} or @code{ST}. @end itemize @cindex Control sequence matcher pattern example The following code is a valid example of patterns: @example const char *patterns[] = @{ CTLSEQS_XTVERSION(), CTLSEQS_CUP(CTLSEQS_PH_NUM, CTLSEQS_PH_NUM), CTLSEQS_DECRQM("1000"), // ... @}; @end example @node Matching String @section Matching String @node Control Sequence Reading @chapter Control Sequence Reading @node Tips @chapter Tips & Hints @node Example Programs @chapter Example Programs @node API Reference @appendix API Reference @node GNU Free Documentation License @appendix GNU Free Documentation License @include fdl.texi @bye