| 1 | #!/usr/bin/env python2 | 
| 2 | """Flag parser defintions.""" | 
| 3 |  | 
| 4 | from __future__ import print_function | 
| 5 |  | 
| 6 | from frontend import args | 
| 7 | from frontend.flag_spec import (FlagSpec, FlagSpecAndMore, _FlagSpecAndMore) | 
| 8 | from frontend import option_def | 
| 9 |  | 
| 10 | # | 
| 11 | # Definitions for builtin_assign | 
| 12 | # | 
| 13 |  | 
| 14 | EXPORT_SPEC = FlagSpec('export_') | 
| 15 | EXPORT_SPEC.ShortFlag('-n') | 
| 16 | EXPORT_SPEC.ShortFlag('-f')  # stubbed | 
| 17 | EXPORT_SPEC.ShortFlag('-p') | 
| 18 |  | 
| 19 | READONLY_SPEC = FlagSpec('readonly') | 
| 20 |  | 
| 21 | # TODO: Check the consistency of -a and -A against values, here and below. | 
| 22 | READONLY_SPEC.ShortFlag('-a') | 
| 23 | READONLY_SPEC.ShortFlag('-A') | 
| 24 | READONLY_SPEC.ShortFlag('-p') | 
| 25 |  | 
| 26 | NEW_VAR_SPEC = FlagSpec('new_var') | 
| 27 |  | 
| 28 | # print stuff | 
| 29 | NEW_VAR_SPEC.ShortFlag('-f') | 
| 30 | NEW_VAR_SPEC.ShortFlag('-F') | 
| 31 | NEW_VAR_SPEC.ShortFlag('-p') | 
| 32 |  | 
| 33 | NEW_VAR_SPEC.ShortFlag('-g')  # Look up in global scope | 
| 34 |  | 
| 35 | # Options +r +x +n | 
| 36 | NEW_VAR_SPEC.PlusFlag('x')  # export | 
| 37 | NEW_VAR_SPEC.PlusFlag('r')  # readonly | 
| 38 | NEW_VAR_SPEC.PlusFlag('n')  # named ref | 
| 39 |  | 
| 40 | # Common between readonly/declare | 
| 41 | NEW_VAR_SPEC.ShortFlag('-a') | 
| 42 | NEW_VAR_SPEC.ShortFlag('-A') | 
| 43 | NEW_VAR_SPEC.ShortFlag('-i')  # no-op for integers | 
| 44 |  | 
| 45 | UNSET_SPEC = FlagSpec('unset') | 
| 46 | UNSET_SPEC.ShortFlag('-v') | 
| 47 | UNSET_SPEC.ShortFlag('-f') | 
| 48 | #UNSET_SPEC.ShortFlag('-z', args.String) | 
| 49 |  | 
| 50 | # | 
| 51 | # Definitions for builtin_meta | 
| 52 | # | 
| 53 |  | 
| 54 | # Unused because there are no flags!  Just --. | 
| 55 | EVAL_SPEC = FlagSpec('eval') | 
| 56 | SOURCE_SPEC = FlagSpec('source') | 
| 57 | SOURCE_SPEC.LongFlag('--builtin') | 
| 58 |  | 
| 59 | COMMAND_SPEC = FlagSpec('command') | 
| 60 | COMMAND_SPEC.ShortFlag('-v') | 
| 61 | COMMAND_SPEC.ShortFlag('-V') | 
| 62 | COMMAND_SPEC.ShortFlag('-p') | 
| 63 |  | 
| 64 | TYPE_SPEC = FlagSpec('type') | 
| 65 | TYPE_SPEC.ShortFlag('-f') | 
| 66 | TYPE_SPEC.ShortFlag('-t') | 
| 67 | TYPE_SPEC.ShortFlag('-p') | 
| 68 | TYPE_SPEC.ShortFlag('-P') | 
| 69 | TYPE_SPEC.ShortFlag('-a') | 
| 70 |  | 
| 71 | # | 
| 72 | # Definitions for builtin_pure | 
| 73 | # | 
| 74 |  | 
| 75 | ALIAS_SPEC = FlagSpec('alias')  # no flags yet | 
| 76 | UNALIAS_SPEC = FlagSpec('unalias')  # no flags yet | 
| 77 | UNALIAS_SPEC.ShortFlag('-a') | 
| 78 |  | 
| 79 | SHOPT_SPEC = FlagSpec('shopt') | 
| 80 | SHOPT_SPEC.ShortFlag('-s', long_name='--set') | 
| 81 | SHOPT_SPEC.ShortFlag('-u', long_name='--unset') | 
| 82 | SHOPT_SPEC.ShortFlag('-o')  # use 'set -o' names | 
| 83 | # TODO: --print could print in a verbose format.  (Annoying: codegen conflicts | 
| 84 | # with Python keyword.) | 
| 85 | SHOPT_SPEC.ShortFlag('-p') | 
| 86 | SHOPT_SPEC.ShortFlag('-q')  # query option settings | 
| 87 |  | 
| 88 | HASH_SPEC = FlagSpec('hash') | 
| 89 | HASH_SPEC.ShortFlag('-r') | 
| 90 |  | 
| 91 | ECHO_SPEC = FlagSpec('echo') | 
| 92 | ECHO_SPEC.ShortFlag('-e')  # no backslash escapes | 
| 93 | ECHO_SPEC.ShortFlag('-n') | 
| 94 |  | 
| 95 | # | 
| 96 | # osh/builtin_printf.py | 
| 97 | # | 
| 98 |  | 
| 99 | PRINTF_SPEC = FlagSpec('printf') | 
| 100 | PRINTF_SPEC.ShortFlag('-v', args.String) | 
| 101 |  | 
| 102 | # | 
| 103 | # osh/builtin_misc.py | 
| 104 | # | 
| 105 |  | 
| 106 | READ_SPEC = FlagSpec('read') | 
| 107 | READ_SPEC.ShortFlag('-r') | 
| 108 | READ_SPEC.ShortFlag('-s')  # silent | 
| 109 | READ_SPEC.ShortFlag('-u', args.Int)  # file descriptor | 
| 110 | READ_SPEC.ShortFlag('-t', args.Float)  # timeout | 
| 111 | READ_SPEC.ShortFlag('-n', args.Int) | 
| 112 | READ_SPEC.ShortFlag('-N', args.Int) | 
| 113 | READ_SPEC.ShortFlag('-a', args.String)  # name of array to read into | 
| 114 | READ_SPEC.ShortFlag('-d', args.String) | 
| 115 | READ_SPEC.ShortFlag('-p', args.String)  # prompt | 
| 116 |  | 
| 117 | # YSH extensions | 
| 118 | READ_SPEC.ShortFlag('-0')  # until NUL, like -r -d '' | 
| 119 | READ_SPEC.LongFlag('--all') | 
| 120 | READ_SPEC.LongFlag('--line') | 
| 121 | READ_SPEC.LongFlag('--raw-line') | 
| 122 | READ_SPEC.LongFlag('--num-bytes', args.Int) | 
| 123 | # don't strip the trailing newline | 
| 124 | READ_SPEC.LongFlag('--with-eol') | 
| 125 | READ_SPEC.LongFlag('--json', | 
| 126 | args.Bool, | 
| 127 | default=False, | 
| 128 | help='Read elements as JSON strings') | 
| 129 | READ_SPEC.LongFlag('--j8', | 
| 130 | args.Bool, | 
| 131 | default=False, | 
| 132 | help='Read elements as J8 strings') | 
| 133 |  | 
| 134 | MAPFILE_SPEC = FlagSpec('mapfile') | 
| 135 | MAPFILE_SPEC.ShortFlag('-t') | 
| 136 |  | 
| 137 | CD_SPEC = FlagSpec('cd') | 
| 138 | CD_SPEC.ShortFlag('-L') | 
| 139 | CD_SPEC.ShortFlag('-P') | 
| 140 |  | 
| 141 | PUSHD_SPEC = FlagSpec('pushd') | 
| 142 |  | 
| 143 | POPD_SPEC = FlagSpec('popd') | 
| 144 |  | 
| 145 | DIRS_SPEC = FlagSpec('dirs') | 
| 146 | DIRS_SPEC.ShortFlag('-c') | 
| 147 | DIRS_SPEC.ShortFlag('-l') | 
| 148 | DIRS_SPEC.ShortFlag('-p') | 
| 149 | DIRS_SPEC.ShortFlag('-v') | 
| 150 |  | 
| 151 | PWD_SPEC = FlagSpec('pwd') | 
| 152 | PWD_SPEC.ShortFlag('-L') | 
| 153 | PWD_SPEC.ShortFlag('-P') | 
| 154 |  | 
| 155 | HELP_SPEC = FlagSpec('help') | 
| 156 | #HELP_SPEC.ShortFlag('-i')  # show index | 
| 157 | # Note: bash has help -d -m -s, which change the formatting | 
| 158 |  | 
| 159 | HISTORY_SPEC = FlagSpec('history') | 
| 160 | HISTORY_SPEC.ShortFlag('-a') | 
| 161 | HISTORY_SPEC.ShortFlag('-r') | 
| 162 | HISTORY_SPEC.ShortFlag('-c') | 
| 163 | HISTORY_SPEC.ShortFlag('-d', args.Int) | 
| 164 |  | 
| 165 | # | 
| 166 | # osh/builtin_process.py | 
| 167 | # | 
| 168 |  | 
| 169 | EXEC_SPEC = FlagSpec('exec') | 
| 170 |  | 
| 171 | WAIT_SPEC = FlagSpec('wait') | 
| 172 | WAIT_SPEC.ShortFlag('-n') | 
| 173 |  | 
| 174 | TRAP_SPEC = FlagSpec('trap') | 
| 175 | TRAP_SPEC.ShortFlag('-p') | 
| 176 | TRAP_SPEC.ShortFlag('-l') | 
| 177 |  | 
| 178 | JOB_SPEC = FlagSpec('jobs') | 
| 179 | JOB_SPEC.ShortFlag('-l', help='long format') | 
| 180 | JOB_SPEC.ShortFlag('-p', help='prints PID only') | 
| 181 | JOB_SPEC.LongFlag('--debug', help='display debug info') | 
| 182 |  | 
| 183 | ULIMIT_SPEC = FlagSpec('ulimit') | 
| 184 |  | 
| 185 | ULIMIT_SPEC.ShortFlag('-a', help='Print all limits') | 
| 186 | ULIMIT_SPEC.LongFlag('--all', help='Alias for -a') | 
| 187 | ULIMIT_SPEC.ShortFlag('-H', help='Use hard limit') | 
| 188 | ULIMIT_SPEC.ShortFlag('-S', help='Use soft limit') | 
| 189 |  | 
| 190 | _ULIMIT_RESOURCES = [ | 
| 191 | '-c', | 
| 192 | '-d', | 
| 193 | '-f', | 
| 194 | '-n', | 
| 195 | '-s', | 
| 196 | '-t', | 
| 197 | '-v', | 
| 198 | ] | 
| 199 |  | 
| 200 | for u_flag in _ULIMIT_RESOURCES: | 
| 201 | ULIMIT_SPEC.ShortFlag(u_flag) | 
| 202 |  | 
| 203 | # | 
| 204 | # FlagSpecAndMore | 
| 205 | # | 
| 206 |  | 
| 207 | # | 
| 208 | # set and shopt | 
| 209 | # | 
| 210 |  | 
| 211 |  | 
| 212 | def _AddShellOptions(spec): | 
| 213 | # type: (_FlagSpecAndMore) -> None | 
| 214 | """Shared between 'set' builtin and the shell's own arg parser.""" | 
| 215 | spec.InitOptions() | 
| 216 | spec.InitShopt() | 
| 217 |  | 
| 218 | for opt in option_def.All(): | 
| 219 | if opt.builtin == 'set': | 
| 220 | spec.Option(opt.short_flag, opt.name) | 
| 221 | # Notes: | 
| 222 | # - shopt option don't need to be registered; we validate elsewhere | 
| 223 | # - 'interactive' Has a cell for internal use, but isn't allowed to be | 
| 224 | # modified. | 
| 225 |  | 
| 226 |  | 
| 227 | MAIN_SPEC = FlagSpecAndMore('main') | 
| 228 |  | 
| 229 | MAIN_SPEC.ShortFlag('-c', args.String, | 
| 230 | quit_parsing_flags=True)  # command string | 
| 231 | MAIN_SPEC.LongFlag('--help') | 
| 232 | MAIN_SPEC.LongFlag('--version') | 
| 233 |  | 
| 234 | # --tool ysh-ify, etc. | 
| 235 | # default is '' | 
| 236 | # | 
| 237 | # More ideas for tools | 
| 238 | #   undefined-vars - a static analysis pass | 
| 239 | #   parse-glob - to debug parsing | 
| 240 | #   parse-printf | 
| 241 | MAIN_SPEC.LongFlag('--tool', [ | 
| 242 | 'tokens', 'lossless-cat', 'syntax-tree', 'fmt', 'test', 'ysh-ify', 'deps', | 
| 243 | 'cat-em' | 
| 244 | ]) | 
| 245 |  | 
| 246 | MAIN_SPEC.ShortFlag('-i')  # interactive | 
| 247 | MAIN_SPEC.ShortFlag('-l')  # login - currently no-op | 
| 248 | MAIN_SPEC.LongFlag('--login')  # login - currently no-op | 
| 249 | MAIN_SPEC.LongFlag('--headless')  # accepts ECMD, etc. | 
| 250 |  | 
| 251 | # TODO: -h too | 
| 252 | # the output format when passing -n | 
| 253 | MAIN_SPEC.LongFlag( | 
| 254 | '--ast-format', | 
| 255 | ['text', 'abbrev-text', 'html', 'abbrev-html', 'oheap', 'none'], | 
| 256 | default='abbrev-text') | 
| 257 |  | 
| 258 | # Defines completion style. | 
| 259 | MAIN_SPEC.LongFlag('--completion-display', ['minimal', 'nice'], default='nice') | 
| 260 | # TODO: Add option for YSH prompt style?  RHS prompt? | 
| 261 |  | 
| 262 | MAIN_SPEC.LongFlag('--completion-demo') | 
| 263 |  | 
| 264 | # Debugging feature only.  $SH -n won't reparse a[x+1] and ``.  Note that $SH | 
| 265 | # --tool automatically turns it on. | 
| 266 | MAIN_SPEC.LongFlag('--do-lossless') | 
| 267 |  | 
| 268 | MAIN_SPEC.LongFlag('--print-status')  # TODO: Replace with a shell hook | 
| 269 | MAIN_SPEC.LongFlag('--debug-file', args.String) | 
| 270 | MAIN_SPEC.LongFlag('--xtrace-to-debug-file') | 
| 271 |  | 
| 272 | # This flag has is named like bash's equivalent.  We got rid of --norc because | 
| 273 | # it can simply by --rcfile /dev/null. | 
| 274 | MAIN_SPEC.LongFlag('--rcfile', args.String) | 
| 275 | MAIN_SPEC.LongFlag('--rcdir', args.String) | 
| 276 | MAIN_SPEC.LongFlag('--norc') | 
| 277 |  | 
| 278 | # e.g. to pass data on stdin but pretend that it came from a .hay file | 
| 279 | MAIN_SPEC.LongFlag('--location-str', args.String) | 
| 280 | MAIN_SPEC.LongFlag('--location-start-line', args.Int) | 
| 281 |  | 
| 282 | _AddShellOptions(MAIN_SPEC) | 
| 283 |  | 
| 284 | SET_SPEC = FlagSpecAndMore('set') | 
| 285 | _AddShellOptions(SET_SPEC) | 
| 286 |  | 
| 287 | # | 
| 288 | # Types for completion | 
| 289 | # | 
| 290 |  | 
| 291 |  | 
| 292 | def _DefineCompletionFlags(spec): | 
| 293 | # type: (_FlagSpecAndMore) -> None | 
| 294 | spec.ShortFlag('-F', args.String, help='Complete with this function') | 
| 295 | spec.ShortFlag('-W', args.String, help='Complete with these words') | 
| 296 | spec.ShortFlag('-C', | 
| 297 | args.String, | 
| 298 | help='Complete with stdout lines of this command') | 
| 299 |  | 
| 300 | spec.ShortFlag( | 
| 301 | '-P', | 
| 302 | args.String, | 
| 303 | help= | 
| 304 | 'Prefix is added at the beginning of each possible completion after ' | 
| 305 | 'all other options have been applied.') | 
| 306 | spec.ShortFlag('-S', | 
| 307 | args.String, | 
| 308 | help='Suffix is appended to each possible completion after ' | 
| 309 | 'all other options have been applied.') | 
| 310 | spec.ShortFlag('-X', | 
| 311 | args.String, | 
| 312 | help=''' | 
| 313 | A glob pattern to further filter the matches.  It is applied to the list of | 
| 314 | possible completions generated by the preceding options and arguments, and each | 
| 315 | completion matching filterpat is removed from the list. A leading ! in | 
| 316 | filterpat negates the pattern; in this case, any completion not matching | 
| 317 | filterpat is removed. | 
| 318 | ''') | 
| 319 |  | 
| 320 |  | 
| 321 | def _DefineCompletionOptions(spec): | 
| 322 | # type: (_FlagSpecAndMore) -> None | 
| 323 | """Common -o options for complete and compgen.""" | 
| 324 | spec.InitOptions() | 
| 325 |  | 
| 326 | # bashdefault, default, filenames, nospace are used in git | 
| 327 | spec.Option2('bashdefault', | 
| 328 | help='If nothing matches, perform default bash completions') | 
| 329 | spec.Option2( | 
| 330 | 'default', | 
| 331 | help="If nothing matches, use readline's default filename completion") | 
| 332 | spec.Option2( | 
| 333 | 'filenames', | 
| 334 | help="The completion function generates filenames and should be " | 
| 335 | "post-processed") | 
| 336 | spec.Option2('dirnames', | 
| 337 | help="If nothing matches, perform directory name completion") | 
| 338 | spec.Option2( | 
| 339 | 'nospace', | 
| 340 | help="Don't append a space to words completed at the end of the line") | 
| 341 | spec.Option2( | 
| 342 | 'plusdirs', | 
| 343 | help="After processing the compspec, attempt directory name completion " | 
| 344 | "and return those matches.") | 
| 345 |  | 
| 346 |  | 
| 347 | def _DefineCompletionActions(spec): | 
| 348 | # type: (_FlagSpecAndMore) -> None | 
| 349 | """Common -A actions for complete and compgen.""" | 
| 350 |  | 
| 351 | # NOTE: git-completion.bash uses -f and -v. | 
| 352 | # My ~/.bashrc on Ubuntu uses -d, -u, -j, -v, -a, -c, -b | 
| 353 | spec.InitActions() | 
| 354 | spec.Action('a', 'alias') | 
| 355 | spec.Action('b', 'binding') | 
| 356 | spec.Action('c', 'command') | 
| 357 | spec.Action('d', 'directory') | 
| 358 | spec.Action('e', 'export') | 
| 359 | spec.Action('f', 'file') | 
| 360 | spec.Action('k', 'keyword') | 
| 361 | spec.Action('j', 'job') | 
| 362 | spec.Action('u', 'user') | 
| 363 | spec.Action('v', 'variable') | 
| 364 | spec.Action(None, 'builtin') | 
| 365 | spec.Action(None, 'function') | 
| 366 | spec.Action(None, 'helptopic')  # help | 
| 367 | spec.Action(None, 'setopt')  # set -o | 
| 368 | spec.Action(None, 'shopt')  # shopt -s | 
| 369 | spec.Action(None, 'signal')  # kill -s | 
| 370 | spec.Action(None, 'stopped') | 
| 371 |  | 
| 372 |  | 
| 373 | COMPLETE_SPEC = FlagSpecAndMore('complete') | 
| 374 |  | 
| 375 | _DefineCompletionFlags(COMPLETE_SPEC) | 
| 376 | _DefineCompletionOptions(COMPLETE_SPEC) | 
| 377 | _DefineCompletionActions(COMPLETE_SPEC) | 
| 378 |  | 
| 379 | COMPLETE_SPEC.ShortFlag('-E', help='Define the compspec for an empty line') | 
| 380 | COMPLETE_SPEC.ShortFlag( | 
| 381 | '-D', help='Define the compspec that applies when nothing else matches') | 
| 382 |  | 
| 383 | # I would like this to be less compatible | 
| 384 | # Field name conflicts with 'print' keyword | 
| 385 | #COMPLETE_SPEC.LongFlag( | 
| 386 | #    '--print', help='Print spec') | 
| 387 |  | 
| 388 | COMPGEN_SPEC = FlagSpecAndMore('compgen')  # for -o and -A | 
| 389 |  | 
| 390 | # TODO: Add -l for COMP_LINE.  -p for COMP_POINT ? | 
| 391 | _DefineCompletionFlags(COMPGEN_SPEC) | 
| 392 | _DefineCompletionOptions(COMPGEN_SPEC) | 
| 393 | _DefineCompletionActions(COMPGEN_SPEC) | 
| 394 |  | 
| 395 | COMPOPT_SPEC = FlagSpecAndMore('compopt')  # for -o | 
| 396 | _DefineCompletionOptions(COMPOPT_SPEC) | 
| 397 |  | 
| 398 | COMPADJUST_SPEC = FlagSpecAndMore('compadjust') | 
| 399 |  | 
| 400 | COMPADJUST_SPEC.ShortFlag( | 
| 401 | '-n', | 
| 402 | args.String, | 
| 403 | help= | 
| 404 | 'Do NOT split by these characters.  It omits them from COMP_WORDBREAKS.') | 
| 405 | COMPADJUST_SPEC.ShortFlag('-s', | 
| 406 | help='Treat --foo=bar and --foo bar the same way.') | 
| 407 |  | 
| 408 | COMPEXPORT_SPEC = FlagSpecAndMore('compexport') | 
| 409 |  | 
| 410 | COMPEXPORT_SPEC.ShortFlag('-c', | 
| 411 | args.String, | 
| 412 | help='Shell string to complete, like sh -c') | 
| 413 |  | 
| 414 | COMPEXPORT_SPEC.LongFlag('--begin', | 
| 415 | args.Int, | 
| 416 | help='Simulate readline begin index into line buffer') | 
| 417 |  | 
| 418 | COMPEXPORT_SPEC.LongFlag('--end', | 
| 419 | args.Int, | 
| 420 | help='Simulate readline end index into line buffer') | 
| 421 |  | 
| 422 | # jlines is an array of strings with NO header line | 
| 423 | # TSV8 has a header line.  It can have flag descriptions and other data. | 
| 424 | COMPEXPORT_SPEC.LongFlag('--format', ['jlines', 'tsv8'], | 
| 425 | default='jlines', | 
| 426 | help='Output format') | 
| 427 |  | 
| 428 | # | 
| 429 | # Pure YSH | 
| 430 | # | 
| 431 |  | 
| 432 | TRY_SPEC = FlagSpec('try_') | 
| 433 | TRY_SPEC.LongFlag('--assign', | 
| 434 | args.String, | 
| 435 | help='Assign status to this variable, and return 0') | 
| 436 |  | 
| 437 | ERROR_SPEC = FlagSpec('error') | 
| 438 | FAILED_SPEC = FlagSpec('failed') | 
| 439 |  | 
| 440 | BOOLSTATUS_SPEC = FlagSpec('boolstatus') | 
| 441 |  | 
| 442 | # Future directions: | 
| 443 | # run --builtin, run --command, run --proc: | 
| 444 | #   to "replace" 'builtin' and # 'command' | 
| 445 |  | 
| 446 | APPEND_SPEC = FlagSpec('append') | 
| 447 |  | 
| 448 | SHVAR_SPEC = FlagSpec('shvar') | 
| 449 | #SHVAR_SPEC.Flag('-temp', args.String, | 
| 450 | #    help='Push a NAME=val binding') | 
| 451 | #SHVAR_SPEC.Flag('-env', args.String, | 
| 452 | #    help='Push a NAME=val binding and set the -x flag') | 
| 453 |  | 
| 454 | CTX_SPEC = FlagSpec('ctx') | 
| 455 |  | 
| 456 | PP_SPEC = FlagSpec('pp') | 
| 457 |  | 
| 458 | SHVM_SPEC = FlagSpec('shvm') | 
| 459 |  | 
| 460 | # --verbose? | 
| 461 | FORK_SPEC = FlagSpec('fork') | 
| 462 | FORKWAIT_SPEC = FlagSpec('forkwait') | 
| 463 |  | 
| 464 | # Might want --list at some point | 
| 465 | MODULE_SPEC = FlagSpec('module') | 
| 466 |  | 
| 467 | RUNPROC_SPEC = FlagSpec('runproc') | 
| 468 | RUNPROC_SPEC.ShortFlag('-h', args.Bool, help='Show all procs') | 
| 469 |  | 
| 470 | WRITE_SPEC = FlagSpec('write') | 
| 471 | WRITE_SPEC.LongFlag('--sep', | 
| 472 | args.String, | 
| 473 | default='\n', | 
| 474 | help='Characters to separate each argument') | 
| 475 | WRITE_SPEC.LongFlag('--end', | 
| 476 | args.String, | 
| 477 | default='\n', | 
| 478 | help='Characters to terminate the whole invocation') | 
| 479 | WRITE_SPEC.ShortFlag('-n', | 
| 480 | args.Bool, | 
| 481 | help="Omit newline (synonym for -end '')") | 
| 482 | # Do we need these two? | 
| 483 | WRITE_SPEC.LongFlag('--json', | 
| 484 | args.Bool, | 
| 485 | default=False, | 
| 486 | help='Write elements as JSON strings(lossy)') | 
| 487 | WRITE_SPEC.LongFlag('--j8', | 
| 488 | args.Bool, | 
| 489 | default=False, | 
| 490 | help='Write elements as J8 strings') | 
| 491 | # TODO: --jlines for conditional j"" prefix?  Like maybe_shell_encode() | 
| 492 |  | 
| 493 | # Legacy that's not really needed with J8 notation.  The = operator might use a | 
| 494 | # separate pretty printer that shows \u{3bc} | 
| 495 | # | 
| 496 | #   x means I want \x00 | 
| 497 | #   u means I want \u{1234} | 
| 498 | #   raw is utf-8 | 
| 499 | if 0: | 
| 500 | WRITE_SPEC.LongFlag( | 
| 501 | '--unicode', ['raw', 'u', 'x'], | 
| 502 | default='raw', | 
| 503 | help='Encode QSN with these options.  ' | 
| 504 | 'x assumes an opaque byte string, while raw and u try to ' | 
| 505 | 'decode UTF-8.') | 
| 506 |  | 
| 507 | PUSH_REGISTERS_SPEC = FlagSpec('push-registers') | 
| 508 |  | 
| 509 | FOPEN_SPEC = FlagSpec('fopen') | 
| 510 |  | 
| 511 | # | 
| 512 | # JSON | 
| 513 | # | 
| 514 |  | 
| 515 | JSON_WRITE_SPEC = FlagSpec('json_write') | 
| 516 |  | 
| 517 | # TODO: --compact is probably better | 
| 518 | # --pretty=F is like JSON.stringify(d, null, 0) | 
| 519 | JSON_WRITE_SPEC.LongFlag('--pretty', | 
| 520 | args.Bool, | 
| 521 | default=True, | 
| 522 | help='Whitespace in output (default true)') | 
| 523 |  | 
| 524 | # Unused: | 
| 525 | # JSON has the questionable decision of allowing (unpaired) surrogate like | 
| 526 | # \udc00. | 
| 527 | # When encoding, we try to catch the error on OUR side, rather than letting it | 
| 528 | # travel over the wire.  But you can disable this. | 
| 529 | JSON_WRITE_SPEC.LongFlag( | 
| 530 | '--surrogate-ok', | 
| 531 | args.Bool, | 
| 532 | default=False, | 
| 533 | help='Invalid UTF-8 can be encoded as surrogate like \\udc00') | 
| 534 |  | 
| 535 | JSON_WRITE_SPEC.LongFlag('--indent', | 
| 536 | args.Int, | 
| 537 | default=2, | 
| 538 | help='Indent JSON by this amount') | 
| 539 |  | 
| 540 | JSON_READ_SPEC = FlagSpec('json_read') |