od_parse_cmd_line()¶
Processes the command-line options understood by OpenDoors.
Synopsis¶
#ifdef ODPLAT_WIN32
void od_parse_cmd_line(LPSTR pszCmdLine);
void od_parse_cmd_line_cons(INT nArgCount, char *papszArguments[]);
#else
void od_parse_cmd_line(INT nArgCount, char *papszArguments[]);
#endif
Parameters¶
Windows¶
pszCmdLine is the argument string supplied to WinMain(). It does not include
the executable name. OpenDoors applies the Windows CommandLineToArgvW quote
and backslash grammar before parsing it. See
od_split_cmd_line() for the exact platform-specific
rules.
Console-subsystem applications may call
od_parse_cmd_line_cons(argc, argv) explicitly.
Alternatively, define OD_WINDOWS_CONSOLE before including
OpenDoor.h; the header aliases this function to
od_parse_cmd_line_cons(), so the
od_parse_cmd_line(argc, argv) spelling has the same
effect. CMake's OpenDoors::SharedConsole, OpenDoors::StaticConsole, and
OpenDoors::StaticMTConsole targets provide that definition automatically.
These are two equivalent source interfaces, not different library binaries.
The raw-string interface is valid only in a GUI-subsystem executable and the
argument-vector interface only in a console-subsystem executable. A mismatch
is diagnosed on standard error and through the debugger, sets
od_control.od_error to
ERR_PARAMETER, and terminates before
the arguments or application callbacks are processed.
DOS¶
nArgCount and papszArguments are the argc and argv values supplied to
main() by the compiler's C runtime. DOS itself supplies a raw command tail in
the PSP rather than an argument vector. OpenDoors does not parse that command
tail; division into arguments, including any treatment of quotes, is therefore
determined by the particular DOS compiler and runtime.
Unix-like systems¶
nArgCount and papszArguments are the argc and argv values supplied to
main(). These arguments are ordinarily constructed by the invoking shell,
although another process may provide them directly. OpenDoors does not perform
shell parsing. Element zero, conventionally the executable name, is ignored.
Passing a null argument array sets
od_control.od_error to
ERR_PARAMETER and returns. The
function otherwise reports malformed command lines by printing a message and
terminating the process, as described below.
Return value¶
This function does not return a value. The help options and missing required values terminate the process rather than returning to the caller.
When to call it¶
Call od_parse_cmd_line() before od_init() or any API call that
can initialize OpenDoors implicitly. Initialization settings and command-line
callbacks must therefore be installed before this call. An
od_add_personality() call may precede it because that
function does not initialize the library.
Each call records that command-line parsing has occurred and initializes two caller settings before examining the arguments:
od_control.user_ansiis set toTRUE.od_control.user_timelimitis set to 60 minutes.
These assignments occur even if neither setting appears on the command line.
Configuration-file processing and door-information-file processing occur later
during initialization and may replace settings populated here. The command-line
parser specially records only the BPS and PORT values as preset connection
information; providing both permits initialization to continue without a drop
file when no-file handling would otherwise fail.
General syntax¶
Option names begin with either - or / and are compared without regard to
case. Thus -LOCAL, /local, and -L select the same option. A value is a
separate argument; forms such as -NODE=2 are not recognized.
Arguments without a - or / prefix are not options. They are consumed as
values where an option requires or accepts them and are otherwise ignored.
The parser does not reject an unrecognized option unless an application callback
chooses to do so.
Recognized options¶
The following table gives every spelling recognized by the current parser. Aliases in the same row have identical behavior.
| Options | Value | Effect |
|---|---|---|
-C, -CONFIG, -CONFIGFILE, -CFGFILE, -CFG |
filename | Sets od_control.od_config_filename. The parser retains at most 79 characters in its internal filename buffer. |
-L, -LOCAL |
none | Sets od_control.od_force_local to TRUE. |
-B, -BPS, -BAUD |
decimal number | Stores the result of atol() in od_control.baud and marks the BPS setting as preset. |
-P, -PORT |
port | Sets od_control.port as an explicit override. A value beginning with COM, such as COM1, is converted to the zero-based value 0. A plain decimal value is stored directly, so -P 0 also selects COM1. The override is retained when a door-information file names another port. |
-N, -NODE |
decimal number | Stores the result of atoi() in od_control.od_node. |
-?, -H, -HELP |
none | Displays command-line help and exits. |
-MAXTIME |
decimal number | Stores the result of atoi() in od_control.od_maxtime. |
-ADDRESS |
hexadecimal number | Parses the value in base 16 and stores its low WORD value in od_control.od_com_address. |
-IRQ |
decimal number | Stores the result of atoi() in od_control.od_com_irq. |
-NOFOSSIL |
none | Sets od_control.od_no_fossil to TRUE. |
-NOFIFO |
none | Sets od_control.od_com_no_fifo to TRUE. |
-D, -DROPFILE |
path | Copies the path to od_control.info_path, truncated to fit that field. The value may name a directory or a particular door-information file. |
-USERNAME |
one or more words | Stores the words in od_control.user_name, retaining at most 35 bytes plus the terminating nul. |
-TIMELEFT |
decimal number | Stores the result of atoi() in od_control.user_timelimit. |
-SECURITY |
decimal number | Stores the result of atoi() in od_control.user_security. |
-LOCATION |
one or more words | Stores the words in od_control.user_location, retaining at most 25 bytes plus the terminating nul. |
-G, -GRAPHICS |
optional value | Enables or disables od_control.user_ansi, as detailed below. |
-BBSNAME |
one or more words | Stores the words in od_control.system_name, retaining at most 39 bytes plus the terminating nul. |
-HANDLE |
decimal number | On Windows and Unix-like systems, supplies an existing native communications handle in od_control.od_open_handle. |
-SOCKET |
decimal number | On Windows and Unix-like systems, supplies an existing connected socket in od_control.od_open_handle and sets od_control.od_use_socket to TRUE. There is no -S alias. |
-SILENT |
none | Sets od_control.od_silent_mode to TRUE. |
-CP437UTF8 |
none | Sets od_control.od_cp437_to_utf8_out to TRUE. |
-PERSONALITY |
none in this parser | Recognized but deliberately ignored, allowing application code such as the diagnostic example to process it separately. This parser does not consume a following personality name. |
The -SOCKET spelling is the only socket option. In particular, -S is an
unknown application option, not an abbreviation for -SOCKET or -SILENT.
Multi-word values¶
-USERNAME, -LOCATION, and -BBSNAME collect consecutive arguments that do
not begin with - or /, inserting one space between them. This joining takes
place after the platform-specific processing described under Parameters: the
Win32 build first applies the Windows command-line grammar, DOS uses the
argument array constructed by the compiler's C runtime, and Unix-like builds
use the argument array supplied to main().
Collection stops before the next prefixed option. If the joined value is too
large for its destination, OpenDoors retains the initial bytes which fit and
discards the remainder, while still advancing to the next prefixed option.
The destination is always nul-terminated. Because a leading slash denotes an
option, a word beginning with / also ends collection on every platform.
For example:
-USERNAME Jane Q Public -LOCATION Ann Arbor Michigan -NODE 2
sets the name to Jane Q Public, the location to Ann Arbor Michigan, and the
node number to 2.
Graphics value¶
With no following plain argument, -G or -GRAPHICS enables ANSI mode. If a
plain argument follows, the current implementation passes it to atoi() and
disables ANSI when the result is zero; the single letter N also disables it.
Consequently, the reliable explicit forms are a nonzero decimal number to enable
graphics and 0 or N to disable it. Do not use words such as Y or ANSI:
atoi() also converts those strings to zero, which disables graphics.
The disabling value is consumed. A nonzero enabling value is subsequently seen as an ordinary non-option argument and ignored, with the same final result.
Numeric conversion¶
Except for -ADDRESS, -HANDLE, and -SOCKET, numeric options use atoi() or
atol() exactly as shown in the table. The parser does not check those values
for trailing characters, overflow, or a range meaningful to the destination
field. Applications should supply valid decimal values within the documented
range of that field. -ADDRESS uses strtol(..., 16) and then converts the
result to WORD.
On Windows and Unix-like systems, -HANDLE and -SOCKET accept an optional
leading + followed by one or more decimal digits. The entire value must fit
in DWORD_PTR; this permits the full native handle
width in both 32-bit and 64-bit builds. An empty, negative, partially numeric,
or overflowing value sets od_control.od_error
to ERR_PARAMETER. It does not change
od_control.od_open_handle, and a
rejected -SOCKET value does not change
od_control.od_use_socket.
DOS does not support adopting a native communications object through these options. Its serial and FOSSIL interfaces are selected through the port-related options instead.
Application-defined options¶
Two callbacks can receive an option that starts with - or / but does not
match any name in the table:
- If
od_control.od_cmd_line_flag_handleris non-null, OpenDoors calls it with the original argument, including its prefix and original letter case. ATRUEreturn marks the option handled. - If the flag callback is absent or returns
FALSE, andod_control.od_cmd_line_handleris non-null, OpenDoors calls it with the original option and the consecutive non-prefixed arguments that follow it, joined with spaces.
The second callback's option text is assembled in an internal 80-byte buffer. OpenDoors retains at most the first 79 bytes of the joined text and supplies a terminating nul. It discards any remaining non-option text while advancing to the next prefixed option. The callback is called with an empty string when the next argument is another prefixed option. If neither callback handles an unknown option, it and any otherwise unclaimed plain arguments are ignored.
Recognized OpenDoors options are not passed to these callbacks. -PERSONALITY
is also not passed to them because the parser recognizes and ignores it.
Install callbacks before calling od_parse_cmd_line():
static BOOL ODCALL
handle_flag(const char *option)
{
if (stricmp(option, "-FAST") == 0 || stricmp(option, "/FAST") == 0) {
/* Enable the application's fast mode. */
return TRUE;
}
return FALSE;
}
int
main(int argc, char **argv)
{
od_control.od_cmd_line_flag_handler = handle_flag;
od_parse_cmd_line(argc, argv);
od_init();
/* ... */
}
Help and errors¶
Set od_control.od_cmd_line_help_func
before parsing to replace help handling completely. When a help option is
encountered, OpenDoors calls this function and then exits with status 0 if the
function returns.
Without a help function, od_control.od_cmd_line_help
replaces the built-in help text. Windows displays it in a message box; other
targets write it to standard output. OpenDoors then exits with status 1. The
built-in help text is not a complete list of the names accepted by the parser;
the table on this page is complete for the current implementation.
When an option that requires a separate value is the final argument, OpenDoors
prints Missing parameter for option: followed by the option and exits with
status 1. Multi-word options make the same check for the presence of a following
argument, although that argument can itself be another prefixed option and thus
produce an empty stored value.
On Windows, failure to divide the command line because memory could not be
allocated leaves od_control.od_error set to
ERR_MEMORY and makes this function return
without parsing.
Portable startup example¶
#include "OpenDoor.h"
#ifdef ODPLAT_WIN32
int WINAPI
WinMain(HINSTANCE instance, HINSTANCE previous,
LPSTR command_line, int show_command)
{
(void)instance;
(void)previous;
od_control.od_cmd_show = show_command;
od_parse_cmd_line(command_line);
od_init();
/* Door code goes here. */
od_exit(0, FALSE);
return 0;
}
#else
int
main(int argc, char **argv)
{
od_parse_cmd_line(argc, argv);
od_init();
/* Door code goes here. */
od_exit(0, FALSE);
return 0;
}
#endif
See also¶
od_split_cmd_line(),
od_free_split_cmd_line(),
od_init(),
Configuration and command lines