summaryrefslogtreecommitdiff
path: root/elpa/irony-20220110.849
diff options
context:
space:
mode:
Diffstat (limited to 'elpa/irony-20220110.849')
-rw-r--r--elpa/irony-20220110.849/.dir-locals.el10
-rw-r--r--elpa/irony-20220110.849/irony-autoloads.el169
-rw-r--r--elpa/irony-20220110.849/irony-cdb-clang-complete.el79
-rw-r--r--elpa/irony-20220110.849/irony-cdb-clang-complete.elcbin0 -> 1655 bytes
-rw-r--r--elpa/irony-20220110.849/irony-cdb-json.el336
-rw-r--r--elpa/irony-20220110.849/irony-cdb-json.elcbin0 -> 10353 bytes
-rw-r--r--elpa/irony-20220110.849/irony-cdb-libclang.el73
-rw-r--r--elpa/irony-20220110.849/irony-cdb-libclang.elcbin0 -> 1744 bytes
-rw-r--r--elpa/irony-20220110.849/irony-cdb.el218
-rw-r--r--elpa/irony-20220110.849/irony-cdb.elcbin0 -> 6228 bytes
-rw-r--r--elpa/irony-20220110.849/irony-completion.el426
-rw-r--r--elpa/irony-20220110.849/irony-completion.elcbin0 -> 10814 bytes
-rw-r--r--elpa/irony-20220110.849/irony-diagnostics.el90
-rw-r--r--elpa/irony-20220110.849/irony-diagnostics.elcbin0 -> 2215 bytes
-rw-r--r--elpa/irony-20220110.849/irony-iotask.el441
-rw-r--r--elpa/irony-20220110.849/irony-iotask.elcbin0 -> 33819 bytes
-rw-r--r--elpa/irony-20220110.849/irony-pkg.el13
-rw-r--r--elpa/irony-20220110.849/irony-snippet.el135
-rw-r--r--elpa/irony-20220110.849/irony-snippet.elcbin0 -> 2997 bytes
-rw-r--r--elpa/irony-20220110.849/irony.el917
-rw-r--r--elpa/irony-20220110.849/irony.elcbin0 -> 31843 bytes
-rw-r--r--elpa/irony-20220110.849/server/.clang-format8
-rw-r--r--elpa/irony-20220110.849/server/.clang-tidy24
-rw-r--r--elpa/irony-20220110.849/server/CMakeLists.txt33
-rw-r--r--elpa/irony-20220110.849/server/build-aux/run-clang-tidy/LICENSE.TXT43
-rw-r--r--elpa/irony-20220110.849/server/build-aux/run-clang-tidy/README12
-rwxr-xr-xelpa/irony-20220110.849/server/build-aux/run-clang-tidy/run-clang-tidy.py236
-rw-r--r--elpa/irony-20220110.849/server/cmake/CheckClangResourceDir.cmake90
-rw-r--r--elpa/irony-20220110.849/server/cmake/LibClangDiagnosticsChecker.cpp47
-rw-r--r--elpa/irony-20220110.849/server/cmake/modules/FindLibClang.cmake106
-rw-r--r--elpa/irony-20220110.849/server/src/CMakeLists.txt111
-rw-r--r--elpa/irony-20220110.849/server/src/Command.cpp278
-rw-r--r--elpa/irony-20220110.849/server/src/Command.h73
-rw-r--r--elpa/irony-20220110.849/server/src/Commands.def39
-rw-r--r--elpa/irony-20220110.849/server/src/CompDBCache.cpp71
-rw-r--r--elpa/irony-20220110.849/server/src/CompDBCache.h86
-rw-r--r--elpa/irony-20220110.849/server/src/Irony.cpp638
-rw-r--r--elpa/irony-20220110.849/server/src/Irony.h147
-rw-r--r--elpa/irony-20220110.849/server/src/Style.h17
-rw-r--r--elpa/irony-20220110.849/server/src/TUManager.cpp182
-rw-r--r--elpa/irony-20220110.849/server/src/TUManager.h109
-rw-r--r--elpa/irony-20220110.849/server/src/main.cpp235
-rw-r--r--elpa/irony-20220110.849/server/src/support/CIndex.h33
-rw-r--r--elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp119
-rw-r--r--elpa/irony-20220110.849/server/src/support/CommandLineParser.h21
-rw-r--r--elpa/irony-20220110.849/server/src/support/NonCopyable.h34
-rw-r--r--elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp74
-rw-r--r--elpa/irony-20220110.849/server/src/support/TemporaryFile.h36
-rw-r--r--elpa/irony-20220110.849/server/src/support/iomanip_quoted.h52
-rw-r--r--elpa/irony-20220110.849/server/test/CMakeLists.txt3
-rw-r--r--elpa/irony-20220110.849/server/test/elisp/CMakeLists.txt47
-rw-r--r--elpa/irony-20220110.849/server/test/elisp/irony-cdb-json.el87
-rw-r--r--elpa/irony-20220110.849/server/test/elisp/irony-iotask.el249
-rw-r--r--elpa/irony-20220110.849/server/test/elisp/irony.el121
-rw-r--r--elpa/irony-20220110.849/server/test/elisp/test-config.el14
55 files changed, 6382 insertions, 0 deletions
diff --git a/elpa/irony-20220110.849/.dir-locals.el b/elpa/irony-20220110.849/.dir-locals.el
new file mode 100644
index 0000000..5e9bd93
--- /dev/null
+++ b/elpa/irony-20220110.849/.dir-locals.el
@@ -0,0 +1,10 @@
+((nil
+ (indent-tabs-mode . nil))
+ (c++-mode
+ (c-basic-offset . 2)
+ (c-file-style . "gnu")
+ (eval . (c-set-offset 'innamespace 0))))
+
+;; Local Variables:
+;; no-byte-compile: t
+;; End
diff --git a/elpa/irony-20220110.849/irony-autoloads.el b/elpa/irony-20220110.849/irony-autoloads.el
new file mode 100644
index 0000000..8e7cf2b
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-autoloads.el
@@ -0,0 +1,169 @@
+;;; irony-autoloads.el --- automatically extracted autoloads
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+
+;;;### (autoloads nil "irony" "irony.el" (0 0 0 0))
+;;; Generated autoloads from irony.el
+
+(defvar irony-additional-clang-options nil "\
+Additional command line options to pass down to libclang.
+
+Please, do NOT use this variable to add header search paths, only
+additional warnings or compiler options.
+
+These compiler options will be prepended to the command line, in
+order to not override the value coming from a compilation
+database.")
+
+(custom-autoload 'irony-additional-clang-options "irony" t)
+
+(autoload 'irony-mode "irony" "\
+Minor mode for C, C++ and Objective-C, powered by libclang.
+
+If called interactively, enable Irony mode if ARG is positive,
+and disable it if ARG is zero or negative. If called from Lisp,
+also enable the mode if ARG is omitted or nil, and toggle it if
+ARG is `toggle'; disable the mode otherwise.
+
+\(fn &optional ARG)" t nil)
+
+(autoload 'irony-version "irony" "\
+Return the version number of the file irony.el.
+
+If called interactively display the version in the echo area.
+
+\(fn &optional SHOW-VERSION)" t nil)
+
+(autoload 'irony-server-kill "irony" "\
+Kill the running irony-server process, if any." t nil)
+
+(autoload 'irony-get-type "irony" "\
+Get the type of symbol under cursor." t nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "irony" '("irony-")))
+
+;;;***
+
+;;;### (autoloads nil "irony-cdb" "irony-cdb.el" (0 0 0 0))
+;;; Generated autoloads from irony-cdb.el
+
+(autoload 'irony-cdb-autosetup-compile-options "irony-cdb" nil t nil)
+
+(autoload 'irony-cdb-menu "irony-cdb" nil t nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "irony-cdb" '("irony-cdb-")))
+
+;;;***
+
+;;;### (autoloads nil "irony-cdb-clang-complete" "irony-cdb-clang-complete.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from irony-cdb-clang-complete.el
+
+(autoload 'irony-cdb-clang-complete "irony-cdb-clang-complete" "\
+
+
+\(fn COMMAND &rest ARGS)" nil nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "irony-cdb-clang-complete" '("irony-cdb-clang-complete--")))
+
+;;;***
+
+;;;### (autoloads nil "irony-cdb-json" "irony-cdb-json.el" (0 0 0
+;;;;;; 0))
+;;; Generated autoloads from irony-cdb-json.el
+
+(autoload 'irony-cdb-json "irony-cdb-json" "\
+
+
+\(fn COMMAND &rest ARGS)" nil nil)
+
+(autoload 'irony-cdb-json-add-compile-commands-path "irony-cdb-json" "\
+Add an out-of-source compilation database.
+
+Files below the PROJECT-ROOT directory will use the JSON
+Compilation Database as specified by COMPILE-COMMANDS-PATH.
+
+The JSON Compilation Database are often generated in the build
+directory. This functions helps mapping out-of-source build
+directories to project directory.
+
+\(fn PROJECT-ROOT COMPILE-COMMANDS-PATH)" t nil)
+
+(autoload 'irony-cdb-json-select "irony-cdb-json" "\
+Select CDB to use with a prompt.
+
+It is useful when you have several CDBs with the same project
+root.
+
+The completion function used internally is `completing-read' so
+it could easily be used with other completion functions by
+temporarily using a let-bind on `completing-read-function'. Or
+even helm by enabling `helm-mode' before calling the function." t nil)
+
+(autoload 'irony-cdb-json-select-most-recent "irony-cdb-json" "\
+Select CDB that is most recently modified." t nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "irony-cdb-json" '("irony-cdb-json--")))
+
+;;;***
+
+;;;### (autoloads nil "irony-cdb-libclang" "irony-cdb-libclang.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from irony-cdb-libclang.el
+
+(autoload 'irony-cdb-libclang "irony-cdb-libclang" "\
+
+
+\(fn COMMAND &rest ARGS)" nil nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "irony-cdb-libclang" '("irony-cdb-libclang--")))
+
+;;;***
+
+;;;### (autoloads nil "irony-completion" "irony-completion.el" (0
+;;;;;; 0 0 0))
+;;; Generated autoloads from irony-completion.el
+
+(autoload 'irony-completion-at-point "irony-completion" nil nil nil)
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "irony-completion" '("irony-")))
+
+;;;***
+
+;;;### (autoloads nil "irony-diagnostics" "irony-diagnostics.el"
+;;;;;; (0 0 0 0))
+;;; Generated autoloads from irony-diagnostics.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "irony-diagnostics" '("irony-diagnostics-")))
+
+;;;***
+
+;;;### (autoloads nil "irony-iotask" "irony-iotask.el" (0 0 0 0))
+;;; Generated autoloads from irony-iotask.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "irony-iotask" '("irony-iotask-")))
+
+;;;***
+
+;;;### (autoloads nil "irony-snippet" "irony-snippet.el" (0 0 0 0))
+;;; Generated autoloads from irony-snippet.el
+
+(if (fboundp 'register-definition-prefixes) (register-definition-prefixes "irony-snippet" '("irony-snippet-")))
+
+;;;***
+
+;;;### (autoloads nil nil ("irony-pkg.el") (0 0 0 0))
+
+;;;***
+
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; irony-autoloads.el ends here
diff --git a/elpa/irony-20220110.849/irony-cdb-clang-complete.el b/elpa/irony-20220110.849/irony-cdb-clang-complete.el
new file mode 100644
index 0000000..a9143a8
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-cdb-clang-complete.el
@@ -0,0 +1,79 @@
+;;; irony-cdb-clang-complete.el --- .clang_complete compilation database
+
+;; Copyright (C) 2014 Guillaume Papin
+
+;; Author: Guillaume Papin <guillaume.papin@epitech.eu>
+;; Keywords: c, convenience, tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This file defines a compilation database for .clang_complete and
+;; compile_flags.txt, both of which have the same format.
+;;
+
+;;; Code:
+
+(require 'irony-cdb)
+
+(require 'cl-lib)
+
+;;;###autoload
+(defun irony-cdb-clang-complete (command &rest args)
+ (cl-case command
+ (get-compile-options (irony-cdb-clang-complete--get-compile-options))))
+
+(defun irony-cdb-clang-complete--get-compile-options ()
+ (irony--awhen (irony-cdb-clang-complete--locate-db)
+ (irony-cdb-clang-complete--load-db it)))
+
+(defun irony-cdb-clang-complete--locate-db ()
+ (when buffer-file-name
+ (catch 'fname
+ (locate-dominating-file
+ buffer-file-name
+ ;; locate-dominating-file will invoke the lambda on suitable
+ ;; directories, and if we have either of our files there, we
+ ;; return its filename, by throwing it.
+ (lambda (d)
+ (let ((cfname (concat (file-name-as-directory d) "compile_flags.txt"))
+ (ccname (concat (file-name-as-directory d) ".clang_complete")))
+ (if (file-exists-p cfname)
+ (throw 'fname cfname)
+ (if (file-exists-p ccname)
+ (throw 'fname ccname)
+ nil))))))))
+
+(defun irony-cdb-clang-complete--load-db (cc-file)
+ (with-temp-buffer
+ (insert-file-contents cc-file)
+ (list
+ (cons
+ ;; compile options with trailing whitespaces removed
+ (mapcar #'(lambda (line)
+ (if (string-match "[ \t]+$" line)
+ (replace-match "" t t line)
+ line))
+ (split-string (buffer-string) "\n" t))
+ ;; working directory
+ (expand-file-name (file-name-directory cc-file))))))
+
+(provide 'irony-cdb-clang-complete)
+
+;; Local Variables:
+;; byte-compile-warnings: (not cl-functions)
+;; End:
+
+;;; irony-cdb-clang-complete ends here
diff --git a/elpa/irony-20220110.849/irony-cdb-clang-complete.elc b/elpa/irony-20220110.849/irony-cdb-clang-complete.elc
new file mode 100644
index 0000000..841def6
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-cdb-clang-complete.elc
Binary files differ
diff --git a/elpa/irony-20220110.849/irony-cdb-json.el b/elpa/irony-20220110.849/irony-cdb-json.el
new file mode 100644
index 0000000..f24e144
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-cdb-json.el
@@ -0,0 +1,336 @@
+;;; irony-cdb-json.el --- JSON Compilation Database support for irony
+
+;; Copyright (C) 2014 Guillaume Papin
+
+;; Author: Guillaume Papin <guillaume.papin@epitech.eu>
+;; Keywords: c, convenience, tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; JSON Compilation Database support for Irony, see
+;; http://clang.llvm.org/docs/JSONCompilationDatabase.html.
+;;
+
+;;; Code:
+
+(require 'irony-cdb)
+
+(require 'cl-lib)
+
+(require 'json)
+(require 'pp)
+
+(defvar irony-cdb-json--project-alist nil
+ "Alist of source directory and compile_commands.json locations.
+
+Note, the compile_commands.json location may be relative to the
+source directory.")
+
+(defconst irony-cdb-json--project-alist-file
+ (concat irony-user-dir "cdb-json-projects"))
+
+;;;###autoload
+(defun irony-cdb-json (command &rest args)
+ (cl-case command
+ (get-compile-options (irony-cdb-json--get-compile-options))))
+
+;;;###autoload
+(defun irony-cdb-json-add-compile-commands-path (project-root
+ compile-commands-path)
+ "Add an out-of-source compilation database.
+
+Files below the PROJECT-ROOT directory will use the JSON
+Compilation Database as specified by COMPILE-COMMANDS-PATH.
+
+The JSON Compilation Database are often generated in the build
+directory. This functions helps mapping out-of-source build
+directories to project directory."
+ (interactive
+ (progn
+ (let ((proot (read-directory-name "Project root:" nil nil t)))
+ (list proot (read-file-name "Compile commands:" proot nil t
+ "compile_commands.json")))))
+ (add-to-list 'irony-cdb-json--project-alist
+ (cons (expand-file-name project-root)
+ (expand-file-name compile-commands-path)))
+ (irony-cdb-json--save-project-alist)
+
+ ; and tell irony to load it now
+ (irony-cdb-autosetup-compile-options))
+
+(defun irony-cdb-json--put-first (pos target-list)
+ (if (>= pos (length target-list))
+ target-list
+ (let ((elm (nth pos target-list)))
+ (append (list elm) (delete elm target-list)))))
+
+(defun irony-cdb-json--choose-cdb ()
+ "Prompt to select CDB from current project root."
+ (let* ((proot (irony-cdb-json--find-best-prefix-path
+ (irony-cdb-json--target-path)
+ (mapcar 'car irony-cdb-json--project-alist)))
+ (cdbs (mapcar 'cdr
+ (cl-remove-if-not (lambda (x) (string-equal proot (car x)))
+ irony-cdb-json--project-alist))))
+ (completing-read "Choose Irony CDB: " cdbs nil 'require-match nil)))
+
+;;;###autoload
+(defun irony-cdb-json-select ()
+ "Select CDB to use with a prompt.
+
+It is useful when you have several CDBs with the same project
+root.
+
+The completion function used internally is `completing-read' so
+it could easily be used with other completion functions by
+temporarily using a let-bind on `completing-read-function'. Or
+even helm by enabling `helm-mode' before calling the function."
+ (interactive)
+ (let ((pos (cl-position (irony-cdb-json--choose-cdb)
+ irony-cdb-json--project-alist
+ :test (lambda (x y) (string-equal x (cdr y))))))
+ (setq irony-cdb-json--project-alist
+ (irony-cdb-json--put-first pos irony-cdb-json--project-alist))
+ (irony-cdb-json--save-project-alist)
+ (irony-cdb-autosetup-compile-options)))
+
+(defun irony-cdb-json--last-mod (file)
+ "File modification time or null time if file doesn't exist."
+ (or (nth 5 (file-attributes file))
+ '(0 0 0 0)))
+
+;;;###autoload
+(defun irony-cdb-json-select-most-recent ()
+ "Select CDB that is most recently modified."
+ (interactive)
+ (setq irony-cdb-json--project-alist
+ (sort irony-cdb-json--project-alist
+ (lambda (x y)
+ (time-less-p (irony-cdb-json--last-mod (cdr y))
+ (irony-cdb-json--last-mod (cdr x))))))
+ (irony-cdb-json--save-project-alist)
+ (irony-cdb-autosetup-compile-options))
+
+(defun irony-cdb-json--get-compile-options ()
+ (irony--awhen (irony-cdb-json--locate-db)
+ (let ((db (irony-cdb-json--load-db it)))
+ (irony--aif (irony-cdb-json--exact-flags db)
+ it
+ (let ((dir-cdb (irony-cdb-json--compute-directory-cdb db)))
+ (irony-cdb-json--guess-flags dir-cdb))))))
+
+(defsubst irony-cdb-json--target-path ()
+ (or buffer-file-name (expand-file-name default-directory)))
+
+(defun irony-cdb-json--ensure-project-alist-loaded ()
+ (unless irony-cdb-json--project-alist
+ (irony-cdb-json--load-project-alist)))
+
+(defun irony-cdb-json--save-project-alist ()
+ (with-temp-file irony-cdb-json--project-alist-file
+ (insert ";; -*- emacs-lisp -*-\n\
+;;\n\
+;; JSON Compilation Database project list.\n\
+;;\n\
+;; File auto-generated by irony-cdb-json.\n\
+;;\n")
+ (pp irony-cdb-json--project-alist (current-buffer))
+ (insert "\n")))
+
+(defun irony-cdb-json--load-project-alist ()
+ (when (file-exists-p irony-cdb-json--project-alist-file)
+ (setq irony-cdb-json--project-alist
+ (with-temp-buffer
+ (insert-file-contents irony-cdb-json--project-alist-file)
+ (read (current-buffer))))))
+
+(defun irony-cdb-json--find-best-prefix-path (file prefixes)
+ (cl-loop for prefix in prefixes
+ with found = nil
+ ;; keep the closest directory
+ if (and (string-prefix-p prefix file)
+ (> (length prefix) (length found)))
+ do (setq found prefix)
+ finally return found))
+
+(defun irony-cdb-json--locate-db ()
+ (irony-cdb-json--ensure-project-alist-loaded)
+ (irony--aif (irony-cdb-json--find-best-prefix-path
+ (irony-cdb-json--target-path)
+ (mapcar 'car irony-cdb-json--project-alist))
+ (expand-file-name
+ (cdr (assoc it irony-cdb-json--project-alist))
+ it)
+ ;; If not in the project table, look in the dominating directories
+ (irony--awhen (irony-cdb--locate-dominating-file-with-dirs
+ (irony-cdb-json--target-path)
+ "compile_commands.json"
+ irony-cdb-search-directory-list)
+ (expand-file-name it))))
+
+(defvar irony-cdb-json--cache-key nil
+ "The name of the last loaded JSON file and its modification time.")
+(defvar irony-cdb-json--cache-cdb nil
+ "The last loaded compilation database.")
+
+(defun irony-cdb-json--make-cache-key (file)
+ (irony--aif (file-attributes file)
+ (cons file (nth 5 it))))
+
+(defun irony-cdb-json--load-db (json-file)
+ (let ((cache-key (irony-cdb-json--make-cache-key json-file)))
+ (unless (and cache-key (equal irony-cdb-json--cache-key cache-key))
+ (setq irony-cdb-json--cache-cdb
+ (delq nil (mapcar #'irony-cdb-json--transform-compile-command
+ ;; JSON read may throw
+ (json-read-file json-file))))
+ (setq irony-cdb-json--cache-key cache-key)))
+ irony-cdb-json--cache-cdb)
+
+(defun irony-cdb-json--exact-flags (file-cdb)
+ (when buffer-file-name
+ (mapcar #'(lambda (e)
+ (cons (nth 1 e) (nth 2 e)))
+ (irony--assoc-all buffer-file-name file-cdb))))
+
+(defun irony-cdb-json--guess-flags (dir-cdb)
+ (cl-loop for e in dir-cdb
+ with buf-path = (irony-cdb-json--target-path)
+ with found = nil
+ for dir = (car e)
+ ;; keep the closest directory
+ if (and (string-prefix-p dir buf-path)
+ (> (length dir) (length (car found))))
+ do (setq found e)
+ finally return (list (cons (nth 1 found) (nth 2 found)))))
+
+(defsubst irony-cdb-json--compile-command-directory (compile-command)
+ (cdr (assq 'directory compile-command)))
+
+(defsubst irony-cdb-json--compile-command-file (compile-command)
+ (cdr (assq 'file compile-command)))
+
+(defun irony-cdb-json--compile-command-options (compile-command)
+ "Return the compile options of COMPILE-COMMAND as a list."
+ (let ((command (assq 'command compile-command))
+ (arguments (assq 'arguments compile-command)))
+ (irony-cdb--remove-compiler-from-flags
+ (cond (command (irony--split-command-line (cdr command)))
+ (arguments (append (cdr arguments) nil))))))
+
+(defun irony-cdb-json--adjust-compile-options (compile-options file default-dir)
+ "Adjust COMPILE-OPTIONS to only use options useful for parsing.
+
+COMPILE-OPTIONS is modified by side effects but the returned list
+should be used since elements can change at the head.
+
+Removes the input file, the output file, ...
+
+Relative paths are relative to DEFAULT-DIR."
+ ;; compute the truename of the absolute path for FILE only once
+ (setq file (file-truename (expand-file-name file default-dir)))
+ (let* ((head (cons 'nah compile-options))
+ (it head)
+ opt)
+ (while (setq opt (cadr it))
+ (cond
+ ;; end of options, skip all positional arguments (source files)
+ ((string= opt "--")
+ (setcdr it nil))
+ ;; strip -c
+ ((string= "-c" opt)
+ (setcdr it (nthcdr 2 it)))
+ ;; strip -o <output-file> and -o<output-file>
+ ((string-prefix-p "-o" opt)
+ (if (string= opt "-o")
+ (setcdr it (nthcdr 3 it))
+ (setcdr it (nthcdr 2 it))))
+ ;; skip input file; avoid invoking file commands if an option argument
+ ((and (not (string-prefix-p "-" opt)) (string= file (file-truename (expand-file-name opt default-dir))))
+ (setcdr it (nthcdr 2 it)))
+ (t
+ ;; if head of cdr hasn't been skipped, iterate, otherwise check if the
+ ;; new cdr need skipping
+ (setq it (cdr it)))))
+ (cdr head)))
+
+(defun irony-cdb-json--transform-compile-command (compile-command)
+ "Transform a compile command in the JSON compilation database
+into a friendlier format.
+
+The returned value is a list composed of the following elements:
+0. The absolute path to the file.
+1. The compile options.
+2. The invocation directory. Relative paths in the compile
+ options elements are relative to this directory.
+
+Return nil if the compile command is invalid or the compile
+options are empty."
+ (let* ((directory (irony-cdb-json--compile-command-directory compile-command))
+ (path (expand-file-name
+ (irony-cdb-json--compile-command-file compile-command) directory))
+ (options (irony-cdb-json--compile-command-options compile-command)))
+ (when (and path directory options)
+ (list path
+ (irony-cdb-json--adjust-compile-options options path directory)
+ directory))))
+
+(defun irony-cdb-json--compute-directory-cdb (file-cdb)
+ ;; collect flags by directory, e.g: for headers in source directories or
+ ;; new files that are not yet present in the compilation database
+ (let ((dir-cdb (irony-cdb-json--collect-compile-options-by-dir file-cdb)))
+ (nconc dir-cdb
+ ;; collect flags for header search paths too
+ (irony-cdb-json--collect-compile-options-for-include-dirs dir-cdb))))
+
+(defun irony-cdb-json--collect-compile-options-by-dir (file-cdb)
+ "Collect the compile options per directory from a file compilation database.
+
+The returned value similar to
+`irony-cdb-json--transform-compile-command' except for the first
+argument which represents a whole directory (ending with slash on
+Unix, `file-name-as-directory') instead of a single file."
+ (let ((dir-cdb (delete-dups
+ (mapcar #'(lambda (e)
+ (cons (file-name-directory (car e)) (cdr e)))
+ file-cdb))))
+ ;; TODO: remove directories when a parent directory has the same flags, for
+ ;; example, writing the following in CMake:
+ ;; add_executable(exe foo.cpp sub/bar.cpp)
+ ;; will result in duplicated compile options for the subdirectory 'sub/'.
+ dir-cdb))
+
+(defun irony-cdb-json--collect-compile-options-for-include-dirs (dir-cdb)
+ "Guess the compile options to use for directories in the search path.
+
+The returned value is in the same format as the input value, see
+`irony-cdb-json--collect-compile-options-for-include-dirs'."
+ (let ((include-dirs (delete-dups (mapcar 'car dir-cdb)))
+ out)
+ (dolist (e dir-cdb)
+ (dolist (dir (irony--extract-user-search-paths (nth 1 e) (nth 2 e)))
+ (unless (member dir include-dirs)
+ (setq include-dirs (cons dir include-dirs)
+ out (cons (cons dir (cdr e)) out)))))
+ out))
+
+(provide 'irony-cdb-json)
+
+;; Local Variables:
+;; byte-compile-warnings: (not cl-functions)
+;; End:
+
+;;; irony-cdb-json ends here
diff --git a/elpa/irony-20220110.849/irony-cdb-json.elc b/elpa/irony-20220110.849/irony-cdb-json.elc
new file mode 100644
index 0000000..d43d948
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-cdb-json.elc
Binary files differ
diff --git a/elpa/irony-20220110.849/irony-cdb-libclang.el b/elpa/irony-20220110.849/irony-cdb-libclang.el
new file mode 100644
index 0000000..79d5849
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-cdb-libclang.el
@@ -0,0 +1,73 @@
+;;; irony-cdb-libclang.el --- Compilation Database for irony using libclang
+
+;; Copyright (C) 2015 Karl Hylén
+
+;; Author: Karl Hylén <karl.hylen@gmail.com>
+;; Keywords: c, convenience, tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; Compilation Database support for Irony using libclangs CXCompilationDatabase,
+;; http://clang.llvm.org/doxygen/group__COMPILATIONDB.html
+
+;;; Code:
+
+(require 'irony-cdb)
+(require 'irony-cdb-json)
+
+(require 'cl-lib)
+
+;;;###autoload
+(defun irony-cdb-libclang (command &rest args)
+ (cl-case command
+ (get-compile-options (irony-cdb-libclang--get-compile-options))))
+
+(defun irony-cdb-libclang--get-compile-options ()
+ (irony--awhen (irony-cdb-json--locate-db)
+ (irony-cdb-libclang--server-exact-flags it)))
+
+(defun irony-cdb-libclang--server-exact-flags (db-file)
+ "Get compilation options from irony-server.
+
+The parameter DB-FILE is the database file."
+ (when buffer-file-name
+ (let* ((build-dir (file-name-directory db-file))
+ (file buffer-file-name)
+ (task (irony--get-compile-options-task build-dir file))
+ (compile-options (irony--run-task task)))
+ (irony-cdb-libclang--adjust-options-and-remove-compiler
+ file compile-options))))
+
+(defun irony-cdb-libclang--adjust-options-and-remove-compiler (file cmds)
+ "Remove compiler, target file FILE and output file from CMDS.
+
+The parameter CMDS is a list of conses. In each cons, the car holds the options
+and the cdr holds the working directory where the compile command was issued."
+ (mapcar (lambda (cmd)
+ (let ((opt (irony-cdb--remove-compiler-from-flags (car cmd)))
+ (wdir (cdr cmd)))
+ (cons
+ (irony-cdb-json--adjust-compile-options opt file wdir)
+ wdir)))
+ cmds))
+
+(provide 'irony-cdb-libclang)
+
+;; Local Variables:
+;; byte-compile-warnings: (not cl-functions)
+;; End:
+
+;;; irony-cdb-libclang ends here
diff --git a/elpa/irony-20220110.849/irony-cdb-libclang.elc b/elpa/irony-20220110.849/irony-cdb-libclang.elc
new file mode 100644
index 0000000..da23bf2
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-cdb-libclang.elc
Binary files differ
diff --git a/elpa/irony-20220110.849/irony-cdb.el b/elpa/irony-20220110.849/irony-cdb.el
new file mode 100644
index 0000000..e7d678b
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-cdb.el
@@ -0,0 +1,218 @@
+;;; irony-cdb.el --- compilation databases support for irony
+
+;; Copyright (C) 2012-2014 Guillaume Papin
+
+;; Author: Guillaume Papin <guillaume.papin@epitech.eu>
+;; Keywords: c, convenience, tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This file defines the compilation database interface of irony-mode.
+;;
+;; Note:For compilation database that looks for a specific file, such as
+;; .clang_complete or compile_commands.json, favor `locate-dominating-file' to a
+;; handwritten logic if possible as it may be configured by the user to do "the
+;; Right Thing (TM)". See `locate-dominating-stop-dir-regexp'.
+;;
+
+;;; Code:
+
+(require 'irony)
+
+(require 'cl-lib)
+
+(autoload 'irony-cdb-clang-complete "irony-cdb-clang-complete")
+(autoload 'irony-cdb-json "irony-cdb-json")
+(autoload 'irony-cdb-libclang "irony-cdb-libclang")
+
+
+;;
+;; Customizable variables
+;;
+
+(defgroup irony-cdb nil
+ "Irony's compilation database interface."
+ :group 'irony)
+
+(defcustom irony-cdb-compilation-databases '(irony-cdb-clang-complete
+ irony-cdb-libclang
+ irony-cdb-json)
+ "List of active compilation databases.
+
+The compilation database should respond for the following commands:
+
+`get-compile-options': Takes no argument. This function finds the
+compile options used for the current buffer. It must return a
+list of cons where the first element is a set of compile options
+and the second element the working directory expected for these
+commands. The compilation database should return an empty list
+for files that it cannot handle."
+ :type '(repeat function)
+ :group 'irony-cdb)
+
+(defcustom irony-cdb-search-directory-list '("." "build")
+ "List of relative subdirectory paths to be searched for cdb files
+
+Irony looks for cdb files in any of the supported format by checking
+each directory from the currently loaded file and recursively through
+parent directories until it hits the root directory or a cdb is
+found. At each level of the search irony looks at the subdirectories
+listed in `irony-cdb-search-directory-list' for the files. Customize this
+list if your cdb is held in a custom directory within you project,
+such as a custom named build directory.
+"
+ :type '(repeat string)
+ :group 'irony-cdb)
+
+
+;;
+;; Internal variables
+;;
+
+(defvar-local irony-cdb--compilation-database nil)
+
+
+;;
+;; Irony Compilation Database Interface
+;;
+
+;;;###autoload
+(defun irony-cdb-autosetup-compile-options ()
+ (interactive)
+ (irony--awhen (irony-cdb--autodetect-compile-options)
+ (setq irony-cdb--compilation-database (nth 0 it))
+ (irony-cdb--update-compile-options (nth 1 it) (nth 2 it))))
+
+;;;###autoload
+(defun irony-cdb-menu ()
+ (interactive)
+ (let ((compilation-database irony-cdb--compilation-database)
+ (working-directory irony--working-directory)
+ (compile-options irony--compile-options))
+ (save-excursion
+ (save-window-excursion
+ (delete-other-windows)
+ (let ((buffer (get-buffer-create "*Irony/Compilation DB Menu*")))
+ (with-current-buffer buffer
+ (erase-buffer)
+ (if (null compilation-database)
+ (insert "No compilation database in use.\n")
+ (insert (format "Compilation Database: %s\n\n"
+ (symbol-name compilation-database)))
+ (insert (format " Working Directory: %s\n" working-directory))
+ (insert (format " Compile Options: %s\n"
+ (mapconcat 'identity compile-options " "))))
+ (insert "\n[q] to quit"))
+ (let ((pop-up-windows t))
+ (display-buffer buffer t))
+ (fit-window-to-buffer (get-buffer-window buffer))
+ (irony--read-char-choice "Irony CDB Buffer" (list ?q)))))
+ ;; clear `read-char-choice' prompt
+ (message "")))
+
+
+;;
+;; Functions
+;;
+
+(defun irony-cdb--choose-closest-path (file paths)
+ "Find the \"best\" path in PATHS matching FILE
+
+If any paths in PATHS is belongs to the same directory
+or a subdirectory of file, we disregard other candidates.
+
+For remaining candidates, \"nearest\" is measured as abs. difference
+in path depth.
+- We prefer deeper paths at level +N to those at level -N.
+- If multiple paths are equally good, we return the last one.
+
+Returns nil if paths isn't a list of at least one element.
+"
+ (when (listp paths)
+ (let ((paths (or
+ ;; if we find a cdb in cwd or below, don't consider other candidates
+ (cl-remove-if-not (lambda (x) (string-prefix-p (file-name-directory file) x)) paths)
+ paths)))
+ (cl-loop for path in paths
+ with best-depth-delta = 999999 ; start at +inf
+ with best-path = nil ; we keep the best so far here
+ ;; all candidates have their depth compared to that of target file
+ with file-depth = (length (split-string (expand-file-name file) "/")) ;
+ for candidate-depth = (length (split-string (expand-file-name path) "/"))
+ ;; Our metric. We use signum as a tie-breaker to choose deeper candidates
+ for depth-delta = (+ (abs (- file-depth candidate-depth))
+ (* 0.1 (- file-depth candidate-depth)))
+ do (when (< depth-delta best-depth-delta)
+ (progn
+ (setq best-depth-delta depth-delta)
+ (setq best-path path)))
+ finally return best-path))))
+
+(defun irony-cdb--locate-dominating-file-with-dirs (file
+ name
+ subdirectories)
+ "Convenience wrapper around `locate-dominating-file'
+
+Looks up the directory hierarchy from FILE for to locate any directory
+in `subdirectories` which contains NAME. If multiple files are found,
+chooses the one located at the nearest directory level. if multiple
+files are found at the same level, picks the first one encountered.
+returns the full path to file if found, or nil otherwise."
+ (let ((candidates
+ (cl-loop for subdir in subdirectories
+ for relpath = (concat (file-name-as-directory subdir) name)
+ for match-maybe = (locate-dominating-file file relpath)
+ when match-maybe collect (expand-file-name (concat match-maybe relpath)))))
+ (irony-cdb--choose-closest-path file candidates)))
+
+
+(defun irony-cdb--update-compile-options (compile-options
+ &optional working-directory)
+ (setq irony--compile-options compile-options
+ irony--working-directory working-directory))
+
+(defun irony-cdb--autodetect-compile-options ()
+ (catch 'found
+ (dolist (compilation-database irony-cdb-compilation-databases)
+ (with-demoted-errors "Irony CDB: error in compilation database: %S"
+ (irony--awhen (funcall compilation-database 'get-compile-options)
+ (throw 'found (list compilation-database
+ (caar it)
+ (cdar it))))))))
+
+(defun irony-cdb--string-suffix-p (suffix string &optional ignore-case)
+ "Return non-nil if SUFFIX is a suffix of STRING."
+ (let ((start-pos (- (length string) (length suffix))))
+ (and (>= start-pos 0)
+ (eq t (compare-strings suffix nil nil
+ string start-pos nil ignore-case)))))
+
+(defun irony-cdb--remove-compiler-from-flags (flags)
+ "Remove the compiler from FLAGS read from a compilation database.
+
+When using ccache, the compiler might be present in FLAGS since
+the compiler is `ccache compiler'."
+ (let* ((first (car flags))
+ (flags (cdr flags)))
+ (if (irony-cdb--string-suffix-p "ccache" first) (cdr flags) flags)))
+
+(provide 'irony-cdb)
+
+;; Local Variables:
+;; byte-compile-warnings: (not cl-functions)
+;; End:
+
+;;; irony-cdb.el ends here
diff --git a/elpa/irony-20220110.849/irony-cdb.elc b/elpa/irony-20220110.849/irony-cdb.elc
new file mode 100644
index 0000000..dca07a8
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-cdb.elc
Binary files differ
diff --git a/elpa/irony-20220110.849/irony-completion.el b/elpa/irony-20220110.849/irony-completion.el
new file mode 100644
index 0000000..a994c32
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-completion.el
@@ -0,0 +1,426 @@
+;;; irony-completion.el --- irony-mode completion interface -*- lexical-binding: t -*-
+
+;; Copyright (C) 2012-2014 Guillaume Papin
+
+;; Author: Guillaume Papin <guillaume.papin@epitech.eu>
+;; Keywords: c, convenience, tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Handle the search of completion points, the triggering of the
+;; completion when needed and the "parsing" of completion results.
+
+;;; Code:
+
+(require 'irony)
+(require 'irony-snippet)
+
+(require 'cl-lib)
+
+
+;;
+;; Customizable variables
+;;
+
+(defgroup irony-completion nil
+ "Irony's completion interface."
+ :group 'irony)
+
+(defcustom irony-completion-trigger-commands '(self-insert-command
+ newline-and-indent
+ c-context-line-break
+ c-scope-operator
+ ;; electric commands
+ c-electric-backspace
+ c-electric-brace
+ c-electric-colon
+ c-electric-lt-gt
+ c-electric-paren
+ c-electric-pound
+ c-electric-semi&comma
+ c-electric-slash
+ c-electric-star)
+ "List of commands to watch for asynchronous completion triggering."
+ :type '(repeat function)
+ :group 'irony-completion)
+
+(defcustom irony-duplicate-candidates-filter nil
+ "Remove duplicate candidates.
+
+If non-nil, the completion candidate list will not contain
+duplicate entries. As an example, duplicate candidates are
+displayed when a derived class overrides virtual methods."
+ :type 'boolean
+ :group 'irony-completion)
+
+
+;;
+;; Utility functions
+;;
+
+(defun irony-completion-symbol-bounds ()
+ (let ((pt (point))
+ (syntax (syntax-ppss)))
+ ;; no prefix for strings or comments
+ ;; TODO: Use fontlock faces instead? at least
+ ;; #warning In the middle of a warning|
+ ;; will be handled properly but things like links when
+ ;; `goto-address-prog-mode' is enabled will mess up things:
+ ;; #error see bug report XY: http://example.com/XY
+ (unless (or (nth 3 syntax) ;skip strings
+ (nth 4 syntax)) ;skip comments
+ (save-excursion
+ (skip-chars-backward "_a-zA-Z0-9")
+ (let ((ch (char-after)))
+ (unless (and ch (>= ch ?0) (<= ch ?9)) ;skip numbers
+ (when (eq (char-before) ?~)
+ (backward-char))
+ (setq pt (point))
+ (skip-chars-forward "_a-zA-Z0-9~")
+ (cons pt (point))))))))
+
+(defun irony-completion-beginning-of-symbol ()
+ (car (irony-completion-symbol-bounds)))
+
+(defun irony-completion-end-of-symbol ()
+ (cdr (irony-completion-symbol-bounds)))
+
+(defsubst irony-completion--skip-whitespaces-backward ()
+ ;;(skip-syntax-backward "-") doesn't seem to care about newlines
+ (skip-chars-backward " \t\n\r"))
+
+(defun irony-completion--parse-context-position (&optional pos)
+ (save-excursion
+ (when pos
+ (goto-char pos))
+ (irony-completion--skip-whitespaces-backward)
+ (point)))
+
+(defun irony--completion-line-column (&optional pos)
+ (save-excursion
+ (when pos
+ (goto-char pos))
+ ;; `position-bytes' to handle multibytes and 'multicolumns' (i.e
+ ;; tabulations) characters properly
+ (irony--without-narrowing
+ (cons
+ (line-number-at-pos)
+ (1+ (- (position-bytes (point))
+ (position-bytes (point-at-bol))))))))
+
+
+;;
+;; Functions
+;;
+
+(defun irony-completion--enter ()
+ (add-hook 'completion-at-point-functions 'irony-completion-at-point nil t))
+
+(defun irony-completion--exit ()
+ (remove-hook 'completion-at-point-functions 'irony-completion-at-point t))
+
+(defun irony-completion--post-complete-yas-snippet (str placeholders)
+ (let ((ph-count 0)
+ (from 0)
+ to snippet)
+ (while
+ (setq to (car placeholders)
+ snippet (concat
+ snippet
+ (substring str from to)
+ (format "${%d:%s}"
+ (cl-incf ph-count)
+ (substring str
+ (car placeholders)
+ (cadr placeholders))))
+ from (cadr placeholders)
+ placeholders (cddr placeholders)))
+ ;; handle the remaining non-snippet string, if any.
+ (concat snippet (substring str from) "$0")))
+
+
+;;
+;; Interface with irony-server
+;;
+
+(irony-iotask-define-task irony--t-complete
+ "`complete' server command."
+ :start (lambda (file line column compile-options)
+ (apply #'irony--server-send-command "complete" file line column "--"
+ compile-options))
+ :update irony--server-command-update)
+
+(defun irony--complete-task-1 (&optional buffer pos)
+ (with-current-buffer (or buffer (current-buffer))
+ (let ((line-column (irony--completion-line-column pos)))
+ (irony-iotask-package-task irony--t-complete
+ (irony--get-buffer-path-for-server)
+ (car line-column)
+ (cdr line-column)
+ (irony--adjust-compile-options)))))
+
+(defun irony--complete-task (&optional buffer pos)
+ (let ((unsaved-tasks (irony--unsaved-buffers-tasks))
+ (complete-task (irony--complete-task-1 buffer pos)))
+ (if unsaved-tasks
+ (irony-iotask-chain unsaved-tasks complete-task)
+ complete-task)))
+
+(irony-iotask-define-task irony--t-candidates
+ "`candidates' server command."
+ :start (lambda (prefix style)
+ (irony--server-send-command
+ "candidates" prefix
+ (cl-case style
+ (case-insensitive "case-insensitive")
+ (smart-case "smart-case")
+ (t "exact"))))
+ :update irony--server-query-update)
+
+(defun irony--candidates-task (&optional buffer pos prefix style)
+ (irony-iotask-chain
+ (irony--complete-task buffer pos)
+ (irony-iotask-package-task irony--t-candidates prefix style)))
+
+
+;;
+;; Irony Completion Interface
+;;
+
+(defun irony-completion-typed-text (candidate)
+ (nth 0 candidate))
+
+(defun irony-completion-priority (candidate)
+ (nth 1 candidate))
+
+(defun irony-completion-type (candidate)
+ (nth 2 candidate))
+
+(defun irony-completion-brief (candidate)
+ (nth 3 candidate))
+
+(defun irony-completion-annotation (candidate)
+ (substring (nth 4 candidate) (nth 5 candidate)))
+
+(defun irony-completion-post-comp-str (candidate)
+ (car (nth 6 candidate)))
+
+(defun irony-completion-post-comp-placeholders (candidate)
+ (cdr (nth 6 candidate)))
+
+(defun irony-completion--filter-candidates (candidates)
+ "Filter candidates by removing duplicates if
+`irony-duplicate-candidates-filter' is non nil; Duplicate
+candidates are those that have the same
+`irony-completion-typed-text', `irony-completion-annotation' and
+`irony-completion-type'. An example of when this is useful is
+when there are many derived classes that override a virtual
+method resulting in redundant duplicate entries being displayed
+in the list of completions."
+ (let (unique-candidates)
+ (cl-remove-if-not
+ (lambda (candidate)
+ (or (not irony-duplicate-candidates-filter)
+ (let ((unique-key (list (irony-completion-typed-text candidate)
+ (irony-completion-annotation candidate)
+ (irony-completion-type candidate))))
+ (and (not (member unique-key unique-candidates))
+ (push unique-key unique-candidates)))))
+ candidates)))
+
+(defun irony-completion-candidates (&optional prefix style)
+ "Return the list of candidates at point.
+
+A candidate is composed of the following elements:
+ 0. The typed text. Multiple candidates can share the same string
+ because of overloaded functions, default arguments, etc.
+ 1. The priority.
+ 2. The [result-]type of the candidate, if any.
+ 3. If non-nil, contains the Doxygen brief documentation of the
+ candidate.
+ 4. The signature of the candidate excluding the result-type
+ which is available separately.
+ Example: \"foo(int a, int b) const\"
+ 5. The annotation start, a 0-based index in the prototype string.
+ 6. Post-completion data. The text to insert followed by 0 or
+ more indices. These indices work by pairs and describe ranges
+ of placeholder text.
+ Example: (\"(int a, int b)\" 1 6 8 13)"
+ (irony--awhen (irony-completion-symbol-bounds)
+ (irony-completion--filter-candidates
+ (irony--run-task
+ (irony--candidates-task nil (car it) prefix style)))))
+
+(defun irony-completion-candidates-async (callback &optional prefix style)
+ (irony--aif (irony-completion-symbol-bounds)
+ (irony--run-task-asynchronously
+ (irony--candidates-task nil (car it) prefix style)
+ (lambda (candidates-result)
+ (funcall callback (irony-completion--filter-candidates
+ (irony-iotask-result-get candidates-result)))))
+ (funcall callback nil)))
+
+(defun irony-completion-post-complete (candidate)
+ (let ((str (irony-completion-post-comp-str candidate))
+ (placeholders (irony-completion-post-comp-placeholders candidate)))
+ (if (and placeholders (irony-snippet-available-p))
+ (irony-snippet-expand
+ (irony-completion--post-complete-yas-snippet str placeholders))
+ (insert (substring str 0 (car placeholders))))))
+
+(defun irony-completion-at-trigger-point-p ()
+ (when (eq (point) (irony-completion-beginning-of-symbol))
+ (save-excursion
+ (cond
+ ;; use `re-search-backward' so that the cursor is moved just before the
+ ;; member access, if any
+ ((re-search-backward
+ (format "%s\\=" (regexp-opt '("." ;object member access
+ "->" ;pointer member access
+ "::"))) ;scope operator
+ (point-at-bol) t)
+ (unless
+ ;; ignore most common uses of '.' where it's not a member access
+ (and (eq (char-after) ?.)
+ (or
+ ;; include statements: #include <foo.|>
+ (looking-back "^#\\s-*include\\s-+[<\"][^>\"]*"
+ (point-at-bol))
+ ;; floating point numbers (not thorough, see:
+ ;; http://en.cppreference.com/w/cpp/language/floating_literal)
+ (looking-back "[^_a-zA-Z0-9][[:digit:]]+" (point-at-bol))))
+ ;; except the above exceptions we use a "whitelist" for the places
+ ;; where it looks like a member access
+ (irony-completion--skip-whitespaces-backward)
+ (or
+ ;; after brackets consider it's a member access so things like
+ ;; 'getFoo().|' match
+ (memq (char-before) (list ?\) ?\] ?} ?>))
+ ;; identifiers but ignoring some keywords
+ ;;
+ ;; handle only a subset of template parameter packs, where the
+ ;; ellipsis is preceded by a keyword, in situation like:
+ ;; template<typename ... Args> class X {...};
+ ;; template<typename .|
+ ;; or just look if the face is: font-lock-keyword-face?
+ (save-excursion
+ (and (re-search-backward "\\b\\([_a-zA-Z][_a-zA-Z0-9]*\\)\\="
+ (point-at-bol) t)
+ (not (member (match-string 0)
+ '("class" "sizeof" "typename"))))))))))))
+
+
+;;
+;; Irony CAPF
+;;
+
+(defsubst irony-completion--capf-candidate (candidate)
+ (get-text-property 0 'irony-capf candidate))
+
+(defun irony-completion--capf-annotate (candidate)
+ (irony-completion-annotation
+ (irony-completion--capf-candidate candidate)))
+
+(defun irony-completion--capf-postcomp-commonprefix (candidates)
+ (let ((prefixes (mapcar
+ (lambda (candidate)
+ (let ((str (irony-completion-post-comp-str candidate))
+ (phs (irony-completion-post-comp-placeholders
+ candidate)))
+ (substring str 0 (car phs))))
+ candidates)))
+ (cl-loop for i from 0 below (apply #'min (mapcar #'length prefixes))
+ while (apply #'= (mapcar (lambda (string) (aref string i))
+ prefixes))
+ finally (return (cl-subseq (first prefixes) 0 i)))))
+
+(defun irony-completion--capf-postcomp-all-equal-p (candidates)
+ (when (cdr candidates)
+ (let ((expected-str (irony-completion-post-comp-str (car candidates)))
+ (expected-phs (irony-completion-post-comp-placeholders
+ (car candidates))))
+ (while (and (setq candidates (cdr candidates))
+ (string= expected-str (irony-completion-post-comp-str (car candidates)))
+ (equal expected-phs (irony-completion-post-comp-placeholders (car candidates))))))
+ (null candidates)))
+
+(defun irony-completion--capf-exit-function (candidates str status)
+ "Insert post completion string or snippet after STR has been completed."
+ ;; according to `pcomplete-completions-at-point',
+ ;; react on `finished' but not `sole',
+ ;; because it does not work properly when cycling completions
+ (when (eq status 'finished)
+ (let ((candidate (irony-completion--capf-candidate str))
+ matches)
+ ;; `completion-at-point' doesn't provides the propertized string created
+ ;; with the `irony-capf' text property
+ ;; but `company-capf' does, and maybe `completion-at-point' some day.
+ ;; So if the candidate data is found use it,
+ ;; otherwise try to find the candidate in the completion list
+ ;; at the risk of dealing with overloaded functions and not being able to
+ ;; make the right decision
+ (setq matches
+ (if candidate
+ (list candidate)
+ (cl-remove-if-not (lambda (candidate)
+ (string= (car candidate) str))
+ candidates)))
+ ;; all equals can happen with when the difference in the annotation
+ ;; is the return type and constness attributes,
+ ;; for example `std::string' `at(n)' function is overloaded that way:
+ ;; const char & at(size_type n) const;
+ ;; char & at(size_type n);
+ (if (or (= (length matches) 1)
+ (irony-completion--capf-postcomp-all-equal-p matches))
+ ;; with a perfect match we are able to give complete post-completion
+ (irony-completion-post-complete (car matches))
+ ;; more than one candidates possible,
+ ;; provide the beginning of the post-completion data as a best effort.
+ ;; For overloaded functions this inserts the opening parenthesis.
+ (irony--awhen (irony-completion--capf-postcomp-commonprefix matches)
+ (insert it))))))
+
+;;;###autoload
+(defun irony-completion-at-point ()
+ (irony--awhen (and irony-mode (irony-completion-symbol-bounds))
+ (let ((candidates (irony-completion--filter-candidates
+ (irony--run-task
+ (irony--candidates-task
+ nil
+ (car it)
+ (buffer-substring-no-properties
+ (car it) (cdr it))
+ (if completion-ignore-case
+ 'case-insensitive
+ 'exact))))))
+ (list
+ (car it) ;start
+ (cdr it) ;end
+ (mapcar (lambda (candidate) ;completion table
+ (propertize (car candidate) 'irony-capf candidate))
+ candidates)
+ :annotation-function #'irony-completion--capf-annotate
+ :exit-function
+ (lambda (str status)
+ (irony-completion--capf-exit-function candidates str status))))))
+
+(provide 'irony-completion)
+
+;; Local Variables:
+;; byte-compile-warnings: (not cl-functions)
+;; End:
+
+;;; irony-completion.el ends here
diff --git a/elpa/irony-20220110.849/irony-completion.elc b/elpa/irony-20220110.849/irony-completion.elc
new file mode 100644
index 0000000..20adb70
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-completion.elc
Binary files differ
diff --git a/elpa/irony-20220110.849/irony-diagnostics.el b/elpa/irony-20220110.849/irony-diagnostics.el
new file mode 100644
index 0000000..76c268d
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-diagnostics.el
@@ -0,0 +1,90 @@
+;;; irony-diagnostics.el --- irony-mode diagnostic reporting
+
+;; Copyright (C) 2014 Guillaume Papin
+
+;; Author: Guillaume Papin <guillaume.papin@epitech.eu>
+;; Keywords: c, convenience, tools
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Interface libclang's "Diagnostic Reporting", see
+;; http://clang.llvm.org/doxygen/group__CINDEX__DIAG.html
+
+;;; Code:
+
+(require 'irony)
+(require 'irony-iotask)
+
+(eval-when-compile
+ (require 'cl)) ;for lexical-let macro
+
+
+;;
+;; Irony Diagnostics Interface
+;;
+
+(defun irony-diagnostics-file (diagnostic)
+ (nth 0 diagnostic))
+
+(defun irony-diagnostics-line (diagnostic)
+ (nth 1 diagnostic))
+
+(defun irony-diagnostics-column (diagnostic)
+ (nth 2 diagnostic))
+
+(defun irony-diagnostics-severity (diagnostic)
+ (nth 4 diagnostic))
+
+(defun irony-diagnostics-message (diagnostic)
+ (nth 5 diagnostic))
+
+(defun irony-diagnostics-async (callback)
+ "Perform an asynchronous diagnostic request for the current
+buffer.
+
+CALLBACK is called with at least one argument, a symbol
+representing the status of the request. Depending on the status
+more argument are provided. Possible values are explained below:
+
+- success
+
+ When quering the diagnostics work, the additional argument is a
+ list of diagnostic object, diagnostics fields can be queried
+ with the functions `irony-diagnostics-<xxx>'.
+
+- error
+
+ Retrieving the diagnostics wasn't possible. A string explaining
+ the reason is passed as a second argument.
+
+- cancelled
+
+ Retrieving the diagnostics was cancelled, e.g: because the
+ buffer has changed since the beginning of the request, and as
+ such the diagnostics are considered no longer relevant. A
+ reason string is passed as a second argument."
+ (lexical-let ((cb callback))
+ (irony--run-task-asynchronously
+ (irony--diagnostics-task)
+ (lambda (diagnostics-result)
+ (condition-case err
+ (funcall cb 'success (irony-iotask-result-get diagnostics-result))
+ (error
+ (funcall cb 'error (error-message-string err))))))))
+
+(provide 'irony-diagnostics)
+
+;;; irony-diagnostics.el ends here
diff --git a/elpa/irony-20220110.849/irony-diagnostics.elc b/elpa/irony-20220110.849/irony-diagnostics.elc
new file mode 100644
index 0000000..dfcae2a
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-diagnostics.elc
Binary files differ
diff --git a/elpa/irony-20220110.849/irony-iotask.el b/elpa/irony-20220110.849/irony-iotask.el
new file mode 100644
index 0000000..2226a69
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-iotask.el
@@ -0,0 +1,441 @@
+;;; irony-iotask.el --- Abstraction for I/O-based tasks
+
+;; Copyright (C) 2015 Guillaume Papin
+
+;; Author: Guillaume Papin <guillaume.papin@epitech.eu>
+;; Keywords: processes, convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Purpose is to work with both processes and network streams.
+;;
+;; Unlike tq.el we want tasks to be composed of 0, 1-1, or n-n communications.
+;; tq.el only supports 1-1.
+;;
+;; 0 is useful if a server command has been cached, it means there is no need
+;; for communication. We may only know if a task is still cached when the
+;; callback is called (maybe after some other asynchronous tasks, so the context
+;; may have changed since the task was initially posted)
+;;
+;; n-n is useful if the number of request depends on the answer to a previous
+;; request but we still want to be able to push new tasks.
+
+;;; Code:
+
+(eval-when-compile
+ (require 'cl)) ;for lexical-let macro
+
+(require 'cl-lib)
+
+
+;;
+;; Error conditions
+;;
+
+;; `define-error' breaks backward compatibility with Emacs < 24.4
+(defun irony-iotask--define-error (name message &optional parent)
+ "Define NAME as a new error signal.
+MESSAGE is a string that will be output to the echo area if such an error
+is signaled without being caught by a `condition-case'.
+PARENT is either a signal or a list of signals from which it inherits.
+Defaults to `error'."
+ (unless parent (setq parent 'error))
+ (let ((conditions
+ (if (consp parent)
+ (apply #'nconc
+ (mapcar (lambda (parent)
+ (cons parent
+ (or (get parent 'error-conditions)
+ (error "Unknown signal `%s'" parent))))
+ parent))
+ (cons parent (get parent 'error-conditions)))))
+ (put name 'error-conditions
+ (delete-dups (copy-sequence (cons name conditions))))
+ (when message (put name 'error-message message))))
+
+(irony-iotask--define-error 'irony-iotask-error "I/O task error")
+(irony-iotask--define-error 'irony-iotask-filter-error "I/O task filter error")
+(irony-iotask--define-error 'irony-iotask-bad-task "Bad I/O task")
+(irony-iotask--define-error 'irony-iotask-bad-data "Bad I/O task data")
+
+
+;;
+;; Structures
+;;
+
+(cl-defstruct (irony-iotask-result (:constructor irony-iotask-result-create))
+ -tag ;; 'value or 'error, or nil when unset
+ -value
+ -error -error-data
+ )
+
+(defun irony-iotask-result-valid-p (result)
+ (and (irony-iotask-result--tag result) t))
+
+(defun irony-iotask-result-value-p (result)
+ (eq (irony-iotask-result--tag result) 'value))
+
+(defun irony-iotask-result-error-p (result)
+ (eq (irony-iotask-result--tag result) 'error))
+
+(defun irony-iotask-result-set-value (result value)
+ (setf (irony-iotask-result--tag result) 'value)
+ (setf (irony-iotask-result--value result) value))
+
+(defun irony-iotask-result-set-error (result error &rest error-data)
+ (setf (irony-iotask-result--tag result) 'error)
+ (setf (irony-iotask-result--error result) error)
+ (setf (irony-iotask-result--error-data result) error-data))
+
+(irony-iotask--define-error 'irony-iotask-result-get-error
+ "Result not set before call to get")
+
+(defun irony-iotask-result-get (result)
+ (cl-case (irony-iotask-result--tag result)
+ ('value (irony-iotask-result--value result))
+ ('error (signal (irony-iotask-result--error result)
+ (irony-iotask-result--error-data result)))
+ (t
+ (signal 'irony-iotask-result-get-error (list result)))))
+
+;; FIXME: quoting issues? I cannot write "#'(lambda ()...)" as property value
+(defmacro irony-iotask-define-task (var docstring &rest properties)
+ "A task is simply a property list.
+
+Each of these function are called in the buffer they were
+originally created (at schedule time).
+
+The functions `irony-iotask-put', `irony-iotask-get',
+`irony-iotask-set-result' and `irony-iotask-set-error' are
+available to the task's functions to set the task's result.
+
+Properties:
+
+`:start' (mandatory)
+ Function to call to launch the task.
+
+ Usually the function sends a string/command/message to the
+ execution context. If the task do some caching it's possible
+ that nothing is send, instead the execution context result
+ should be set to indicate that the task is ready.
+
+ The following additional functions are available to call
+ inside the `:start' function to communicate with the
+ underlying process:
+
+ - `irony-iotask-send-string'
+ - `irony-iotask-send-region'
+ - `irony-iotask-send-eof'
+
+`:update' (mandatory)
+ Function to call when some process output is available.
+
+ The function should determine whether a message is complete
+ and set the result when it is. It should also detect if the
+ message is invalid and throw the 'invalid-msg tag with a
+ value of t in this case. If the message is incomplete, the
+ function should do nothing.
+
+ The process output is the current buffer.
+
+`:finish' (optional)
+
+ Function to call after the result has been set but before
+ the callback is called.
+
+ Usually performs some kind of cleanup operation.
+
+ Note: it makes no sense to set a result or error in this
+ function as it is necessarily been set beforehand.
+
+`:on-success' (optional)
+
+ Same as `:finish' but called only if the result IS NOT an error.
+
+`:on-error' (optional)
+
+ Same as `:finish' but called only if the result IS an error."
+ (declare (indent 1)
+ (doc-string 2))
+ `(progn
+ (defvar ,var nil ,docstring)
+ ;; Use `setq' to reset the var every time the macro is called.
+ ;; This is useful, for example when evaluating using C-M-x (`eval-defun').
+ ;; Trick stolen from auto-complete's `ac-define-source'
+ (setq ,var '(,@properties))))
+
+(cl-defstruct (irony-iotask-packaged-task
+ (:constructor irony-iotask-packaged-task--create))
+ task
+ args
+ result
+ plist
+ continuation)
+
+(defun irony-iotask-package-task (task &rest args)
+ (irony-iotask-packaged-task--create :task task
+ :result (irony-iotask-result-create)
+ :args args))
+
+(defvar irony-iotask--current-packaged-task) ;dynamically bound
+(defun irony-iotask-package-task-invoke (packaged-task prop-fn
+ &optional ignore-missing
+ &rest leading-args)
+ (let* ((task (irony-iotask-packaged-task-task packaged-task))
+ (args (irony-iotask-packaged-task-args packaged-task))
+ (fn (plist-get task prop-fn)))
+ (condition-case err
+ (if fn
+ ;; let binding for irony-iotask-{get,put}
+ ;; and irony-iotask-set-{result,error}
+ (let ((irony-iotask--current-packaged-task packaged-task))
+ (apply fn (append leading-args args)))
+ (unless ignore-missing
+ (signal 'irony-iotask-bad-task
+ (list task (format "no %s function" prop-fn)))))
+ (error
+ (apply #'irony-iotask-result-set-error
+ (irony-iotask-packaged-task-result packaged-task)
+ (car err) (cdr err))))))
+
+(defun irony-iotask--chain-1 (packaged-task-1 packaged-task-2)
+ (while (irony-iotask-packaged-task-continuation packaged-task-1)
+ (setq packaged-task-1
+ (irony-iotask-packaged-task-continuation packaged-task-1)))
+ (setf (irony-iotask-packaged-task-continuation packaged-task-1)
+ packaged-task-2))
+
+(defun irony-iotask-chain (packaged-task-1 packaged-task-2 &rest others)
+ (setq others (cons packaged-task-2 others))
+ (while others
+ (irony-iotask--chain-1 packaged-task-1 (car others))
+ (setq others (cdr others)))
+ packaged-task-1)
+
+(cl-defstruct (irony-iotask-ectx
+ (:constructor irony-iotask-ectx--create))
+ started
+ packaged-task
+ callback
+ schedule-buffer)
+
+(defun irony-iotask-ectx-call-callback (ectx result)
+ (let ((cb-buffer (irony-iotask-ectx-schedule-buffer ectx)))
+ (when (buffer-live-p cb-buffer) ;[GH-427]
+ (with-demoted-errors "Irony I/O task: error in callback: %S"
+ (with-current-buffer cb-buffer
+ (funcall (irony-iotask-ectx-callback ectx) result))))))
+
+(defvar irony-iotask--process)
+
+(defun irony-iotask--start-next (process)
+ (let* ((ectx (car (process-get process :ectx-q)))
+ (packaged-task (irony-iotask-ectx-packaged-task ectx)))
+ (setf (irony-iotask-ectx-started ectx) t)
+ ;; erase the buffer before we call :start so the next :update starts anew
+ (erase-buffer)
+ ;; for `irony-iotask-send-string', `irony-iotask-send-region' and
+ ;; `irony-iotask-send-eof'
+ (let ((irony-iotask--process process))
+ (save-current-buffer
+ (irony-iotask-package-task-invoke packaged-task :start)))
+ (irony-iotask--check-result process)))
+
+(defun irony-iotask--start-next-safe (process)
+ "Run the next task, if any."
+ (let ((ectx-q (process-get process :ectx-q)))
+ (when (and ectx-q (not (irony-iotask-ectx-started (car ectx-q))))
+ (irony-iotask--start-next process))))
+
+(defun irony-iotask--check-result (process)
+ (let* ((ectx (car (process-get process :ectx-q)))
+ (packaged-task (irony-iotask-ectx-packaged-task ectx))
+ (result (irony-iotask-packaged-task-result packaged-task)))
+ (when (irony-iotask-result-valid-p result)
+ (save-current-buffer
+ (if (irony-iotask-result-value-p result)
+ (irony-iotask-package-task-invoke packaged-task :on-success t)
+ (irony-iotask-package-task-invoke packaged-task :on-error t)))
+ (save-current-buffer
+ (irony-iotask-package-task-invoke packaged-task :finish t))
+ (if (and (irony-iotask-packaged-task-continuation packaged-task)
+ (irony-iotask-result-value-p result))
+ ;; we got a non-error, we can chain to the next continuation
+ (progn
+ (setf (irony-iotask-ectx-packaged-task ectx)
+ (irony-iotask-packaged-task-continuation packaged-task))
+ (irony-iotask--start-next process))
+ ;; no continuation or an error, call the callback
+ ;; and skip any potential continuation
+ (setq ectx (pop (process-get process :ectx-q)))
+ (irony-iotask-ectx-call-callback ectx result)
+ (irony-iotask--start-next-safe process)))))
+
+(irony-iotask--define-error 'irony-iotask-aborted "I/O task aborted")
+
+(defun irony-iotask--abort-all (process &rest reasons)
+ (let ((result (irony-iotask-result-create))
+ ectx)
+ (apply #'irony-iotask-result-set-error result 'irony-iotask-aborted reasons)
+ (while (setq ectx (pop (process-get process :ectx-q)))
+ (irony-iotask-ectx-call-callback ectx result))))
+
+
+;;
+;; Implementation details, internal mechanic
+;;
+
+(defun irony-iotask-process-filter (process output)
+ (when (buffer-live-p (process-buffer process))
+ (with-current-buffer (process-buffer process)
+ (let ((ectx (car (process-get process :ectx-q)))
+ packaged-task
+ result)
+ ;; if no task this is an error, a spurious message is an error
+ (unless ectx
+ (signal 'irony-iotask-filter-error (list "spurious output" output)))
+ (setq packaged-task (irony-iotask-ectx-packaged-task ectx))
+ (setq result (irony-iotask-packaged-task-result packaged-task))
+ (goto-char (process-mark process))
+ (insert output)
+ (set-marker (process-mark process) (point))
+ ;; go to the first char, so the `:update' function is called at the
+ ;; beginning of the buffer, it is more convenient
+ (goto-char (point-min))
+ (when (catch 'invalid-msg
+ (save-current-buffer
+ (irony-iotask-package-task-invoke packaged-task :update))
+ nil)
+ (irony-iotask-result-set-error result
+ 'irony-iotask-bad-data
+ packaged-task
+ (buffer-string)))
+ (irony-iotask--check-result process)))))
+
+(defun irony-iotask-process-sentinel (process event)
+ ;; events usually ends with a newline, we don't want it
+ (setq event (replace-regexp-in-string "\n\\'" "" event))
+ (unless (process-live-p process)
+ (irony-iotask--abort-all process "process stopped running" event)
+ (message "%s process stopped!" (process-name process))))
+
+(defun irony-iotask-check-process (process)
+ (let ((pfilter (process-filter process))
+ (psentinel (process-sentinel process)))
+ (unless (eq pfilter 'irony-iotask-process-filter)
+ (signal 'irony-iotask-error
+ (list "invalid process filter" pfilter
+ "did you call `irony-iotask-setup-process'?")))
+ (unless (eq psentinel 'irony-iotask-process-sentinel)
+ (signal 'irony-iotask-error
+ (list "invalid process sentinel" psentinel
+ "did you call `irony-iotask-setup-process'?"))))
+ (unless (process-live-p process)
+ (signal 'irony-iotask-error (list "Process ain't running!")))
+ (unless (buffer-live-p (process-buffer process))
+ (signal 'irony-iotask-error (list "Process' buffer dead!"))))
+
+
+;;
+;; Public API
+;;
+
+(defun irony-iotask-setup-process (process)
+ "Call after creating the asynchronous process to let
+irony-iotask setup the PROCESS filter and anything else that may
+be needed."
+ (with-current-buffer (process-buffer process)
+ (set-process-filter process #'irony-iotask-process-filter)
+ (set-process-sentinel process #'irony-iotask-process-sentinel)
+ (buffer-disable-undo)))
+
+(defun irony-iotask-schedule (process packaged-task callback)
+ (let ((ectx (irony-iotask-ectx--create :packaged-task packaged-task
+ :callback callback
+ :schedule-buffer (current-buffer))))
+ (irony-iotask-check-process process)
+ (with-current-buffer (process-buffer process)
+ ;; append the new task to the queue
+ (process-put process :ectx-q (append (process-get process :ectx-q)
+ (list ectx)))
+ ;; run task if none were running
+ (unless (cdr (process-get process :ectx-q))
+ (irony-iotask--start-next process)))))
+
+(defun irony-iotask-run (process packaged-task)
+ "Blocking/waiting counterpart of `irony-iotask-schedule'.
+
+Return the result (or signal the stored error) instead of passing
+it to a callback.
+
+Returns nil when quitting.
+
+This function isn't reentrant, do not call it from another task."
+ (lexical-let (run-result)
+ ;; schedule an asynchronous task that set result when done
+ (irony-iotask-schedule process
+ packaged-task
+ (lambda (result)
+ (setq run-result result)))
+
+ ;; wait for the task to complete
+ ;; quitting is allowed, in this case the task will still run but
+ ;; asynchronously, it won't block the user interface but the result will be
+ ;; lost
+ (if (with-local-quit
+ (while (not run-result)
+ (accept-process-output process 0.05))
+ t)
+ ;; didn't quit, task was completed
+ (irony-iotask-result-get run-result)
+ ;; C-g was used
+ ;; TODO: We cannot abort the task because that may break the other tasks,
+ ;; the process will be in an unpredictable state. Howewer we can cancel
+ ;; the continuations.
+ )))
+
+(defun irony-iotask-get (propname)
+ (plist-get (irony-iotask-packaged-task-plist
+ irony-iotask--current-packaged-task)
+ propname))
+
+(defun irony-iotask-put (propname value)
+ (setf (irony-iotask-packaged-task-plist irony-iotask--current-packaged-task)
+ (plist-put (irony-iotask-packaged-task-plist
+ irony-iotask--current-packaged-task)
+ propname
+ value)))
+
+(defun irony-iotask--result ()
+ (irony-iotask-packaged-task-result irony-iotask--current-packaged-task))
+
+(defun irony-iotask-set-result (value)
+ (irony-iotask-result-set-value (irony-iotask--result) value))
+
+(defun irony-iotask-set-error (err &rest error-data)
+ (apply #'irony-iotask-result-set-error (irony-iotask--result) err error-data))
+
+(defun irony-iotask-send-string (string)
+ (process-send-string irony-iotask--process string))
+
+(defun irony-iotask-send-region (start end)
+ (process-send-region irony-iotask--process start end))
+
+(defun irony-iotask-send-eof (string)
+ (process-send-eof irony-iotask--process))
+
+(provide 'irony-iotask)
+;;; irony-iotask.el ends here
diff --git a/elpa/irony-20220110.849/irony-iotask.elc b/elpa/irony-20220110.849/irony-iotask.elc
new file mode 100644
index 0000000..b575c2d
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-iotask.elc
Binary files differ
diff --git a/elpa/irony-20220110.849/irony-pkg.el b/elpa/irony-20220110.849/irony-pkg.el
new file mode 100644
index 0000000..d685cdf
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-pkg.el
@@ -0,0 +1,13 @@
+(define-package "irony" "20220110.849" "C/C++ minor mode powered by libclang"
+ '((cl-lib "0.5")
+ (json "1.2"))
+ :commit "870d1576fb279bb93f776a71e65f45283c423a9e" :authors
+ '(("Guillaume Papin" . "guillaume.papin@epitech.eu"))
+ :maintainer
+ '("Guillaume Papin" . "guillaume.papin@epitech.eu")
+ :keywords
+ '("c" "convenience" "tools")
+ :url "https://github.com/Sarcasm/irony-mode")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
diff --git a/elpa/irony-20220110.849/irony-snippet.el b/elpa/irony-20220110.849/irony-snippet.el
new file mode 100644
index 0000000..b12b587
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-snippet.el
@@ -0,0 +1,135 @@
+;;; irony-snippet.el --- Snippet support for Irony-Mode
+
+;; Copyright (C) 2013-2014 Guillaume Papin
+
+;; Author: Guillaume Papin <guillaume.papin@epitech.eu>
+;; Keywords: c, convenience
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Snippet support functions, support all version of YASnippet and
+;; maybe further frameworks later.
+;;
+;; It is possible to check snippet support by calling
+;; `irony-snippet-available-p'.
+;;
+;; Note: Some YASnippet versions require to have
+;; `yas/minor-mode' or `yas-minor-mode' enabled to work.
+
+;;; Code:
+
+
+;; Private variables
+;;
+(defvar irony-snippet--expand-function nil
+ "Function to expand a snippet at a given point (by default to
+the current position).
+
+e.g: (defun my-expand-snippet (snippet-str &optional pos)
+ (do-stuff (or pos (point)))
+
+Will be set to nil if no snippet expansion function is found.")
+
+
+;;
+;; "Public" functions
+;;
+(defun irony-snippet-available-p ()
+ "Return t if snippets are supported."
+ (and (irony-snippet--get-expand-function)
+ (not (irony-snippet--yas-disabled-p))))
+
+(defun irony-snippet-expand (snippet-str &optional pos)
+ "Expand SNIPPET-STR starting at POS.
+
+If `irony-snippet-available-p' return t then"
+ (let ((expand-func (irony-snippet--get-expand-function)))
+ (funcall expand-func snippet-str pos)))
+
+
+;; Private functions
+;;
+(defun irony-snippet--get-expand-function ()
+ (unless irony-snippet--expand-function
+ (irony-snippet--init-yas))
+ irony-snippet--expand-function)
+
+(defun irony-snippet--init-yas ()
+ ;; find the snippet expand function
+ (when (require 'yasnippet nil t)
+ (let ((yas-version (or (and (boundp 'yas--version) yas--version)
+ (and (boundp 'yas/version) yas/version)))) ;for old versions
+ (when (stringp yas-version)
+ (setq yas-version (replace-regexp-in-string "(\\|)" "" yas-version))
+ (setq irony-snippet--expand-function
+ ;; (string= ... "0.6.0c"), the 'c' suffix is not supported by
+ ;; `version-to-list' in emacs versions < 24, treat this one
+ ;; specifically.
+ (cond
+ ((or (string= yas-version "0.6.0c")
+ (version<= yas-version "0.6.0b"))
+ 'irony-snippet--expand-yas-1)
+ ;; `version<' thinks "0.8beta" < "0.8", we want to consider
+ ;; anything starting with "0.8" as "0.8" and more.
+ ((and (version< yas-version "0.8")
+ (not (string-prefix-p "0.8" yas-version)))
+ 'irony-snippet--expand-yas-2)
+ (t
+ 'irony-snippet--expand-yas-3)))))))
+
+(defun irony-snippet--yas-disabled-p ()
+ "If the current yasnippet version offers a minor-mode, check if
+this mode is disable by returning t, otherwise returns nil and
+it's partially safe to assume that yasnippet expansion can be
+used."
+ ;; XXX: work only when yasnippet is enabled, otherwise some
+ ;; variables used for the snippet expansion are not set and it
+ ;; causes some errors.
+ (if (boundp 'yas-minor-mode)
+ (not yas-minor-mode)
+ (if (boundp 'yas/minor-mode)
+ (not yas/minor-mode))))
+
+(defun irony-snippet--expand-yas-1 (snippet-str &optional pos)
+ "Expand snippets for YASnippet version <= 0.6.0c."
+ (declare-function yas/expand-snippet "ext:yasnippet" t nil)
+ (unless (irony-snippet--yas-disabled-p)
+ (yas/expand-snippet (or pos (point))
+ (or pos (point))
+ snippet-str)))
+
+(defun irony-snippet--expand-yas-2 (snippet-str &optional pos)
+ "Expand snippets for YASnippet version < 0.8.
+
+See also `irony-snippet--expand-yas-1'."
+ (declare-function yas/expand-snippet "ext:yasnippet" t nil)
+ (unless (irony-snippet--yas-disabled-p)
+ (when pos
+ (goto-char pos))
+ (yas/expand-snippet snippet-str)))
+
+(defun irony-snippet--expand-yas-3 (snippet-str &optional pos)
+ "Expand snippets for YASnippet version >= 0.8.
+
+See also `irony-snippet--expand-yas-2'."
+ (declare-function yas-expand-snippet "ext:yasnippet" t nil)
+ (unless (irony-snippet--yas-disabled-p)
+ (when pos
+ (goto-char pos))
+ (yas-expand-snippet snippet-str)))
+
+(provide 'irony-snippet)
+;;; irony-snippet.el ends here
diff --git a/elpa/irony-20220110.849/irony-snippet.elc b/elpa/irony-20220110.849/irony-snippet.elc
new file mode 100644
index 0000000..a5762f6
--- /dev/null
+++ b/elpa/irony-20220110.849/irony-snippet.elc
Binary files differ
diff --git a/elpa/irony-20220110.849/irony.el b/elpa/irony-20220110.849/irony.el
new file mode 100644
index 0000000..f70eca3
--- /dev/null
+++ b/elpa/irony-20220110.849/irony.el
@@ -0,0 +1,917 @@
+;;; irony.el --- C/C++ minor mode powered by libclang
+
+;; Copyright (C) 2011-2016 Guillaume Papin
+
+;; Author: Guillaume Papin <guillaume.papin@epitech.eu>
+;; Version: 1.5.0
+;; URL: https://github.com/Sarcasm/irony-mode
+;; Compatibility: GNU Emacs 24.x
+;; Keywords: c, convenience, tools
+;; Package-Requires: ((cl-lib "0.5") (json "1.2"))
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; This file provides `irony-mode', a minor mode for C, C++ and Objective-C.
+;;
+;; Usage:
+;; (add-hook 'c++-mode-hook 'irony-mode)
+;; (add-hook 'c-mode-hook 'irony-mode)
+;; (add-hook 'objc-mode-hook 'irony-mode)
+;;
+;; ;; Windows performance tweaks
+;; ;;
+;; (when (boundp 'w32-pipe-read-delay)
+;; (setq w32-pipe-read-delay 0))
+;; ;; Set the buffer size to 64K on Windows (from the original 4K)
+;; (when (boundp 'w32-pipe-buffer-size)
+;; (setq irony-server-w32-pipe-buffer-size (* 64 1024)))
+;;
+;; See also:
+;; - https://github.com/Sarcasm/company-irony
+;; - https://github.com/Sarcasm/flycheck-irony
+;; - https://github.com/Sarcasm/ac-irony
+
+;;; Code:
+
+(require 'irony-iotask)
+
+(autoload 'irony-completion--enter "irony-completion")
+(autoload 'irony-completion--exit "irony-completion")
+
+(require 'cl-lib)
+
+(autoload 'find-library-name "find-func")
+(autoload 'lm-version "lisp-mnt")
+
+
+;;
+;; Compatibility
+;;
+
+(eval-and-compile
+
+ ;; As seen in flycheck/magit
+ ;;
+ ;; Added in Emacs 24.3 (mirrors/emacs@b335efc3).
+ (unless (fboundp 'setq-local)
+ (defmacro setq-local (var val)
+ "Set variable VAR to value VAL in current buffer."
+ (list 'set (list 'make-local-variable (list 'quote var)) val)))
+
+ ;; Added in Emacs 24.3 (mirrors/emacs@b335efc3).
+ (unless (fboundp 'defvar-local)
+ (defmacro defvar-local (var val &optional docstring)
+ "Define VAR as a buffer-local variable with default value VAL.
+Like `defvar' but additionally marks the variable as being
+automatically buffer-local wherever it is set."
+ (declare (debug defvar) (doc-string 3))
+ (list 'progn (list 'defvar var val docstring)
+ (list 'make-variable-buffer-local (list 'quote var)))))
+
+ ) ;; eval-and-compile
+
+
+;;
+;; Customizable variables
+;;
+
+(defgroup irony nil
+ "C/C++ minor mode powered by libclang."
+ :group 'c)
+
+(defcustom irony-lighter " Irony"
+ "Text to display in the mode line when irony mode is on."
+ :type 'string
+ :group 'irony)
+
+(defcustom irony-extra-cmake-args nil
+ "Extra arguments to CMake when compiling the server."
+ :type '(repeat string)
+ :group 'irony)
+
+(defcustom irony-user-dir (locate-user-emacs-file "irony/")
+ "Directory containing the Irony generated files.
+
+The slash is expected at the end."
+ :type 'directory
+ :risky t
+ :group 'irony)
+
+(defcustom irony-supported-major-modes '(c++-mode
+ c-mode
+ objc-mode)
+ "List of modes known to be compatible with Irony."
+ :type '(repeat symbol)
+ :group 'irony)
+
+;;;###autoload
+(defcustom irony-additional-clang-options nil
+ "Additional command line options to pass down to libclang.
+
+Please, do NOT use this variable to add header search paths, only
+additional warnings or compiler options.
+
+These compiler options will be prepended to the command line, in
+order to not override the value coming from a compilation
+database."
+ :type '(repeat string)
+ :options '("-Wdocumentation")
+ :group 'irony)
+
+(defcustom irony-lang-compile-option-alist
+ '((c++-mode . "c++")
+ (c-mode . "c")
+ (objc-mode . "objective-c"))
+ "Alist to decide the language option to used based on the `major-mode'."
+ :type '(alist :key-type symbol :value-type string)
+ :group 'irony)
+
+(defcustom irony-cmake-executable "cmake"
+ "Name or path of the CMake executable."
+ :type 'string
+ :group 'irony)
+
+(defcustom irony-server-source-dir nil
+ "Points to the irony-server source directory.
+
+This should point to the directory that contains the top-most
+CMakeLists.txt used to build the server.
+
+By default it will find the directory based on the irony.el directory."
+ :type 'directory
+ :group 'irony
+ :package-version '(irony . "1.2.0"))
+
+(defcustom irony-server-build-dir nil
+ "Build directory for irony-server.
+
+If set to nil the default is to create a build directory in
+`temporary-file-directory'/build-irony-server-`(irony-version)'."
+ :type 'directory
+ :group 'irony)
+
+(defcustom irony-server-install-prefix irony-user-dir
+ "Installation prefix used to install irony-server.
+
+The irony-server executable is expected to be in
+`irony-server-install-prefix'/bin/."
+ :type 'directory
+ :group 'irony)
+
+(defcustom irony-server-w32-pipe-buffer-size nil
+ "Windows-only setting,
+the buffer size to use for the irony-server process pipe on Windows.
+
+Larger values can improve performances on large buffers.
+
+If non-nil, `w32-pipe-buffer-size' will be let-bound to this value
+during the creation of the irony-server process.")
+
+
+;;
+;; Public/API variables
+;;
+;; Non-customizable variables provided by Irony that can be useful to other
+;; packages.
+;;
+;; Note that they shouldn't be modified directly by external packages, just
+;; read.
+;;
+
+;; TODO: make this variable public when the CDB API stabilizes.
+(defvar-local irony--compile-options nil
+ "Compile options for the current file.
+
+The compile options used by the compiler to build the current
+buffer file.")
+
+;; TODO: make this variable public when the CDB API stabilizes.
+(defvar-local irony--working-directory nil
+ "The working directory to pass to libclang, if any.")
+
+
+;;
+;; Internal variables
+;;
+;; The prefix `irony--' is used when something can completely change (or
+;; disappear) from one release to the other.
+;;
+;; -- https://lists.gnu.org/archive/html/emacs-devel/2013-06/msg01129.html
+
+(defconst irony--eot "\n;;EOT\n"
+ "String sent by the server to signal the end of a response.")
+
+
+;;
+;; Error conditions
+;;
+
+;; `define-error' breaks backward compatibility with Emacs < 24.4
+(defun irony--define-error (name message &optional parent)
+ "Define NAME as a new error signal.
+MESSAGE is a string that will be output to the echo area if such an error
+is signaled without being caught by a `condition-case'.
+PARENT is either a signal or a list of signals from which it inherits.
+Defaults to `error'."
+ (unless parent (setq parent 'error))
+ (let ((conditions
+ (if (consp parent)
+ (apply #'nconc
+ (mapcar (lambda (parent)
+ (cons parent
+ (or (get parent 'error-conditions)
+ (error "Unknown signal `%s'" parent))))
+ parent))
+ (cons parent (get parent 'error-conditions)))))
+ (put name 'error-conditions
+ (delete-dups (copy-sequence (cons name conditions))))
+ (when message (put name 'error-message message))))
+
+(irony--define-error 'irony-error "Irony-Mode error")
+(irony--define-error 'irony-parse-error "Irony-Mode parsing error" 'irony-error)
+(irony--define-error 'irony-server-error "Irony-Mode server error" 'irony-error)
+
+
+;;
+;; Utility functions & macros
+;;
+
+;; TODO: remove and use `if-let' when supported version jumps to Emacs 25.1
+(defmacro irony--aif (test if-expr &rest else-body)
+ (declare (indent 2))
+ `(let ((it ,test))
+ (if it
+ ,if-expr
+ (progn ,@else-body))))
+
+;; TODO: remove and use `when-let' when supported version jumps to Emacs 25.1
+(defmacro irony--awhen (test &rest body)
+ (declare (indent 1))
+ `(let ((it ,test))
+ (when it
+ (progn ,@body))))
+
+(defun irony--assoc-all (key list)
+ (delq nil (mapcar (lambda (c)
+ (when (equal (car c) key)
+ c))
+ list)))
+
+(defmacro irony--without-narrowing (&rest body)
+ "Remove the effect of narrowing for the current buffer.
+
+Note: If `save-excursion' is needed for BODY, it should be used
+before calling this macro."
+ (declare (indent 0) (debug t))
+ `(save-restriction
+ (widen)
+ (progn ,@body)))
+
+(defun irony--buffer-size-in-bytes ()
+ "Return the buffer size, in bytes."
+ (1- (position-bytes (point-max))))
+
+(defun irony--read-char-choice (prompt chars)
+ "Wrapper around `read-char-choice', available since Emacs 24."
+ (setq prompt (concat prompt " [" chars "]: "))
+ (if (fboundp 'read-char-choice)
+ (read-char-choice prompt chars)
+ (setq prompt (propertize prompt 'face 'minibuffer-prompt))
+ (let ((cursor-in-echo-area t)
+ k)
+ (while (not (member k chars))
+ (setq k (read-char-exclusive prompt)))
+ k)))
+
+(defun irony--shorten-path (path)
+ "Make PATH as short as possible.
+
+The given path can be considered understandable by human but not
+necessary a valid path string to use in code. Its only purpose is
+to be displayed to the user."
+ (let ((relative (file-relative-name path))
+ (abbreviated (abbreviate-file-name path)))
+ (if (< (string-width relative) (string-width abbreviated))
+ relative
+ abbreviated)))
+
+(defun irony--split-command-line-1 (quoted-str)
+ "Remove the escaped quotes and backlash from a QUOTED-STR.
+
+Return a list of the final characters in the reverse order.
+
+Only to be consumed by `irony--split-command-line'."
+ (let ((len (length quoted-str))
+ (i 0)
+ ch next-ch
+ result)
+ (while (< i len)
+ (setq ch (aref quoted-str i))
+ (when (eq ch ?\\)
+ (let ((next-ch (and (< (1+ i) len)
+ (aref quoted-str (1+ i)))))
+ (when (member next-ch '(?\\ ?\"))
+ (setq ch next-ch)
+ (cl-incf i))))
+ (push ch result)
+ (cl-incf i))
+ result))
+
+;; TODO: rewrite the function correctly to handle things like the following:
+;;
+;; "/usr/bin/clang++ -Irelative -DSOMEDEF=\"With spaces, quotes and \\-es.\" <args...>"
+(defun irony--split-command-line (cmd-line)
+ "Split CMD-LINE into a list of arguments.
+
+Takes care of double quotes as well as backslash.
+
+Sadly I had to write this because `split-string-and-unquote'
+breaks with escaped quotes in compile_commands.json, such as in:
+
+ /usr/bin/c++ -DLLVM_VERSION_INFO=\\\\\\\"3.2svn\\\\\\\" <args>"
+ ;; everytime I write a function like this one, it makes me feel bad
+ (let* ((len (length cmd-line))
+ (spaces (string-to-list " \f\t\n\r\v"))
+ (first-not-spaces-re (concat "[^" spaces "]"))
+ (i 0)
+ ch
+ args cur-arg)
+ (while (< i len)
+ (setq ch (aref cmd-line i))
+ (cond
+ ((member ch spaces) ;spaces
+ (when cur-arg
+ (setq args (cons (apply 'string (nreverse cur-arg)) args)
+ cur-arg nil))
+ ;; move to the next char
+ (setq i (or (string-match-p first-not-spaces-re cmd-line i)
+ len)))
+ ((eq ch ?\") ;quoted string
+ (let ((endq (string-match-p "[^\\]\"" cmd-line i)))
+ (unless endq
+ (signal 'irony-parse-error (list "ill formed command line" cmd-line)))
+ (let ((quoted-str (substring cmd-line (1+ i) (1+ endq))))
+ (setq cur-arg (append (irony--split-command-line-1 quoted-str)
+ cur-arg)
+ i (+ endq 2)))))
+ (t ;a valid char
+ ;; if it's an escape of: a backslash, a quote or a space push
+ ;; only the following char.
+ (when (eq ch ?\\)
+ (let ((next-ch (and (< (1+ i) len)
+ (aref cmd-line (1+ i)))))
+ (when (or (member next-ch '(?\\ ?\"))
+ (member next-ch spaces))
+ (setq ch next-ch)
+ (cl-incf i))))
+ (push ch cur-arg)
+ (cl-incf i))))
+ (when cur-arg
+ (setq args (cons (apply 'string (nreverse cur-arg)) args)))
+ (nreverse args)))
+
+(defun irony--get-buffer-path-for-server (&optional buffer)
+ "Get the path of the current buffer to send to irony-server.
+
+If no such file exists on the filesystem the special file '-' is
+ returned instead."
+ (let ((file (buffer-file-name buffer)))
+ (if (and file (file-exists-p file))
+ file
+ "-")))
+
+
+;;
+;; Mode
+;;
+
+(defvar irony-mode-map (make-sparse-keymap)
+ "Keymap used in `irony-mode' buffers.")
+
+;;;###autoload
+(define-minor-mode irony-mode
+ "Minor mode for C, C++ and Objective-C, powered by libclang."
+ nil
+ irony-lighter
+ irony-mode-map
+ :group 'irony
+ (if irony-mode
+ (irony--mode-enter)
+ (irony--mode-exit)))
+
+(defun irony--mode-enter ()
+ ;; warn the user about modes such as php-mode who inherits c-mode
+ (when (not (memq major-mode irony-supported-major-modes))
+ (display-warning 'irony "Major mode is unknown to Irony,\
+ see `irony-supported-major-modes'."))
+ ;; warn the user about Windows-specific issues
+ (when (eq system-type 'windows-nt)
+ (cond
+ ((version< emacs-version "24.4")
+ (display-warning 'irony "Emacs >= 24.4 expected on Windows."))
+ ((and (boundp 'w32-pipe-read-delay) (> w32-pipe-read-delay 0))
+ (display-warning 'irony "Performance will be bad because a\
+ pipe delay is set for this platform (see variable\
+ `w32-pipe-read-delay')."))))
+ (irony-completion--enter))
+
+(defun irony--mode-exit ()
+ (irony-completion--exit))
+
+;;;###autoload
+(defun irony-version (&optional show-version)
+ "Return the version number of the file irony.el.
+
+If called interactively display the version in the echo area."
+ (interactive (list t))
+ ;; Shamelessly stolen from `company-mode'.
+ (with-temp-buffer
+ (insert-file-contents (find-library-name "irony"))
+ (let ((v (lm-version)))
+ (when show-version
+ (message "irony version: %s" v))
+ v)))
+
+
+;;
+;; Compile options handling
+;;
+
+(defun irony--lang-compile-option ()
+ (irony--awhen (cdr-safe (assq major-mode irony-lang-compile-option-alist))
+ (list "-x" it)))
+
+(defun irony--extract-working-directory-option (flags)
+ "Return working directory specified on the command line, if
+any."
+ (catch 'found
+ (while flags
+ (let ((flag (car flags)))
+ (cond
+ ((string= "-working-directory" flag)
+ (throw 'found (cadr flags)))
+ ((string-prefix-p "-working-directory=" flag)
+ (throw 'found (substring flag (length "-working-directory="))))
+ (t
+ (setq flags (cdr flags))))))))
+
+(defun irony--adjust-compile-options ()
+ "The compile options to send to libclang."
+ ;; TODO: if current buffer has no associated file (will be sent as '-') but is
+ ;; in an existing directory, we will want to add -I (directory-file-name
+ ;; buffer-file-name) to find the relative headers
+ (append
+ (irony--lang-compile-option)
+ (irony--awhen irony--working-directory
+ (unless (irony--extract-working-directory-option irony--compile-options)
+ (list "-working-directory" it)))
+ irony-additional-clang-options
+ irony--compile-options))
+
+(defun irony--extract-user-search-paths (compile-options work-dir)
+ "Retrieve the user search paths present in COMPILE-OPTIONS.
+
+Relative paths are expanded to be relative to WORK-DIR.
+
+The returned paths are returned as
+directory (`file-name-as-directory').
+
+Note: WORK-DIR is not used when the compile option
+'-working-directory=<directory>' is detected in COMPILE-OPTIONS."
+ (setq work-dir (or (irony--extract-working-directory-option compile-options)
+ work-dir))
+ (let (include-dirs opt)
+ (while (setq opt (car compile-options))
+ (cond
+ ((string= "-I" opt)
+ (add-to-list 'include-dirs (nth 1 compile-options) t)
+ (setq compile-options (cddr compile-options)))
+ ((string-prefix-p "-I" opt)
+ (add-to-list 'include-dirs (substring opt 2) t)
+ (setq compile-options (cdr compile-options)))
+ (t
+ (setq compile-options (cdr compile-options)))))
+ (delete-dups (mapcar #'(lambda (path)
+ (file-name-as-directory
+ (expand-file-name path work-dir)))
+ include-dirs))))
+
+
+;;
+;; Irony-Server setup
+;;
+
+(defvar irony--server-install-command-history nil)
+(defun irony--install-server-read-command (command)
+ (read-shell-command
+ "Install command: " command
+ (if (equal (car irony--server-install-command-history) command)
+ '(irony--server-install-command-history . 1)
+ 'irony--server-install-command-history)))
+
+(defun irony-install-server (command)
+ "Install or reinstall the Irony server.
+
+The installation requires CMake and the libclang development package."
+ (interactive
+ (list (let ((command
+ (format
+ (concat "%s %s %s %s && %s --build . "
+ "--use-stderr --config Release --target install")
+ (shell-quote-argument irony-cmake-executable)
+ (shell-quote-argument (concat "-DCMAKE_INSTALL_PREFIX="
+ (expand-file-name
+ irony-server-install-prefix)))
+ (mapconcat 'shell-quote-argument irony-extra-cmake-args " ")
+ (shell-quote-argument
+ (or irony-server-source-dir
+ (expand-file-name "server"
+ (file-name-directory
+ (find-library-name "irony")))))
+ (shell-quote-argument irony-cmake-executable))))
+ (irony--install-server-read-command command))))
+ (let ((build-dir (or irony-server-build-dir
+ (concat
+ (file-name-as-directory temporary-file-directory)
+ (file-name-as-directory (format "build-irony-server-%s"
+ (irony-version)))))))
+ (make-directory build-dir t)
+ (let ((default-directory build-dir))
+ ;; we need to kill the process to be able to install a new one,
+ ;; at least on Windows
+ (irony-server-kill)
+ (with-current-buffer (compilation-start command nil
+ #'(lambda (maj-mode)
+ "*irony-server build*"))
+ (setq-local compilation-finish-functions
+ '(irony--server-install-finish-function))))))
+
+(defun irony--server-install-finish-function (buffer msg)
+ (if (string= "finished\n" msg)
+ (message "irony-server installed successfully!")
+ (message "Failed to build irony-server, you are on your own buddy!")))
+
+(defun irony--find-server-executable ()
+ "Return the path to the irony-server executable.
+
+Throw an `irony-server-error' if a proper executable cannot be
+found."
+ (let* ((exec-path (cons (expand-file-name "bin" irony-server-install-prefix)
+ exec-path))
+ (exe (executable-find "irony-server")))
+ (condition-case err
+ (let ((version (car (process-lines exe "--version"))))
+ (if (and (string-match "^irony-server version " version)
+ (version= (irony-version)
+ (substring version
+ (length "irony-server version "))))
+ ;; irony-server is working and up-to-date!
+ exe
+ (signal 'irony-server-error
+ (list
+ (format "irony-server version mismatch: %s"
+ (substitute-command-keys
+ "type `\\[irony-install-server]' to reinstall"))))))
+ (irony-server-error
+ (signal (car err) (cdr err)))
+ (error
+ (signal 'irony-server-error
+ (if (and exe
+ (file-executable-p exe))
+ ;; failed to execute due to a runtime problem, i.e:
+ ;; libclang.so isn't in the ld paths
+ (list (format "irony-server is broken! %s"
+ (error-message-string err)))
+ ;; irony-server doesn't exists, first time irony-mode is used?
+ ;; inform the user about how to build the executable
+ (list
+ (format "irony-server not installed! %s"
+ (substitute-command-keys
+ "Type `\\[irony-install-server]' to install")))))))))
+
+
+;;
+;; irony-server process management.
+;;
+
+(defvar irony--server-executable nil)
+(defvar irony--server-process nil)
+(defvar irony--server-buffer " *Irony*"
+ "The name of the buffer for the irony process to run in.
+
+When using a leading space, the buffer is hidden from the buffer
+list (and undo information is not kept).")
+
+(defun irony--start-server-process ()
+ (unless irony--server-executable
+ ;; if not found, an `irony-server-error' error is signaled
+ (setq irony--server-executable (irony--find-server-executable)))
+ (let ((process-connection-type nil)
+ (process-adaptive-read-buffering nil)
+ (w32-pipe-buffer-size (when (boundp 'w32-pipe-buffer-size)
+ (or irony-server-w32-pipe-buffer-size
+ w32-pipe-buffer-size)))
+ process)
+ (setq process
+ (start-process-shell-command
+ "Irony" ;process name
+ irony--server-buffer ;buffer
+ (format "%s -i 2> %s" ;command
+ (shell-quote-argument irony--server-executable)
+ (expand-file-name
+ (format-time-string "irony.%Y-%m-%d_%Hh-%Mm-%Ss.log")
+ temporary-file-directory))))
+ (set-process-query-on-exit-flag process nil)
+ (irony-iotask-setup-process process)
+ process))
+
+;;;###autoload
+(defun irony-server-kill ()
+ "Kill the running irony-server process, if any."
+ (interactive)
+ (when (process-live-p irony--server-process)
+ (kill-process irony--server-process)
+ (setq irony--server-process nil)))
+
+(defun irony--get-server-process-create ()
+ (unless (process-live-p irony--server-process)
+ (setq irony--server-process (irony--start-server-process)))
+ irony--server-process)
+
+(defun irony--run-task (task)
+ (irony-iotask-run (irony--get-server-process-create) task))
+
+(defun irony--run-task-asynchronously (task callback)
+ (irony-iotask-schedule (irony--get-server-process-create) task callback))
+
+(defun irony--quote-strings (strings &optional separator)
+ "Like `combine-and-quote-strings', but when the string is \"\" or nil,
+`irony--quote-strings' will convert it to \"\" instead of <SPC>.
+That is:
+
+ (irony--quote-strings \'(\"a\" \"\" \"b\")) => \"a \\\"\\\" b\"
+ (combine-and-quote-strings \'(\"a\" \"\" \"b\")) => \"a b\"
+"
+ (let* ((sep (or separator " "))
+ (re (concat "[\\\"]" "\\|" (regexp-quote sep))))
+ (mapconcat
+ (lambda (str)
+ (cond
+ ((or (not str) (string= str ""))
+ "\"\"")
+ ((string-match re str)
+ (concat "\"" (replace-regexp-in-string "[\\\"]" "\\\\\\&" str) "\""))
+ (t str)))
+ strings sep)))
+
+(defun irony--server-send-command (command &rest args)
+ (let ((command-line (concat (irony--quote-strings
+ (mapcar (lambda (arg)
+ (if (numberp arg)
+ (number-to-string arg)
+ arg))
+ (cons command args)))
+ "\n")))
+ (irony-iotask-send-string command-line)))
+
+;; XXX: this code can run in very tight very sensitive on big inputs,
+;; every change should be measured
+(defun irony--server-command-update (&rest _args)
+ (when (and (>= (buffer-size) (length irony--eot))
+ (string-equal (buffer-substring-no-properties
+ (- (point-max) (length irony--eot)) (point-max))
+ irony--eot))
+ (condition-case-unless-debug nil
+ (let ((result (read (current-buffer))))
+ (cl-case (car result)
+ (success
+ (irony-iotask-set-result (cdr result)))
+ (error
+ (apply #'irony-iotask-set-error 'irony-server-error
+ (cdr result)))))
+ (error
+ (throw 'invalid-msg t)))))
+
+;; FIXME: code duplication with `irony--server-command-update'
+;; XXX: this code can run in very tight very sensitive on big inputs,
+;; every change should be measured
+(defun irony--server-query-update (&rest _args)
+ (when (and (>= (buffer-size) (length irony--eot))
+ (string-equal (buffer-substring-no-properties
+ (- (point-max) (length irony--eot)) (point-max))
+ irony--eot))
+ (condition-case-unless-debug nil
+ (irony-iotask-set-result (read (current-buffer)))
+ (error
+ (throw 'invalid-msg t)))))
+
+
+;;
+;; Server commands
+;;
+
+(irony-iotask-define-task irony--t-get-compile-options
+ "`get-compile-options' server command."
+ :start (lambda (build-dir file)
+ (irony--server-send-command "get-compile-options" build-dir file))
+ :update irony--server-command-update)
+
+(defun irony--get-compile-options-task (build-dir file)
+ (irony-iotask-package-task irony--t-get-compile-options build-dir file))
+
+(cl-defstruct (irony--buffer-state
+ (:constructor irony--buffer-state-create-1))
+ file
+ exists
+ modified
+ tick)
+
+(defun irony--buffer-state-create (buffer)
+ (let ((file (buffer-file-name buffer)))
+ (irony--buffer-state-create-1 :file file
+ :exists (and file (file-exists-p file))
+ :modified (buffer-modified-p buffer)
+ :tick (buffer-chars-modified-tick buffer))))
+
+(defun irony--buffer-state-compare (old new)
+ (unless (equal old new)
+ (cond
+ ((irony--buffer-state-modified new) 'set-unsaved)
+ ((null old) nil) ;noop
+ ((and
+ (irony--buffer-state-modified old)
+ (irony--buffer-state-exists old)) 'reset-unsaved))))
+
+(irony-iotask-define-task irony--t-set-unsaved
+ "`set-unsaved' server command."
+ :start (lambda (process buffer buf-state)
+ (let ((elem (assq buffer (process-get process :unsaved-buffers)))
+ temp-file)
+ (if (eq (cdr elem) buf-state)
+ ;; early exit if already cached
+ (irony-iotask-set-result t)
+ (setq temp-file (make-temp-file "irony-unsaved-"))
+ (irony-iotask-put :temp-file temp-file)
+ (irony-iotask-put :buffer-state buf-state)
+ (process-put process :buffer-state buf-state)
+ (with-current-buffer buffer
+ (irony--without-narrowing
+ (let ((write-region-inhibit-fsync t))
+ (write-region nil nil temp-file nil 0)))
+ (irony--server-send-command "set-unsaved"
+ (irony--get-buffer-path-for-server)
+ temp-file)))))
+ :update irony--server-command-update
+ :finish (lambda (&rest _args)
+ (delete-file (irony-iotask-get :temp-file)))
+ :on-success
+ (lambda (process buffer &rest _args)
+ (let* ((unsaved-buffers (process-get process :unsaved-buffers))
+ (elem (assq buffer unsaved-buffers))
+ (buf-state (irony-iotask-get :buffer-state)))
+ (if elem
+ (setcdr elem buf-state)
+ (process-put process :unsaved-buffers (cons (cons buffer buf-state)
+ unsaved-buffers))))))
+
+(defun irony--set-unsaved-task (process buffer buf-state)
+ (irony-iotask-package-task irony--t-set-unsaved process buffer buf-state))
+
+(irony-iotask-define-task irony--t-reset-unsaved
+ "`reset-unsaved' server command."
+ :start (lambda (process buffer)
+ (if (assq buffer (process-get process :unsaved-buffers))
+ (irony--server-send-command "reset-unsaved"
+ (irony--get-buffer-path-for-server
+ buffer))
+ ;; exit early if already reset
+ (irony-iotask-set-result t)))
+ :update irony--server-command-update
+ :finish (lambda (process buffer)
+ (process-put
+ process
+ :unsaved-buffers
+ (assq-delete-all buffer (process-get process :unsaved-buffers)))))
+
+(defun irony--reset-unsaved-task (process buffer)
+ (irony-iotask-package-task irony--t-reset-unsaved process buffer))
+
+(defun irony--list-unsaved-irony-mode-buffers (&optional ignore-list)
+ (delq nil (mapcar (lambda (buf)
+ (unless (memq buf ignore-list)
+ (when (buffer-modified-p buf)
+ (with-current-buffer buf
+ (and irony-mode buf)))))
+ (buffer-list))))
+
+(defun irony--get-buffer-change-alist (process)
+ "Return a list of (buffer . old-state).
+
+old-state can be nil if the old state isn't known."
+ (let ((unsaved-list (process-get process :unsaved-buffers)))
+ (append unsaved-list
+ (mapcar (lambda (buf)
+ (cons buf nil))
+ (irony--list-unsaved-irony-mode-buffers
+ (mapcar #'car unsaved-list))))))
+
+(defun irony--unsaved-buffers-tasks ()
+ (let ((process (irony--get-server-process-create))
+ result)
+ (dolist (buffer-old-state-cons (irony--get-buffer-change-alist process)
+ result)
+ (let* ((buffer (car buffer-old-state-cons))
+ (old-state (cdr buffer-old-state-cons))
+ (new-state (irony--buffer-state-create buffer))
+ (task
+ (cl-case (irony--buffer-state-compare old-state new-state)
+ (set-unsaved
+ (irony--set-unsaved-task process buffer new-state))
+ (reset-unsaved
+ (irony--reset-unsaved-task process buffer)))))
+ (when task
+ (setq result (if result
+ (irony-iotask-chain result task)
+ task)))))))
+
+(irony-iotask-define-task irony--t-parse
+ "`parse' server command."
+ :start (lambda (file compile-options)
+ (apply #'irony--server-send-command "parse" file "--"
+ compile-options))
+ :update irony--server-command-update)
+
+(defun irony--parse-task-1 (&optional buffer)
+ (with-current-buffer (or buffer (current-buffer))
+ (irony-iotask-package-task irony--t-parse
+ (irony--get-buffer-path-for-server)
+ (irony--adjust-compile-options))))
+
+(defun irony--parse-task (&optional buffer)
+ (let ((unsaved-tasks (irony--unsaved-buffers-tasks))
+ (parse-task (irony--parse-task-1 buffer)))
+ (if unsaved-tasks
+ (irony-iotask-chain unsaved-tasks parse-task)
+ parse-task)))
+
+(irony-iotask-define-task irony--t-diagnostics
+ "`parse' server command."
+ :start (lambda ()
+ (irony--server-send-command "diagnostics"))
+ :update irony--server-query-update)
+
+(defun irony--diagnostics-task (&optional buffer)
+ (irony-iotask-chain
+ (irony--parse-task buffer)
+ (irony-iotask-package-task irony--t-diagnostics)))
+
+(irony-iotask-define-task irony--t-get-type
+ "`get-type' server command."
+ :start (lambda (line col)
+ (irony--server-send-command "get-type" line col))
+ :update irony--server-query-update)
+
+(defun irony--get-type-task (&optional buffer pos)
+ (let ((line-column (irony--completion-line-column pos)))
+ (irony-iotask-chain
+ (irony--parse-task buffer)
+ (irony-iotask-package-task irony--t-get-type
+ (car line-column) (cdr line-column)))))
+
+;;;###autoload
+(defun irony-get-type ()
+ "Get the type of symbol under cursor."
+ (interactive)
+ (let ((types (irony--run-task (irony--get-type-task))))
+ (unless types
+ (user-error "Type not found"))
+ (if (and (cdr types) (not (string= (car types) (cadr types))))
+ (message "%s (aka '%s')" (car types) (cadr types))
+ (message "%s" (car types)))))
+
+(defun irony-parse-buffer-async (&optional callback)
+ "Parse the current buffer sending results to an optional
+ CALLBACK function."
+ (irony--run-task-asynchronously (irony--parse-task)
+ (or callback #'ignore)))
+
+(provide 'irony)
+
+;; Local Variables:
+;; byte-compile-warnings: (not cl-functions)
+;; End:
+
+;;; irony.el ends here
diff --git a/elpa/irony-20220110.849/irony.elc b/elpa/irony-20220110.849/irony.elc
new file mode 100644
index 0000000..1e85f29
--- /dev/null
+++ b/elpa/irony-20220110.849/irony.elc
Binary files differ
diff --git a/elpa/irony-20220110.849/server/.clang-format b/elpa/irony-20220110.849/server/.clang-format
new file mode 100644
index 0000000..68e7062
--- /dev/null
+++ b/elpa/irony-20220110.849/server/.clang-format
@@ -0,0 +1,8 @@
+BasedOnStyle: LLVM
+AllowShortFunctionsOnASingleLine: false
+AlwaysBreakTemplateDeclarations: true
+BinPackParameters: false
+BreakConstructorInitializersBeforeComma: true
+ConstructorInitializerAllOnOneLineOrOnePerLine: true
+ConstructorInitializerIndentWidth: 2
+IndentFunctionDeclarationAfterType: false
diff --git a/elpa/irony-20220110.849/server/.clang-tidy b/elpa/irony-20220110.849/server/.clang-tidy
new file mode 100644
index 0000000..57e038a
--- /dev/null
+++ b/elpa/irony-20220110.849/server/.clang-tidy
@@ -0,0 +1,24 @@
+Checks: '-*,readability-identifier-naming,misc-assert-side-effect,readability-container-size-empty'
+CheckOptions:
+ - key: readability-identifier-naming.TypedefCase
+ value: CamelCase
+ - key: readability-identifier-naming.StructCase
+ value: CamelCase
+ - key: readability-identifier-naming.ClassCase
+ value: CamelCase
+ - key: readability-identifier-naming.VariableCase
+ value: camelBack
+ - key: readability-identifier-naming.ParameterCase
+ value: camelBack
+ - key: readability-identifier-naming.FunctionCase
+ value: camelBack
+ - key: readability-identifier-naming.NamespaceCase
+ value: lower_case
+ - key: readability-identifier-naming.GlobalConstantCase
+ value: UPPER_CASE
+ - key: readability-identifier-naming.PrivateMemberSuffix
+ value: _
+ - key: misc-assert-side-effect.CheckFunctionCalls
+ value: 1
+ - key: misc-assert-side-effect.AssertMacros
+ value: 'assert'
diff --git a/elpa/irony-20220110.849/server/CMakeLists.txt b/elpa/irony-20220110.849/server/CMakeLists.txt
new file mode 100644
index 0000000..21f9c9f
--- /dev/null
+++ b/elpa/irony-20220110.849/server/CMakeLists.txt
@@ -0,0 +1,33 @@
+cmake_minimum_required(VERSION 3.0.2)
+
+project(IronyMode)
+
+set(CMAKE_MODULE_PATH
+ ${PROJECT_SOURCE_DIR}/cmake
+ ${PROJECT_SOURCE_DIR}/cmake/modules
+ ${CMAKE_MODULE_PATH})
+
+include(CTest)
+include(GNUInstallDirs)
+
+# Starting from CMake >= 3.1, if a specific standard is required,
+# it can be set from the command line with:
+# cmake -DCMAKE_CXX_STANDARD=[11|14|17]
+function(irony_target_set_cxx_standard target)
+ set(cxx_standard 11)
+ if (CMAKE_VERSION VERSION_LESS "3.1")
+ if (CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
+ target_compile_options(${target} PRIVATE -std=c++${cxx_standard})
+ endif()
+ elseif (CMAKE_VERSION VERSION_LESS "3.8")
+ set_property(TARGET ${target} PROPERTY CXX_STANDARD ${cxx_standard})
+ else()
+ target_compile_features(${target} PUBLIC cxx_std_${cxx_standard})
+ endif()
+endfunction()
+
+add_subdirectory(src)
+
+if (BUILD_TESTING)
+ add_subdirectory(test)
+endif()
diff --git a/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/LICENSE.TXT b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/LICENSE.TXT
new file mode 100644
index 0000000..a7f579f
--- /dev/null
+++ b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/LICENSE.TXT
@@ -0,0 +1,43 @@
+==============================================================================
+LLVM Release License
+==============================================================================
+University of Illinois/NCSA
+Open Source License
+
+Copyright (c) 2007-2016 University of Illinois at Urbana-Champaign.
+All rights reserved.
+
+Developed by:
+
+ LLVM Team
+
+ University of Illinois at Urbana-Champaign
+
+ http://llvm.org
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal with
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+ * Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimers.
+
+ * Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimers in the
+ documentation and/or other materials provided with the distribution.
+
+ * Neither the names of the LLVM Team, University of Illinois at
+ Urbana-Champaign, nor the names of its contributors may be used to
+ endorse or promote products derived from this Software without specific
+ prior written permission.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
+SOFTWARE.
diff --git a/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/README b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/README
new file mode 100644
index 0000000..ed43509
--- /dev/null
+++ b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/README
@@ -0,0 +1,12 @@
+Origin:
+- http://llvm.org/svn/llvm-project/clang-tools-extra/trunk/clang-tidy/tool/run-clang-tidy.py?p=294607
+- https://github.com/llvm-mirror/clang-tools-extra/blob/c2e903ec98385b82e35bdb303e411854a2e8c032/clang-tidy/tool/run-clang-tidy.py
+
+Modifications:
+- the python version has been frozen to python2,
+ as the script is not python3-compatible
+- added -warnings-as-errors option
+- the run-clang-tidy.py script has been modified
+ to return a sensible exit code when running on Travis CI,
+ i.e. it honors exit code of the underlying processes
+ causing build failures on pull requests
diff --git a/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/run-clang-tidy.py b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/run-clang-tidy.py
new file mode 100755
index 0000000..17db708
--- /dev/null
+++ b/elpa/irony-20220110.849/server/build-aux/run-clang-tidy/run-clang-tidy.py
@@ -0,0 +1,236 @@
+#!/usr/bin/env python2
+#
+#===- run-clang-tidy.py - Parallel clang-tidy runner ---------*- python -*--===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+# FIXME: Integrate with clang-tidy-diff.py
+
+"""
+Parallel clang-tidy runner
+==========================
+
+Runs clang-tidy over all files in a compilation database. Requires clang-tidy
+and clang-apply-replacements in $PATH.
+
+Example invocations.
+- Run clang-tidy on all files in the current working directory with a default
+ set of checks and show warnings in the cpp files and all project headers.
+ run-clang-tidy.py $PWD
+
+- Fix all header guards.
+ run-clang-tidy.py -fix -checks=-*,llvm-header-guard
+
+- Fix all header guards included from clang-tidy and header guards
+ for clang-tidy headers.
+ run-clang-tidy.py -fix -checks=-*,llvm-header-guard extra/clang-tidy \
+ -header-filter=extra/clang-tidy
+
+Compilation database setup:
+http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html
+"""
+
+import argparse
+import json
+import multiprocessing
+import os
+import Queue
+import re
+import shutil
+import subprocess
+import sys
+import tempfile
+import threading
+
+
+def find_compilation_database(path):
+ """Adjusts the directory until a compilation database is found."""
+ result = './'
+ while not os.path.isfile(os.path.join(result, path)):
+ if os.path.realpath(result) == '/':
+ print 'Error: could not find compilation database.'
+ sys.exit(1)
+ result += '../'
+ return os.path.realpath(result)
+
+
+def get_tidy_invocation(f, clang_tidy_binary, checks, tmpdir, build_path,
+ header_filter, extra_arg, extra_arg_before, quiet,
+ warnings_as_errors):
+ """Gets a command line for clang-tidy."""
+ start = [clang_tidy_binary]
+ if header_filter is not None:
+ start.append('-header-filter=' + header_filter)
+ else:
+ # Show warnings in all in-project headers by default.
+ start.append('-header-filter=^' + build_path + '/.*')
+ if checks:
+ start.append('-checks=' + checks)
+ if tmpdir is not None:
+ start.append('-export-fixes')
+ # Get a temporary file. We immediately close the handle so clang-tidy can
+ # overwrite it.
+ (handle, name) = tempfile.mkstemp(suffix='.yaml', dir=tmpdir)
+ os.close(handle)
+ start.append(name)
+ for arg in extra_arg:
+ start.append('-extra-arg=%s' % arg)
+ for arg in extra_arg_before:
+ start.append('-extra-arg-before=%s' % arg)
+ start.append('-p=' + build_path)
+ if quiet:
+ start.append('-quiet')
+ if warnings_as_errors is not None:
+ start.append('-warnings-as-errors=%s' % warnings_as_errors)
+ start.append(f)
+ return start
+
+
+def apply_fixes(args, tmpdir):
+ """Calls clang-apply-fixes on a given directory. Deletes the dir when done."""
+ invocation = [args.clang_apply_replacements_binary]
+ if args.format:
+ invocation.append('-format')
+ invocation.append(tmpdir)
+ ret = subprocess.call(invocation)
+ shutil.rmtree(tmpdir)
+ return ret
+
+
+def run_tidy(args, tmpdir, build_path, queue, results, i):
+ """Takes filenames out of queue and runs clang-tidy on them."""
+ results[i] = 0
+ while True:
+ name = queue.get()
+ invocation = get_tidy_invocation(name, args.clang_tidy_binary, args.checks,
+ tmpdir, build_path, args.header_filter,
+ args.extra_arg, args.extra_arg_before,
+ args.quiet, args.warnings_as_errors)
+ sys.stdout.write(' '.join(invocation) + '\n')
+ if subprocess.call(invocation) != 0:
+ results[i] = 1
+ queue.task_done()
+
+
+def main():
+ parser = argparse.ArgumentParser(description='Runs clang-tidy over all files '
+ 'in a compilation database. Requires '
+ 'clang-tidy and clang-apply-replacements in '
+ '$PATH.')
+ parser.add_argument('-clang-tidy-binary', metavar='PATH',
+ default='clang-tidy',
+ help='path to clang-tidy binary')
+ parser.add_argument('-clang-apply-replacements-binary', metavar='PATH',
+ default='clang-apply-replacements',
+ help='path to clang-apply-replacements binary')
+ parser.add_argument('-checks', default=None,
+ help='checks filter, when not specified, use clang-tidy '
+ 'default')
+ parser.add_argument('-header-filter', default=None,
+ help='regular expression matching the names of the '
+ 'headers to output diagnostics from. Diagnostics from '
+ 'the main file of each translation unit are always '
+ 'displayed.')
+ parser.add_argument('-warnings-as-errors', default=None, metavar='STRING',
+ help='Upgrades warnings to errors. '
+ 'Same format as "-checks".'
+ "This option's value is appended to the value of "
+ "the 'WarningsAsErrors' option in .clang-tidy "
+ "file, if any.'")
+ parser.add_argument('-j', type=int, default=0,
+ help='number of tidy instances to be run in parallel.')
+ parser.add_argument('files', nargs='*', default=['.*'],
+ help='files to be processed (regex on path)')
+ parser.add_argument('-fix', action='store_true', help='apply fix-its')
+ parser.add_argument('-format', action='store_true', help='Reformat code '
+ 'after applying fixes')
+ parser.add_argument('-p', dest='build_path',
+ help='Path used to read a compile command database.')
+ parser.add_argument('-extra-arg', dest='extra_arg',
+ action='append', default=[],
+ help='Additional argument to append to the compiler '
+ 'command line.')
+ parser.add_argument('-extra-arg-before', dest='extra_arg_before',
+ action='append', default=[],
+ help='Additional argument to prepend to the compiler '
+ 'command line.')
+ parser.add_argument('-quiet', action='store_true',
+ help='Run clang-tidy in quiet mode')
+ args = parser.parse_args()
+
+ db_path = 'compile_commands.json'
+
+ if args.build_path is not None:
+ build_path = args.build_path
+ else:
+ # Find our database
+ build_path = find_compilation_database(db_path)
+
+ try:
+ invocation = [args.clang_tidy_binary, '-list-checks']
+ invocation.append('-p=' + build_path)
+ if args.checks:
+ invocation.append('-checks=' + args.checks)
+ invocation.append('-')
+ print subprocess.check_output(invocation)
+ except:
+ print >>sys.stderr, "Unable to run clang-tidy."
+ sys.exit(1)
+
+ # Load the database and extract all files.
+ database = json.load(open(os.path.join(build_path, db_path)))
+ files = [entry['file'] for entry in database]
+
+ max_task = args.j
+ if max_task == 0:
+ max_task = multiprocessing.cpu_count()
+
+ tmpdir = None
+ if args.fix:
+ tmpdir = tempfile.mkdtemp()
+
+ # Build up a big regexy filter from all command line arguments.
+ file_name_re = re.compile('(' + ')|('.join(args.files) + ')')
+
+ try:
+ # Spin up a bunch of tidy-launching threads.
+ results = [None] * max_task
+ queue = Queue.Queue(max_task)
+ for i in range(max_task):
+ t = threading.Thread(target=run_tidy,
+ args=(args, tmpdir, build_path, queue, results, i))
+ t.daemon = True
+ t.start()
+
+ # Fill the queue with files.
+ for name in files:
+ if file_name_re.search(name):
+ queue.put(name)
+
+ # Wait for all threads to be done.
+ queue.join()
+
+ except KeyboardInterrupt:
+ # This is a sad hack. Unfortunately subprocess goes
+ # bonkers with ctrl-c and we start forking merrily.
+ print '\nCtrl-C detected, goodbye.'
+ if args.fix:
+ shutil.rmtree(tmpdir)
+ os.kill(0, 9)
+
+ for ret in results:
+ if ret != 0:
+ sys.exit(ret)
+
+ if args.fix:
+ print 'Applying fixes ...'
+ ret = apply_fixes(args, tmpdir)
+ if ret != 0:
+ sys.exit(ret)
+
+if __name__ == '__main__':
+ main()
diff --git a/elpa/irony-20220110.849/server/cmake/CheckClangResourceDir.cmake b/elpa/irony-20220110.849/server/cmake/CheckClangResourceDir.cmake
new file mode 100644
index 0000000..20bcda9
--- /dev/null
+++ b/elpa/irony-20220110.849/server/cmake/CheckClangResourceDir.cmake
@@ -0,0 +1,90 @@
+#
+# Get the Clang resource directory.
+#
+# If found the following variable will be set:
+# - CLANG_RESOURCE_DIR
+#
+set(CHECK_CLANG_RESOURCE_DIR_CHECKER_CODE_IN
+ ${CMAKE_CURRENT_LIST_DIR}/LibClangDiagnosticsChecker.cpp)
+
+function(check_clang_resource_dir)
+ if (CLANG_RESOURCE_DIR)
+ return() # already in cache
+ endif()
+
+ message(STATUS "Detecting Clang resource directory")
+ find_package (LibClang REQUIRED)
+
+ set(checker_code
+ ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/LibClangDiagnosticsChecker.cpp)
+ set(checked_file
+ "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/check-libclang-stddef.cpp")
+
+ configure_file(${CHECK_CLANG_RESOURCE_DIR_CHECKER_CODE_IN}
+ ${checker_code} COPYONLY)
+ file(WRITE "${checked_file}" "#include <stddef.h>\n")
+
+ # Paths stolen from Rip-Rip/clang_complete#getBuiltinHeaderPath()
+ find_path(CHECK_CLANG_RESOURCE_DIR include/stddef.h
+ NO_DEFAULT_PATH
+ # the default path, favor this one over the other, in case a specific
+ # libclang has been chosen.
+ HINTS "${LIBCLANG_LIBRARY_DIR}/../lib/clang"
+ # other, distribution specific, paths
+ PATHS
+ "${LIBCLANG_LIBRARY_DIR}/../clang" # Gentoo
+ "${LIBCLANG_LIBRARY_DIR}/clang" # openSUSE, Windows
+ "${LIBCLANG_LIBRARY_DIR}/" # Google
+ "/usr/lib64/clang" # x86_64 (openSUSE, Fedora)
+ "/usr/lib/clang"
+ PATH_SUFFIXES ${LIBCLANG_KNOWN_LLVM_VERSIONS})
+
+ if (CHECK_CLANG_RESOURCE_DIR)
+ # On Windows the paths weren't escaped correctly, similar to:
+ # http://public.kitware.com/pipermail/cmake/2006-February/008473.html
+ list(APPEND run_args -resource-dir \"${CHECK_CLANG_RESOURCE_DIR}\")
+ endif()
+
+ list(APPEND run_args ${checked_file})
+
+ try_run(
+ CHECK_CLANG_RESOURCE_DIR_NUM_DIAGNOSTICS
+ CHECK_CLANG_RESOURCE_DIR_COMPILE_RESULT
+ ${CMAKE_BINARY_DIR}
+ ${checker_code}
+ CMAKE_FLAGS
+ "-DINCLUDE_DIRECTORIES:STRING=${LIBCLANG_INCLUDE_DIRS}"
+ "-DLINK_LIBRARIES:STRING=${LIBCLANG_LIBRARIES}"
+ COMPILE_OUTPUT_VARIABLE compile_output
+ RUN_OUTPUT_VARIABLE run_output
+ ARGS ${run_args}
+ )
+
+ if (NOT CHECK_CLANG_RESOURCE_DIR_COMPILE_RESULT)
+ set(CHECK_CLANG_RESOURCE_DIR_NUM_DIAGNOSTICS 1)
+ endif()
+
+ if (CHECK_CLANG_RESOURCE_DIR_NUM_DIAGNOSTICS EQUAL 0)
+ message(STATUS "Detecting libclang builtin headers directory -- success")
+ if (CHECK_CLANG_RESOURCE_DIR)
+ set(CLANG_RESOURCE_DIR "${CHECK_CLANG_RESOURCE_DIR}"
+ CACHE INTERNAL "Clang resource directory.")
+ endif()
+ else()
+ message(STATUS "Detecting Clang resource directory -- fail")
+
+ if (NOT CHECK_CLANG_RESOURCE_DIR_COMPILE_RESULT)
+ message(WARNING "CheckClangResourceDir: failed to compile checker, please report.
+ Compile output:
+ ${compile_output}
+")
+ else()
+ message(WARNING "CheckClangResourceDir: unsupported configuration, please report.
+
+ Check with args: ${run_args}
+ Check output:
+ ${run_output}
+")
+ endif()
+ endif()
+endfunction()
diff --git a/elpa/irony-20220110.849/server/cmake/LibClangDiagnosticsChecker.cpp b/elpa/irony-20220110.849/server/cmake/LibClangDiagnosticsChecker.cpp
new file mode 100644
index 0000000..64ea7aa
--- /dev/null
+++ b/elpa/irony-20220110.849/server/cmake/LibClangDiagnosticsChecker.cpp
@@ -0,0 +1,47 @@
+/*
+ This program takes some forward its command line arguments to libclang and
+ returns the number of diagnostics that occured during the parsing.
+
+ It is used during CMake generation to adjust the default parameters to
+ libclang.
+*/
+
+#include <clang-c/Index.h>
+
+#include <stdio.h>
+
+int main(int argc, const char *argv[]) {
+ for (int i = 1; i < argc; ++i) {
+ fprintf(stdout, "argv[%d]: %s\n", i, argv[i]);
+ }
+
+ CXIndex Idx = clang_createIndex(0, 0);
+ CXTranslationUnit TU = clang_parseTranslationUnit(
+ Idx, NULL, &argv[1], argc - 1, 0, 0, CXTranslationUnit_None);
+ int NumDiagnostics;
+
+ if (TU == NULL) {
+ NumDiagnostics = 1;
+ fprintf(stderr, "failed to create translation unit!\n");
+ } else {
+ int i;
+
+ NumDiagnostics = clang_getNumDiagnostics(TU);
+
+ for (i = 0; i < NumDiagnostics; ++i) {
+ CXDiagnostic Diag = clang_getDiagnostic(TU, i);
+ CXString DiagStr =
+ clang_formatDiagnostic(Diag, clang_defaultDiagnosticDisplayOptions());
+
+ fprintf(stderr, "%s\n", clang_getCString(DiagStr));
+
+ clang_disposeString(DiagStr);
+ clang_disposeDiagnostic(Diag);
+ }
+
+ clang_disposeTranslationUnit(TU);
+ }
+
+ clang_disposeIndex(Idx);
+ return NumDiagnostics;
+}
diff --git a/elpa/irony-20220110.849/server/cmake/modules/FindLibClang.cmake b/elpa/irony-20220110.849/server/cmake/modules/FindLibClang.cmake
new file mode 100644
index 0000000..edc786d
--- /dev/null
+++ b/elpa/irony-20220110.849/server/cmake/modules/FindLibClang.cmake
@@ -0,0 +1,106 @@
+# Find libclang.
+#
+# This module defines the following variables:
+# LIBCLANG_FOUND - true if libclang has been found and can be used
+# LIBCLANG_KNOWN_LLVM_VERSIONS - known LLVM release numbers
+# LIBCLANG_INCLUDE_DIRS - the libclang include directories
+# LIBCLANG_LIBRARIES - the libraries needed to use libclang
+# LIBCLANG_LIBRARY_DIR - the path to the directory containing libclang
+#
+# This module defines the following IMPORTED target:
+# - irony_libclang
+
+# most recent versions come first
+# http://llvm.org/apt/
+set(LIBCLANG_KNOWN_LLVM_VERSIONS 9.0.0 9.0 9
+ 8.0.0 8.0 8
+ 7.0.1 7.0.0 7.0 7
+ 6.0.1 6.0.0 6.0 6
+ 5.0.2 5.0.1 5.0.0 5.0 5
+ 4.0.1 4.0.0 4.0 4
+ 3.9.1 3.9.0 3.9
+ 3.8.1 3.8.0 3.8
+ 3.7.1 3.7.0 3.7
+ 3.6.2 3.6.1 3.6.0 3.6
+ 3.5.2 3.5.1 3.5.0 3.5
+ 3.4.2 3.4.1 3.4
+ 3.3
+ 3.2
+ 3.1)
+
+set(libclang_llvm_header_search_paths)
+set(libclang_llvm_lib_search_paths
+ # LLVM Fedora
+ /usr/lib/llvm
+ )
+
+foreach (version ${LIBCLANG_KNOWN_LLVM_VERSIONS})
+ string(REPLACE "." "" undotted_version "${version}")
+ list(APPEND libclang_llvm_header_search_paths
+ # LLVM Debian/Ubuntu nightly packages: http://llvm.org/apt/
+ "/usr/lib/llvm-${version}/include/"
+ # LLVM MacPorts
+ "/opt/local/libexec/llvm-${version}/include"
+ # LLVM Homebrew
+ "/usr/local/Cellar/llvm/${version}/include"
+ # LLVM Homebrew/versions
+ "/usr/local/lib/llvm-${version}/include"
+ # FreeBSD ports versions
+ "/usr/local/llvm${undotted_version}/include"
+ # Gentoo clang-4
+ "/usr/lib/llvm/${version}/include"
+ )
+
+ list(APPEND libclang_llvm_lib_search_paths
+ # LLVM Debian/Ubuntu nightly packages: http://llvm.org/apt/
+ "/usr/lib/llvm-${version}/lib/"
+ # LLVM MacPorts
+ "/opt/local/libexec/llvm-${version}/lib"
+ # LLVM Homebrew
+ "/usr/local/Cellar/llvm/${version}/lib"
+ # LLVM Homebrew/versions
+ "/usr/local/lib/llvm-${version}/lib"
+ # FreeBSD ports versions
+ "/usr/local/llvm${undotted_version}/lib"
+ # Gentoo clang-4
+ "/usr/lib/llvm/${version}/lib"
+ )
+endforeach()
+
+find_path(LIBCLANG_INCLUDE_DIR clang-c/Index.h
+ PATHS ${libclang_llvm_header_search_paths}
+ PATH_SUFFIXES LLVM/include #Windows package from http://llvm.org/releases/
+ DOC "The path to the directory that contains clang-c/Index.h")
+
+find_library(LIBCLANG_LIBRARY
+ NAMES
+ # On Windows with MSVC, the import library uses the ".imp" file extension
+ # instead of the comon ".lib"
+ libclang.imp
+ libclang
+ clang
+ PATHS ${libclang_llvm_lib_search_paths}
+ PATH_SUFFIXES LLVM/lib #Windows package from http://llvm.org/releases/
+ DOC "The file that corresponds to the libclang library.")
+
+get_filename_component(LIBCLANG_LIBRARY_DIR ${LIBCLANG_LIBRARY} PATH)
+
+set(LIBCLANG_LIBRARIES ${LIBCLANG_LIBRARY})
+set(LIBCLANG_INCLUDE_DIRS ${LIBCLANG_INCLUDE_DIR})
+
+include(FindPackageHandleStandardArgs)
+# handle the QUIETLY and REQUIRED arguments and set LIBCLANG_FOUND to TRUE if
+# all listed variables are TRUE
+find_package_handle_standard_args(LibClang DEFAULT_MSG
+ LIBCLANG_LIBRARY LIBCLANG_INCLUDE_DIR)
+
+mark_as_advanced(LIBCLANG_INCLUDE_DIR LIBCLANG_LIBRARY)
+
+if (LIBCLANG_FOUND AND NOT TARGET irony_libclang)
+ add_library(irony_libclang UNKNOWN IMPORTED)
+ set_target_properties(irony_libclang PROPERTIES
+ IMPORTED_LINK_INTERFACE_LANGUAGES "CXX"
+ IMPORTED_LOCATION "${LIBCLANG_LIBRARY}"
+ INTERFACE_INCLUDE_DIRECTORIES "${LIBCLANG_INCLUDE_DIR}"
+ )
+endif()
diff --git a/elpa/irony-20220110.849/server/src/CMakeLists.txt b/elpa/irony-20220110.849/server/src/CMakeLists.txt
new file mode 100644
index 0000000..c516e70
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/CMakeLists.txt
@@ -0,0 +1,111 @@
+# XXX: if there are issues
+# due to https://reviews.llvm.org/D30911 / SVN Revision 298424
+# then use the fallback when LLVM_VERSION VERSION_LESS 5.0.1
+find_package(Clang)
+
+if (Clang_FOUND)
+ # XXX: at least since Clang 8.0.0
+ # it's looks like the 'libclang' IMPORTED target
+ # does not specify the following target property:
+ # INTERFACE_INCLUDE_DIRECTORIES ${CLANG_INCLUDE_DIRS}
+ # which is confirmed by https://github.com/Sarcasm/irony-mode/issues/530
+ # so we work around this,
+ # but ideally Clang upstream should export fully usable IMPORTED targets
+ add_library(irony_libclang INTERFACE)
+ target_link_libraries(irony_libclang INTERFACE libclang)
+ target_include_directories(irony_libclang INTERFACE ${CLANG_INCLUDE_DIRS})
+
+ get_property(IRONY_CLANG_EXECUTABLE TARGET clang PROPERTY LOCATION)
+ execute_process(
+ COMMAND "${IRONY_CLANG_EXECUTABLE}" -print-resource-dir
+ OUTPUT_VARIABLE CLANG_RESOURCE_DIR
+ OUTPUT_STRIP_TRAILING_WHITESPACE
+ )
+else()
+ # fallback to historically FindLibClang.cmake
+ # and -resource-dir guess mecanism
+ include(CheckClangResourceDir)
+ find_package(LibClang REQUIRED)
+ check_clang_resource_dir()
+endif()
+
+# not to be taken as a module-definition file to link on Windows
+set_source_files_properties(Commands.def PROPERTIES HEADER_FILE_ONLY TRUE)
+
+if(MSVC)
+ # irony-server uses some code that breaks when iterator debugging is enabled
+ #
+ # The culprit is CommandLineArgumentParser who initialize its member
+ # 'Position', of type 'std::string::const_iterator', to 'Input.begin() - 1'.
+ # With checked iterator the begin() - 1 breaks in debug build.
+ add_definitions(/D_ITERATOR_DEBUG_LEVEL=0)
+endif()
+
+add_executable(irony-server
+ support/CommandLineParser.cpp
+ support/CommandLineParser.h
+ support/iomanip_quoted.h
+ support/NonCopyable.h
+ support/CIndex.h
+ support/TemporaryFile.cpp
+ support/TemporaryFile.h
+
+ Command.cpp
+ Commands.def
+ Command.h
+ CompDBCache.h
+ CompDBCache.cpp
+ Irony.cpp
+ Irony.h
+ TUManager.cpp
+ TUManager.h
+
+ main.cpp)
+
+irony_target_set_cxx_standard(irony-server)
+
+target_include_directories(irony-server PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+
+# retrieve the package version from irony.el
+function(irony_find_package_version OUTPUT_VAR)
+ # this is a hack that force CMake to reconfigure, it is necessary to see if
+ # the version in irony.el has changed, this is not possible to add the
+ # definitions at build time
+ configure_file(${PROJECT_SOURCE_DIR}/../irony.el
+ ${CMAKE_CURRENT_BINARY_DIR}/irony.el
+ COPYONLY)
+
+ set(version_header "\;\; Version: ")
+ file(STRINGS ${CMAKE_CURRENT_BINARY_DIR}/irony.el version
+ LIMIT_COUNT 1
+ REGEX "^${version_header}*")
+
+ if (NOT version)
+ message (FATAL_ERROR "couldn't find irony.el's version header!")
+ endif()
+
+ string(LENGTH ${version_header} version_header_length)
+ string(SUBSTRING ${version} ${version_header_length} -1 package_version)
+ set(${OUTPUT_VAR} ${package_version} PARENT_SCOPE)
+endfunction()
+
+irony_find_package_version(IRONY_PACKAGE_VERSION)
+message(STATUS "Irony package version is '${IRONY_PACKAGE_VERSION}'")
+
+set_source_files_properties(main.cpp
+ PROPERTIES
+ COMPILE_DEFINITIONS IRONY_PACKAGE_VERSION=\"${IRONY_PACKAGE_VERSION}\")
+
+if (CLANG_RESOURCE_DIR)
+ # look for CLANG_RESOURCE_DIR_DIR usage in the code for an explanation
+ set_source_files_properties(TUManager.cpp
+ PROPERTIES
+ COMPILE_DEFINITIONS CLANG_RESOURCE_DIR=\"${CLANG_RESOURCE_DIR}\")
+endif()
+
+target_link_libraries(irony-server irony_libclang)
+
+set_target_properties(irony-server
+ PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})
+
+install(TARGETS irony-server DESTINATION ${CMAKE_INSTALL_BINDIR})
diff --git a/elpa/irony-20220110.849/server/src/Command.cpp b/elpa/irony-20220110.849/server/src/Command.cpp
new file mode 100644
index 0000000..363b6cb
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/Command.cpp
@@ -0,0 +1,278 @@
+/**
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * \brief Command parser definitions.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#include "Command.h"
+
+#include "support/CommandLineParser.h"
+
+#include <algorithm>
+#include <cstdlib>
+#include <functional>
+#include <iostream>
+#include <limits>
+#include <map>
+
+
+namespace {
+
+struct StringConverter {
+ StringConverter(std::string *dest) : dest_(dest) {
+ }
+
+ bool operator()(const std::string &str) {
+ *dest_ = str;
+ return true;
+ }
+
+private:
+ std::string *dest_;
+};
+
+struct UnsignedIntConverter {
+ UnsignedIntConverter(unsigned *dest) : dest_(dest) {
+ }
+
+ bool operator()(const std::string &str) {
+ char *end;
+ long num = std::strtol(str.c_str(), &end, 10);
+
+ if (end != (str.c_str() + str.size()))
+ return false;
+
+ if (errno == ERANGE)
+ return false;
+
+ if (num < 0)
+ return false;
+
+ unsigned long unum = static_cast<unsigned long>(num);
+ if (unum > std::numeric_limits<unsigned>::max())
+ return false;
+
+ *dest_ = unum;
+ return true;
+ }
+
+private:
+ unsigned *dest_;
+};
+
+/// Convert "on" and "off" to a boolean
+struct OptionConverter {
+ OptionConverter(bool *dest) : dest_(dest) {
+ }
+
+ bool operator()(const std::string &str) {
+ if (str == "on") {
+ *dest_ = true;
+ } else if (str == "off") {
+ *dest_ = false;
+ } else {
+ return false;
+ }
+ return true;
+ }
+
+private:
+ bool *dest_;
+};
+
+const std::map<std::string, PrefixMatchStyle> PREFIX_MATCH_STYLE_MAP = {
+ { "exact", PrefixMatchStyle::Exact },
+ { "case-insensitive", PrefixMatchStyle::CaseInsensitive },
+ { "smart-case", PrefixMatchStyle::SmartCase},
+};
+
+/// Convert style to a PrefixMatchStyle
+struct PrefixMatchStyleConverter {
+ PrefixMatchStyleConverter(PrefixMatchStyle *dest) : dest_(dest) {
+ }
+
+ bool operator()(const std::string &str) {
+ auto res = PREFIX_MATCH_STYLE_MAP.find(str);
+
+ if (res == PREFIX_MATCH_STYLE_MAP.cend()) {
+ return false;
+ }
+ *dest_ = res->second;
+ return true;
+ }
+
+private:
+ PrefixMatchStyle *dest_;
+};
+
+std::ostream &operator<<(std::ostream &os, PrefixMatchStyle style) {
+ for (auto it : PREFIX_MATCH_STYLE_MAP) {
+ if (it.second == style) {
+ os << it.first;
+ return os;
+ }
+ }
+ os << "UnknownStyle";
+ return os;
+}
+
+
+} // unnamed namespace
+
+std::ostream &operator<<(std::ostream &os, const Command::Action &action) {
+ os << "Command::";
+
+ switch (action) {
+#define X(sym, str, help) \
+ case Command::sym: \
+ os << #sym; \
+ break;
+#include "Commands.def"
+ }
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, const Command &command) {
+ os << "Command{action=" << command.action << ", "
+ << "file='" << command.file << "', "
+ << "unsavedFile='" << command.unsavedFile << "', "
+ << "dir='" << command.dir << "', "
+ << "line=" << command.line << ", "
+ << "column=" << command.column << ", "
+ << "prefix='" << command.prefix << "', "
+ << "caseStyle='" << command.style << "', "
+ << "flags=[";
+ bool first = true;
+ for (const std::string &flag : command.flags) {
+ if (!first)
+ os << ", ";
+ os << "'" << flag << "'";
+ first = false;
+ }
+ os << "], "
+ << "opt=" << (command.opt ? "on" : "off");
+
+ return os << "}";
+}
+
+static Command::Action actionFromString(const std::string &actionStr) {
+#define X(sym, str, help) \
+ if (actionStr == str) \
+ return Command::sym;
+
+#include "Commands.def"
+
+ return Command::Unknown;
+}
+
+CommandParser::CommandParser() : tempFile_("irony-server") {
+}
+
+Command *CommandParser::parse(const std::vector<std::string> &argv) {
+ command_.clear();
+
+ if (argv.begin() == argv.end()) {
+ std::clog << "error: no command specified.\n"
+ "See 'irony-server help' to list available commands\n";
+ return 0;
+ }
+
+ const std::string &actionStr = argv[0];
+
+ command_.action = actionFromString(actionStr);
+
+ bool readCompileOptions = false;
+ std::vector<std::function<bool(const std::string &)>> positionalArgs;
+
+ switch (command_.action) {
+ case Command::SetDebug:
+ positionalArgs.push_back(OptionConverter(&command_.opt));
+ break;
+
+ case Command::Parse:
+ positionalArgs.push_back(StringConverter(&command_.file));
+ readCompileOptions = true;
+ break;
+
+ case Command::Complete:
+ positionalArgs.push_back(StringConverter(&command_.file));
+ positionalArgs.push_back(UnsignedIntConverter(&command_.line));
+ positionalArgs.push_back(UnsignedIntConverter(&command_.column));
+ readCompileOptions = true;
+ break;
+
+ case Command::GetType:
+ positionalArgs.push_back(UnsignedIntConverter(&command_.line));
+ positionalArgs.push_back(UnsignedIntConverter(&command_.column));
+ break;
+
+ case Command::SetUnsaved:
+ positionalArgs.push_back(StringConverter(&command_.file));
+ positionalArgs.push_back(StringConverter(&command_.unsavedFile));
+ break;
+
+ case Command::ResetUnsaved:
+ positionalArgs.push_back(StringConverter(&command_.file));
+ break;
+
+ case Command::Candidates:
+ positionalArgs.push_back(StringConverter(&command_.prefix));
+ positionalArgs.push_back(PrefixMatchStyleConverter(&command_.style));
+ break;
+ case Command::CompletionDiagnostics:
+ case Command::Diagnostics:
+ case Command::Help:
+ case Command::Exit:
+ // no-arguments commands
+ break;
+
+ case Command::GetCompileOptions:
+ positionalArgs.push_back(StringConverter(&command_.dir));
+ positionalArgs.push_back(StringConverter(&command_.file));
+ break;
+
+ case Command::Unknown:
+ std::clog << "error: invalid command specified: " << actionStr << "\n";
+ return 0;
+ }
+
+ auto argsBegin = argv.begin() + 1;
+ const auto argsEnd = std::find(argsBegin, argv.end(), "--");
+ const int argCount = std::distance(argsBegin, argsEnd);
+
+ // compile options are provided after '--'
+ if (readCompileOptions && argsEnd != argv.end()) {
+ command_.flags.assign(std::next(argsEnd), argv.end());
+ }
+
+ if (argCount != static_cast<int>(positionalArgs.size())) {
+ std::clog << "error: invalid number of arguments for '" << actionStr
+ << "' (requires " << positionalArgs.size() << " got " << argCount
+ << ")\n";
+ return 0;
+ }
+
+ for (auto fn : positionalArgs) {
+ if (!fn(*argsBegin)) {
+ std::clog << "error: parsing command '" << actionStr
+ << "': invalid argument '" << *argsBegin << "'\n";
+ return 0;
+ }
+ ++argsBegin;
+ }
+
+ // '-' is used as a special file to inform that the buffer hasn't been saved
+ // on disk and only the buffer content is available. libclang needs a file, so
+ // this is treated as a special value for irony-server to create a temporary
+ // file for this. note that libclang will gladly accept '-' as a filename but
+ // we don't want to let this happen since irony already reads stdin.
+ if (command_.file == "-") {
+ command_.file = tempFile_.getPath();
+ }
+
+ return &command_;
+}
diff --git a/elpa/irony-20220110.849/server/src/Command.h b/elpa/irony-20220110.849/server/src/Command.h
new file mode 100644
index 0000000..9f36aa4
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/Command.h
@@ -0,0 +1,73 @@
+/**-*-C++-*-
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * \brief Command parser declarations.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#ifndef IRONY_MODE_SERVER_COMMAND_H_
+#define IRONY_MODE_SERVER_COMMAND_H_
+
+#include "support/CIndex.h"
+#include "support/TemporaryFile.h"
+#include "Style.h"
+
+#include <iosfwd>
+#include <string>
+#include <vector>
+
+class TemporaryFile;
+
+// TODO: a tagged union?
+struct Command {
+ Command() {
+ clear();
+ }
+
+ void clear() {
+ action = Unknown;
+ flags.clear();
+ file.clear();
+ unsavedFile.clear();
+ dir.clear();
+ prefix.clear();
+ style = PrefixMatchStyle::Exact;
+ line = 0;
+ column = 0;
+ opt = false;
+ }
+
+#define X(sym, str, desc) sym,
+ enum Action {
+#include "Commands.def"
+ } action;
+
+ std::vector<std::string> flags;
+ std::string file;
+ std::string unsavedFile;
+ std::string dir;
+ std::string prefix;
+ PrefixMatchStyle style;
+ unsigned line;
+ unsigned column;
+ bool opt;
+};
+
+std::ostream &operator<<(std::ostream &os, const Command::Action &action);
+std::ostream &operator<<(std::ostream &os, const Command &command);
+
+class CommandParser {
+public:
+ CommandParser();
+
+ Command *parse(const std::vector<std::string> &argv);
+
+private:
+ Command command_;
+ TemporaryFile tempFile_;
+};
+
+#endif // IRONY_MODE_SERVER_COMMAND_H_
diff --git a/elpa/irony-20220110.849/server/src/Commands.def b/elpa/irony-20220110.849/server/src/Commands.def
new file mode 100644
index 0000000..f99d8af
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/Commands.def
@@ -0,0 +1,39 @@
+/**-*-C++-*-
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * \brief Command list.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#ifndef X
+#error Please define the 'X(id, command, description)' macro before inclusion!
+#endif
+
+X(Candidates, "candidates",
+ "PREFIX STYLE - print completion candidates (require previous complete). "
+ "STYLE is \"exact\", \"case-insensitive\" or \"smart-case\"")
+X(Complete, "complete",
+ "FILE LINE COL [-- [COMPILE_OPTIONS...]] - perform code completion at a given location")
+X(CompletionDiagnostics, "completion-diagnostics",
+ "print the diagnostics generated during complete")
+X(Diagnostics, "diagnostics", "print the diagnostics of the last parse")
+X(Exit, "exit", "exit interactive mode, print nothing")
+X(GetCompileOptions, "get-compile-options", "BUILD_DIR FILE - "
+ "get compile options for FILE from JSON database in BUILD_DIR")
+X(GetType, "get-type", "LINE COL - get type of symbol at a given location")
+X(Help, "help", "show this message")
+X(Parse, "parse", "FILE [-- [COMPILE_OPTIONS...]] - parse the given file")
+X(ResetUnsaved, "reset-unsaved", "FILE - reset FILE, its content is up to date")
+X(SetDebug, "set-debug", "ON|OFF - enable or disable verbose logging")
+X(SetUnsaved,
+ "set-unsaved",
+ "FILE UNSAVED-CONTENT-FILE - tell irony-server that "
+ "UNSAVED-CONTENT-FILE contains the effective content of FILE")
+
+// sentinel value, should be the last one
+X(Unknown, "<unkown>", "<unspecified>")
+
+#undef X
diff --git a/elpa/irony-20220110.849/server/src/CompDBCache.cpp b/elpa/irony-20220110.849/server/src/CompDBCache.cpp
new file mode 100644
index 0000000..f79ec8c
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/CompDBCache.cpp
@@ -0,0 +1,71 @@
+#include "CompDBCache.h"
+
+#include <sys/stat.h>
+
+#include <cassert>
+
+CompDBCache::CompDBCache()
+ : db_(nullptr), mtime_(0) {
+}
+
+CompDBCache::~CompDBCache() {
+ clear();
+}
+
+CXCompilationDatabase CompDBCache::fromDirectory(const std::string &buildDir,
+ CXCompilationDatabase_Error *error) {
+ assert(error != nullptr);
+
+ const std::string jsonFilename = constructJsonDbFilename(buildDir);
+ const time_t mtime = modificationTime(jsonFilename);
+
+ if (jsonFilename == filename_ && mtime != 0 && mtime == mtime_) {
+ // Using the cached compilation database.
+ // Just set the provided error code to indicate success.
+ *error = CXCompilationDatabase_NoError;
+ } else {
+ clear();
+
+ db_ = clang_CompilationDatabase_fromDirectory(buildDir.c_str(), error);
+
+ if (mtime != 0 && *error == CXCompilationDatabase_NoError) {
+ // Successfully loaded a JSON compilation database.
+ // Cache the result.
+ filename_ = jsonFilename;
+ mtime_ = mtime;
+ }
+ }
+
+ return db_;
+}
+
+void CompDBCache::clear() {
+ if (db_) {
+ clang_CompilationDatabase_dispose(db_);
+ db_ = nullptr;
+ filename_.clear();
+ mtime_ = 0;
+ }
+}
+
+std::string CompDBCache::constructJsonDbFilename(const std::string &buildDir) const {
+ std::string ret = buildDir;
+ if (!buildDir.empty() && buildDir.back() != '/')
+ ret += '/';
+ ret += "compile_commands.json";
+ return ret;
+}
+
+time_t CompDBCache::modificationTime(const std::string &filename) const {
+ time_t mtime = 0;
+#ifdef _WIN32
+ struct _stat st;
+ const int statRes = _stat(filename.c_str(), &st);
+#else
+ struct stat st;
+ const int statRes = stat(filename.c_str(), &st);
+#endif
+ if (statRes == 0)
+ mtime = st.st_mtime;
+ return mtime;
+}
diff --git a/elpa/irony-20220110.849/server/src/CompDBCache.h b/elpa/irony-20220110.849/server/src/CompDBCache.h
new file mode 100644
index 0000000..568b790
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/CompDBCache.h
@@ -0,0 +1,86 @@
+/**-*-C++-*-
+ * \file
+ * \author Idar Tollefsen <idart@hotmail.com>
+ *
+ * \brief Creates a compilation database and caches it.
+ *
+ * Keeps a cache of the loaded compilation database, only creating a new
+ * one when needed.
+ *
+ * This file is distributed under the GNU General Public License.
+ * See COPYING for details.
+ */
+
+#ifndef IRONY_MODE_COMPDBCACHE_H_
+#define IRONY_MODE_COMPDBCACHE_H_
+
+#include "support/CIndex.h"
+#include "support/NonCopyable.h"
+
+#include <ctime>
+#include <string>
+
+class CompDBCache : public util::NonCopyable {
+public:
+ CompDBCache();
+ ~CompDBCache();
+
+ /**
+ * \brief Get a compilation database from a database found in a directory.
+ *
+ * This in essence a wrapper around
+ * \c clang_CompilationDatabase_fromDirectory() with added caching.
+ * It will either create a new compilation database or return the
+ * already loaded one (if any).
+ *
+ * This class owns the resulting compilation database.
+ * Therefore, unlike \c clang_CompilationDatabase_fromDirectory(),
+ * callers must NOT call \c clang_CompilationDatabase_dispose() on the
+ * returned compilation database. This class will handle that internally.
+ *
+ * \param buildDir Directory containing the database (such as
+ * "compile_commands.json") to create a compilation
+ * database from.
+ * \param error Error code from attempting to create a compilation
+ * database (\c CXCompilationDatabase_NoError on success).
+ *
+ * \return The compilation database or nullptr.
+ */
+ CXCompilationDatabase fromDirectory(const std::string &buildDir,
+ CXCompilationDatabase_Error *error);
+
+private:
+ /**
+ * \brief Clear the cache.
+ *
+ * This will dispose the currently loaded compilation database (if any) by
+ * calling \c clang_CompilationDatabase_dispose() on it. And it will reset
+ * other internal housekeeping variables related to the caching of the
+ * compilation database.
+ */
+ void clear();
+
+ /**
+ * \brief Construct JSON compilation database filename.
+ *
+ * \param buildDir Directory that might contain "compile_commands.json".
+ *
+ * \return Path to "compilation_commands.json" in \c buildDir.
+ */
+ std::string constructJsonDbFilename(const std::string &buildDir) const;
+
+ /**
+ * \brief Get modification time of a file.
+ *
+ * \param filename The file to get last modification time of.
+ *
+ * \return The modification time of \c filename or 0.
+ */
+ time_t modificationTime(const std::string &filename) const;
+
+ CXCompilationDatabase db_;
+ std::string filename_;
+ time_t mtime_;
+};
+
+#endif
diff --git a/elpa/irony-20220110.849/server/src/Irony.cpp b/elpa/irony-20220110.849/server/src/Irony.cpp
new file mode 100644
index 0000000..2157b32
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/Irony.cpp
@@ -0,0 +1,638 @@
+/**
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * \brief irony-server "API" definitions.
+ *
+ * \sa Irony.h for more information.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#include "Irony.h"
+
+#include "support/iomanip_quoted.h"
+
+#include <algorithm>
+#include <cassert>
+#include <iostream>
+#include <fstream>
+#include <cctype>
+
+namespace {
+
+std::string cxStringToStd(CXString cxString) {
+ std::string stdStr;
+
+ if (const char *cstr = clang_getCString(cxString)) {
+ stdStr = cstr;
+ }
+
+ clang_disposeString(cxString);
+ return stdStr;
+}
+
+const char *diagnosticSeverity(const CXDiagnostic &diagnostic) {
+ switch (clang_getDiagnosticSeverity(diagnostic)) {
+ case CXDiagnostic_Ignored:
+ return "ignored";
+ case CXDiagnostic_Note:
+ return "note";
+ case CXDiagnostic_Warning:
+ return "warning";
+ case CXDiagnostic_Error:
+ return "error";
+ case CXDiagnostic_Fatal:
+ return "fatal";
+ }
+
+ return "unknown";
+}
+
+void dumpDiagnostic(const CXDiagnostic &diagnostic) {
+ std::string file;
+ unsigned line = 0, column = 0, offset = 0;
+ CXSourceLocation location = clang_getDiagnosticLocation(diagnostic);
+ if (!clang_equalLocations(location, clang_getNullLocation())) {
+ CXFile cxFile;
+
+// clang_getInstantiationLocation() has been marked deprecated and
+// is aimed to be replaced by clang_getExpansionLocation().
+#if CINDEX_VERSION >= 6
+ clang_getExpansionLocation(location, &cxFile, &line, &column, &offset);
+#else
+ clang_getInstantiationLocation(location, &cxFile, &line, &column, &offset);
+#endif
+
+ file = cxStringToStd(clang_getFileName(cxFile));
+ }
+
+ const char *severity = diagnosticSeverity(diagnostic);
+
+ std::string message = cxStringToStd(clang_getDiagnosticSpelling(diagnostic));
+
+ std::cout << '(' << support::quoted(file) //
+ << ' ' << line //
+ << ' ' << column //
+ << ' ' << offset //
+ << ' ' << severity //
+ << ' ' << support::quoted(message) //
+ << ")\n";
+}
+
+bool readFileContent(const std::string &filename,
+ Irony::UnsavedBuffer &outBuf) {
+ std::ifstream ifs(filename.c_str(),
+ std::ios::in | std::ios::binary | std::ios::ate);
+
+ if (!ifs.is_open()) {
+ return false;
+ }
+
+ // FIXME: it's possible that this method of reading the file is 100% reliable,
+ // I can't confirm that tellg() is guaranteed to return a byte count.
+ // std::streamoff does not mention 'byte'.
+ // In practice it seems to work but this may be just luck.
+ // See also this discussion:
+ // - http://stackoverflow.com/questions/22984956/tellg-function-give-wrong-size-of-file/22986486#22986486
+ auto nbytes = ifs.tellg();
+
+ if (nbytes == std::ifstream::pos_type(-1)) {
+ return false;
+ }
+
+ outBuf.resize(nbytes);
+ ifs.seekg(0, std::ios::beg);
+
+ ifs.read(&outBuf[0], outBuf.size());
+
+ if (!ifs){
+ outBuf.clear();
+ return false;
+ }
+
+ return true;
+}
+
+} // unnamed namespace
+
+Irony::Irony()
+ : activeTu_(nullptr), activeCompletionResults_(nullptr), debug_(false) {
+}
+
+void Irony::parse(const std::string &file,
+ const std::vector<std::string> &flags) {
+ resetCache();
+ activeTu_ = tuManager_.parse(file, flags, cxUnsavedFiles_);
+ file_ = file;
+
+ if (activeTu_ == nullptr) {
+ std::cout << "(error . ("
+ << "parse-error"
+ << " \"failed to parse file\""
+ << " " << support::quoted(file) << "))\n";
+ return;
+ }
+
+ std::cout << "(success . t)\n";
+}
+
+void Irony::diagnostics() const {
+ unsigned diagnosticCount;
+
+ if (activeTu_ == nullptr) {
+ diagnosticCount = 0;
+ } else {
+ diagnosticCount = clang_getNumDiagnostics(activeTu_);
+ }
+
+ std::cout << "(\n";
+
+ for (unsigned i = 0; i < diagnosticCount; ++i) {
+ CXDiagnostic diagnostic = clang_getDiagnostic(activeTu_, i);
+
+ dumpDiagnostic(diagnostic);
+
+ clang_disposeDiagnostic(diagnostic);
+ }
+
+ std::cout << ")\n";
+}
+
+void Irony::resetCache() {
+ activeTu_ = nullptr;
+
+ if (activeCompletionResults_ != nullptr) {
+ clang_disposeCodeCompleteResults(activeCompletionResults_);
+ activeCompletionResults_ = nullptr;
+ }
+}
+
+void Irony::getType(unsigned line, unsigned col) const {
+ if (activeTu_ == nullptr) {
+ std::clog << "W: get-type - parse wasn't called\n";
+
+ std::cout << "nil\n";
+ return;
+ }
+
+ CXFile cxFile = clang_getFile(activeTu_, file_.c_str());
+ CXSourceLocation sourceLoc = clang_getLocation(activeTu_, cxFile, line, col);
+ CXCursor cursor = clang_getCursor(activeTu_, sourceLoc);
+
+ if (clang_Cursor_isNull(cursor)) {
+ // TODO: "error: no type at point"?
+ std::cout << "nil";
+ return;
+ }
+
+ CXType cxTypes[2];
+ cxTypes[0] = clang_getCursorType(cursor);
+ cxTypes[1] = clang_getCanonicalType(cxTypes[0]);
+
+ std::cout << "(";
+
+ for (const CXType &cxType : cxTypes) {
+ CXString typeDescr = clang_getTypeSpelling(cxType);
+ std::string typeStr = clang_getCString(typeDescr);
+ clang_disposeString(typeDescr);
+
+ if (typeStr.empty())
+ break;
+
+ std::cout << support::quoted(typeStr) << " ";
+ }
+
+ std::cout << ")\n";
+}
+
+namespace {
+
+class CompletionChunk {
+public:
+ explicit CompletionChunk(CXCompletionString completionString)
+ : completionString_(completionString)
+ , numChunks_(clang_getNumCompletionChunks(completionString_))
+ , chunkIdx_(0) {
+ }
+
+ bool hasNext() const {
+ return chunkIdx_ < numChunks_;
+ }
+
+ void next() {
+ if (!hasNext()) {
+ assert(0 && "out of range completion chunk");
+ abort();
+ }
+
+ ++chunkIdx_;
+ }
+
+ CXCompletionChunkKind kind() const {
+ return clang_getCompletionChunkKind(completionString_, chunkIdx_);
+ }
+
+ // TODO: operator>> so that one can re-use string allocated buffer
+ std::string text() const {
+ return cxStringToStd(
+ clang_getCompletionChunkText(completionString_, chunkIdx_));
+ }
+
+private:
+ CXCompletionString completionString_;
+ unsigned int numChunks_;
+ unsigned chunkIdx_;
+};
+
+} // unnamed namespace
+
+void Irony::complete(const std::string &file,
+ unsigned line,
+ unsigned col,
+ const std::vector<std::string> &flags) {
+ resetCache();
+
+ if (CXTranslationUnit tu =
+ tuManager_.getOrCreateTU(file, flags, cxUnsavedFiles_)) {
+ activeCompletionResults_ =
+ clang_codeCompleteAt(tu,
+ file.c_str(),
+ line,
+ col,
+ const_cast<CXUnsavedFile *>(cxUnsavedFiles_.data()),
+ cxUnsavedFiles_.size(),
+ (clang_defaultCodeCompleteOptions() &
+ ~CXCodeComplete_IncludeCodePatterns)
+#if HAS_BRIEF_COMMENTS_IN_COMPLETION
+ |
+ CXCodeComplete_IncludeBriefComments
+#endif
+ );
+ }
+
+ if (activeCompletionResults_ == nullptr) {
+ std::cout << "(error . ("
+ << "complete-error"
+ << " \"failed to perform code completion\""
+ << " " << support::quoted(file) << " " << line << " " << col
+ << "))\n";
+ return;
+ }
+
+ clang_sortCodeCompletionResults(activeCompletionResults_->Results,
+ activeCompletionResults_->NumResults);
+
+ std::cout << "(success . t)\n";
+}
+
+namespace {
+
+bool hasUppercase(const std::string &prefix)
+{
+ for (char c : prefix) {
+ if (std::isupper(c)) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool isEqual(const bool insensitive, const char a, const char b)
+{
+ if (insensitive) {
+ return std::tolower(a) == std::tolower(b);
+ } else {
+ return a == b;
+ }
+}
+
+bool startsWith(const std::string& str, const std::string &prefix, bool caseInsensitive)
+{
+ if (str.length() < prefix.length()) {
+ return false;
+ }
+
+ const auto charCmp = [&](const char a, const char b) {
+ return isEqual(caseInsensitive, a, b);
+ };
+
+ auto res = std::mismatch(prefix.begin(), prefix.end(), str.begin(), charCmp);
+ return res.first == prefix.end();
+}
+
+bool isStyleCaseInsensitive(const std::string &prefix, PrefixMatchStyle style)
+{
+ if (style == PrefixMatchStyle::SmartCase) {
+ // For SmartCase style, do case insensitive matching only there isn't upper
+ // case letter.
+ if (!hasUppercase(prefix)) {
+ style = PrefixMatchStyle::CaseInsensitive;
+ }
+ }
+ return style == PrefixMatchStyle::CaseInsensitive;
+}
+
+} // unnamed namespace
+
+void Irony::completionDiagnostics() const {
+ unsigned diagnosticCount;
+
+ if (activeCompletionResults_ == nullptr) {
+ diagnosticCount = 0;
+ } else {
+ diagnosticCount =
+ clang_codeCompleteGetNumDiagnostics(activeCompletionResults_);
+ }
+
+ std::cout << "(\n";
+
+ for (unsigned i = 0; i < diagnosticCount; ++i) {
+ CXDiagnostic diagnostic =
+ clang_codeCompleteGetDiagnostic(activeCompletionResults_, i);
+
+ dumpDiagnostic(diagnostic);
+ clang_disposeDiagnostic(diagnostic);
+ }
+
+ std::cout << ")\n";
+}
+
+void Irony::candidates(const std::string &prefix, PrefixMatchStyle style) const {
+ if (activeCompletionResults_ == nullptr) {
+ std::cout << "nil\n";
+ return;
+ }
+
+ bool caseInsensitive = isStyleCaseInsensitive(prefix, style);
+
+ CXCodeCompleteResults *completions = activeCompletionResults_;
+
+ std::cout << "(\n";
+
+ // re-use the same buffers to avoid unnecessary allocations
+ std::string typedtext, brief, resultType, prototype, postCompCar;
+
+ std::vector<unsigned> postCompCdr;
+
+ for (unsigned i = 0; i < completions->NumResults; ++i) {
+ CXCompletionResult candidate = completions->Results[i];
+ CXAvailabilityKind availability =
+ clang_getCompletionAvailability(candidate.CompletionString);
+
+ unsigned priority =
+ clang_getCompletionPriority(candidate.CompletionString);
+ unsigned annotationStart = 0;
+ bool typedTextSet = false;
+ bool hasPrefix = true;
+
+
+ if (availability == CXAvailability_NotAccessible ||
+ availability == CXAvailability_NotAvailable) {
+ continue;
+ }
+
+ typedtext.clear();
+ brief.clear();
+ resultType.clear();
+ prototype.clear();
+ postCompCar.clear();
+ postCompCdr.clear();
+
+ for (CompletionChunk chunk(candidate.CompletionString); chunk.hasNext();
+ chunk.next()) {
+ char ch = 0;
+
+ auto chunkKind = chunk.kind();
+
+ switch (chunkKind) {
+ case CXCompletionChunk_ResultType:
+ resultType = chunk.text();
+ break;
+
+ case CXCompletionChunk_TypedText:
+ case CXCompletionChunk_Text:
+ case CXCompletionChunk_Placeholder:
+ case CXCompletionChunk_Informative:
+ case CXCompletionChunk_CurrentParameter:
+ prototype += chunk.text();
+ break;
+
+ case CXCompletionChunk_LeftParen: ch = '('; break;
+ case CXCompletionChunk_RightParen: ch = ')'; break;
+ case CXCompletionChunk_LeftBracket: ch = '['; break;
+ case CXCompletionChunk_RightBracket: ch = ']'; break;
+ case CXCompletionChunk_LeftBrace: ch = '{'; break;
+ case CXCompletionChunk_RightBrace: ch = '}'; break;
+ case CXCompletionChunk_LeftAngle: ch = '<'; break;
+ case CXCompletionChunk_RightAngle: ch = '>'; break;
+ case CXCompletionChunk_Comma: ch = ','; break;
+ case CXCompletionChunk_Colon: ch = ':'; break;
+ case CXCompletionChunk_SemiColon: ch = ';'; break;
+ case CXCompletionChunk_Equal: ch = '='; break;
+ case CXCompletionChunk_HorizontalSpace: ch = ' '; break;
+ case CXCompletionChunk_VerticalSpace: ch = '\n'; break;
+
+ case CXCompletionChunk_Optional:
+ // ignored for now
+ break;
+ }
+
+ if (ch != 0) {
+ prototype += ch;
+ // commas look better followed by a space
+ if (ch == ',') {
+ prototype += ' ';
+ }
+ }
+
+ if (typedTextSet) {
+ if (ch != 0) {
+ postCompCar += ch;
+ if (ch == ',') {
+ postCompCar += ' ';
+ }
+ } else if (chunkKind == CXCompletionChunk_Text ||
+ chunkKind == CXCompletionChunk_TypedText) {
+ postCompCar += chunk.text();
+ } else if (chunkKind == CXCompletionChunk_Placeholder ||
+ chunkKind == CXCompletionChunk_CurrentParameter) {
+ postCompCdr.push_back(postCompCar.size());
+ postCompCar += chunk.text();
+ postCompCdr.push_back(postCompCar.size());
+ }
+ }
+
+ // Consider only the first typed text. The CXCompletionChunk_TypedText
+ // doc suggests that exactly one typed text will be given but at least
+ // in Objective-C it seems that more than one can appear, see:
+ // https://github.com/Sarcasm/irony-mode/pull/78#issuecomment-37115538
+ if (chunkKind == CXCompletionChunk_TypedText && !typedTextSet) {
+ typedtext = chunk.text();
+ if (!startsWith(typedtext, prefix, caseInsensitive)) {
+ hasPrefix = false;
+ break;
+ }
+ // annotation is what comes after the typedtext
+ annotationStart = prototype.size();
+ typedTextSet = true;
+ }
+ }
+
+ if (!hasPrefix) {
+ continue;
+ }
+ if (!typedTextSet) {
+ // clang may generate candidates without any typedText, and we may
+ // generate some output like:
+ // ("" 1 "bool" "" "hasUppercase(const std::string &prefix)"
+ // 0 ("") available)
+ // That will cause infinite completion in irony.el
+ continue;
+ }
+
+#if HAS_BRIEF_COMMENTS_IN_COMPLETION
+ brief = cxStringToStd(
+ clang_getCompletionBriefComment(candidate.CompletionString));
+#endif
+
+ // see irony-completion.el#irony-completion-candidates
+ std::cout << '(' << support::quoted(typedtext)
+ << ' ' << priority
+ << ' ' << support::quoted(resultType)
+ << ' ' << support::quoted(brief)
+ << ' ' << support::quoted(prototype)
+ << ' ' << annotationStart
+ << " (" << support::quoted(postCompCar);
+ for (unsigned index : postCompCdr)
+ std::cout << ' ' << index;
+ std::cout << ")"
+ << ")\n";
+ }
+
+ std::cout << ")\n";
+}
+
+void Irony::computeCxUnsaved() {
+ cxUnsavedFiles_.clear();
+
+ for (const auto &p : filenameToContent_) {
+ CXUnsavedFile cxUnsavedFile;
+
+ cxUnsavedFile.Filename = p.first.c_str();
+ cxUnsavedFile.Contents = p.second.data();
+ cxUnsavedFile.Length = p.second.size();
+ cxUnsavedFiles_.push_back(cxUnsavedFile);
+ }
+}
+
+void Irony::setUnsaved(const std::string &file,
+ const std::string &unsavedContentFile) {
+ resetCache();
+
+ UnsavedBuffer content;
+ if (!readFileContent(unsavedContentFile, content)) {
+ filenameToContent_.erase(file);
+ std::cout << "(error . ("
+ << "file-read-error"
+ << " \"failed to read unsaved buffer\""
+ << " " << support::quoted(file) << " "
+ << support::quoted(unsavedContentFile) << ")\n";
+ } else {
+ filenameToContent_[file] = content;
+ std::cout << "(success . t)\n";
+ }
+
+ computeCxUnsaved();
+}
+
+void Irony::resetUnsaved(const std::string &file) {
+ resetCache();
+
+ const auto erasedCount = filenameToContent_.erase(file);
+
+ if (erasedCount == 0) {
+ std::cout << "(error . ("
+ << "no-such-entry"
+ << " \"failed reset unsaved buffer\""
+ << " " << support::quoted(file) << ")\n";
+ } else {
+ std::cout << "(success . t)\n";
+ }
+
+ computeCxUnsaved();
+}
+
+void Irony::getCompileOptions(const std::string &buildDir,
+ const std::string &file) const {
+#if !(HAS_COMPILATION_DATABASE)
+
+ (void)buildDir;
+ (void)file;
+
+ CXString cxVersionString = clang_getClangVersion();
+
+ std::cout << "(error . ("
+ << "unsupported"
+ << " \"compilation database requires Clang >= 3.2\""
+ << " " << support::quoted(clang_getCString(cxVersionString))
+ << "))\n";
+
+ clang_disposeString(cxVersionString);
+
+ return;
+
+#else
+ CXCompilationDatabase_Error error;
+ CXCompilationDatabase db =
+ compDBCache_.fromDirectory(buildDir.c_str(), &error);
+
+ switch (error) {
+ case CXCompilationDatabase_CanNotLoadDatabase:
+ std::cout << "(error . ("
+ << "cannot-load-database"
+ << " \"failed to load compilation database from directory\""
+ << " " << support::quoted(buildDir) << "))\n";
+ return;
+
+ case CXCompilationDatabase_NoError:
+ break;
+ }
+
+ CXCompileCommands compileCommands =
+ clang_CompilationDatabase_getCompileCommands(db, file.c_str());
+
+ std::cout << "(success . (\n";
+
+ for (unsigned i = 0, numCompileCommands =
+ clang_CompileCommands_getSize(compileCommands);
+ i < numCompileCommands; ++i) {
+ CXCompileCommand compileCommand =
+ clang_CompileCommands_getCommand(compileCommands, i);
+
+ std::cout << "("
+ << "(";
+ for (unsigned j = 0,
+ numArgs = clang_CompileCommand_getNumArgs(compileCommand);
+ j < numArgs; ++j) {
+ CXString arg = clang_CompileCommand_getArg(compileCommand, j);
+ std::cout << support::quoted(clang_getCString(arg)) << " ";
+ clang_disposeString(arg);
+ }
+
+ std::cout << ")"
+ << " . ";
+
+ CXString directory = clang_CompileCommand_getDirectory(compileCommand);
+ std::cout << support::quoted(clang_getCString(directory));
+ clang_disposeString(directory);
+
+ std::cout << ")\n";
+ }
+
+ std::cout << "))\n";
+
+ clang_CompileCommands_dispose(compileCommands);
+#endif
+}
diff --git a/elpa/irony-20220110.849/server/src/Irony.h b/elpa/irony-20220110.849/server/src/Irony.h
new file mode 100644
index 0000000..66968f5
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/Irony.h
@@ -0,0 +1,147 @@
+/**-*-C++-*-
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * \brief irony-server "API" declarations.
+ *
+ * Contains the commands that the Emacs package relies on. These commands are
+ * mostly wrappers around a subset of the features provided by libclang. Command
+ * results are printed to \c std::cout as s-expr, in order to make it easy for
+ * Emacs to consume.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#ifndef IRONY_MODE_SERVER_IRONY_H_
+#define IRONY_MODE_SERVER_IRONY_H_
+
+#include "TUManager.h"
+
+#include "CompDBCache.h"
+#include "Style.h"
+
+#include <string>
+#include <vector>
+
+class Irony {
+public:
+ // use std::string over std::vector<char> because I have some doubts
+ // that libclang expect unsaved buffers to be a null terminated C strings
+ typedef std::string UnsavedBuffer;
+
+public:
+ Irony();
+
+ bool isDebugEnabled() const {
+ return debug_;
+ }
+
+ /// \name Command
+ /// \{
+
+ /// \brief Set or unset debugging of commands.
+ void setDebug(bool enable) {
+ debug_ = enable;
+ }
+
+ /// Parse or reparse the given file and compile options.
+ ///
+ /// If the compile options have changed, the translation unit is re-created to
+ /// take this into account.
+ ///
+ /// Output \c nil or \c t, whether or not parsing the translation unit
+ /// succeeded.
+ ///
+ /// \sa diagnostics(), getType()
+ void parse(const std::string &file, const std::vector<std::string> &flags);
+
+ /// Parse the given file for code completion.
+ ///
+ /// Shares the same semantics and output as \c parse().
+ ///
+ /// \sa candidates(), completionDiagnostics()
+ void complete(const std::string &file,
+ unsigned line,
+ unsigned col,
+ const std::vector<std::string> &flags);
+
+ void setUnsaved(const std::string &file,
+ const std::string &unsavedContentFile);
+
+ void resetUnsaved(const std::string &file);
+
+ /// \}
+
+ /// \name Queries
+ /// \{
+
+ /// \brief Retrieve the last parse diagnostics for the given file.
+ ///
+ /// \pre parse() was called.
+ void diagnostics() const;
+
+ /// \brief Get types of symbol at a given location.
+ ///
+ /// Example:
+ ///
+ /// \code
+ /// typedef int MyType;
+ /// MyType a;
+ /// \endcode
+ ///
+ /// Type of cursor location for 'a' is:
+ ///
+ /// \code{.el}
+ /// ("MyType" "int")
+ /// \endcode
+ ///
+ /// TODO: test with CXString(), seems to be twice the same string
+ ///
+ void getType(unsigned line, unsigned col) const;
+
+ /// Get all the completion candidates.
+ ///
+ /// \pre complete() was called.
+ void candidates(const std::string &prefix, PrefixMatchStyle style) const;
+
+ /// Get the diagnostics produced by the last \c complete().
+ ///
+ /// \pre complete() was called.
+ void completionDiagnostics() const;
+
+ /// \brief Get compile options from JSON database.
+ ///
+ /// \param buildDir Directory containing compile_commands.json
+ /// \param file File to obtain compile commands for.
+ ///
+ /// Example output:
+ ///
+ /// \code{.el}
+ /// (
+ /// (("-Wfoo" "-DBAR" "-Iqux") . "/path/to/working/directory")
+ /// (("-Wfoo-alt" "-DBAR_ALT" "-Iqux/alt") . "/alt/working/directory")
+ /// )
+ /// \endcode
+ ///
+ void getCompileOptions(const std::string &buildDir,
+ const std::string &file) const;
+
+ /// \}
+
+private:
+ void resetCache();
+ void computeCxUnsaved();
+
+private:
+ mutable CompDBCache compDBCache_;
+ TUManager tuManager_;
+ std::map<std::string, UnsavedBuffer> filenameToContent_;
+ CXTranslationUnit activeTu_;
+ std::string file_;
+ std::vector<CXUnsavedFile> cxUnsavedFiles_;
+ CXCodeCompleteResults *activeCompletionResults_;
+ bool debug_;
+};
+
+#endif // IRONY_MODE_SERVER_IRONY_H_
diff --git a/elpa/irony-20220110.849/server/src/Style.h b/elpa/irony-20220110.849/server/src/Style.h
new file mode 100644
index 0000000..52adb5e
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/Style.h
@@ -0,0 +1,17 @@
+/**-*-C++-*-
+ * \file
+ *
+ * \brief Style definition.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+#ifndef IRONY_MODE_SERVER_STYLE_H_
+#define IRONY_MODE_SERVER_STYLE_H_
+
+enum class PrefixMatchStyle {
+ Exact, CaseInsensitive, SmartCase,
+};
+
+
+#endif //IRONY_MODE_SERVER_STYLE_H_
diff --git a/elpa/irony-20220110.849/server/src/TUManager.cpp b/elpa/irony-20220110.849/server/src/TUManager.cpp
new file mode 100644
index 0000000..afbdc82
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/TUManager.cpp
@@ -0,0 +1,182 @@
+/**
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * \brief See TUManager.hh
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ *
+ */
+
+#include "TUManager.h"
+
+#include <iostream>
+
+TUManager::TUManager()
+ : index_(clang_createIndex(0, 0))
+ , translationUnits_()
+ , parseTUOptions_(clang_defaultEditingTranslationUnitOptions()) {
+
+ // this seems necessary to trigger "correct" reparse (/codeCompleteAt)
+ // clang_reparseTranslationUnit documentation states:
+ //
+ // > * \param TU The translation unit whose contents will be re-parsed. The
+ // > * translation unit must originally have been built with
+ // > * \c clang_createTranslationUnitFromSourceFile().
+ //
+ // clang_createTranslationUnitFromSourceFile() is just a call to
+ // clang_parseTranslationUnit() with
+ // CXTranslationUnit_DetailedPreprocessingRecord enabled but because we want
+ // some other flags to be set we can't just call
+ // clang_createTranslationUnitFromSourceFile()
+ parseTUOptions_ |= CXTranslationUnit_DetailedPreprocessingRecord;
+
+#if HAS_BRIEF_COMMENTS_IN_COMPLETION
+ parseTUOptions_ |= CXTranslationUnit_IncludeBriefCommentsInCodeCompletion;
+#endif
+
+ // XXX: A bug in old version of Clang (at least '3.1-8') caused the completion
+ // to fail on the standard library types when
+ // CXTranslationUnit_PrecompiledPreamble is used. We disable this option for
+ // old versions of libclang. As a result the completion will work but
+ // significantly slower.
+ //
+ // -- https://github.com/Sarcasm/irony-mode/issues/4
+ if (CINDEX_VERSION < 6) {
+ parseTUOptions_ &= ~CXTranslationUnit_PrecompiledPreamble;
+ }
+
+#if CINDEX_VERSION >= 34
+ // Keep going even after fatal errors, or syntax checking will stop after the
+ // first error. For instance unused variables will not be reported until the
+ // error has been fixed.
+ parseTUOptions_ |= CXTranslationUnit_KeepGoing;
+#endif
+}
+
+TUManager::~TUManager() {
+ clang_disposeIndex(index_);
+}
+
+CXTranslationUnit &TUManager::tuRef(const std::string &filename,
+ const std::vector<std::string> &flags) {
+ CXTranslationUnit &tu = translationUnits_[filename];
+
+ // if the flags changed since the last time, invalidate the translation unit
+ auto &flagsCache = flagsPerFileCache_[filename];
+ if (flagsCache.size() != flags.size() ||
+ !std::equal(flagsCache.begin(), flagsCache.end(), flags.begin())) {
+ if (tu) {
+ clang_disposeTranslationUnit(tu);
+ tu = nullptr;
+ }
+ // remember the flags for the next parse
+ flagsCache = flags;
+ }
+ return tu;
+}
+
+CXTranslationUnit
+TUManager::parse(const std::string &filename,
+ const std::vector<std::string> &flags,
+ const std::vector<CXUnsavedFile> &unsavedFiles) {
+ CXTranslationUnit &tu = tuRef(filename, flags);
+
+ if (tu == nullptr) {
+ std::vector<const char *> argv;
+
+#ifdef CLANG_RESOURCE_DIR
+ // Make sure libclang find its builtin headers, this is a known issue with
+ // libclang, see:
+ // - http://lists.cs.uiuc.edu/pipermail/cfe-dev/2012-July/022893.html
+ //
+ // > Make sure that Clang is using its own . It will be in a directory
+ // > ending in clang/3.2/include/ where 3.2 is the version of clang that you
+ // > are using. You may need to explicitly add it to your header search.
+ // > Usually clang finds this directory relative to the executable with
+ // > CompilerInvocation::GetResourcesPath(Argv0, MainAddr), but using just
+ // > the libraries, it can't automatically find it.
+ argv.push_back("-resource-dir");
+ argv.push_back(CLANG_RESOURCE_DIR);
+#endif
+
+ for (auto &flag : flags) {
+ argv.push_back(flag.c_str());
+ }
+
+ tu = clang_parseTranslationUnit(
+ index_,
+ filename.c_str(),
+ argv.data(),
+ static_cast<int>(argv.size()),
+ const_cast<CXUnsavedFile *>(unsavedFiles.data()),
+ unsavedFiles.size(),
+ parseTUOptions_);
+ }
+
+ if (tu == nullptr) {
+ std::clog << "error: libclang couldn't parse '" << filename << "'\n";
+ return nullptr;
+ }
+
+ // Reparsing is necessary to enable optimizations.
+ //
+ // From the clang mailing list (cfe-dev):
+ // From: Douglas Gregor
+ // Subject: Re: Clang indexing library performance
+ // ...
+ // You want to use the "default editing options" when parsing the translation
+ // unit
+ // clang_defaultEditingTranslationUnitOptions()
+ // and then reparse at least once. That will enable the various
+ // code-completion optimizations that should bring this time down
+ // significantly.
+ if (clang_reparseTranslationUnit(
+ tu,
+ unsavedFiles.size(),
+ const_cast<CXUnsavedFile *>(unsavedFiles.data()),
+ clang_defaultReparseOptions(tu))) {
+ // a 'fatal' error occured (even a diagnostic is impossible)
+ clang_disposeTranslationUnit(tu);
+ std::clog << "error: libclang couldn't reparse '" << filename << "'\n";
+ tu = 0;
+ return nullptr;
+ }
+
+ return tu;
+}
+
+CXTranslationUnit
+TUManager::getOrCreateTU(const std::string &filename,
+ const std::vector<std::string> &flags,
+ const std::vector<CXUnsavedFile> &unsavedFiles) {
+ if (auto tu = tuRef(filename, flags))
+ return tu;
+
+ return parse(filename, flags, unsavedFiles);
+}
+
+void TUManager::invalidateCachedTU(const std::string &filename) {
+ TranslationUnitsMap::iterator it = translationUnits_.find(filename);
+
+ if (it != translationUnits_.end()) {
+ if (CXTranslationUnit &tu = it->second)
+ clang_disposeTranslationUnit(tu);
+
+ translationUnits_.erase(it);
+ }
+}
+
+void TUManager::invalidateAllCachedTUs() {
+ TranslationUnitsMap::iterator it = translationUnits_.begin();
+
+ while (it != translationUnits_.end()) {
+ if (CXTranslationUnit &tu = it->second) {
+ clang_disposeTranslationUnit(tu);
+ translationUnits_.erase(it++); // post-increment keeps the iterator valid
+ } else {
+ ++it;
+ }
+ }
+}
diff --git a/elpa/irony-20220110.849/server/src/TUManager.h b/elpa/irony-20220110.849/server/src/TUManager.h
new file mode 100644
index 0000000..bd7730d
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/TUManager.h
@@ -0,0 +1,109 @@
+/**-*-C++-*-
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * \brief Translation Unit manager.
+ *
+ * Keeps a cache of translation units, reparsing or recreating them as
+ * necessary.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#ifndef IRONY_MODE_SERVER_TUMANAGER_H_
+#define IRONY_MODE_SERVER_TUMANAGER_H_
+
+#include "support/CIndex.h"
+#include "support/NonCopyable.h"
+
+#include <map>
+#include <string>
+#include <vector>
+
+class TUManager : public util::NonCopyable {
+public:
+ TUManager();
+ ~TUManager();
+
+ /**
+ * \brief Parse \p filename with flag \p flags.
+ *
+ * The first time call \c clang_parseTranslationUnit() and save the TU in the
+ * member \c translationUnits_, The next call with the same \p filename will
+ * call \c clang_reparseTranslationUnit().
+ *
+ * usage:
+ * \code
+ * std::vector<std::string> flags;
+ * flags.push_back("-I../utils");
+ * CXTranslationUnit tu = tuManager.parse("file.cpp", flags);
+ *
+ * if (! tu)
+ * std::cerr << "parsing translation unit failed\n";
+ * \endcode
+ *
+ * \return The translation unit, if the parsing failed the translation unit
+ * will be \c NULL.
+ */
+ CXTranslationUnit parse(const std::string &filename,
+ const std::vector<std::string> &flags,
+ const std::vector<CXUnsavedFile> &unsavedFiles);
+
+ /**
+ * \brief Retrieve, creating it if necessary the TU associated to filename.
+ *
+ * \return The translation unit. Will be NULL if the translation unit couldn't
+ * be created.
+ */
+ CXTranslationUnit getOrCreateTU(const std::string &filename,
+ const std::vector<std::string> &flags,
+ const std::vector<CXUnsavedFile> &unsavedFiles);
+
+ /**
+ * \brief Invalidate a given cached TU, the next use of a TU will require
+ * reparsing.
+ *
+ * This can be useful for example: when the flags used to compile a file have
+ * changed.
+ *
+ * \param filename The filename for which the associated
+ * translation unit flags need to be invalidated.
+ *
+ * \sa invalidateAllCachedTUs()
+ */
+ void invalidateCachedTU(const std::string &filename);
+
+ /**
+ * \brief Invalidate all cached TU, the next use of a TU will require
+ * reparsing.
+ *
+ * \sa invalidateCachedTU()
+ */
+ void invalidateAllCachedTUs();
+
+private:
+ /**
+ * \brief Get a reference to the translation unit that matches \p filename
+ * with the given set of flags.
+ *
+ * The TU will be null if it has never been parsed or if the flags have
+ * changed.
+ *
+ * \todo Find a proper name.
+ */
+ CXTranslationUnit &tuRef(const std::string &filename,
+ const std::vector<std::string> &flags);
+
+private:
+ typedef std::map<const std::string, CXTranslationUnit> TranslationUnitsMap;
+ typedef std::map<const std::string, std::vector<std::string>> FilenameFlagsMap;
+
+private:
+ CXIndex index_;
+ TranslationUnitsMap translationUnits_; // cache variable
+ FilenameFlagsMap flagsPerFileCache_;
+ unsigned parseTUOptions_;
+};
+
+#endif /* !IRONY_MODE_SERVER_TUMANAGER_H_ */
diff --git a/elpa/irony-20220110.849/server/src/main.cpp b/elpa/irony-20220110.849/server/src/main.cpp
new file mode 100644
index 0000000..7797528
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/main.cpp
@@ -0,0 +1,235 @@
+/**
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#include "Irony.h"
+#include "Command.h"
+
+#include "support/CIndex.h"
+#include "support/CommandLineParser.h"
+
+#include <cassert>
+#include <cstdlib>
+#include <fstream>
+#include <iomanip>
+#include <iostream>
+#include <iterator>
+#include <memory>
+#include <vector>
+
+static void printHelp() {
+ std::cout << "usage: irony-server [OPTIONS...] [COMMAND] [ARGS...]\n"
+ "\n"
+ "Options:\n"
+ " -v, --version\n"
+ " -h, --help\n"
+ " -i, --interactive\n"
+ " -d, --debug\n"
+ " --log-file PATH\n"
+ "\n"
+ "Commands:\n";
+
+#define X(sym, str, desc) \
+ if (Command::sym != Command::Unknown) \
+ std::cout << std::left << std::setw(25) << " " str << desc << "\n";
+#include "Commands.def"
+}
+
+static void printVersion() {
+ // do not change the format for the first line, external programs should be
+ // able to rely on it
+ std::cout << "irony-server version " IRONY_PACKAGE_VERSION "\n";
+
+ CXString cxVersionString = clang_getClangVersion();
+ std::cout << clang_getCString(cxVersionString) << "\n";
+ clang_disposeString(cxVersionString);
+}
+
+struct CommandProviderInterface {
+ virtual ~CommandProviderInterface() { }
+
+ virtual std::vector<std::string> nextCommand() = 0;
+};
+
+struct CommandLineCommandProvider : CommandProviderInterface {
+ CommandLineCommandProvider(const std::vector<std::string> &argv)
+ : argv_(argv), firstCall_(true) {
+ }
+
+ std::vector<std::string> nextCommand() {
+ if (firstCall_) {
+ firstCall_ = false;
+ return argv_;
+ }
+
+ return std::vector<std::string>(1, "exit");
+ }
+
+private:
+ std::vector<std::string> argv_;
+ bool firstCall_;
+};
+
+struct InteractiveCommandProvider : CommandProviderInterface {
+ std::vector<std::string> nextCommand() {
+ std::string line;
+
+ if (std::getline(std::cin, line)) {
+ return unescapeCommandLine(line);
+ }
+
+ return std::vector<std::string>(1, "exit");
+ }
+};
+
+struct RestoreClogOnExit {
+ RestoreClogOnExit() : rdbuf_(std::clog.rdbuf()) {
+ }
+
+ ~RestoreClogOnExit() {
+ std::clog.rdbuf(rdbuf_);
+ }
+
+private:
+ RestoreClogOnExit(const RestoreClogOnExit &);
+ RestoreClogOnExit &operator=(const RestoreClogOnExit &);
+
+private:
+ std::streambuf *rdbuf_;
+};
+
+int main(int ac, const char *av[]) {
+ std::vector<std::string> argv(&av[1], &av[ac]);
+
+ // stick to STL streams, no mix of C and C++ for IO operations
+ std::ios_base::sync_with_stdio(false);
+
+ bool interactiveMode = false;
+
+ Irony irony;
+
+ if (ac == 1) {
+ printHelp();
+ return 1;
+ }
+
+ std::ofstream logFile;
+
+ // When logging to a specific file, std::clog.rdbuf() is replaced by the log
+ // file's one. When we return from the main, this buffer is deleted (at the
+ // same time as logFile) but std::clog is still active, and will try to
+ // release the rdbuf() which has already been released in logFile's
+ // destructor. To avoid this we restore std::clog()'s original rdbuf on exit.
+ RestoreClogOnExit clogBufferRestorer;
+
+ unsigned optCount = 0;
+ while (optCount < argv.size()) {
+ const std::string &opt = argv[optCount];
+
+ if (opt.c_str()[0] != '-')
+ break;
+
+ if (opt == "--help" || opt == "-h") {
+ printHelp();
+ return 0;
+ }
+
+ if (opt == "--version" || opt == "-v") {
+ printVersion();
+ return 0;
+ }
+
+ if (opt == "--interactive" || opt == "-i") {
+ interactiveMode = true;
+ } else if (opt == "--debug" || opt == "-d") {
+ irony.setDebug(true);
+ } else if (opt == "--log-file" && (optCount + 1) < argv.size()) {
+ ++optCount;
+ logFile.open(argv[optCount]);
+ std::clog.rdbuf(logFile.rdbuf());
+ } else {
+ std::cerr << "error: invalid option '" << opt << "'\n";
+ return 1;
+ }
+
+ ++optCount;
+ }
+
+ argv.erase(argv.begin(), argv.begin() + optCount);
+
+ CommandParser commandParser;
+ std::unique_ptr<CommandProviderInterface> commandProvider;
+
+ if (interactiveMode) {
+ commandProvider.reset(new InteractiveCommandProvider());
+ } else {
+ commandProvider.reset(new CommandLineCommandProvider(argv));
+ }
+
+ while (Command *c = commandParser.parse(commandProvider->nextCommand())) {
+ if (c->action != Command::Exit) {
+ std::clog << "execute: " << *c << std::endl;
+ }
+
+ switch (c->action) {
+ case Command::Help:
+ printHelp();
+ break;
+
+ case Command::Candidates:
+ irony.candidates(c->prefix, c->style);
+ break;
+
+ case Command::CompletionDiagnostics:
+ irony.completionDiagnostics();
+ break;
+
+ case Command::Complete:
+ irony.complete(c->file, c->line, c->column, c->flags);
+ break;
+
+ case Command::Diagnostics:
+ irony.diagnostics();
+ break;
+
+ case Command::Exit:
+ return 0;
+
+ case Command::GetCompileOptions:
+ irony.getCompileOptions(c->dir, c->file);
+ break;
+
+ case Command::GetType:
+ irony.getType(c->line, c->column);
+ break;
+
+ case Command::Parse:
+ irony.parse(c->file, c->flags);
+ break;
+
+ case Command::SetDebug:
+ irony.setDebug(c->opt);
+ break;
+
+ case Command::SetUnsaved:
+ irony.setUnsaved(c->file, c->unsavedFile);
+ break;
+
+ case Command::ResetUnsaved:
+ irony.resetUnsaved(c->file);
+ break;
+
+ case Command::Unknown:
+ assert(0 && "unreacheable code...reached!");
+ break;
+ }
+
+ std::cout << "\n;;EOT\n" << std::flush;
+ }
+
+ return 1;
+}
diff --git a/elpa/irony-20220110.849/server/src/support/CIndex.h b/elpa/irony-20220110.849/server/src/support/CIndex.h
new file mode 100644
index 0000000..89d3f62
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/support/CIndex.h
@@ -0,0 +1,33 @@
+/**
+ * \file
+ * \brief Wrapper around Clang Indexing Public C Interface header.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#ifndef IRONY_MODE_SERVER_SUPPORT_CINDEXVERSION_H_
+#define IRONY_MODE_SERVER_SUPPORT_CINDEXVERSION_H_
+
+#include <clang-c/Index.h>
+
+/// Use <tt>\#if CINDEX_VERSION_VERSION > 10047</tt> to test for
+/// CINDEX_VERSION_MAJOR = 1 and CINDEX_VERSION_MINOR = 47.
+#ifndef CINDEX_VERSION
+#define CINDEX_VERSION 0 // pre-clang 3.2 support
+#endif
+
+#if CINDEX_VERSION >= 6
+#define HAS_BRIEF_COMMENTS_IN_COMPLETION 1
+#else
+#define HAS_BRIEF_COMMENTS_IN_COMPLETION 0
+#endif
+
+#if CINDEX_VERSION >= 6
+#define HAS_COMPILATION_DATABASE 1
+#include <clang-c/CXCompilationDatabase.h>
+#else
+#define HAS_COMPILATION_DATABASE 0
+#endif
+
+#endif /* !IRONY_MODE_SERVER_SUPPORT_CINDEXVERSION_H_ */
diff --git a/elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp b/elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp
new file mode 100644
index 0000000..a838092
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/support/CommandLineParser.cpp
@@ -0,0 +1,119 @@
+/**
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#include "CommandLineParser.h"
+
+namespace {
+
+/// \brief A parser for escaped strings of command line arguments.
+///
+/// Assumes \-escaping for quoted arguments (see the documentation of
+/// unescapeCommandLine(...)).
+class CommandLineArgumentParser {
+public:
+ CommandLineArgumentParser(const std::string &commandLine)
+ : input_(commandLine), position_(input_.begin() - 1) {
+ }
+
+ std::vector<std::string> parse() {
+ bool hasMoreInput = true;
+ while (hasMoreInput && nextNonWhitespace()) {
+ std::string argument;
+ hasMoreInput = parseStringInto(argument);
+ commandLine_.push_back(argument);
+ }
+ return commandLine_;
+ }
+
+private:
+ // All private methods return true if there is more input available.
+
+ bool parseStringInto(std::string &string) {
+ do {
+ if (*position_ == '"') {
+ if (!parseDoubleQuotedStringInto(string))
+ return false;
+ } else if (*position_ == '\'') {
+ if (!parseSingleQuotedStringInto(string))
+ return false;
+ } else {
+ if (!parseFreeStringInto(string))
+ return false;
+ }
+ } while (*position_ != ' ');
+ return true;
+ }
+
+ bool parseDoubleQuotedStringInto(std::string &string) {
+ if (!next())
+ return false;
+ while (*position_ != '"') {
+ if (!skipEscapeCharacter())
+ return false;
+ string.push_back(*position_);
+ if (!next())
+ return false;
+ }
+ return next();
+ }
+
+ bool parseSingleQuotedStringInto(std::string &string) {
+ if (!next())
+ return false;
+ while (*position_ != '\'') {
+ string.push_back(*position_);
+ if (!next())
+ return false;
+ }
+ return next();
+ }
+
+ bool parseFreeStringInto(std::string &string) {
+ do {
+ if (!skipEscapeCharacter())
+ return false;
+ string.push_back(*position_);
+ if (!next())
+ return false;
+ } while (*position_ != ' ' && *position_ != '"' && *position_ != '\'');
+ return true;
+ }
+
+ bool skipEscapeCharacter() {
+ if (*position_ == '\\') {
+ return next();
+ }
+ return true;
+ }
+
+ bool nextNonWhitespace() {
+ do {
+ if (!next())
+ return false;
+ } while (*position_ == ' ');
+ return true;
+ }
+
+ bool next() {
+ ++position_;
+ return position_ != input_.end();
+ }
+
+private:
+ const std::string input_;
+ std::string::const_iterator position_;
+ std::vector<std::string> commandLine_;
+};
+
+} // unnamed namespace
+
+std::vector<std::string>
+unescapeCommandLine(const std::string &escapedCommandLine) {
+ CommandLineArgumentParser parser(escapedCommandLine);
+ return parser.parse();
+}
diff --git a/elpa/irony-20220110.849/server/src/support/CommandLineParser.h b/elpa/irony-20220110.849/server/src/support/CommandLineParser.h
new file mode 100644
index 0000000..b764797
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/support/CommandLineParser.h
@@ -0,0 +1,21 @@
+/**
+ * \file
+ * \brief Facility to parse a command line into a string array.
+ *
+ * \note Please note that the code borrowed from the Clang,
+ * lib/Tooling/JSONCompilationDatabase.cpp.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#ifndef IRONY_MODE_SERVER_SUPPORT_COMMAND_LINE_PARSER_H_
+#define IRONY_MODE_SERVER_SUPPORT_COMMAND_LINE_PARSER_H_
+
+#include <string>
+#include <vector>
+
+std::vector<std::string>
+unescapeCommandLine(const std::string &escapedCommandLine);
+
+#endif // IRONY_MODE_SERVER_SUPPORT_COMMAND_LINE_PARSER_H_
diff --git a/elpa/irony-20220110.849/server/src/support/NonCopyable.h b/elpa/irony-20220110.849/server/src/support/NonCopyable.h
new file mode 100644
index 0000000..d30a5b2
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/support/NonCopyable.h
@@ -0,0 +1,34 @@
+/**-*-C++-*-
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * \brief NonCopyable class like in Boost.
+ *
+ * \see http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Non-copyable_Mixin
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#ifndef IRONY_MODE_SERVER_SUPPORT_NONCOPYABLE_H_
+#define IRONY_MODE_SERVER_SUPPORT_NONCOPYABLE_H_
+
+namespace util {
+
+class NonCopyable {
+protected:
+ NonCopyable() {
+ }
+
+ // Protected non-virtual destructor
+ ~NonCopyable() {
+ }
+
+private:
+ NonCopyable(const NonCopyable &);
+ NonCopyable &operator=(const NonCopyable &);
+};
+
+} // ! namespace util
+
+#endif /* !IRONY_MODE_SERVER_SUPPORT_NONCOPYABLE_H_ */
diff --git a/elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp b/elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp
new file mode 100644
index 0000000..e7393e1
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/support/TemporaryFile.cpp
@@ -0,0 +1,74 @@
+/**
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#include "TemporaryFile.h"
+
+#include <algorithm>
+#include <cstdio>
+#include <cstdlib>
+#include <fstream>
+#include <iostream>
+#include <random>
+
+static std::string getTemporaryFileDirectory() {
+ const char *temporaryDirEnvVars[] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"};
+
+ for (const char *envVar : temporaryDirEnvVars) {
+ if (const char *dir = std::getenv(envVar))
+ return dir;
+ }
+
+ return "/tmp";
+}
+
+TemporaryFile::TemporaryFile(const std::string &prefix,
+ const std::string &suffix)
+ : pathOrPattern_(prefix + "-%%%%%%" + suffix) {
+}
+
+TemporaryFile::~TemporaryFile() {
+ if (openedFile_) {
+ openedFile_.reset();
+ std::remove(pathOrPattern_.c_str());
+ }
+}
+
+const std::string &TemporaryFile::getPath() {
+ if (!openedFile_) {
+ openedFile_.reset(new std::fstream);
+
+ std::random_device rd;
+ std::default_random_engine e(rd());
+ std::uniform_int_distribution<int> dist(0, 15);
+ std::string pattern = pathOrPattern_;
+ std::string tmpDir = getTemporaryFileDirectory() + "/";
+ int i = 0;
+
+ do {
+ // exiting is better than infinite loop
+ if (++i > TemporaryFile::MAX_ATTEMPS) {
+ std::cerr << "error: couldn't create temporary file, please check your "
+ "temporary file directory (" << tmpDir << ")\n";
+ exit(EXIT_FAILURE);
+ }
+
+ // make the filename based on the pattern
+ std::transform(pattern.begin(),
+ pattern.end(),
+ pathOrPattern_.begin(),
+ [&e, &dist](char ch) {
+ return ch == '%' ? "0123456789abcdef"[dist(e)] : ch;
+ });
+ // create the file
+ openedFile_->open(tmpDir + pathOrPattern_, std::ios_base::out);
+ } while (!openedFile_->is_open());
+ pathOrPattern_ = tmpDir + pathOrPattern_;
+ }
+
+ return pathOrPattern_;
+}
diff --git a/elpa/irony-20220110.849/server/src/support/TemporaryFile.h b/elpa/irony-20220110.849/server/src/support/TemporaryFile.h
new file mode 100644
index 0000000..5bf77f4
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/support/TemporaryFile.h
@@ -0,0 +1,36 @@
+/**-*-C++-*-
+ * \file
+ * \author Guillaume Papin <guillaume.papin@epitech.eu>
+ *
+ * \brief Not the best piece of code out there.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#ifndef IRONY_MODE_SERVER_SUPPORT_TEMPORARY_FILE_H_
+#define IRONY_MODE_SERVER_SUPPORT_TEMPORARY_FILE_H_
+
+#include <iosfwd>
+#include <memory>
+#include <string>
+
+class TemporaryFile {
+ enum {
+ // if we can't create the temp file, exits.
+ MAX_ATTEMPS = 25
+ };
+
+public:
+ TemporaryFile(const std::string &prefix, const std::string &suffix = "");
+ ~TemporaryFile();
+
+ /// Returns the path of this temporary filename
+ const std::string &getPath();
+
+private:
+ std::string pathOrPattern_;
+ std::unique_ptr<std::fstream> openedFile_;
+};
+
+#endif // IRONY_MODE_SERVER_SUPPORT_TEMPORARY_FILE_H_
diff --git a/elpa/irony-20220110.849/server/src/support/iomanip_quoted.h b/elpa/irony-20220110.849/server/src/support/iomanip_quoted.h
new file mode 100644
index 0000000..a8ca38b
--- /dev/null
+++ b/elpa/irony-20220110.849/server/src/support/iomanip_quoted.h
@@ -0,0 +1,52 @@
+/**-*-C++-*-
+ * \file
+ * \brief Dumb implementation of something that might look like C++14
+ * std::quoted.
+ *
+ * This file is distributed under the GNU General Public License. See
+ * COPYING for details.
+ */
+
+#ifndef IRONY_MODE_SERVER_SUPPORT_IOMANIP_QUOTED_H_
+#define IRONY_MODE_SERVER_SUPPORT_IOMANIP_QUOTED_H_
+
+#include <ostream>
+#include <string>
+
+namespace support {
+namespace detail {
+
+struct QuotedStringProxy {
+ QuotedStringProxy(const std::string &s) : s(s) {
+ }
+
+ std::string s;
+};
+
+std::ostream &operator<<(std::ostream &os, const QuotedStringProxy &q) {
+ const std::string &s = q.s;
+
+ os << '"';
+ if (s.find_first_of("\"\\") == std::string::npos) {
+ os << s;
+ } else {
+ for (auto ch : s) {
+ if (ch == '\\' || ch == '"')
+ os << '\\';
+
+ os << ch;
+ }
+ }
+ os << '"';
+ return os;
+}
+
+} // namespace detail
+
+detail::QuotedStringProxy quoted(const std::string &s) {
+ return detail::QuotedStringProxy(s);
+}
+
+} // namespace support
+
+#endif // IRONY_MODE_SERVER_SUPPORT_IOMANIP_QUOTED_H_
diff --git a/elpa/irony-20220110.849/server/test/CMakeLists.txt b/elpa/irony-20220110.849/server/test/CMakeLists.txt
new file mode 100644
index 0000000..078b69a
--- /dev/null
+++ b/elpa/irony-20220110.849/server/test/CMakeLists.txt
@@ -0,0 +1,3 @@
+add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND} --output-on-failure)
+
+add_subdirectory (elisp)
diff --git a/elpa/irony-20220110.849/server/test/elisp/CMakeLists.txt b/elpa/irony-20220110.849/server/test/elisp/CMakeLists.txt
new file mode 100644
index 0000000..8877a89
--- /dev/null
+++ b/elpa/irony-20220110.849/server/test/elisp/CMakeLists.txt
@@ -0,0 +1,47 @@
+# On MS-Windows, emacs_dir is a special environment variable, which
+# indicates the full path of the directory in which Emacs is
+# installed.
+#
+# There is no standard location that I know of for Emacs on Windows so
+# using this special environment variable will at least help people
+# who build the server from inside Emacs.
+if(DEFINED ENV{emacs_dir})
+ list(APPEND EMACS_EXECUTABLE_HINTS $ENV{emacs_dir}/bin)
+endif()
+
+find_program(EMACS_EXECUTABLE emacs
+ HINTS ${EMACS_EXECUTABLE_HINTS})
+
+if (EMACS_EXECUTABLE)
+ message(STATUS "Found emacs: ${EMACS_EXECUTABLE}")
+else()
+ message(WARNING "emacs not found: elisp tests will be skipped!")
+ return()
+endif()
+
+#
+# add_ert_test(<FileName>)
+#
+# Create a test which run the given Elisp script using the Emacs ERT testing
+# framework.
+#
+# The target is deduced from the ``FileName`` argument, e.g: the file foo.el
+# will be the target 'check-foo-el'.
+#
+# FIXME: assumes MELPA is configured...
+function(add_ert_test test_file)
+ get_filename_component(name ${test_file} NAME_WE)
+ add_test(check-${name}-el
+ ${EMACS_EXECUTABLE} -Q --batch
+ -l package
+ --eval "(package-initialize)"
+ --eval "(unless (require 'cl-lib nil t) (package-refresh-contents) (package-install 'cl-lib))"
+ -l ${CMAKE_CURRENT_SOURCE_DIR}/${test_file}
+ -f ert-run-tests-batch-and-exit)
+
+ set_tests_properties(check-${name}-el PROPERTIES TIMEOUT 15)
+endfunction()
+
+add_ert_test(irony.el)
+add_ert_test(irony-iotask.el)
+add_ert_test(irony-cdb-json.el)
diff --git a/elpa/irony-20220110.849/server/test/elisp/irony-cdb-json.el b/elpa/irony-20220110.849/server/test/elisp/irony-cdb-json.el
new file mode 100644
index 0000000..a810dae
--- /dev/null
+++ b/elpa/irony-20220110.849/server/test/elisp/irony-cdb-json.el
@@ -0,0 +1,87 @@
+;; -*-no-byte-compile: t; -*-
+(load
+ (concat (file-name-directory (or load-file-name buffer-file-name))
+ "test-config"))
+
+(require 'irony-cdb-json)
+(require 'cl-lib)
+
+(defconst irony-cdb/compile-command
+ '((file . "../src/file.cc")
+ (directory . "/home/user/project/build")
+ (command . "/usr/bin/clang++ -DSOMEDEF=1 -c -o file.o /home/user/project/src/file.cc")))
+
+(ert-deftest cdb/parse/simple/path-is-absolute ()
+ (should
+ (equal "/home/user/project/src/file.cc"
+ (nth 0 (irony-cdb-json--transform-compile-command
+ irony-cdb/compile-command)))))
+
+(ert-deftest cdb/parse/simple/compile-options ()
+ (should
+ (equal '("-DSOMEDEF=1")
+ (nth 1 (irony-cdb-json--transform-compile-command
+ irony-cdb/compile-command)))))
+
+(ert-deftest cdb/parse/simple/invocation-directory ()
+ (should
+ (equal "/home/user/project/build"
+ (nth 2 (irony-cdb-json--transform-compile-command
+ irony-cdb/compile-command)))))
+
+(ert-deftest cdb/choose-closest-path/chooses-closest ()
+ (should
+ (equal "/tmp/a/cdb"
+ (irony-cdb--choose-closest-path "/tmp/a/1"
+ '("/tmp/a/cdb" "/tmp/cdb")))))
+
+(ert-deftest cdb/choose-closest-path/chooses-closest2 ()
+ (should
+ (equal "/tmp/a/cdb"
+ (irony-cdb--choose-closest-path "/tmp/a/1"
+ '("/tmp/cdb" "/tmp/a/cdb")))))
+
+(ert-deftest cdb/choose-closest-path/prefers-deeper ()
+ (should
+ (equal "/tmp/a/build/cdb"
+ (irony-cdb--choose-closest-path "/tmp/a/1"
+ '("/tmp/a/build/cdb" "/tmp/cdb")))))
+
+(ert-deftest cdb/choose-closest-path/prefers-deeper2 ()
+ (should
+ (equal "/tmp/a/build/cdb"
+ (irony-cdb--choose-closest-path "/tmp/a/1"
+ '("/tmp/cdb" "/tmp/a/build/cdb")))))
+
+(ert-deftest cdb/choose-closest-path/will-survive-garbage ()
+ (should
+ (equal nil
+ (irony-cdb--choose-closest-path "/tmp/a/1"
+ 'ordures))))
+
+; http://endlessparentheses.com/understanding-letf-and-how-it-replaces-flet.html
+(ert-deftest cdb/locate-db/choose-among-candidates ()
+ (should
+ (equal "/foo/build/cdb"
+ (cl-letf (((symbol-function 'locate-dominating-file)
+ (lambda (file name)
+ (cond
+ ((string= name "./cdb") "/") ; found /cdb
+ ((string= name "build/cdb") "/foo/") ; found /foo/build/cdb
+ ))))
+ (irony-cdb--locate-dominating-file-with-dirs "/foo/bar/qux.cpp"
+ "cdb"
+ '("." "build" "out/x86_64"))))))
+
+(ert-deftest cdb/locate-dominating-file-with-dirs/children-first ()
+ (should
+ (equal "/tmp/foo/bar/out/x86_64/cdb"
+ (cl-letf (((symbol-function 'locate-dominating-file)
+ (lambda (file name)
+ (cond
+ ((string= name "./cdb") "/tmp/foo/") ; found /tmp/foo/cdb
+ ((string= name "out/x86_64/cdb") "/tmp/foo/bar/") ;found /tmp/foo/bar/out/x86_64/cdb
+ ))))
+ (irony-cdb--locate-dominating-file-with-dirs "/tmp/foo/bar/qux.cpp"
+ "cdb"
+ '("." "out/x86_64" ))))))
diff --git a/elpa/irony-20220110.849/server/test/elisp/irony-iotask.el b/elpa/irony-20220110.849/server/test/elisp/irony-iotask.el
new file mode 100644
index 0000000..7ef213b
--- /dev/null
+++ b/elpa/irony-20220110.849/server/test/elisp/irony-iotask.el
@@ -0,0 +1,249 @@
+;; -*-no-byte-compile: t; -*-
+(load (concat (file-name-directory (or load-file-name
+ buffer-file-name))
+ "test-config"))
+
+;; load irony-iotask
+;;
+;; XXX: No idea why this is necessary, test-config already adds the directory to
+;; the load-path so irony is found...
+(unless (require 'irony-iotask nil t)
+ (let ((irony-iotask-dir (expand-file-name "../../.." test-dir)))
+ (add-to-list 'load-path irony-iotask-dir)
+ (require 'irony-iotask)))
+
+(defun irony-iotask-echo-process-exit-filter (process output)
+ (when (buffer-live-p (process-buffer process))
+ (with-current-buffer (process-buffer process)
+ (goto-char (process-mark process))
+ (insert output)
+ (set-marker (process-mark process) (point))
+ (when (>= (buffer-size) (length "exit\n"))
+ (should (string= (buffer-string) "exit\n"))
+ (erase-buffer)))))
+
+;; Note: these tests use process communication with the standard I/O streams.
+;; The subprocess used for this communication is Emacs.
+;;
+;; The following article provides useful information for using Elisp as a
+;; scripting language, Emacs as an interpreter, it details how the standard I/O
+;; streams works in Elisp scripts:
+;; - http://www.lunaryorn.com/2014/08/12/emacs-script-pitfalls.html
+
+(defmacro irony-iotask/with-echo-process (&rest body)
+ "Start an Emacs process that runs the given PROCESS-SCRIPT.
+
+The process is setup with `irony-iotask-setup-process'.
+
+It's possible to schedule some iotasks in the BODY for testing.
+
+There is an exposed variable named `process' available for use in
+BODY.
+
+Elisp is used as a scripting language because it should be
+available on all OSes irony-iotask support."
+ (declare (indent 1))
+ `(let ((process-connection-type nil)
+ (process-adaptive-read-buffering nil)
+ process)
+ (setq process
+ (start-process "emacs-irony-test"
+ "*emacs-irony-test*"
+ (expand-file-name invocation-name
+ invocation-directory)
+ "-Q"
+ "--batch"
+ "--eval"
+ (prin1-to-string
+ '(let ((msg))
+ (while (not (equal msg "exit"))
+ (setq msg (read-from-minibuffer ""))
+ (message msg))))))
+ (unwind-protect
+ (progn
+ (irony-iotask-setup-process process)
+ ,@body)
+ ;; the iotask process filter does not clean the process buffer
+ ;; at the end of a request, but at the begining of a new one
+ (with-current-buffer (process-buffer process)
+ (erase-buffer))
+ (set-process-filter process #'irony-iotask-echo-process-exit-filter)
+ (process-send-string process "exit\n")
+ ;; wait for the process to finish normally, or kill it if it doesn't
+ (with-timeout (1 (kill-process process))
+ (while (process-live-p process)
+ (sit-for 0.05)))
+ ;; start with a clean buffer,
+ ;; Emacs 24.3 seems to keep some
+ (kill-buffer (process-buffer process))
+ (delete-process process))))
+
+;; irony-iotask-result
+
+(ert-deftest irony-iotask-result/ready-p-value ()
+ (let ((result (irony-iotask-result-create)))
+ (should-not (irony-iotask-result-valid-p result))
+ (irony-iotask-result-set-value result 1)
+ (should (irony-iotask-result-valid-p result))))
+
+(ert-deftest irony-iotask-result/ready-p-error ()
+ (let ((result (irony-iotask-result-create)))
+ (should-not (irony-iotask-result-valid-p result))
+ (irony-iotask-result-set-error result 'irony-iotask-error (list "blah"))
+ (should (irony-iotask-result-valid-p result))))
+
+(ert-deftest irony-iotask-result/set-value ()
+ (let ((result (irony-iotask-result-create)))
+ (irony-iotask-result-set-value result 'blah)
+ (should (eq (irony-iotask-result-get result) 'blah))))
+
+(irony--define-error 'irony-iotask-result/test-error
+ "Irony I/O task sample error")
+
+(ert-deftest irony-iotask-result/set-error ()
+ (let ((result (irony-iotask-result-create)))
+ (irony-iotask-result-set-error result 'irony-iotask-result/test-error)
+ (should-error (irony-iotask-result-get result)
+ :type 'irony-iotask-result/test-error)))
+
+(ert-deftest irony-iotask-result/set-error-data ()
+ (let ((result (irony-iotask-result-create)))
+ (irony-iotask-result-set-error result
+ 'irony-iotask-result/test-error
+ 'foo 'bar 'baz 'qux)
+ (condition-case err
+ (irony-iotask-result-get result)
+ (irony-iotask-result/test-error
+ (should (equal (cdr err) '(foo bar baz qux)))))))
+
+(ert-deftest irony-iotask-result/get-empty ()
+ (let ((result (irony-iotask-result-create)))
+ (should-error (irony-iotask-result-get result)
+ :type 'irony-iotask-result-get-error)))
+
+;; task
+
+(irony-iotask-define-task irony-iotask/task-start-t
+ "doc"
+ :start (lambda (&optional value)
+ (irony-iotask-set-result (or value 42))))
+
+(ert-deftest irony-iotask/task-start/simple ()
+ (let ((task (irony-iotask-package-task irony-iotask/task-start-t)))
+ (irony-iotask/with-echo-process
+ (should (equal 42 (irony-iotask-run process task))))))
+
+(ert-deftest irony-iotask/task-start/with-arguments ()
+ (let ((task (irony-iotask-package-task irony-iotask/task-start-t 43)))
+ (irony-iotask/with-echo-process
+ (should (equal 43 (irony-iotask-run process task))))))
+
+(irony-iotask-define-task irony-iotask/task-update-t
+ "doc"
+ :start (lambda (&optional hello)
+ (irony-iotask-send-string (format "%s\n" (or hello "hello"))))
+ :update (lambda (&optional hello)
+ (setq hello (or hello "hello"))
+ (when (string= (buffer-string) (format "%s\n" hello))
+ (irony-iotask-set-result (format "%s ok" hello)))))
+
+(ert-deftest irony-iotask-schedule/task-update/simple ()
+ (let ((task (irony-iotask-package-task irony-iotask/task-update-t)))
+ (irony-iotask/with-echo-process
+ (should (string= "hello ok" (irony-iotask-run process task))))))
+
+(ert-deftest irony-iotask-schedule/task-update/with-arguments ()
+ (let ((task (irony-iotask-package-task irony-iotask/task-update-t "bonjour")))
+ (irony-iotask/with-echo-process
+ (should (string= "bonjour ok" (irony-iotask-run process task))))))
+
+(irony-iotask-define-task irony-iotask/task-invalid-msg-t
+ "doc"
+ :start (lambda ()
+ (irony-iotask-send-string "ping\n"))
+ :update (lambda ()
+ (when (string= (buffer-string) "ping\n")
+ (throw 'invalid-msg t))))
+
+(ert-deftest irony-iotask-schedule/task-update/invalid-msg ()
+ (let ((task (irony-iotask-package-task irony-iotask/task-invalid-msg-t)))
+ (irony-iotask/with-echo-process
+ (should-error (irony-iotask-run process task)
+ :type 'irony-iotask-bad-data))))
+
+(ert-deftest irony-iotask-chain/simple ()
+ (let ((task (irony-iotask-chain
+ (irony-iotask-package-task irony-iotask/task-update-t "hi")
+ (irony-iotask-package-task irony-iotask/task-update-t "hej"))))
+ (irony-iotask/with-echo-process
+ (should (equal "hej ok" (irony-iotask-run process task))))))
+
+(defvar irony-iotask/task-finish-var nil)
+(defvar irony-iotask/task-on-var nil)
+(irony-iotask-define-task irony-iotask/task-finish-t
+ "doc"
+ :start (lambda ()
+ (irony-iotask-put :text "how")
+ (irony-iotask-send-string "hello\n"))
+ :update (lambda ()
+ (cond
+ ((string= (buffer-string) "hello\n")
+ (irony-iotask-put :text (concat (irony-iotask-get :text) " are"))
+ (irony-iotask-set-result t))
+ ((>= (buffer-size) (1+ (length "hello\n")))
+ (throw 'invalid-msg t))))
+ :on-success (lambda ()
+ (setq irony-iotask/task-on-var "success"))
+ :finish (lambda ()
+ (setq irony-iotask/task-finish-var (concat (irony-iotask-get :text)
+ " you?"))))
+
+(ert-deftest irony-iotask-schedule/task-finish/simple ()
+ (let ((task (irony-iotask-package-task irony-iotask/task-finish-t)))
+ (irony-iotask/with-echo-process
+ (setq irony-iotask/task-finish-var nil)
+ (irony-iotask-run process task)
+ (should (equal "how are you?" irony-iotask/task-finish-var)))))
+
+(ert-deftest irony-iotask-schedule/task-on-success/simple ()
+ (let ((task (irony-iotask-package-task irony-iotask/task-finish-t)))
+ (irony-iotask/with-echo-process
+ (setq irony-iotask/task-on-var nil)
+ (irony-iotask-run process task)
+ (should (equal "success" irony-iotask/task-on-var)))))
+
+(irony-iotask-define-task irony-iotask/task-on-error-t
+ "doc"
+ :start (lambda ()
+ (irony-iotask-set-error 'irony-iotask-error))
+ :on-error (lambda ()
+ (setq irony-iotask/task-on-var "error")))
+
+(ert-deftest irony-iotask-schedule/task-on-error/simple ()
+ (let ((task (irony-iotask-package-task irony-iotask/task-on-error-t)))
+ (irony-iotask/with-echo-process
+ (setq irony-iotask/task-on-var nil)
+ (ignore-errors
+ (irony-iotask-run process task))
+ (should (equal "error" irony-iotask/task-on-var)))))
+
+(ert-deftest irony-iotask-schedule/callback/recalls-schedule ()
+ (let ((task (irony-iotask-package-task irony-iotask/task-update-t "a")))
+ (irony-iotask/with-echo-process
+ (lexical-let ((run-process process)
+ results)
+ (irony-iotask-schedule process task
+ (lambda (result)
+ (setq results (list result))
+ (irony-iotask-schedule
+ run-process
+ (irony-iotask-package-task
+ irony-iotask/task-update-t "b")
+ (lambda (result)
+ (setq results (append results (list result)))))))
+ (should (with-local-quit
+ (while (< (length results) 2)
+ (accept-process-output process 0.05))
+ t))
+ (should (string= "a ok" (irony-iotask-result-get (nth 0 results))))
+ (should (string= "b ok" (irony-iotask-result-get (nth 1 results))))))))
diff --git a/elpa/irony-20220110.849/server/test/elisp/irony.el b/elpa/irony-20220110.849/server/test/elisp/irony.el
new file mode 100644
index 0000000..fe2378b
--- /dev/null
+++ b/elpa/irony-20220110.849/server/test/elisp/irony.el
@@ -0,0 +1,121 @@
+;; -*-no-byte-compile: t; -*-
+(load (concat (file-name-directory (or load-file-name
+ buffer-file-name))
+ "test-config"))
+
+(ert-deftest irony/buffer-size-in-bytes ()
+ (with-temp-buffer
+ ;; this smiley takes 3 bytes apparently
+ (insert "☺")
+ (should (equal 3 (irony--buffer-size-in-bytes)))
+ (erase-buffer)
+ (insert "☺\n")
+ (should (equal 4 (irony--buffer-size-in-bytes)))
+ (erase-buffer)
+ (insert "\t")
+ (should (equal 1 (irony--buffer-size-in-bytes)))))
+
+(ert-deftest irony/find-server-executable/does-not-exists ()
+ (let ((irony-server-install-prefix "/does/not/exists")
+ (exec-path nil))
+ (should-error (irony--find-server-executable)
+ :type 'irony-server-error)))
+
+(ert-deftest irony/split-command-line/just-spaces ()
+ (let ((cmd-line "clang -Wall -Wextra"))
+ (should (equal
+ '("clang" "-Wall" "-Wextra")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/split-command-line/start-with-space ()
+ (let ((cmd-line " clang -Wall -Wextra"))
+ (should (equal
+ '("clang" "-Wall" "-Wextra")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/split-command-line/end-with-space ()
+ (let ((cmd-line "clang -Wall -Wextra "))
+ (should (equal
+ '("clang" "-Wall" "-Wextra")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/split-command-line/space-everywhere ()
+ (let ((cmd-line " \t clang \t -Wall \t -Wextra\t"))
+ (should (equal
+ '("clang" "-Wall" "-Wextra")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/split-command-line/with-quotes ()
+ (let ((cmd-line "clang -Wall -Wextra \"-I/tmp/dir with spaces\""))
+ (should (equal
+ '("clang" "-Wall" "-Wextra" "-I/tmp/dir with spaces")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/split-command-line/with-quotes ()
+ "Test if files are removed from the arguments list.
+
+https://github.com/Sarcasm/irony-mode/issues/101"
+ (let ((cmd-line "g++ -DFOO=\\\"\\\""))
+ (should (equal
+ '("g++" "-DFOO=\"\"")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/split-command-line/start-with-quotes ()
+ (let ((cmd-line "\"cl ang\" -Wall -Wextra \"-I/tmp/dir with spaces\""))
+ (should (equal
+ '("cl ang" "-Wall" "-Wextra" "-I/tmp/dir with spaces")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/split-command-line/quotes-in-word ()
+ (let ((cmd-line "clang -Wall -Wextra -I\"/tmp/dir with spaces\""))
+ (should (equal
+ '("clang" "-Wall" "-Wextra" "-I/tmp/dir with spaces")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/split-command-line/ill-end-quote ()
+ (let ((cmd-line "clang -Wall -Wextra\""))
+ (should-error (irony--split-command-line cmd-line)
+ :type 'irony-parse-error)))
+
+(ert-deftest irony/split-command-line/backslash-1 ()
+ (let ((cmd-line "clang\\ -Wall"))
+ (should (equal
+ '("clang -Wall")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/split-command-line/backslash-2 ()
+ (let ((cmd-line "\\\\\\ clang\\ -Wall\\"))
+ (should (equal
+ '("\\ clang -Wall\\")
+ (irony--split-command-line cmd-line)))))
+
+(ert-deftest irony/extract-working-directory-option/not-specified ()
+ (let ((compile-flags '("-Wall")))
+ (should
+ (not (irony--extract-working-directory-option compile-flags)))))
+
+(ert-deftest irony/extract-working-directory-option/specified-1 ()
+ (let ((compile-flags '("-working-directory" "/tmp/lol")))
+ (should (equal "/tmp/lol"
+ (irony--extract-working-directory-option compile-flags)))))
+
+(ert-deftest irony/extract-working-directory-option/specified-2 ()
+ (let ((compile-flags '("-Wall" "-working-directory=/tmp/lol" "-Wshadow")))
+ (should (equal "/tmp/lol"
+ (irony--extract-working-directory-option compile-flags)))))
+
+;; TODO: restore functionality
+;; (ert-deftest irony/include-directories-1 ()
+;; (let ((irony-compile-flags '("-Iinclude" "-I/tmp/foo"))
+;; (irony-compile-flags-work-dir "/tmp/blah/"))
+;; (should (equal
+;; '("/tmp/blah/include" "/tmp/foo")
+;; (irony-user-search-paths)))))
+
+;; (ert-deftest irony/include-directories-2 ()
+;; (let ((irony-compile-flags '("-Wextra" "-Iinclude" "-I" "foo" "-Wall"))
+;; (irony-compile-flags-work-dir "/tmp/blah/"))
+;; (should (equal
+;; '("/tmp/blah/include"
+;; "/tmp/blah/foo")
+;; (irony-user-search-paths)))))
diff --git a/elpa/irony-20220110.849/server/test/elisp/test-config.el b/elpa/irony-20220110.849/server/test/elisp/test-config.el
new file mode 100644
index 0000000..224cdd0
--- /dev/null
+++ b/elpa/irony-20220110.849/server/test/elisp/test-config.el
@@ -0,0 +1,14 @@
+;; -*-no-byte-compile: t; -*-
+(defvar test-dir (if load-file-name
+ (file-name-as-directory
+ (expand-file-name (concat (file-name-directory
+ load-file-name)))))
+ "Elisp test directory path.")
+
+;; load irony
+(unless (require 'irony nil t)
+ (let ((irony-dir (expand-file-name "../../.." test-dir)))
+ (add-to-list 'load-path irony-dir)
+ (require 'irony)))
+
+(require 'ert)