On Mon, Dec 10, 2007 at 11:02:22PM +0100, Stefan Schimanski wrote:
> Jean-Marc Lasgouttes schrieb:
>> Stefan Schimanski <[EMAIL PROTECTED]> writes:
>>
>>   
>>> For insets you are right, I assume they open an environment, which is
>>> not correct in general. Have to check how to do this properly. The
>>> InsetBranch is on my list anyway. Haven't looked into that.
>>>     
>>
>> The best is probably a virtual method for insets telling whether there
>> is a scope.
> Added isMacroScope() to Inset as virtual method, defaulting to "true".
>
> I added an implementation to InsetBranch which sets the scope only if the 
> branch is deselected. So the macros follow the Branch semantics now.
>
> Stefan
>

[...]

>  ///
>  class MacroData {
>  public:
> -     ///
> +     /// Constructor to make STL containers happy
>       MacroData();
> +     /// Create lazy MacroData which only queries the macro template when 
> needed
> +     MacroData(Buffer const & buf, DocIterator const & pos);

This works?

> +     /// Create non-lazy MacroData which directly queries the macro template
> +     MacroData(MathMacroTemplate const & macro);
> +
>       ///
> -     MacroData(docstring const & definition,
> -             std::vector<docstring> const & defaults, int nargs, int 
> optionals, 
> -             docstring const & display, std::string const & requires);
> +     virtual ~MacroData() {}

Do we ever derive from MacroData? If not, why 'virtual'?

> -void MathData::collectOptionalParameters(Cursor & cur, 
> +void MathData::collectOptionalParameters(Cursor * cur, 
>       const size_type numOptionalParams, std::vector<MathData> & params, 
>       size_t & pos, const pos_type macroPos, const int thisPos, const int 
> thisSlice)
>  {
> @@ -614,7 +626,7 @@
>               // is a [] block following which could be an optional parameter?
>               if (operator[](pos)->getChar() != '[')
>                       break;
> -                             
> +             

_no_ trailing whitespace would be even nicer ;-)

> [...]
> -MacroData::MacroData(docstring const & definition,
> -             std::vector<docstring> const & defaults, 
> -             int numargs, int optionals, docstring const & display,
> -             string const & requires)
> -     : definition_(definition), numargs_(numargs), display_(display),
> -             requires_(requires), lockCount_(0), redefinition_(false),
> -             optionals_(optionals), defaults_(defaults)
> +     
> +     
> +MacroData::MacroData(Buffer const & buf, DocIterator const & pos)
> +     : buffer_(&buf), pos_(pos), queried_(false), numargs_(0),
> +       optionals_(0), lockCount_(0), redefinition_(false),
> +       type_(MacroTypeNewcommand)
>  {
> -     defaults_.resize(optionals);
>  }

This seems to rely for a certain time on the validity of the passed and
stored DocIterator. We have almost no guarantee for that, though.
Could you please elaborate a bit on what assumptions are made here and
why they will be fulfilled?

 [...]
> +void MacroData::queryData(MathMacroTemplate const & macro) const
> +{
> +     if (!queried_) {
> +             queried_ = true;
> +             definition_ = macro.definition();
> +             numargs_ = macro.numArgs();
> +             display_ = macro.displayDefinition();
> +             redefinition_ = macro.redefinition();
> +             type_ = macro.type();
> +             optionals_ = macro.numOptionals();
> +             macro.getDefaults(defaults_);
> +     }
> +}

Early return please. (More occurences below)

> +void MacroData::updateData() const
> +{
> +     if (!queried_) {
> +             BOOST_ASSERT(buffer_ != 0);
> +             
> +             // Try to fix position DocIterator. Should not do anything in 
> theory.

> -MacroData const & MacroTable::get(docstring const & name) const
> -{
>       const_iterator it = find(name);
> -     BOOST_ASSERT(it != end());
> -     return it->second;
> +     if (it == end())
> +             return 0;
> +     else
> +             return &it->second;

I find 

   return it == end() ? 0 : &it->second;  

less verbose and clearer.


> -     /// macro table
> -     typedef std::map<unsigned int, MacroData, std::greater<int> > 
> PositionToMacroMap;
> -     typedef std::map<docstring, PositionToMacroMap> NameToPositionMacroMap;
> -     NameToPositionMacroMap macros;
> +     /// macro tables
> +     typedef std::pair<DocIterator, MacroData> ScopeMacro;
> +     typedef std::map<DocIterator, ScopeMacro, std::greater<DocIterator> > 
> PositionScopeMacroMap;

Does this 'inverted logic' make things much clearer in the
implementation? If not (and I don't see it...) I'd think it'd
be better to stick with the default...

[...]
> +     // find macros in included files
> +     Impl::PositionScopeBufferMap::iterator it
> +     = d->position_to_children.upper_bound(pos);
> +     while (it != d->position_to_children.end()) {
> +             // do we know something better (i.e. later) already?
> +             if (it->first < bestPos )               
> +                     break;
> +
> +             // scope ends behind pos?
> +             if (pos < it->second.first) {
> +                     // look for macro in external file
> +                     d->macro_lock = true;
> +                     MacroData const * data
> +                     = it->second.second->getMacro(name, false);
> +                     d->macro_lock = false;
> +                     if (data) {
> +                             bestPos = it->first;
> +                             bestData = data;                               
> +                             break;
> +                     }
> +             }
> +             
> +             // External file out of scope, try the previous
> +             // NOTE: the map is sorted backwards, 
> +             //       hence it's a logical it--
> +             it++;

Especially if it makes explanations necessary ;-)

Apart from that: Patch _looks_ nice and I have no clue whether it works
;-}

Andre'

Reply via email to