вторник, 11 октября 2011 г.

Тонкости bash

Не могу не поделится рецептом так как решения "в лоб" я не нашел. Ситуация следующая. В скрипте нужно ненавязчиво проверить установленны ли переменные окружение и если не установлены то установить. При все простоте формулировке задача сложнее чем кажется т.к. например надо учитывать что ряд переменных содержат набор значений. Приветствуйте мой велосипед, он же "деликатный экспорт"

function softexport()
{
eval tmp_export_val=\$$1
if [[ $tmp_export_val == "" ]]
then
eval "export $1=$2"
else
if [ $(expr match $tmp_export_val $2) = 0 ]
then
eval "export $1=\$$1:$2"
fi
fi
}
вызывать соответственно например так
softexport LD_LIBRARY_PATH ${ORACLE_HOME}/lib

З.Ы. пишу скорее как памятку себе потому извините за отсутствие подробностей. Ежеели кому чего не понятно станет спрашивайте - отвечу.

lisp'овое

Продолжаю корчить из себя лиспера. Поскольку часто в emacs, в запале страсти программирования путаю раскладку то и решил по быстрому набросать транслитератор(да, я знаю про xneur). Решил сделать его на CL и потом перевести на eLisp. И опять наткнулся на некую неполноценность elisp. Оказалось что коллекции и строки в нем не тоже самое, в отличие от CL. Ниже приведу код на том и на другом. CL мне нравится все больше. И даже loop который по началу показался чудовищным вдруг начинает нравится.

CommonLisp во все красе.

(defvar *latsym* "qwertyuiop[]asdfghjkl;'zxcvbnm,.`/QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?~")
(defvar *russym* "йцукенгшщзхъфывапролджэячсмитьбю.ёЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,Ё")
(defvar *etalon-rus* "йцукенгшщзхъфывапролджэячсмитьбюёЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ№")
(defvar *ignore-syms* ",./?:\";'{}[]")

(defun translit (bad-string bad-list good-list)
(let ((goot-string "")
     (pos 0))
 (loop for letter across  bad-string
       do (progn
            (setf pos (position letter bad-list))
            (if (equalp pos nil)
                (setf goot-string (concatenate
                                   'string goot-string (string letter)))
              (setf goot-string
                    (concatenate 'string goot-string
                                 (string (elt good-list pos)))))))
 goot-string))

(defun find-in-rus(line)
(loop for letter across line
     do (if (equal (position letter *ignore-syms*) nil)
            (return (position letter *etalon-rus*)))))

(defun reverse-lang(input-str)
(if (find-in-rus input-str)
   (translit input-str *russym* *latsym*)
 (translit input-str   *latsym* *russym*)))

(format t "~s~%" (reverse-lang '"ghbdtn"))

Elisp с проблесками нищеты.
(defvar *latsym* "qwertyuiop[]asdfghjkl;'zxcvbnm,.`/QWERTYUIOP{}ASDFGHJKL:\"ZXCVBNM<>?~")
(defvar *russym* "йцукенгшщзхъфывапролджэячсмитьбю.ёЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮ,Ё")
(defvar *etalon-rus* "йцукенгшщзхъфывапролджэячсмитьбюёЙЦУКЕНГШЩЗХЪФЫВАПРОЛДЖЭЯЧСМИТЬБЮЁ№")
(defvar *ignore-syms* ",./?:\";'{}[]")

(defun str-position(param where-col)  (let ((i 0)
     (retindex -1))
 (while (< i (length where-col))
   (if (string= (string (elt where-col i)) param)
     (setq retindex i))
   (setq i (+ i 1)))
 retindex))

(defun translit (bad-string bad-list good-list)  (let ((goot-string "")
     (pos 0)
     (len 0)
     (letter ""))
 (while (< len (length bad-string))
   (progn
     (setq letter (string (elt bad-string len)))
     (setq pos (str-position letter bad-list))
     (if (equal pos -1)
         (setq goot-string (concat goot-string letter))
       (setq goot-string (concat goot-string
                                 (string (elt good-list pos)))))
     (setq len (+ len 1))))
 goot-string))

(defun find-in-rus(line)  (let ((pos 0)
     (letter "")
     (result -1))
 (while (< pos (length line))
   (progn
     (setq letter (string (elt line pos)))
     (if (equal (str-position letter *ignore-syms*) -1)
         (setq result (str-position letter *etalon-rus*)))
     (setq pos (+ pos 1))))
 result))

(defun reverse-lang(input-str)  (if (>= (find-in-rus input-str) 0)
   (translit input-str *russym* *latsym*)
 (translit input-str   *latsym* *russym*)))

Тем не менее это все работает и тем самым радует меня.

четверг, 6 октября 2011 г.

Переделывание .emacs

Поскольку сейчас на досуге ковыряю Common Lisp то заглянув в свой .emacs пришел в легкий ужас от того что было сделано ранее. Ну и поскольку зуд в руках было не унять переделал все немного. Добавил функцию тригерного подсвечивания слов. Т.е. если слово не подсвечено оно подсвечивается по всему тексту. Если подсвечено то подсветка снимается. Удобно. В процессе создания меня ждало несколько обломов и разочарований.

1) Зачем было давать в elisp другие имена функциям имеющим сходное поведение в CL??

2) Не нашел аналога функции position из CL пришлось писать свой велосипед

3) Удаление элемента из списка. В доке по elisp сказано буквально следующее

— Function: delete object sequence

If sequence is a list, this function destructively removes all
elements equal to object from sequence. For lists, delete is to
delq as member is to memq: it uses equal to compare elements with
object, like member; when it finds an element that matches, it
cuts the element out just as delq would.

оказалось она ни разу не деструктивная.

В результате получилось следующее. Предыдущий вариант можно посмотреть в более ранних постах.
(defvar*highlited* '())

(defunmy-extract-word ()
(interactive)
(let((start 0)
(end 0))
(backward-word 1)
(setq start (point))
(forward-word 1)
(setq end (point))
(buffer-substring start end)))

(defun find-highlited (param)
(let((i 0)
(retindex -1))
(while (< i (length *highlited*))
(if (string= (elt *highlited* i) param)
(setq retindex i))
(setq i (+ i 1)))
retindex))

(defun my-highlight-phrase ()
(interactive)
(let ((curr-word (my-extract-word)))
(if (>= (find-highlited curr-word) 0)
(progn (unhighlight-regexp
(elt *highlited* (find-highlited curr-word)))
(setq *highlited* (delete curr-word *highlited*)))
(progn (highlight-regexp (my-extract-word) 'hi-yellow)
(add-to-list '*highlited* curr-word)))))