lserver.ros 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. #!/bin/sh
  2. #|-*- mode:lisp -*-|#
  3. #|
  4. exec ros -Q -- $0 "$@"
  5. |#
  6. (progn ;;init forms
  7. (ros:ensure-asdf)
  8. (ql:quickload '(:lserver :uiop :alexandria) :silent t))
  9. (defpackage :ros.script.lserver.3766064847
  10. (:use :cl))
  11. (in-package :ros.script.lserver.3766064847)
  12. (import 'alexandria:starts-with-subseq)
  13. (import 'alexandria:ensure-list)
  14. (defun help ()
  15. (format t "~&Usage:
  16. lserver --home ~~/.lserver --socket \"my\"~%"))
  17. (defun terminate (&optional message args)
  18. (when message
  19. (format *error-output* "~&Error: ~A~%"
  20. (apply #'format nil (princ-to-string message) (ensure-list args))))
  21. (uiop:quit -1))
  22. (defun parse-args (args)
  23. (flet ((keyp (string)
  24. (starts-with-subseq "--" string))
  25. (parse-value (value)
  26. (or (ignore-errors
  27. (let ((read-value (read-from-string value)))
  28. (if (and (symbolp read-value)
  29. (not (keywordp read-value)))
  30. value
  31. read-value)))
  32. value)))
  33. (let ((path (pop args)))
  34. (when (starts-with-subseq "--" path)
  35. (terminate "No path given."))
  36. (cons (pathname path)
  37. (loop for index from 0 below (length args)
  38. for first = (elt args index)
  39. for rest = (subseq args (incf index))
  40. for key = (or (when (not (keyp first))
  41. (terminate "Invalid option: ~S" first))
  42. (intern (string-upcase (subseq first 2)) :keyword))
  43. for value = (if (eql key :depends-on)
  44. (loop for (item . rest) on rest
  45. collecting item
  46. until (keyp (car rest))
  47. do (incf index))
  48. (parse-value (car rest)))
  49. nconc (list key (parse-value value)))))))
  50. (defparameter options '(:home :socket :help))
  51. (defun argv->args (argv)
  52. (flet ((keyp (string)
  53. (starts-with-subseq "--" string))
  54. (parse-value (value)
  55. (or (ignore-errors
  56. (let ((read-value (read-from-string value)))
  57. (if (and (symbolp read-value)
  58. (not (keywordp read-value)))
  59. value
  60. read-value)))
  61. value)))
  62. (loop for index from 0 below (length argv)
  63. for first = (elt argv index)
  64. for key = (or (when (not (keyp first))
  65. (terminate "Invalid option: ~S" first))
  66. (when (string= first "--help")
  67. (help)
  68. (terminate))
  69. (let ((key (intern (string-upcase (subseq first 2)) :keyword)))
  70. (when (not (member key options))
  71. (terminate "Invalid option: ~S" first))
  72. key))
  73. for second = (or (when (eql (1+ index) (length argv))
  74. (terminate "Invalid null option value: ~S " (list first)))
  75. (elt argv (incf index)))
  76. for value = (or (when (keyp second)
  77. (terminate "Invalid option value: ~S ~S" (list first second)))
  78. second)
  79. nconc (list key (parse-value value)))))
  80. (defun main (&rest argv)
  81. (let ((args (argv->args argv)))
  82. (apply 'lserver:run-server args)))
  83. ;;; vim: set ft=lisp lisp: