1 | ;;;; $Id: utility.lisp 2 2004-01-05 14:13:03Z eenge $ |
---|
2 | ;;;; $Source$ |
---|
3 | |
---|
4 | ;;;; See the LICENSE file for licensing information. |
---|
5 | |
---|
6 | (in-package :irc) |
---|
7 | |
---|
8 | (defun get-day-name (day-number) |
---|
9 | "Given a number, such as 1, return the appropriate day name, |
---|
10 | abbrevated, such as \"Tue\". Index 0 is Monday." |
---|
11 | (case day-number |
---|
12 | (0 "Mon") |
---|
13 | (1 "Tue") |
---|
14 | (2 "Wed") |
---|
15 | (3 "Thu") |
---|
16 | (4 "Fri") |
---|
17 | (5 "Sat") |
---|
18 | (6 "Sun") |
---|
19 | (otherwise |
---|
20 | (error "Unknown day ~A." day-number)))) |
---|
21 | |
---|
22 | (defun get-month-name (month-number) |
---|
23 | "Index 1 is January." |
---|
24 | (case month-number |
---|
25 | (1 "Jan") |
---|
26 | (2 "Feb") |
---|
27 | (3 "Mar") |
---|
28 | (4 "Apr") |
---|
29 | (5 "May") |
---|
30 | (6 "Jun") |
---|
31 | (7 "Jul") |
---|
32 | (8 "Aug") |
---|
33 | (9 "Sep") |
---|
34 | (10 "Oct") |
---|
35 | (11 "Nov") |
---|
36 | (12 "Dec") |
---|
37 | (otherwise |
---|
38 | (error "Unknown month ~A." month-number)))) |
---|
39 | |
---|
40 | (defun make-time-message (second minute hour date month year day) |
---|
41 | "Returns a string composed of the input parameters so that it |
---|
42 | represents a time message as by the IRC protocol." |
---|
43 | (format nil "~A ~A ~2D ~2,'0D:~2,'0D:~2,'0D ~D" |
---|
44 | (get-day-name day) |
---|
45 | (get-month-name month) |
---|
46 | date |
---|
47 | hour |
---|
48 | minute |
---|
49 | second |
---|
50 | year)) |
---|
51 | |
---|
52 | (defun make-irc-message (command &key (arguments nil) |
---|
53 | (trailing-argument nil)) |
---|
54 | "Return a valid IRC message, as a string, composed of the input |
---|
55 | parameters." |
---|
56 | (let ((*print-circle* nil)) |
---|
57 | (format nil "~A~{ ~A~}~A~A~A~A" command arguments |
---|
58 | (if trailing-argument |
---|
59 | " :" |
---|
60 | "") |
---|
61 | (or trailing-argument "") |
---|
62 | #\Return |
---|
63 | #\Linefeed))) |
---|
64 | |
---|
65 | (defun make-ctcp-message (string) |
---|
66 | "Return a valid IRC CTCP message, as a string, composed by |
---|
67 | `string'." |
---|
68 | (format nil "~A~A~A" +soh+ string +soh+)) |
---|
69 | |
---|
70 | (defun tokenize-string (string &key |
---|
71 | (delimiters '(#\Space #\Return #\Linefeed #\Newline))) |
---|
72 | "Split string into a list, splitting on `delimiters' and removing any |
---|
73 | empty subsequences." |
---|
74 | (split-sequence:split-sequence-if #'(lambda (character) |
---|
75 | (member character delimiters)) |
---|
76 | string :remove-empty-subseqs t)) |
---|
77 | |
---|
78 | (defun list-of-strings-to-integers (list) |
---|
79 | "Take a list of strings and return a new list of integers (from |
---|
80 | parse-integer) on each of the string elements." |
---|
81 | (let ((new-list nil)) |
---|
82 | (dolist (element (reverse list)) |
---|
83 | (push (parse-integer element) new-list)) |
---|
84 | new-list)) |
---|
85 | |
---|
86 | (defun host-byte-order (string) |
---|
87 | "Convert a string, such as 192.168.1.1, to host-byte-order, such as |
---|
88 | 3232235777." |
---|
89 | (let ((list (list-of-strings-to-integers (split-sequence:split-sequence #\. string)))) |
---|
90 | (+ (* (first list) 256 256 256) (* (second list) 256 256) |
---|
91 | (* (third list) 256) (fourth list)))) |
---|
92 | |
---|
93 | (defun hbo-to-dotted-quad (integer) |
---|
94 | "Host-byte-order integer to dotted-quad string conversion utility." |
---|
95 | (let ((first (ldb (byte 8 24) integer)) |
---|
96 | (second (ldb (byte 8 16) integer)) |
---|
97 | (third (ldb (byte 8 8) integer)) |
---|
98 | (fourth (ldb (byte 8 0) integer))) |
---|
99 | (format nil "~A.~A.~A.~A" first second third fourth))) |
---|
100 | |
---|
101 | (defun hbo-to-vector-quad (integer) |
---|
102 | "Host-byte-order integer to dotted-quad string conversion utility." |
---|
103 | (let ((first (ldb (byte 8 24) integer)) |
---|
104 | (second (ldb (byte 8 16) integer)) |
---|
105 | (third (ldb (byte 8 8) integer)) |
---|
106 | (fourth (ldb (byte 8 0) integer))) |
---|
107 | (vector first second third fourth))) |
---|
108 | |
---|
109 | (defun cut-between (string start-char end-chars &key (start 0) (cut-extra t)) |
---|
110 | "If `start-char' is not nil, cut string between `start-char' and any |
---|
111 | of the `end-chars', from `start'. If `start-char' is nil, cut from |
---|
112 | `start' until any of the `end-chars'. |
---|
113 | |
---|
114 | If `cut-extra' is t, we will cut from start + 1 instead of just |
---|
115 | `start'. |
---|
116 | |
---|
117 | When there is no string matching the input parameters `start' and nil |
---|
118 | will be returned, otherwise `end-position' and the string are |
---|
119 | returned." |
---|
120 | (let ((end-position (position-if #'(lambda (char) |
---|
121 | (member char end-chars)) |
---|
122 | string :start (1+ start))) |
---|
123 | (cut-from (if cut-extra |
---|
124 | (1+ start) |
---|
125 | start))) |
---|
126 | (if (and end-position start-char) |
---|
127 | (if (eql (char string start) start-char) |
---|
128 | (values end-position |
---|
129 | (subseq string cut-from end-position)) |
---|
130 | (values start nil)) |
---|
131 | (if end-position |
---|
132 | (values end-position |
---|
133 | (subseq string cut-from end-position)) |
---|
134 | (values start nil))))) |
---|