Description: Avoid deprecated Bison directive %error-verbose with Bison version >= 3
Author: Rafael Laboissière <rafael@debian.org>
Forwarded: https://github.com/zgimbutas/mwrap/pull/15
Applied-Upstream: https://github.com/zgimbutas/mwrap/commit/0a5f204109b83d06547f7c9f1bf8f50ea81e2688
Last-Update: 2025-03-12
--- a/src/Makefile	2025-03-11 20:19:34.873831242 -0300
+++ b/src/Makefile	2025-03-11 20:17:09.654677147 -0300
@@ -14,6 +14,15 @@
 mwrap.cc: mwrap.y
 	$(BISON) -d -v mwrap.y -o mwrap.cc
 
+ifeq ($(shell bison --version 2>&1 | sed -n 's/^.*GNU Bison.* \([0-9]*\).*$$/\1/p'), 3)
+ERROR_VERBOSE = %define parse.error verbose
+else
+ERROR_VERBOSE = %error-verbose
+endif
+
+mwrap.y: mwrap.y.in
+	sed -e 's/@ERROR_VERBOSE@/$(ERROR_VERBOSE)/' < mwrap.y.in > mwrap.y
+
 lex.yy.o: lex.yy.c mwrap.cc
 
 lex.yy.c: mwrap.l
@@ -50,5 +59,5 @@ clean:
 	rm -f stringify
 
 realclean: clean
-	rm -f lex.yy.c mwrap.cc mwrap.hh mwrap-support.h mwrap.pdf
+	rm -f mwrap.y lex.yy.c mwrap.cc mwrap.hh mwrap-support.h mwrap.pdf
 
--- /dev/null
+++ mwrap-1.1.1/src/mwrap.y.in
@@ -0,0 +1,350 @@
+%{
+/*
+ * mwrap.y
+ *   Parser for mwrap.
+ *
+ * Copyright (c) 2007  David Bindel
+ * See the file COPYING for copying permissions
+ */
+
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+#include "mwrap-ast.h"
+
+extern "C" {
+    int yylex();
+    int yywrap();
+    int yyerror(const char* s);
+}
+
+using std::string;
+
+bool  mw_generate_catch = false;  // Catch C++ exceptions?
+bool  mw_use_cpp_complex = false; // Use C++ complex types?
+bool  mw_use_c99_complex = false; // Use C99 complex types?
+int   mw_promote_int = 0;     // Convert integer types to mwSize?
+int   mw_use_int32_t = 0;     // Use C99 int32_t?
+int   mw_use_int64_t = 0;     // Use C99 int64_t?
+int   mw_use_uint32_t = 0;     // Use C99 uint32_t?
+int   mw_use_uint64_t = 0;     // Use C99 uint64_t?
+int   mw_use_ulong = 0;     // Use unsigned long?
+int   mw_use_uint = 0;     // Use unsigned int?
+int   mw_use_ushort = 0;     // Use unsigned short?
+int   mw_use_uchar = 0;     // Use unsigned char?
+int   listing_flag = 0;           // Output filenames from @ commands?
+int   mbatching_flag = 0;         // Output on @ commands?
+int   linenum = 0;                // Lexer line number
+FILE* outfp   = 0;                // MATLAB output file
+FILE* outcfp  = 0;                // C output file
+
+static int    type_errs = 0;            // Number of typecheck errors
+static int    func_id = 0;              // Assign stub numbers
+static Func*  funcs   = 0;              // AST - linked list of functions
+static Func*  lastfunc = 0;             // Last link in funcs list
+static const char*  mexfunc = "mexfunction";  // Name of mex function
+static string current_ifname;           // Current input file name
+
+
+#define MAX_INCLUDE_DEPTH 10
+static string include_stack_names[MAX_INCLUDE_DEPTH];
+extern int include_stack_ptr;
+
+extern "C" void set_include_name(const char* s)
+{
+    include_stack_names[include_stack_ptr] = current_ifname;
+    current_ifname = s;
+}
+
+extern "C" void get_include_name()
+{
+    current_ifname = include_stack_names[include_stack_ptr].c_str();
+}
+
+
+inline void add_func(Func* func)
+{
+    static std::map<string,Func*> func_lookup;
+    if (!funcs) {
+        funcs = func;
+        lastfunc = func;
+        return;
+    } 
+
+    Func*& func_ptr = func_lookup[id_string(func)];
+    if (func_ptr) {
+        func_ptr->same_next = func;
+    } else {
+        lastfunc->next = func;
+        lastfunc = func;
+    }
+    func_ptr = func;
+}
+
+%}
+
+%union {
+    char* string;
+    struct Func* func;
+    struct Var* var;
+    struct TypeQual* qual;
+    struct Expr* expr;
+    struct InheritsDecl* inherits;
+    char c;
+}
+
+%token NON_C_LINE
+%token NEW TYPEDEF CLASS FORTRAN
+%token <string> ID 
+%token <string> NUMBER STRING
+%token <char> INPUT OUTPUT INOUT
+
+%type <func> func funcall
+%type <var>  var basevar args argsrest
+%type <c>    iospec
+%type <qual> quals aqual
+%type <expr> arrayspec exprs exprrest expr
+%type <inherits> inheritslist inheritsrest
+
+@ERROR_VERBOSE@
+
+%%
+statements: statement statements | ;
+
+statement:
+  basevar '=' funcall { 
+      $3->ret = $1; 
+      $3->id = ++func_id;
+      type_errs += typecheck($3, linenum);
+      if (outfp)
+          print_matlab_call(outfp, $3, mexfunc); 
+      add_func($3);
+  }
+  | funcall { 
+      $1->id = ++func_id;
+      type_errs += typecheck($1, linenum);
+      if (outfp)
+          print_matlab_call(outfp, $1, mexfunc); 
+      add_func($1);
+  } 
+  | tdef 
+  | classdef 
+  | NON_C_LINE 
+  | error ';' { yyerrok; } ;
+
+tdef: 
+  TYPEDEF ID ID ';' { 
+      if (strcmp($2, "numeric") == 0) {
+          add_scalar_type($3);
+      } else if (strcmp($2, "dcomplex") == 0) {
+          add_zscalar_type($3);
+      } else if (strcmp($2, "fcomplex") == 0) {
+          add_cscalar_type($3);
+      } else if (strcmp($2, "mxArray") == 0) {
+          add_mxarray_type($3);
+      } else {
+          fprintf(stderr, "Unrecognized typespace: %s\n", $2);
+          ++type_errs;
+      }
+      delete[] $2;
+      delete[] $3;
+  } ;
+
+classdef:
+  CLASS ID ':' inheritslist ';' {
+      add_inherits($2, $4);
+      delete[] $2;
+      destroy($4);
+  }
+
+inheritslist:
+  ID inheritsrest { $$ = new InheritsDecl($1, $2); } ;
+
+inheritsrest:
+  ',' ID inheritsrest { $$ = new InheritsDecl($2, $3); }
+  | { $$ = NULL; } ;
+
+funcall: func '(' args ')' ';' { $$ = $1; $$->args = $3; } ;
+
+args:
+  var argsrest { $$ = $1; $$->next = $2; }
+  | { $$ = NULL; } ;
+
+argsrest:
+  ',' var argsrest {$$ = $2; $$->next = $3; }
+  | { $$ = NULL; } ;
+
+basevar: ID ID               { $$ = new Var('o', promote_int($1), NULL, $2); }
+basevar: ID quals ID         { $$ = new Var('o', promote_int($1), $2,   $3); }
+basevar: ID ID aqual         { $$ = new Var('o', promote_int($1), $3,   $2); }
+
+var: iospec ID ID            { $$ = new Var($1,  promote_int($2), NULL, $3); }
+var: iospec ID quals ID      { $$ = new Var($1,  promote_int($2), $3,   $4); }
+var: iospec ID ID aqual      { $$ = new Var($1,  promote_int($2), $4,   $3); }
+
+var: iospec ID NUMBER        { $$ = new Var($1,  promote_int($2), NULL, $3); }
+var: iospec ID quals NUMBER  { $$ = new Var($1,  promote_int($2), $3,   $4); }
+
+var: iospec ID STRING        { $$ = new Var($1,  promote_int($2), NULL, $3); }
+var: iospec ID quals STRING  { $$ = new Var($1,  promote_int($2), $3,   $4); }
+
+iospec: 
+  INPUT    { $$ = 'i'; }
+  | OUTPUT { $$ = 'o'; }
+  | INOUT  { $$ = 'b'; }
+  |        { $$ = 'i'; } ;
+
+quals: 
+  '*'         { $$ = new TypeQual('*', NULL); }
+  | '&'       { $$ = new TypeQual('&', NULL); } 
+  | aqual     { $$ = $1; } ;
+
+aqual:
+  arrayspec       { $$ = new TypeQual('a', $1); } 
+  | arrayspec '&' { $$ = new TypeQual('r', $1); } ;
+
+arrayspec: '[' exprs ']' { $$ = $2; } ;
+
+exprs: 
+  expr exprrest { $$ = $1; $$->next = $2; }
+  |             { $$ = NULL; } 
+
+exprrest: 
+  ',' expr exprrest { $$ = $2; $$->next = $3; }
+  |                 { $$ = NULL; }
+
+expr: 
+  ID       { $$ = new Expr($1); }
+  | NUMBER { $$ = new Expr($1); }
+
+func: 
+  ID '-' '>' ID '.' ID { $$ = new Func($1, $4, $6, current_ifname, linenum); }
+  | ID          { $$ = new Func(NULL, NULL, $1, current_ifname, linenum); } 
+  | FORTRAN ID  { $$ = new Func(NULL, NULL, $2, current_ifname, linenum); 
+                  $$->fort = true;
+                } 
+  | NEW ID  { $$ = new Func(NULL, $2, mwrap_strdup("new"), 
+                          current_ifname, linenum); 
+            }
+  ;
+
+%%
+#include <stdio.h>
+#include <string.h>
+
+extern FILE* yyin;
+
+int yywrap()
+{
+    return 1;
+}
+
+int yyerror(const char* s)
+{
+    fprintf(stderr, "Parse error (%s:%d): %s\n", current_ifname.c_str(),
+            linenum, s);
+    return 0;
+}
+
+char* mwrap_strdup(const char* s)
+{
+    char* result = new char[strlen(s)+1];
+    strcpy(result, s);
+    return result;
+}
+
+const char* help_string = 
+"mwrap 1.1 - MEX file generator for MATLAB and Octave\n"
+"\n"
+"Syntax:\n"
+"  mwrap [-mex outputmex] [-m output.m] [-c outputmex.c] [-mb] [-list]\n"
+"        [-catch] [-i8] [-c99complex] [-cppcomplex] infile1 infile2 ...\n"
+"\n"
+"  -mex outputmex -- specify the MATLAB mex function name\n"
+"  -m output.m    -- generate the MATLAB stub called output.m\n"
+"  -c outputmex.c -- generate the C file outputmex.c\n"
+"  -mb            -- generate .m files specified with @ redirections\n"
+"  -list          -- list files specified with @ redirections\n"
+"  -catch         -- generate C++ exception handling code\n"
+"  -i8            -- convert int, long, uint, ulong to int64_t, uint64_t\n"
+"  -c99complex    -- add support code for C99 complex types\n"
+"  -cppcomplex    -- add support code for C++ complex types\n"
+"\n";
+
+int main(int argc, char** argv)
+{
+    int j;
+    int err_flag = 0;
+    init_scalar_types();
+
+    if (argc == 1) {
+        fprintf(stderr, "%s", help_string);
+        return 0;
+    } else {
+        for (j = 1; j < argc; ++j) {
+            if (strcmp(argv[j], "-m") == 0 && j+1 < argc)
+                outfp = fopen(argv[j+1], "w+");
+            if (strcmp(argv[j], "-c") == 0 && j+1 < argc)
+                outcfp = fopen(argv[j+1], "w+");
+            if (strcmp(argv[j], "-mex") == 0 && j+1 < argc)
+                mexfunc = argv[j+1];
+            if (strcmp(argv[j], "-mb") == 0)
+                mbatching_flag = 1;
+            if (strcmp(argv[j], "-list") == 0)
+                listing_flag = 1;
+            if (strcmp(argv[j], "-catch") == 0)
+                mw_generate_catch = true;
+            if (strcmp(argv[j], "-i8") == 0)
+                mw_promote_int = 4;
+            if (strcmp(argv[j], "-c99complex") == 0) 
+                mw_use_c99_complex = true;
+            if (strcmp(argv[j], "-cppcomplex") == 0) 
+                mw_use_cpp_complex = true;
+        }
+
+        if (mw_use_c99_complex || mw_use_cpp_complex) {
+            add_zscalar_type("dcomplex");
+            add_cscalar_type("fcomplex");
+        }
+
+        for (j = 1; j < argc; ++j) {
+            if (strcmp(argv[j], "-m") == 0 ||
+                strcmp(argv[j], "-c") == 0 ||
+                strcmp(argv[j], "-mex") == 0)
+                ++j;
+            else if (strcmp(argv[j], "-mb") == 0 ||
+                     strcmp(argv[j], "-list") == 0 ||
+                     strcmp(argv[j], "-catch") == 0 ||
+		     strcmp(argv[j], "-i8") == 0 ||
+                     strcmp(argv[j], "-c99complex") == 0 ||
+                     strcmp(argv[j], "-cppcomplex") == 0);
+            else {
+                linenum = 1;
+                type_errs = 0;
+                yyin = fopen(argv[j], "r");
+                if (yyin) {
+                    current_ifname = argv[j];
+		    if (outcfp)
+                        print_mex_init(outcfp);
+                    err_flag += yyparse();
+                    fclose(yyin);
+                } else {
+                    fprintf(stderr, "Could not read %s\n", argv[j]);
+                }
+                if (type_errs)
+                    fprintf(stderr, "%s: %d type errors detected\n", 
+                            argv[j], type_errs);
+                err_flag += type_errs;
+            }
+        }
+    }
+    if (!err_flag && outcfp)
+        print_mex_file(outcfp, funcs);
+    destroy(funcs);
+    destroy_inherits();
+    if (outfp)
+        fclose(outfp);
+    if (outcfp)
+        fclose(outcfp);
+    return err_flag;
+}
