bugGNU Octave - Bugs: bug #60882, error parsing command syntax

 
 

bug #60882: error parsing command syntax

Submitted by:  Guillaume <gyom>
Submitted on:  Mon 05 Jul 2021 09:33:15 AM UTC  
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Regression
Status:  In Progress Assigned to:  None
Originator Name:  Guillaume Open/Closed:  Open
Release:  dev Operating System:  Any

Add a New Comment (Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

( Jump to the original submission)

Wed 25 Aug 2021 12:51:34 AM UTC, comment #40: 

Per Octave Developer Call today, we will deprecate

**
.**

but keep

Rik <rik5>
Project Administrator
Tue 24 Aug 2021 10:14:10 AM UTC, comment #39: 

Rik: until recent changes, when executing code at the command line, Octave checked whether a symbol was defined as a variable and if so, did not attempt to parse a statement as a command-style function call.  I believe that is also what Matlab used to do.  But now, for consistency in behavior, Matlab uses the same syntax-only rules to parse statements.  It doesn't consult the current workspace at parse time.  The "used as variable and later as function" message happens after parsing is already done, at the time the code is executed.

I think the only question left is whether to handle our extended set of operators (++, +=, etc.) specially or in a fully Matlab-compatible way when parsing command syntax.  Since Matlab doesn't have += (for example), I believe that an expression like

foo +=

is parsed as a command-style function call regardless of what follows the +=.  If we do the same for Octave, then it is impossible to use += as an operator unless the expression is written with no space after the identifier:

foo+=something    ## OP=
foo+= something   ## OP=
foo +=something   ## command-style function call
foo += something  ## command-style function call

That seems bad to me, so I left the special treatment of these operators in Octave so that the only one that causes command-style function parsing is

foo +=something

similar to the way that both Octave and Matlab handle other binary operators (i.e., only the "foo +something" is handled as command-style function syntax).

Since ++ is a unary operator and + by itself is both a binary and prefix unary operator, the rules are a little different.  In Matlab, the parsing of expressions involving repeated + characters is a bit weird:

foo ++            %% command-style function call
foo ++ something  %% command-style function call
foo++something    %% expression: foo + (+something)
foo++ something   %% expression: foo + (+something)
foo ++something   %% command-style function call

See also

https://octave.discourse.group/t/parsing-command-style-function-call-syntax/1414/4

where I posted a test function to verify current behavior of Matlab and Octave.  Note that in the results that Markus posted for Matlab, the "OK" doesn't mean that Octave and Matlab behavior is the same, just that we know what the behaviors are.  Looking at the function itself shows that there are currently differences between  Octave and Matlab for the following operators:

@
\
~
.+
.-
.**
!=
**
++
--

all the OP= operators.

It would probably be fairly painless to phase out and eventually remove

.+
.-
.**
**

We are already eliminating the problem with backslash as a continuation character outside of character strings.  I think we can make the behavior of @ and ~ compatible with Matlab.  Changing != (and !) to be compatible would be very unpleasant.

Since ++ and -- are not binary operators anyway, we can get closer to the Matlab behavior if we reject them as two-character tokens in some cases depending on the surrounding context, return just '+' (or '-') from the lexer, and continue parsing beginning with the next '+' (or '-') character from the input stream.  That should provide compatibility with Matlab by parsing expressions like "foo++something" as "foo + (+something)".

John W. Eaton <jwe>
Project Administrator
Sat 21 Aug 2021 09:50:24 PM UTC, comment #38: 

I assume this is related, but I get an error for this code:

octave:2> myvar = 5
myvar = 5
octave:3> myvar .^2
error: myvar used as variable and later as function
octave:4> myvar .^ 2
ans = 25

In Octave 6.3 there is no error for the above code.

Rik <rik5>
Project Administrator
Fri 06 Aug 2021 05:33:43 PM UTC, comment #37: 

I should clarify that "x ++ + 3" evaluates to 3 when x is originally 0. I neglected to mention the initial value of x. In general it evaluates to x+3 overall, and increments x as a side-effect. This behavior is actually consistent with C++ and Java, so might not be wrong though it is ill-advised to write such an expression in production code.

Anonymous
Fri 06 Aug 2021 07:39:10 AM UTC, comment #36: 

Matlab and Octave differentiate between command syntax and function syntax (see section 11.13 of the current manual).
`x ++` is interpreted as command syntax. Thus, it requires that `x` is valid function identifier. If it is not, an error is emitted.
`y = x ++` cannot be interpreted in command syntax (because of the assignment which is impossible in command syntax). Thus, it is treated as function syntax. That means `++` cannot be a function argument (or the user would need to write `y = x('++')`). Thus, it is treated as an operator.

`x ++ + 3` evaluating to 3 might be a bug. IIUC, it should be evaluated the same as `x('++', '+', '3')` which should result in an error if `x` is not a valid function identifier.

Markus Mützel <mmuetzel>
Project Member
Thu 05 Aug 2021 06:26:48 PM UTC, comment #35: 

I request clarification. The statement "x ++" causes an error but the command "y = x ++" does not, which evaluates to "y = x; x += 1;". Nor does the admittedly pathological statement "x ++ + 3" cause an error, which evaluates to 3. That is, "x ++" with the space only causes an error when it occurs by itself, not when embedded in a bigger statement. Is this behavior intended?

Anonymous
Fri 30 Jul 2021 06:14:17 PM UTC, comment #34: 

There was a bunch of work on this and discussion over on the Discourse site.  Is there more to be done or can this report be closed?

Rik <rik5>
Project Administrator
Wed 21 Jul 2021 05:51:00 PM UTC, comment #33: 

Imho, we don't need to aim for full syntax compatibility for the operators that Octave has but Matlab does not have.

From a user point of view, it is possible to write code that is compatible with Octave and with Matlab without too much effort at all: Just avoid command syntax if the arguments look like operators.

Markus Mützel <mmuetzel>
Project Member
Wed 21 Jul 2021 05:40:04 PM UTC, comment #32: 

I wrote:

I think it is better if there is not special treatment at the command line, so I undid that part of my previous change, here:

and forgot the link to the change.  It is here:

http://hg.savannah.gnu.org/hgweb/octave/rev/ef865fcd4611

John W. Eaton <jwe>
Project Administrator
Wed 21 Jul 2021 05:38:00 PM UTC, comment #31: 

BTW, this trouble all started when I was working on handling the new "arguments" block syntax and I decided to try to eliminate some duplicated information in the parser and interpreter.  Instead of storing lists of pending variables (function parameters and identifiers found on the LHS of assignment operators) in the lexer and storing identifiers in the symbol table, I thought it would be best to just tag the symbols in the symbol table as (expected) variables based on syntax alone.  A mistake in that change caused the bug reported here.  (The mistake was entering "diary" as a variable when it appeared in an expression like "job.diary = ...", even though "diary" by itself here isn't a variable.)

Now I think I'm just confused about what we should be doing here, because I just made a change so that we are once again treating

a=1;
b=2;
a -b

at the command line differently from what happens in a function or script because my change made Octave look at the symbol table to decide whether "a" is a variable when parsing "a -b", and if it is, to not handle that statement as a command.  But according to comment #15, current versions of Matlab are no longer doing that?  I think it is better if there is not special treatment at the command line, so I undid that part of my previous change, here:

I also think it is best if we can parse the command-style syntax completely based on syntax, so I would prefer to stick with that change.  But it does present some compatibility problems.  If we use syntax alone and opt for full Matlab compatibility, then none  of the OP= operators can work properly with simple identifiers at the beginning of an expression because Matlab will always parse statements like "foo -= bar" as commands (please correct me if that's not the case).

John W. Eaton <jwe>
Project Administrator
Wed 21 Jul 2021 05:29:22 PM UTC, comment #30: 

Thanks, that's good news because it is much simpler to not have to recognize expressions like that as commands.

John W. Eaton <jwe>
Project Administrator
Wed 21 Jul 2021 05:13:30 PM UTC, comment #29: 

That doesn't seem to be working in Matlab R2021a either:

>> type +a/b

function b(arg1, arg2)
disp(arg1);
disp(arg2);
end
>> a.b('foo', 'bar')
foo
bar
>> a.b foo bar
a.b foo bar
     ↑
Invalid expression. Check for missing multiplication operator, missing or unbalanced delimiters, or other syntax error. To construct matrices, use brackets instead of parentheses.

Markus Mützel <mmuetzel>
Project Member
Wed 21 Jul 2021 05:07:19 PM UTC, comment #28: 

Rik: RE comment #27, an expression like

foo() ++

wouldn't be interpreted as a command anyway because with the way the parser is now, that can only happen when the token before the operator is a simple identifier.

This raises another question about how Matlab works though...

Is a name like PKG.FCN allowed as the name of a command?  In other words, is it possible to use the full name of a package function as a command?  If so, then Octave's parser still isn't handling this syntax "correctly".

John W. Eaton <jwe>
Project Administrator
Wed 21 Jul 2021 04:45:08 PM UTC, comment #27: 

I fixed the one example in core octave in _strip_html_tags_.m.  See http://hg.savannah.gnu.org/hgweb/octave/rev/ee84485289ce.

I used grep to look for ' --' and ' ++' sequences in the scripts directory and that was the only one I found.

Rik <rik5>
Project Administrator
Wed 21 Jul 2021 04:23:12 PM UTC, comment #26: 

Definitely this should go in the NEWS file for Octave 7.

And documentation should be updated to strongly recommend cuddling postfix operators (--, ++) with their variable for clarity.

For testing, I do think it will simply come down to loading a package and running regression tests.  I would hope that programmers have not used a space between variables and post-fix operators extensively.

Rik <rik5>
Project Administrator
Wed 21 Jul 2021 04:22:48 PM UTC, comment #25: 

Re comment #24: That change only affects the .m file parser. It shouldn't affect C or C++ code.

Markus Mützel <mmuetzel>
Project Member
Wed 21 Jul 2021 04:20:43 PM UTC, comment #24: 

Re Comment #22, agreed, it would make sense to require postfix ++ and -- operators to immediately follow their variable without a space.

For uses of "foo ++" within the Octave codebase and in Octave Forge packages, they should probably be changed to "foo++" or "foo += 1" as preferred.

Please note the following potentially problematic uses of postfix notation within the Octave codebase, to be changed if required:

libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp:728:        begin.rx () --;
libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp:734:      end.rx () ++;

libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp:742:      begin.rx () --;
libgui/qterminal/libqterminal/win32/QWinTerminalImpl.cpp:748:      end.rx () ++;

scripts/help/private/__strip_html_tags__.m:63:      groups(end, 2) ++;

Anonymous
Wed 21 Jul 2021 04:15:43 PM UTC, comment #23: 

Thanks.
That might be the best way forward.

With Octave 6, `x --` was interpreted as decrement operation.
IIUC, the same syntax will be interpreted as command syntax in Octave 7. This might break code that currently uses something like that.
I gather there is no easy way to deprecate that syntax for a few versions before we finally change its meaning.

IIUC, syntax like that can be fixed easily by removing the whitespace (`x--`) or by forcing it to an expression (e.g. with `(x --)`). That should have the same meaning in Octave 6 and in Octave 7.

Is there a way we can reach out to users and developers (e.g. of Octave Forge packages) to give them some head start of that upcoming change?

Markus Mützel <mmuetzel>
Project Member
Wed 21 Jul 2021 03:58:08 PM UTC, comment #22: 

I pushed the following changeset to make Octave treat all binary ops the same whether they are in Matlab or not. 

http://hg.savannah.gnu.org/hgweb/octave/rev/da6e5914ddaf

So now

x-=2    %% operator
x-= 2   %% operator
x -= 2  %% operator
x -=2   %% command syntax

Attempting to handle postfix ++ and -- as operators just by looking at syntax and when they are preceded by spaces is complicated.  If we do the same as shown above, then it is impossible to use common use of '--' to indicate the end of options:

foo -- -this-is-not-an-option  %% should be a command?

John W. Eaton <jwe>
Project Administrator
Wed 21 Jul 2021 01:08:41 PM UTC, comment #21: 

@jwe: I like your proposition in comment #17.
That logic will probably succeed for most use cases.

We could treat `a -= b` (which is a command in Matlab, but an assignment in Octave) as a known incompatibility.
There is syntax that will work the same in both Matlab and in Octave (i.e. using the function syntax): `a ('-=', 'b')`. That is arguably clearer anyway.

Should we use the same logic for Octave's unary appended operators?

Markus Mützel <mmuetzel>
Project Member
Tue 20 Jul 2021 03:20:54 PM UTC, comment #20: 

The following Octave Forge packages cannot currently be installed on Octave 7 hg id 744bb06fea2a as a result of this change to the parser:

signal (therefore communications)

optim (therefore data-smoothing, econometrics)

Anonymous
Mon 19 Jul 2021 07:05:36 PM UTC, comment #19: 

The '=' symbol is always treated as an operator regardless of spacing.

It may be incorrect for Octave to parse "x ++" as a command at the command line when "x" is already defined as a variable.  We may be missing a check for that.

Also, I didn't verify the actual behavior of the current development version of Octave, but if it is still parsing the full command line before evaluating anything, then input like "x = 1; x ++" all on one line would behave differently from executing those two expressions on separate input lines.

John W. Eaton <jwe>
Project Administrator
Mon 19 Jul 2021 06:32:47 PM UTC, comment #18: 

Request: please do continue to allow spaces in "x += 1" and "x -= 1" statements. I use those constructions 493 + 138 == 631 times in my code alone, not counting other people's code.

Question: the following test gives an error in one case but not another. Is that intended?

octave:4> x = y = 0; x = y ++, x, y
x = 0
x = 0
y = 1
octave:5> x = y = 0; x ++
error: x used as variable and later as function

Anonymous
Mon 19 Jul 2021 06:00:56 PM UTC, comment #17: 

The Matlab docs also explain that at the command line, Matlab may check the current workspace to determine whether the first symbol in an expression is a variable.  But in a script or function, command syntax is recognized purely from syntax.  They also explain that when looking at syntax alone, '=' is always recognized as assignment regardless of whitespace but

v1 OPv2  %% command
v1 OP v2 %% expression
v1OPv2   %% expression

We attempt the same, but we have the following extra operators:

 !=
++  --
**
.**  .+   .-
+=   -=   *=   /=   \\=    ^=   **=   &=   |=
.+=  .-=  .*=  ./=  .\\=   .^=  .**=

I already made the OP= operators always behave as operators regardless of spacing and added the following comment to lex.ll:

// Use the following to handle computed assignment operators
// (+=, -=, etc.) in word list commands in a way that is compatible
// with Matlab.  However, that will also make it impossible to use
// these operators with a space before them:
//
//   x = 1;
//   x+=2;   ## ok
//   x+= 2;  ## ok
//   x +=2;  ## error: invalid use of symbol as both variable and command
//   x += 2; ## error: invalid use of symbol as both variable and command

but maybe that's not the correct behavior anyway.  Instead, would it be OK if we could make Octave behave as follows?

  x-=2   %% -= is an operator
  x-= 2  %% -= is an operator
  x -= 2 %% -= is an operator
  x -=2  %% -=2 is an argument to a command-style function call

The difference with Matlab would still be that "-=" by itself is recognized as an argument to a command-style function call because Matlab doesn't have "-=" as an operator so it recognizes this as "-" followed by another character with no space, so that looks like a command-style argument instead of an operator.  This behavior may break some valid Matlab code that currently works in Octave because users expect "-ANYTHING" to be recognized as a command option.

John W. Eaton <jwe>
Project Administrator
Mon 19 Jul 2021 05:39:27 PM UTC, comment #16: 

> The documentation of the increment operators doesn't use spaces. Should we write explicitly that spaces are discouraged/forbidden for the appended increment and decrement operators (unless used in an assignment)?


YES!  I find "c ++" to be a very confusing way to write the increment operator on the variable 'c'.  For clarity alone we should recommend cuddling the operator with the variable name.  And we can mention that there are potential problems with parsing with the other syntax.

Rik <rik5>
Project Administrator
Mon 19 Jul 2021 05:05:31 PM UTC, comment #15: 

You are right.
In Matlab R2021a:
On the command line:

>> clear all
>> a=1;
>> b=2;
>> a -b
Error: "a" was previously used as a variable, conflicting with its use here as the name of a function or command.
See "How MATLAB Recognizes Command Syntax" in the MATLAB documentation for details.

With a script:

>> type tst_command_script

a=1;
b=2

a -b
>> tst_command_script
Error: File: tst_command_script.m Line: 4 Column: 1
"a" was previously used as a variable, conflicting with its use here as the name of a function or command.
See "How MATLAB Recognizes Command Syntax" in the MATLAB documentation for details.

With a function:

>> type tst_command_function

function tst_command_function()

a=1;
b=2

a -b

end
>> tst_command_function
Error: File: tst_command_function.m Line: 6 Column: 1
"a" was previously used as a variable, conflicting with its use here as the name of a function or command.
See "How MATLAB Recognizes Command Syntax" in the MATLAB documentation for details.

The current behavior might be the best we can do when it comes to compatibility and syntax extension.
Nevertheless, this change might be breaking some existing code that was written for Octave.
Would it be possible to emit a warning about deprecated syntax in this case and still recognize some operators which are currently treated as arguments?

Independent of this: Should we add a note about this in the NEWS file?

The documentation of the increment operators doesn't use spaces. Should we write explicitly that spaces are discouraged/forbidden for the appended increment and decrement operators (unless used in an assignment)?

Markus Mützel <mmuetzel>
Project Member
Mon 19 Jul 2021 04:48:23 PM UTC, comment #14: 

I believe that is the way that Matlab parses this syntax because it doesn't have "++" or "--" operators.  When I made the previous change, I made the "OP=" operators special so that they are not recognized as command-style syntax arguments but I missed others.

I believe Matlab command-style parsing depends on whitespace.  For example, "foo - var" (expression) vs. "foo -var" (command), correct?  And the behavior may be different at the command line vs. in a function or script.

So I'm not sure what the best solution is for providing a reasonable degree of compatibility vs. Octave extensions to the Matlab language.

John W. Eaton <jwe>
Project Administrator
Mon 19 Jul 2021 03:49:48 PM UTC, comment #13: 

This change might have caused bug #60920.

That bug is about the optim package. But the error might be in the parser/interpreter:

octave:2> which lsqlin
error: parse error near line 118 of file /path/to/optim-1.6.1/lsqlin.m

  n_out: invalid use of symbol as both variable and command

>>>     n_out --;
       ^

It looks like appended increment or decrement operators are interpreted as function arguments.

Markus Mützel <mmuetzel>
Project Member
Mon 19 Jul 2021 02:53:00 PM UTC, comment #12: 

I made the additional changes described in comment #11 in the following changeset:

http://hg.savannah.gnu.org/hgweb/octave/rev/e2e493712818

OK to close this report now?

John W. Eaton <jwe>
Project Administrator
Wed 07 Jul 2021 03:30:44 AM UTC, comment #11: 

I pushed the following change for now:

http://hg.savannah.gnu.org/hgweb/octave/rev/0b01806bb663

As noted in one of the comments I added, it might be possible to store the (expected) variable status of symbols in the symbol_scope object instead of in a separate list of sets.

Also, as noted in the discussion here:  https://octave.discourse.group/t/need-help-understanding-matlab-behavior/1313/12, we might be able to do a better job of parsing command-style function call syntax and detecting variables later used as commands if we always consider an identifier at the beginning of a statement as a possible command when parsing a function and parse it that way regardless of the status of any symbols that appear to be variables. Then, after the file is completely parsed and subfunctions and nested function scopes have been sorted out, walk the parse trees of the functions defined in the file and detect any command-style function calls that are using a symbol name that has previously appeared to be used as a variable. If I have some free time I’ll take a look at doing that.

John W. Eaton <jwe>
Project Administrator
Tue 06 Jul 2021 08:30:41 PM UTC, comment #10: 

I'm attaching an updated diff.  It still needs a commit message and some tests.  I'll try to get to that tonight.  I could also use some feedback my latest question here:

https://octave.discourse.group/t/need-help-understanding-matlab-behavior/1313/10

(file #51654)

John W. Eaton <jwe>
Project Administrator
Tue 06 Jul 2021 06:33:48 PM UTC, comment #9: 

I think we just need a stack of sets of local variables recognized by the parser instead of just a single set.  I'm looking at it now.  If I can't make a proper change quickly, I'll push the simpler fix.

John W. Eaton <jwe>
Project Administrator
Tue 06 Jul 2021 06:21:51 PM UTC, comment #8: 

@jwe: Is it okay to push the patch you attached to this bug report to at least resolve this one issue?  Or do you think that you will get time to re-visit some of the larger issues with variables in different contexts soon and that work will obviate the need for this patch?

Rik <rik5>
Project Administrator
Mon 05 Jul 2021 06:49:16 PM UTC, comment #7: 

Thank you. Your patch fixes the issue for me.

Your comment doesn't get displayed entirely, the example with nested functions is:

function main ()
  function nested ()
    warning = 1;
    ...
  end
  warning off all
end

Guillaume <gyom>
Mon 05 Jul 2021 05:28:25 PM UTC, comment #6: 

This error was introduced with changeset 6858992dfadf
because "diary" was being added as a variable name in the expression

  job.diary = ...

because the name was followed by '='.

I think the attached change will help.

While looking at this, I realized that there are some other issues that need to be fixed to properly reset the parser and lexer state when parsing nested functions.  For example, Octave will fail to parse the following even though the "warning" variable inside the nested function should be local.  Some more work needs to be done to properly track the status of identifiers as variables in contexts like this.

John W. Eaton <jwe>
Project Administrator
Mon 05 Jul 2021 04:47:23 PM UTC, comment #5: 

Sorry, messed up the verbatim tags. Here it is again:

function varargout = parse_error (varargin)
  job.format = 0;
  format "long g"     %% no parse error
  format "long" "g"   %% this works too
endfunction

Anonymous
Mon 05 Jul 2021 04:46:03 PM UTC, comment #4: 

Turns out it doesn't need the function form diary('off') but simply calling diary "off" with quotes but without parentheses also works:

Anonymous
Mon 05 Jul 2021 04:39:09 PM UTC, comment #3: 

This is like a function name being shadowed by a variable name. The problem is when the variable name is from another scope or inside another structure.

The same thing happens with other command-style functions:

function varargout = parse_error (varargin)
  job.axis = 0;
  axis off
endfunction

function varargout = parse_error (varargin)
  job.format = 0;
  format long g
endfunction

Anonymous
Mon 05 Jul 2021 04:31:43 PM UTC, comment #2: 

Possible relations: bug #48031 (fixed) and bug #51988 (open).

Anonymous
Mon 05 Jul 2021 03:33:32 PM UTC, comment #1: 

Confirmed.

If the structure variable is renamed to something besides 'diary' then the code works correctly.  Similarly, if the the code `diary off` is changed to use the functional form of calling

diary ('off')

then the code works.

It would appear that the interpreter is somehow accidentally maintaining state that shows the structure field 'diary' as a top-level variable?

Rik <rik5>
Project Administrator
Mon 05 Jul 2021 09:33:15 AM UTC, original submission:  

Using current dev (hg id: b2455f0a8297+), there is a parse error with the following example:

function varargout = parse_error (varargin)

  job.diary = {};

  diary off

endfunction

octave> parse_error
error: parse error near line 5 of file parse_error.m

  syntax error

>>>   diary off
              ^

Guillaume <gyom>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

Attached Files
file #51654:  mark-as-var-patch-v2.txt added by jwe (8KiB - text/plain)
file #51648:  mark-as-var-patch.txt added by jwe (2KiB - text/plain)

 

Carbon-Copy List
  • -email is unavailable- added by mmuetzel (Posted a comment)
  • -email is unavailable- added by jwe (Updated the item)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by gyom (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

     

     

    Follow 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2021-07-21 mmuetzel StatusReady For Test => In Progress
    2021-07-19 mmuetzel Dependencies- => bugs #60941 is dependent
    2021-07-19 mmuetzel Dependencies- => bugs #60920 is dependent
    2021-07-07 jwe StatusConfirmed => Ready For Test
    2021-07-06 jwe Attached File- => Added mark-as-var-patch-v2.txt, #51654
    2021-07-05 jwe Attached File- => Added mark-as-var-patch.txt, #51648
        SummaryParse error => error parsing command syntax
    2021-07-05 rik5 StatusNone => Confirmed

    Back to the top


    Powered by Savane 3.6