$EPIC: expansions,v 1.1 2003/05/29 23:09:03 jnelson Exp $ $-expansion and Quoting Hell Whenever you give epic a string of text, epic will usually run it through the "expander" before it uses it. The expander has four main jobs: 1) Substitute $-expandos with whatever they evaluate to 2) Remove any \c sequences (c is any character) (**** SEE BELOW ****) 3) Find the start of the "next" command in a command set. 4) Determine if a numeric expando is used in the text. The following places use the expander: * alias.c prepare_alias_call * To expand "default" values in argument list, eg /alias oof (var1 default "$ooga") {...} * commands.c parse_line (**** SEE BELOW ****) * To extract and expand the first command from a block of commands prior to execution; to determine if the command uses a numeric expando and to append $* if it does not, eg /alias oof {echo $ooga;echo hi} /alias booya msg * expr.c next_unit (SETUP_IMPLIED) * To expand the variable name on the left hand side of an implied assignment, eg @ $ooga += 3 * expr.c next_unit ([...] handling) * To expand the inside of [...] operator in an expression which starts with $ but is not a numeric expando, eg @ var = [$ooga] * expr.c next_unit ([...] handling) * To expand the inside of [...] operator that contains a $ or \ character, eg @ var = [one two $ooga my shoe] @ var = [one two \three four] * expr.c next_unit (pre/post in/decrement operator) * To expand the variable name operand of the pre or post increment or decrement operators, eg @ $ooga++ @ --$ooga * expr.c next_unit (= operator handling) * To expand the variable name on the left hand side of a straight assignment, eg @ $ooga = 3 * expr.c alias_special_char * To expand the inside of the width qualifier following a $, eg $[$ooga]var1 * expr.c alias_special_char * To expand the inside of $(...) (``indirect'') expando, eg $($ooga) * expr2.c get_raw_token (NEW MATH PARSER) * To convert an operand that is available as an "LVAL" when it is needed to be used in a "RAW" context, eg @ var1 = $ooga * expr2.c get_token_expanded (NEW MATH PARSER) * To convert an operand that is available as a "RAW" value when it is needed to be used in an "EXPANDED" context, eg @ var1 = [$ooga] * functions.c call_function * To expand the argument list contained within parenthesis to a function being called, eg @ func($ooga) * functions.c function_cparse ($cparse()) * To expand the resulting string after the cparse substitutions, for BitchX compatability, eg /echo $cparse("one two" buckle my $1 shoes $ooga) * hook.c do_hook * To expand the inside of a flexible hook before pattern matching, eg /on msg '$ooga *' {...} * if.c fe * To expand the word list argument to the /FE command, eg /fe ($ooga) {...} * if.c for_fe_cmd * To expand the word list argument to the /FOR I IN (...) command, eg /for i in ($ooga) {...} * if.c switchcmd * To expand the control string argument to the /SWITCH command, eg /switch ($ooga) {....} * if.c switcmd * To expand the matching string argument to the /SWITCH command, eg /switch ($*) {($ooga) {...}} * if.c repeatcmd * To expand the number-iterations argument to the /REPEAT command, eg /repeat $ooga .... * input.c update_input * To expand the value of /set input_prompt prior to display, eg /set input_prompt ${ooga}> * ircaux.c remove_brackets * To expand the inside of a variable array qualifier, eg $var1[$ooga] * log.c add_to_log * To rewrite text sent to a log before writing it, eg /set log_rewrite $ooga $1- /log new rewrite "$ooga $1-" * numbers.c banner * To expand /set banner prior to display when /set banner_expand on, eg /set banner $ooga /set banner_expand on * output.c vsay * To expand /set banner prior to display when /set banner_expand on, eg /set banner $ooga /set banner_expand on * queue.c queuecmd * To expand the command bodies at registration time if -expand_now is used, eg /queue -expand_now {$ooga} * screen.c add_to_window * To rewrite text sent to a window before displaying it, eg /set output_rewrite $ooga $1- * status.c make_status * To expand the status bar after substitution but before displaying it when /set status_does_expandos on, eg /set status_user1 $ooga /set status_does_expandos on ============================================================================== The "dequoter" is the function that removes \'s from a text string. It is the place that most commonly causes ``quoting hell''. Each time a function is passed through the "dequoter", another level of \'s are removed. The "dequoter" is malloc_strcat_ues_c, and it is called by the following: * expr.c expand_alias * To copy portions of the original string that are not part of a $-expando, contained withing parenthesis, or braces, * window.c window_channel * To convert \" to " from the argument to /window channel so you may join channels with quotes in them, eg /window channel "#one\"two" /window channel #foobar "key\"withquote" ============================================================================== The "Evaluator" is the function that runs a block of commands that you give it. It is the basis of the /eval command and every command you run in the language goes through it at least once. The evaluator may pass the commands through expand_alias, which means support for {}s, semicolons between commands, and $-expansion. The evaluator may just treat the entire thing as one big command however. The caller sets a flag to decide this The "evaluator" is parse_line, and it is called by the following: * alias.c parse_line_alias_special * To run a command alias's block of commands. * Full expansion handling * $* is passed in from above * commands.c do_defered_commands * To run commands that were /DEFERed previously * Full expansion handling * $* is saved from when /DEFER was registered * commands.c xevalcmd * To run a command through the evaluator a second time, possibly in a different window or server context. * Full expansion handling (could result in double expansion) * $* is passed in from above * commands.c evalcmd * To run a command through the evaluator a second time * Full expansion handling (could result in double expansion) * $* is passed in from above * commands.c loader_std * To run one command from within a /LOADed script * Full expansion if /SET INPUT_ALIASES is ON (usually not though) * Full expansion if /LOAD -ARGS filename ... was used * $* is [] if /LOAD -ARGS is not used. * commands.c loader_pf * To run an entire pre-formatted block of commands within a script * Full expansion handling * $* is [] if /LOAD -ARGS is not used. * commands.c redirect * To run commands to watch for data sent to server * Full expansion handling (could result in double expansion) * $* is passed in from above. * commands.c sendlinecmd * To run commands unconditionally as if from the command line * Full expansion if /SET INPUT_ALIASES is ON (usually not though) * $* is [] in all cases. * commands.c waitcmd (/WAIT FOR ....) * To run commands to watch for data sent to server in * Full expansion handling (could result in double expansion) * $* is passed in from above * commands.c send_text * To run the "AWAY" command or alias when sending a message from the input line and when away and when /SET AUTO_UNMARK_AWAY is on. * Full expansion handling (nothing to expand, however) * $* is [] in all cases * commands.c eval_inputlist * To run commands passed to /INPUT "prompt" <commands> * Full expansion handling (could result in double expansion) * $* is saved from when the /input prompt was registered * commands.c parse_line * To run the insides of {...} blocks passed to parse_line. * Full expansion ({...} are protected; no double expansion) * $* is passed in from above. * exec.c handle_fieldesc * To run the commands of /exec -line, -error, -linepart, -errorpart, or /exec -end. * Full expansion (syntax forces use of {}s, so no double expansion) * $* is provided on the fly. * exec.c cleanup_dead_processes * To run the commands of /wait %proc -cmd {...} * Full expansion (could result in double expansion) * $* is provided on the fly. * expr.c next_unit * To run the inside of the {...} operator as a function. * Full expansion ({} is protected; no double expansion) * $* is passed in from above. * hook.c do_hook * To run the hook command body * Full expansion (could result in double expansion) * $* is provided on the fly. * if.c ifcmd * To run commands in an /IF decision block * Full expansion (syntax usually requires {}, so no double expansion) * $* is passed in from above * if.c docmd * To run commands in a /DO {...} (...) loop block * Full expansion (syntax requires {}, so no double expansion) * $* is passed in from above * if.c docmd * To run commands in a /DO .... command block * Full expansion (double expansion if {}s are not used) * $* is passed in from above * if.c whilecmd * To run commands in a /WHILE (...) loop block * Full expansion (double expansion if {}s are not used) * $* is passed in from above * if.c foreach * To run commands in a /FOREACH head var {...} loop block * Full expansion (syntax requires {}, so no double expansion) * $* is passed in from above * if.c fe * To run commands in a /FE loop block * Full expansion (syntax requires {}, so no double expansion) * $* is passed in from above * if.c for_next_cmd * To run commands in a /FOR var FROM start TO end {...} loop block * Full expansion (syntax requires {}, so no double expansion) * $* is passed in from above * if.c for_fe_cmd * To run commands in a /FOR var IN (list) {...} loop block * Full expansion (syntax requires {}, so no double expansion) * $* is passed in from above * if.c forcmd * To run commands in a /FOR (...,<expr>,...) {...} loop block * To run prelim and loop iteration commands in above. * Full expansion (syntax requires a {}, so no double expansion) * $* is passed in from above * if.c switchmd * To run commands in a /SWITCH body * Full expansion (syntax requires {} so no double expansion) * $* is passed in from above * if.c repeatcmd * To run commands to /REPEAT * Full expansion (Double expansion if {} is not used) * $* is passed in from above * input.c send_line (key binding) * To run the command in the input prompt * Full expansion depends on /SET INPUT_ALIASES (normally off) * $* is [] in all cases * input.c parse_text (key binding) * Runs the command argument to the binding, eg /bind ^X parse_command CMD ooga booga * Full expansion (double expansion if {} is not used argument cmds) * $* is [] in all cases * keys.c key_exec * Runs an alias that is associated with a key binding * Full expansion (double expansion if {} was not used to create bind) * $* is [] in all cases. * perl.c XS_cmd * Runs a command passed in from perl as if it were executed at the input prompt with /SET INPUT_ALIASES OFF * No expansion (naturally) * $* is irrelevant. * perl.c XS_eval * Runs a command passed in from perl as if it were executed at the input prompt with /SET INPUT_ALIASES ON * Full expansion * $* is [] in every case * queue.c run_queue * Runs a queued command when the queue itself is run * Full expansion (may have previously been expanded!) * $* is saved from when the command was put into the queue. * screen.c do_screens * Runs a command from standard input when in "dumb mode" * Expansion depends on /SET INPUT_ALIASES (usually off) * $* is [] in every case * server.c check_server_wait * Runs a command registered with /WAIT -cmd ... * Full expansion (double expansion if {} is not used) * $* is [] in every case * tcl.c Tcl_epicCmd * Runs a command passed in from the tcl commands "cmd" or "eval" as in the perl case. * Expansion depends on the command (see perl case) * $* is [] in every case * timer.c ExecuteTimers * Runs commands scheduled for later execution with /TIMER time ... * Full expansion (double expansion if {} is not used) * $* is saved from when the command was scheduled * who.c whoreply * Runs commands from /WHO -LINE {....} * Full expansion (syntax requires {}, so no double expansion) * $* is provided on the fly. * who.c whoend * Runs commands from /WHO -END {....} * Full expansion (syntax requires {}, so no double expansion) * $* is provided on the fly. * who.c fake_who_end * Runs commands from /WHO -END {....} * Full expansion (syntax requires {}, so no double expansion) * $* is provided on the fly. * who.c userhost_cmd_returned * Runs commands from /USERHOST <nicks> -CMD .... * Full expansion (double expansion if {} is not used) * $* is provided on the fly. #end of file