aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2011-06-15 15:38:27 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2011-06-15 15:38:27 +0300
commit516f479a1ddb3bb783a01e9ffb20ba051243ffd0 (patch)
treebaa64c57bf1cc11bed2bd894d75cd605e21c3ff9
parent3340ce32eb576ff355b83fc78a189b897b7fc424 (diff)
downloadellinika-516f479a1ddb3bb783a01e9ffb20ba051243ffd0.tar.gz
ellinika-516f479a1ddb3bb783a01e9ffb20ba051243ffd0.tar.bz2
Improve error handling in conj.
* src/cgi-bin/conj.scm4: Add error handling. * src/ellinika/conjugator.scm: Throw 'conjugator-error instead of calling (error). * src/ellinika/elmorph.c: Use ~A in error messages when referring to elstrs. Guile's ~S sucks on UTF-8. * src/ellinika/utf8scm.c: Likewise. * style.css (.error): Output in red.
-rw-r--r--src/cgi-bin/conj.scm480
-rw-r--r--src/ellinika/conjugator.scm6
-rw-r--r--src/ellinika/elmorph.c28
-rw-r--r--src/ellinika/utf8scm.c8
-rw-r--r--style.css1
5 files changed, 89 insertions, 34 deletions
diff --git a/src/cgi-bin/conj.scm4 b/src/cgi-bin/conj.scm4
index 931c580..253de1d 100644
--- a/src/cgi-bin/conj.scm4
+++ b/src/cgi-bin/conj.scm4
@@ -21,6 +21,7 @@
(use-modules ifelse(IFACE,[CGI],(www cgi),(guile-user))
(srfi srfi-1)
(ice-9 rdelim)
+ (ice-9 optargs)
(xmltools dict)
(ellinika elmorph)
(ellinika tenses)
@@ -133,7 +134,7 @@ ifelse(IFACE,[CGI],(cgi:init))
lst))
-(define (format-tenses count tense-names voice mood verb)
+(define (format-tenses count tense-list voice mood)
(let ((prosopa (if (string=? mood "imp")
'(2 5)
'(1 2 3 4 5 6))))
@@ -150,21 +151,20 @@ ifelse(IFACE,[CGI],(cgi:init))
(display "</tr>"))))
(transpose
(map
- (lambda (tense)
- (let ((conj (conjugator verb voice mood tense)))
- (compact-conj-list (transpose (map conjugation:table conj)))))
- tense-names))
+ (lambda (conj)
+ (compact-conj-list (transpose (map conjugation:table conj))))
+ tense-list))
'(1 2 3 4 5 6)
'("odd" "even" "odd" "even" "odd" "even"))))
-(define (show-conjugation:mood voice mood tense-list verb)
+(define (show-conjugation:mood voice mood tense-list)
(format #t "<div class=\"subsection\"><h3>~A</h3>"
(ellinika-conjugation-term mood))
(for-each
(lambda (count)
(let ((tenses (list-head tense-list count)))
- (table-header count tenses)
- (format-tenses count tenses voice mood verb)
+ (table-header count (map car tenses))
+ (format-tenses count (map cdr tenses) voice mood)
(table-footer)
(set! tense-list (list-tail tense-list count))
(if (not (null? tense-list))
@@ -172,19 +172,71 @@ ifelse(IFACE,[CGI],(cgi:init))
(assoc-ref tense-driver-list mood))
(display "</div>"))
-(define (show-conjugation:voice voice verb)
+(define (show-conjugation:voice voice)
(format #t "<div class=\"section\"><h2>~A</h2>"
- (ellinika-conjugation-term voice))
+ (ellinika-conjugation-term (car voice)))
(for-each
(lambda (mood-tenses)
- (show-conjugation:mood voice (car mood-tenses) (cdr mood-tenses) verb))
- ellinika-tense-list)
+ (show-conjugation:mood voice (car mood-tenses) (cdr mood-tenses)))
+ (cdr voice))
(display "</div>"))
+(define (conjugate-all verb)
+ (map
+ (lambda (voice)
+ (cons voice
+ (map
+ (lambda (mood-tenses)
+ (let ((mood (car mood-tenses)))
+ (cons mood
+ (map
+ (lambda (tense)
+ (cons tense
+ (conjugator verb voice mood tense)))
+ (cdr mood-tenses)))))
+ ellinika-tense-list)))
+ '("act" "pas")))
+
+(define (force-string str)
+ (if (elstr? str)
+ (elstr->string str)
+ str))
+
+(define (error-message fmtstr . fmtargs)
+ (display "<h2 class=\"error\">")
+ (apply format #t fmtstr fmtargs)
+ (display "</h2>"))
+
(define (show-conjugation verb)
- (show-conjugation:voice "act" verb)
- (show-conjugation:voice "pas" verb))
+ (catch #t
+ (lambda ()
+ (for-each
+ (lambda (voice)
+ (show-conjugation:voice voice))
+ (conjugate-all verb)))
+ (lambda (key . args)
+ (case key
+ ((conjugator-error)
+ (let-optional
+ args
+ (subkey fmtstr fmtargs)
+ (case subkey
+ ((conjugator-error-input)
+ (error-message "Invalid input"))
+ (else
+ (error-message "CONJUGATOR ERROR: ~A ~A"
+ subkey (apply format #f fmtstr fmtargs))))))
+ ((misc-error)
+ (let-optional
+ args
+ (func-name fmtstr fmtargs sys-err)
+ (error-message "MISC ERROR in ~A: ~A"
+ func-name
+ (apply format #f fmtstr
+ (map force-string fmtargs)))))
+ (else
+ (error-message "OTHER ERROR: ~S ~S" key args))))))
(define (do-conj)
(let ((keyval (cgi:value "key")))
diff --git a/src/ellinika/conjugator.scm b/src/ellinika/conjugator.scm
index 41575c2..8172686 100644
--- a/src/ellinika/conjugator.scm
+++ b/src/ellinika/conjugator.scm
@@ -178,7 +178,8 @@ WHERE verb=\"~A\" AND voice=\"~A\" AND thema=\"~A\""
((elstr-suffix? verb "ομαι")
(elstr-trim verb -4))
(else
- (error "cannot handle ~A~%" verb))))
+ (throw 'conjugator-error 'conjugator-error-input
+ "cannot handle ~A" (list (force-string verb))))))
(define (complement-verb-info vinfo verb voice thema)
; (format #t "COMPLEMENT ~A~%" vinfo)
@@ -417,7 +418,8 @@ AND c.tense=\"~A\" AND c.flect = f.ident ORDER by fold"
(else 3)))
obj))))
(else
- (error "invalid accent character" acc))))
+ (throw 'conjugator-error 'conjugator-error-db
+ "invalid accent character ~A" (list acc)))))
(conj-info #:flect conj)
accmap)))
(if (conj-info #:particle conj)
diff --git a/src/ellinika/elmorph.c b/src/ellinika/elmorph.c
index 56bead3..90a156d 100644
--- a/src/ellinika/elmorph.c
+++ b/src/ellinika/elmorph.c
@@ -265,7 +265,7 @@ force_elstr(struct elstr **ep, SCM scm, int sylopt,
free(str);
if (newscm == SCM_EOL)
scm_misc_error(func_name,
- "Invalid input string: ~S",
+ "Invalid input string: ~A",
scm_list_1(scm));
scm = newscm;
elstr = (struct elstr*) SCM_CDR(newscm);
@@ -357,7 +357,7 @@ SCM_DEFINE_PUBLIC(scm_elstr_syllable_prop, "elstr-syllable-prop",
if (num > elstr->nsyl)
scm_misc_error(FUNC_NAME,
"cannot get syllable #~S: not enough syllables: ~S",
- scm_list_2(el, n));
+ scm_list_2(n, el));
num = elstr->nsyl - num;
return scm_list_3(scm_from_uint(elstr->sylmap[num].char_start),
@@ -406,7 +406,7 @@ SCM_DEFINE_PUBLIC(scm_elstr_syllable, "elstr-syllable",
if (num > elstr->nsyl)
scm_misc_error(FUNC_NAME,
"cannot get syllable #~S: not enough syllables: ~S",
- scm_list_2(el, n));
+ scm_list_2(n, el));
num = elstr->nsyl - num;
if (utf8_wc_to_mbstr(elstr->str + elstr->sylmap[num].char_start,
elstr->sylmap[num].char_count,
@@ -437,7 +437,7 @@ SCM_DEFINE_PUBLIC(scm_elstr_character, "elstr-character",
if (num >= elstr->len)
scm_misc_error(FUNC_NAME,
"cannot get character #~S: not enough characters: ~S",
- scm_list_2(el, n));
+ scm_list_2(n, el));
len = utf8_wctomb(r, elstr->str[num]);
if (len <= 0)
scm_misc_error(FUNC_NAME,
@@ -574,7 +574,7 @@ _elstr_set_accent(SCM el, SCM n, int destructive, const char *func_name)
num = scm_to_uint(n);
if (num == 0 | num > elstr->nsyl)
scm_misc_error(func_name,
- "cannot set accent on syllable #~S: not enough syllables: ~S",
+ "cannot set accent on syllable #~S: not enough syllables: ~A",
scm_list_2(n, el));
acc_num = elstr->nsyl - num;
@@ -607,7 +607,7 @@ _elstr_set_accent(SCM el, SCM n, int destructive, const char *func_name)
}
if (!phoneme)
scm_misc_error(func_name,
- "cannot set accent on syllable #~S of ~S: "
+ "cannot set accent on syllable #~S of ~A: "
"INTERNAL ERROR",
scm_list_2(n, el));
else if (phoneme->flags & CHF_DIPHTHONG)
@@ -659,12 +659,12 @@ _elstr_set_accent_on_char(SCM el, SCM n, int destructive, const char *func_name)
num = scm_to_uint(n);
if (num > elstr->len)
scm_misc_error(func_name,
- "cannot set accent on character #~S: not enough characters: ~S",
- scm_list_2(el, n));
+ "cannot set accent on character #~S: not enough characters: ~A",
+ scm_list_2(n, el));
if (!elchr_isvowel(elstr->str[num]))
scm_misc_error(func_name,
- "cannot set accent on character #~S: not a vowel: ~S",
- scm_list_2(el, n));
+ "cannot set accent on character #~S: not a vowel: ~A",
+ scm_list_2(n, el));
if (destructive)
scm = SCM_UNSPECIFIED;
@@ -718,8 +718,8 @@ SCM_DEFINE_PUBLIC(scm_elstr_char_prop_bitmask, "elstr-char-prop-bitmask",
num += elstr->len;
if (num >= elstr->len)
scm_misc_error(FUNC_NAME,
- "cannot get character #~S: not enough characters: ~S",
- scm_list_2(el, n));
+ "cannot get character #~S: not enough characters: ~A",
+ scm_list_2(n, el));
return scm_from_uint(elchr_flags(elstr->str[num]));
}
#undef FUNC_NAME
@@ -763,8 +763,8 @@ SCM_DEFINE_PUBLIC(scm_elstr_char_phoneme, "elstr-char-phoneme",
num += elstr->len;
if (num >= elstr->len)
scm_misc_error(FUNC_NAME,
- "cannot get character #~S: not enough characters: ~S",
- scm_list_2(el, n));
+ "cannot get character #~S: not enough characters: ~A",
+ scm_list_2(n, el));
return scm_from_uint(elchr_phoneme(elstr->str[num]));
}
#undef FUNC_NAME
diff --git a/src/ellinika/utf8scm.c b/src/ellinika/utf8scm.c
index 89f5fba..1cb7f76 100644
--- a/src/ellinika/utf8scm.c
+++ b/src/ellinika/utf8scm.c
@@ -35,7 +35,7 @@ SCM_DEFINE_PUBLIC(scm_utf8_toupper, "utf8-toupper", 1, 0, 0,
str = scm_to_locale_string(string);
if (utf8_toupper(str, strlen(str)))
scm_misc_error(FUNC_NAME,
- "cannot convert to upper case: ~S",
+ "cannot convert to upper case: ~A",
scm_list_1(string));
scm = scm_from_locale_string(str);
free(str);
@@ -55,7 +55,7 @@ SCM_DEFINE_PUBLIC(scm_utf8_tolower, "utf8-tolower", 1, 0, 0,
str = scm_to_locale_string(string);
if (utf8_tolower(str, strlen(str)))
scm_misc_error(FUNC_NAME,
- "cannot convert to lower case: ~S",
+ "cannot convert to lower case: ~A",
scm_list_1(string));
scm = scm_from_locale_string(str);
free(str);
@@ -90,7 +90,7 @@ SCM_DEFINE_PUBLIC(scm_utf8_escape, "utf8-escape", 1, 1, 0,
if (utf8_mbstr_to_wc(s, &wptr, &wlen))
scm_misc_error(FUNC_NAME,
- "cannot convert ~S to UTF-8",
+ "cannot convert ~A to UTF-8",
scm_list_1(string));
free(s);
@@ -106,7 +106,7 @@ SCM_DEFINE_PUBLIC(scm_utf8_escape, "utf8-escape", 1, 1, 0,
if (utf8_mbstr_to_wc(s, &escbase, &esclen)) {
free(wptr);
scm_misc_error(FUNC_NAME,
- "cannot convert ~S to UTF-8",
+ "cannot convert ~A to UTF-8",
scm_list_1(escapable));
}
escptr = escbase;
diff --git a/style.css b/style.css
index b09f8b7..67cf8a1 100644
--- a/style.css
+++ b/style.css
@@ -366,6 +366,7 @@ sup {
}
.error {
+ color: red;
}
.date {

Return to:

Send suggestions and report system problems to the System administrator.