[meson] Add ragel subproject

If ragel 6.10 is not found, build it from source.

Seems to work, except that ragel uses exceptions and we configure
HarfBuzz build to not use exceptions, and I can’t find away to enable
exceptions only for the ragel subproject. I had to remove cpp_eh=none
from default options and try to disable exceptions in MSVC manually
(other compilers are already handled).
diff --git a/Makefile.am b/Makefile.am
index 95ef32f..3055e5a 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -23,6 +23,8 @@
 	subprojects/freetype2.wrap \
 	subprojects/glib.wrap \
 	subprojects/google-benchmark.wrap \
+	subprojects/ragel.wrap \
+	subprojects/packagefiles/ragel/meson.build \
 	subprojects/ttf-parser.wrap \
 	perf/meson.build \
 	perf/perf-draw.hh \
diff --git a/meson.build b/meson.build
index 5b4849a..6b3d558 100644
--- a/meson.build
+++ b/meson.build
@@ -2,7 +2,6 @@
   meson_version: '>= 0.52.0',
   version: '2.9.1',
   default_options: [
-    'cpp_eh=none',          # Just to support msvc, we are passing -fno-rtti also anyway
     'cpp_rtti=false',       # Just to support msvc, we are passing -fno-exceptions also anyway
     'cpp_std=c++11',
     'wrap_mode=nofallback', # Use --wrap-mode=default to revert, https://github.com/harfbuzz/harfbuzz/pull/2548
@@ -37,6 +36,8 @@
   add_project_arguments(msvc_args, language: ['c', 'cpp'])
   # Disable SAFESEH with MSVC for libs that use external deps that are built with MinGW
   # noseh_link_args = ['/SAFESEH:NO']
+  # disable exception handling
+  add_project_arguments(['/EHs-', '/EHc-'], language: 'cpp')
 endif
 
 add_project_link_arguments(cpp.get_supported_link_arguments([
diff --git a/src/gen-ragel-artifacts.py b/src/gen-ragel-artifacts.py
index d22e03a..8bbb375 100755
--- a/src/gen-ragel-artifacts.py
+++ b/src/gen-ragel-artifacts.py
@@ -4,16 +4,16 @@
 
 import os, os.path, sys, subprocess, shutil
 
-ragel = os.getenv ('RAGEL', shutil.which ('ragel'))
+ragel = sys.argv[1]
 if not ragel:
 	sys.exit ('You have to install ragel if you are going to develop HarfBuzz itself')
 
 if len (sys.argv) < 4:
 	sys.exit (__doc__)
 
-OUTPUT = sys.argv[1]
-CURRENT_SOURCE_DIR = sys.argv[2]
-INPUT = sys.argv[3]
+OUTPUT = sys.argv[2]
+CURRENT_SOURCE_DIR = sys.argv[3]
+INPUT = sys.argv[4]
 
 outdir = os.path.dirname (OUTPUT)
 shutil.copy (INPUT, outdir)
diff --git a/src/meson.build b/src/meson.build
index 07c477c..444e614 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -291,6 +291,9 @@
 )
 
 ragel = find_program('ragel', version: '6.10', required: false)
+if not ragel.found() and meson.can_run_host_binaries() and cpp.get_id() != 'msvc'
+  ragel = subproject('ragel').get_variable('ragel')
+endif
 if not ragel.found()
   warning('You have to install ragel if you are going to develop HarfBuzz itself')
 else
@@ -301,7 +304,7 @@
       build_by_default: true,
       input: rl,
       output: hh,
-      command: [ragel_helper, '@OUTPUT@', meson.current_source_dir(), '@INPUT@'],
+      command: [ragel_helper, ragel, '@OUTPUT@', meson.current_source_dir(), '@INPUT@'],
     )
   endforeach
 endif
diff --git a/subprojects/.gitignore b/subprojects/.gitignore
index 74c2003..ea3bb20 100644
--- a/subprojects/.gitignore
+++ b/subprojects/.gitignore
@@ -3,3 +3,4 @@
 /packagecache
 /benchmark-1.4.1
 /cairo
+/ragel-6.10
diff --git a/subprojects/packagefiles/ragel/meson.build b/subprojects/packagefiles/ragel/meson.build
new file mode 100644
index 0000000..cd317c2
--- /dev/null
+++ b/subprojects/packagefiles/ragel/meson.build
@@ -0,0 +1,58 @@
+project('ragel', 'c', 'cpp',
+  version : '6.10'
+)
+
+conf = configuration_data()
+conf.set_quoted('PACKAGE', meson.project_name())
+conf.set_quoted('VERSION', meson.project_version())
+configure_file(
+  output : 'config.h',
+  configuration : conf
+)
+
+ragel_sources = files(
+  'ragel/buffer.h', 'ragel/cdcodegen.cpp', 'ragel/cdcodegen.h',
+  'ragel/cdfflat.cpp', 'ragel/cdfflat.h', 'ragel/cdfgoto.cpp',
+  'ragel/cdfgoto.h', 'ragel/cdflat.cpp', 'ragel/cdflat.h',
+  'ragel/cdftable.cpp', 'ragel/cdftable.h', 'ragel/cdgoto.cpp',
+  'ragel/cdgoto.h', 'ragel/cdipgoto.cpp', 'ragel/cdipgoto.h',
+  'ragel/cdsplit.cpp', 'ragel/cdsplit.h', 'ragel/cdtable.cpp',
+  'ragel/cdtable.h', 'ragel/common.cpp', 'ragel/common.h',
+  'ragel/cscodegen.cpp', 'ragel/cscodegen.h', 'ragel/csfflat.cpp',
+  'ragel/csfflat.h', 'ragel/csfgoto.cpp', 'ragel/csfgoto.h',
+  'ragel/csflat.cpp', 'ragel/csflat.h', 'ragel/csftable.cpp',
+  'ragel/csftable.h', 'ragel/csgoto.cpp', 'ragel/csgoto.h',
+  'ragel/csipgoto.cpp', 'ragel/csipgoto.h', 'ragel/cssplit.cpp',
+  'ragel/cssplit.h', 'ragel/cstable.cpp', 'ragel/cstable.h',
+  'ragel/dotcodegen.cpp', 'ragel/dotcodegen.h', 'ragel/fsmap.cpp',
+  'ragel/fsmattach.cpp', 'ragel/fsmbase.cpp', 'ragel/fsmgraph.cpp',
+  'ragel/fsmgraph.h', 'ragel/fsmmin.cpp', 'ragel/fsmstate.cpp',
+  'ragel/gendata.cpp', 'ragel/gendata.h', 'ragel/gocodegen.cpp',
+  'ragel/gocodegen.h', 'ragel/gofflat.cpp', 'ragel/gofflat.h',
+  'ragel/gofgoto.cpp', 'ragel/gofgoto.h', 'ragel/goflat.cpp', 'ragel/goflat.h',
+  'ragel/goftable.cpp', 'ragel/goftable.h', 'ragel/gogoto.cpp',
+  'ragel/gogoto.h', 'ragel/goipgoto.cpp', 'ragel/goipgoto.h',
+  'ragel/gotable.cpp', 'ragel/gotable.h', 'ragel/gotablish.cpp',
+  'ragel/gotablish.h', 'ragel/inputdata.cpp', 'ragel/inputdata.h',
+  'ragel/javacodegen.cpp', 'ragel/javacodegen.h', 'ragel/main.cpp',
+  'ragel/mlcodegen.cpp', 'ragel/mlcodegen.h', 'ragel/mlfflat.cpp',
+  'ragel/mlfflat.h', 'ragel/mlfgoto.cpp', 'ragel/mlfgoto.h',
+  'ragel/mlflat.cpp', 'ragel/mlflat.h', 'ragel/mlftable.cpp',
+  'ragel/mlftable.h', 'ragel/mlgoto.cpp', 'ragel/mlgoto.h',
+  'ragel/mltable.cpp', 'ragel/mltable.h', 'ragel/parsedata.cpp',
+  'ragel/parsedata.h', 'ragel/parsetree.cpp', 'ragel/parsetree.h',
+  'ragel/pcheck.h', 'ragel/ragel.h', 'ragel/rbxgoto.cpp', 'ragel/rbxgoto.h',
+  'ragel/redfsm.cpp', 'ragel/redfsm.h', 'ragel/rlparse.cpp', 'ragel/rlparse.h',
+  'ragel/rlscan.cpp', 'ragel/rlscan.h', 'ragel/rubycodegen.cpp',
+  'ragel/rubycodegen.h', 'ragel/rubyfflat.cpp', 'ragel/rubyfflat.h',
+  'ragel/rubyflat.cpp', 'ragel/rubyflat.h', 'ragel/rubyftable.cpp',
+  'ragel/rubyftable.h', 'ragel/rubytable.cpp', 'ragel/rubytable.h',
+  'ragel/version.h', 'ragel/xmlcodegen.cpp', 'ragel/xmlcodegen.h',
+)
+
+ragel = executable(
+  meson.project_name(),
+  ragel_sources,
+  include_directories : ['aapl', 'ragel'],
+  install : true,
+)
diff --git a/subprojects/ragel.wrap b/subprojects/ragel.wrap
new file mode 100644
index 0000000..1dabcbc
--- /dev/null
+++ b/subprojects/ragel.wrap
@@ -0,0 +1,11 @@
+[wrap-file]
+directory = ragel-6.10
+source_url = https://www.colm.net/files/ragel/ragel-6.10.tar.gz
+source_filename = ragel-6.10.tar.gz
+source_hash = 5f156edb65d20b856d638dd9ee2dfb43285914d9aa2b6ec779dac0270cd56c3f
+patch_directory = ragel
+
+[provide]
+ragel = ragel
+
+