diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-06-15 15:38:27 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2011-06-15 15:38:27 +0300 |
commit | 516f479a1ddb3bb783a01e9ffb20ba051243ffd0 (patch) | |
tree | baa64c57bf1cc11bed2bd894d75cd605e21c3ff9 /src | |
parent | 3340ce32eb576ff355b83fc78a189b897b7fc424 (diff) | |
download | ellinika-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/cgi-bin/conj.scm4 | 80 | ||||
-rw-r--r-- | src/ellinika/conjugator.scm | 6 | ||||
-rw-r--r-- | src/ellinika/elmorph.c | 28 | ||||
-rw-r--r-- | src/ellinika/utf8scm.c | 8 |
4 files changed, 88 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; |