added more documentation with some code fix

This commit is contained in:
hyung-hwan 2009-06-08 06:11:56 +00:00
parent a6c0d71710
commit cc1438a2cf
4 changed files with 128 additions and 24 deletions

View File

@ -3,9 +3,10 @@
@section sed_intro INTRODUCTION
The sed stream editor is a non-interactive text editing tool commonly used
on Unix environment. Sed reads text from an input stream, applies a set of
editing commands, and writes the results to an output stream. Typically,
the input and output streams are a console or a file.
on Unix environment. Sed reads text from an input stream, stores it to
pattern space, manipulates the pattern space by applying a set of editing
commands, and writes the pattern space to an output stream. Typically, the
input and output streams are a console or a file.
@b QSE provides an embeddable stream editor that supports most of
the conventional sed commands and implements input and output streams as a
@ -28,7 +29,8 @@ A line selector selects input lines to apply a command to and has the following
forms:
- address - specify a single address
- address,address - specify an address range
- start~step - specify a starting line and a step
- start~step - specify a starting line and a step.
#QSE_SED_CLASSIC disables this form.
An @b address is a line number, a regular expression, or a dollar sign ($)
while a @b start and a @b step is a line number.
@ -58,15 +60,15 @@ lines except the first line.
A command without a line selector is applied to all input lines;
A command with a single address is applied to an input line that matches
the address; A command with an address range is applied to all input
lines within the range, inclusive; A command with a starting line and
a step is applied to every @b step'th line starting from the line @b start.
lines within the range, inclusive; A command with a start and a step is
applied to every @b step'th line starting from the line @b start.
Here is the summary of the commands.
- <b># comment text</b>
The text beginning from # to the line end is ignored by @b sed;
# in a line following <b>a \\</b>, <b>i \\</b>, and <b>c \\</b> is treated
literally and does not introduce a comment.
The text beginning from # to the line end is ignored; # in a line following
<b>a \\</b>, <b>i \\</b>, and <b>c \\</b> is treated literally and does not
introduce a comment.
- <b>: label</b>
A label can be composed of letters, digits, periods, hyphens, and underlines.
It remembers a target label for @b b and @b t commands and prohibits a line
@ -74,6 +76,55 @@ selector.
- <b>{</b>
The left curly bracket forms a command group where you can nest other
commands. It should be paired with an ending }.
- <b>q, Q</b>
Both commands terminates the exection of commands.
- <b>q</b>
Terminates the exection of commands. Upon termination, it prints the pattern
space if #QSE_SED_QUIET is not set.
- <b>Q</b>
Terminates the exection of commands quietly.
- <b>a \\ \n text</b>
Stores @b text into an append buffer which is printed after the pattern
space for each input line. If #QSE_SED_CLASSIC is specified, an address range
is not allowed in the line selector.
- <b>i \\ \n text</b>
Inserts @b text into an insert buffer which is printed before the pattern
space for each input line. If #QSE_SED_CLASSIC is specified, an address range
is not allowed in the line selector.
- <b>c \\ \n text</b>
If a single line is selected for the command (i.e. no line selector, a single
address line selector, or a start~step line selector is specified), it changes
pattern space to @b text and skips all subsequent commands for the line.
If an address range is specified, it deletes pattern space and skips
subsequent commands for all input lines but the last, and changes pattern
space to @b text and skips subsequent commands for the last line.
- <b>d</b>
Deletes pattern space and skips subsequent commands for each selected line.
- <b>D</b>
Deletes the first line of pattern space. If the pattern space is emptied,
subsequent commands are skipped. Otherwise, the commands from the first are
reapplied to the current pattern space.
- <b>=</b>
Prints the current line number. If #QSE_SED_CLASSIC is speccified, an address
range is not allowed in the line selector.
- <b>p</b>
Prints pattern space.
- <b>P</b>
Prints the first line of pattern space.
- <b>l</b>
Prints pattern space in a visually unambiguous form.
- <b>h</b>
Copies pattern space to hold space
- <b>H</b>
Appends pattern space to hold space
- <b>g</b>
Copies hold space to pattern space
- <b>G</b>
Appends hold space to pattern space
- <b>x</b>
Exchanges pattern space and hold space
- <b>n</b>
Prints pattern space and read the next line from the input stream to fill
pattern space.
- <b>N</b>
Prints pattern space and read the next line from the input stream to append it
to pattern space with a newline inserted.
*/

View File

@ -1,5 +1,5 @@
/*
* $Id: opt.h 189 2009-06-07 06:23:53Z hyunghwan.chung $
* $Id: opt.h 190 2009-06-07 12:11:56Z hyunghwan.chung $
*
Copyright 2006-2009 Chung, Hyung-Hwan.
@ -22,6 +22,11 @@
#include <qse/types.h>
#include <qse/macros.h>
/** @file
* <qse/cmn/opt.h> defines functions and data structures to process
* command-line arguments.
*/
typedef struct qse_opt_t qse_opt_t;
typedef struct qse_opt_lng_t qse_opt_lng_t;
@ -56,12 +61,24 @@ extern "C" {
#endif
/**
* The qse_getopt() function returns QSE_CHAR_EOF when it finishes processing
* command line options. The return values of QSE_T('?') indicates an error.
* The qse_getopt() function processes the @a argc command-line arguments
* pointed to by @a argv as configured in @a opt. It can process two
* different option styles: a single character starting with '-', and a
* long name starting with '--'.
*
* A character in @a opt.str is treated as a single character option. Should
* it require a parameter, specify ':' after it.
*
* Two special returning option characters indicate special error conditions.
* - @b ? indicates a bad option stored in the @a opt->opt field.
* - @b : indicates a bad parameter for an option stored in the
* @a opt->opt field.
*
* @return an option character on success, QSE_CHAR_EOF on no more options.
*/
qse_cint_t qse_getopt (
int argc /* argument count */,
qse_char_t* const* argv /* argument array */,
int argc, /* argument count */
qse_char_t* const* argv, /* argument array */
qse_opt_t* opt /* option configuration */
);

View File

@ -52,7 +52,7 @@ static const qse_char_t* dflerrstr (qse_sed_t* sed, qse_sed_errnum_t errnum)
QSE_T("failed to compile regular expression '${0}'"),
QSE_T("failed to match regular expression"),
QSE_T("address 1 prohibited for '${0}'"),
QSE_T("address 2 prohibited"),
QSE_T("address 2 prohibited for '${0}'"),
QSE_T("address 2 missing or invalid"),
QSE_T("newline expected"),
QSE_T("backslash expected"),
@ -1139,7 +1139,10 @@ static int get_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (sed->option & QSE_SED_CLASSIC &&
cmd->a2.type != QSE_SED_ADR_NONE)
{
SETERR0 (sed, QSE_SED_EA2PHB, sed->src.lnum);
SETERR1 (
sed, QSE_SED_EA2PHB,
sed->src.lnum, &cmd->type, 1
);
return -1;
}
@ -1149,6 +1152,16 @@ static int get_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
case QSE_T('a'):
case QSE_T('i'):
if (sed->option & QSE_SED_CLASSIC &&
cmd->a2.type != QSE_SED_ADR_NONE)
{
qse_char_t tmpc = c;
SETERR1 (
sed, QSE_SED_EA2PHB,
sed->src.lnum, &tmpc, 1
);
return -1;
}
case QSE_T('c'):
{
cmd->type = c;
@ -1186,16 +1199,21 @@ static int get_command (qse_sed_t* sed, qse_sed_cmd_t* cmd)
if (sed->option & QSE_SED_CLASSIC &&
cmd->a2.type != QSE_SED_ADR_NONE)
{
SETERR0 (sed, QSE_SED_EA2PHB, sed->src.lnum);
qse_char_t tmpc = c;
SETERR1 (
sed, QSE_SED_EA2PHB,
sed->src.lnum, &tmpc, 1
);
return -1;
}
case QSE_T('p'):
case QSE_T('P'):
case QSE_T('l'):
case QSE_T('d'):
case QSE_T('D'):
case QSE_T('p'):
case QSE_T('P'):
case QSE_T('l'):
case QSE_T('h'):
case QSE_T('H'):
case QSE_T('g'):
@ -1326,7 +1344,8 @@ int qse_sed_comp (qse_sed_t* sed, const qse_char_t* sptr, qse_size_t slen)
return -1;
}
}
else if (delim == QSE_T('~'))
else if (!(sed->option & QSE_SED_CLASSIC) &&
(delim == QSE_T('~')))
{
if (cmd->a1.type != QSE_SED_ADR_LINE ||
cmd->a2.type != QSE_SED_ADR_LINE)

View File

@ -138,6 +138,22 @@ static int handle_args (int argc, qse_char_t* argv[])
print_usage (QSE_STDERR, argc, argv);
return -1;
case QSE_T('?'):
qse_fprintf (QSE_STDERR,
QSE_T("ERROR: bad option - %c\n"),
opt.opt
);
print_usage (QSE_STDERR, argc, argv);
return -1;
case QSE_T(':'):
qse_fprintf (QSE_STDERR,
QSE_T("ERROR: bad parameter for %c\n"),
opt.opt
);
print_usage (QSE_STDERR, argc, argv);
return -1;
case QSE_T('h'):
print_usage (QSE_STDOUT, argc, argv);
return 0;
@ -156,12 +172,13 @@ static int handle_args (int argc, qse_char_t* argv[])
if (opt.ind < argc) g_script = argv[opt.ind++];
if (opt.ind < argc) g_infile = argv[opt.ind++];
if (g_script == QSE_NULL)
if (g_script == QSE_NULL || opt.ind < argc)
{
print_usage (QSE_STDERR, argc, argv);
return -1;
}
return 1;
}