Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: 'emulate sh -c' and $0



On 2014-06-03 17:21, Bart Schaefer wrote:
> On Jun 3, 2014 1:15 PM, "Richard Hansen" <rhansen@xxxxxxx> wrote:
>>
>> Wow, thank you for committing this change to master!  It works well in
>> my limited testing, except for the documented limitation that
>> POSIX_ARGZERO stays enabled when calling a non-emulated function from a
>> function defined in 'emulate <shell> -c'.  I'm not sure how much this
>> will matter in practice, but if backward compatibility wasn't a concern
>> it'd be nice if zsh temporarily restored options when invoking a
>> function outside the 'emulate <shell> -c' boundary.
> 
> What this is effectively requesting is that all functions have "sticky"
> options, always.

Not necessarily -- I was thinking more along the lines of temporarily
restoring the top-level (non-emulated) option state when calling a
function that was not defined inside of 'emulate <shell> -c'.  (Maybe
there's not a significant implementation difference between what I'm
thinking and assigning sticky options to all functions.)

I'm not familiar with Zsh's implementation, but this is my current
(probably flawed) mental model:

  * there is a structure type (e.g., 'struct option_state') that is
    effectively an array of booleans (one for each option) that is
    intended to record which options are enabled/disabled
  * there is a global variable (e.g., 'global_option_state') of the
    above structure type that stores which options are enabled/disabled
    when *not* running in an emulation mode
  * there is a global variable (e.g., 'current_option_state') of type
    pointer to the above structure type that is used to indicate which
    options are currently active
  * when it's time to call a function, the following happens:

      if the function was defined under an emulation mode and that
      emulation mode differs from the current emulation mode (if
      applicable):
          1. create a new struct option_state
          2. load the sticky options into the new struct option_state
          3. back up the current_option_state pointer
          4. set current_option_state to point to the new struct
             option_state
          5. call the function
          6. restore current_option_state
          7. delete the new struct option_state
      else:
          1. call the function

If my mental model is roughly correct, then the following could be
inserted between the above 'if' case and the 'else' case to temporarily
restore options when invoking a function outside the 'emulate -c' boundary:

      else if the function was not defined under an emulation mode but
      we're currently running under an emulation mode:
          1. back up the current_option_state pointer
          2. set current_option_state to point to global_option_state
          3. call the function
          4. restore current_option_state

> We already rejected that idea for reasons of dynamic
> scoping when originally designing "emulate ... -c".  I suppose a special
> case could be made of POSIX_ARGZERO such that it is always sticky even when
> other options are not, but that seems like an awful lot of effort for
> something that doesn't matter most of the time.

Yeah, that doesn't seem worthwhile.  In general I dislike special cases,
and it seems like the other options would also benefit from being
temporarily restored to their non-emulation state when calling a
function defined outside of 'emulate <shell> -c'.

-Richard



Messages sorted by: Reverse Date, Date, Thread, Author