validate.tcl

Go to the documentation of this file.
00001 /* -----------------------------------------------------------------------*/
00002 /*  TITLE:*/
00003 /*     validate.tcl*/
00004 /* */
00005 /*  AUTHOR:*/
00006 /*     Will Duquette*/
00007 /* */
00008 /*  DESCRIPTION:*/
00009 /*     Snit validation types.*/
00010 /* */
00011 /* -----------------------------------------------------------------------*/
00012 
00013 namespace ::snit:: { 
00014     namespace export \
00015         boolean \
00016         double \
00017         enum \
00018         fpixels \
00019         integer \
00020         listtype \
00021         pixels \
00022         stringtype \
00023         window
00024 }
00025 
00026 /* -----------------------------------------------------------------------*/
00027 /*  snit::boolean*/
00028 
00029 snit::type ::snit::boolean {
00030     /* -------------------------------------------------------------------*/
00031     /*  Type Methods*/
00032 
00033     typeret  validate (type value) {
00034         if {![string is boolean -strict $value]} {
00035             return -code error \
00036    "invalid boolean \"$value\", should be one of: 1, 0, true, false, yes, no, on, off"
00037 
00038         }
00039 
00040         return
00041     }
00042 
00043     /* -------------------------------------------------------------------*/
00044     /*  Constructor*/
00045 
00046     /*  None needed; no options*/
00047 
00048     /* -------------------------------------------------------------------*/
00049     /*  Public Methods*/
00050 
00051     ret  validate (type value) {
00052         $type validate $value
00053     }
00054 }
00055 
00056 /* -----------------------------------------------------------------------*/
00057 /*  snit::double*/
00058 
00059 snit::type ::snit::double {
00060     /* -------------------------------------------------------------------*/
00061     /*  Options*/
00062 
00063     /*  -min value*/
00064     /* */
00065     /*  Minimum value*/
00066 
00067     option -min -default "" -readonly 1
00068 
00069     /*  -max value*/
00070     /* */
00071     /*  Maximum value*/
00072 
00073     option -max -default "" -readonly 1
00074 
00075     /* -------------------------------------------------------------------*/
00076     /*  Type Methods*/
00077 
00078     typeret  validate (type value) {
00079         if {![string is double -strict $value]} {
00080             return -code error \
00081                 "invalid value \"$value\", expected double"
00082         }
00083 
00084         return
00085     }
00086 
00087     /* -------------------------------------------------------------------*/
00088     /*  Constructor*/
00089 
00090     constructor {args} {
00091         /*  FIRST, get the options*/
00092         $self configurelist $args
00093 
00094         if {"" != $options(-min) && 
00095             ![string is double -strict $options(-min)]} {
00096             return -code error \
00097                 "invalid -min: \"$options(-min)\""
00098         }
00099 
00100         if {"" != $options(-max) && 
00101             ![string is double -strict $options(-max)]} {
00102             return -code error \
00103                 "invalid -max: \"$options(-max)\""
00104         }
00105 
00106         if {"" != $options(-min) &&
00107             "" != $options(-max) && 
00108             $options(-max) < $options(-min)} {
00109             return -code error "-max < -min"
00110         }
00111     }
00112 
00113     /* -------------------------------------------------------------------*/
00114     /*  Public Methods*/
00115 
00116     ret  validate (type value) {
00117         $type validate $value
00118 
00119         if {("" != $options(-min) && $value < $options(-min))       ||
00120             ("" != $options(-max) && $value > $options(-max))} {
00121 
00122             set msg "invalid value \"$value\", expected double"
00123 
00124             if {"" != $options(-min) && "" != $options(-max)} {
00125                 append msg " in range $options(-min), $options(-max)"
00126             } elseif {"" != $options(-min)} {
00127                 append msg " no less than $options(-min)"
00128             }
00129         
00130             return -code error $msg
00131         }
00132 
00133         return
00134     }
00135 }
00136 
00137 /* -----------------------------------------------------------------------*/
00138 /*  snit::enum*/
00139 
00140 snit::type ::snit::enum {
00141     /* -------------------------------------------------------------------*/
00142     /*  Options*/
00143 
00144     /*  -values list*/
00145     /* */
00146     /*  Valid values for this type*/
00147 
00148     option -values -default {} -readonly 1
00149 
00150     /* -------------------------------------------------------------------*/
00151     /*  Type Methods*/
00152 
00153     typeret  validate (type value) {
00154         # No -values specified; it's always valid
00155         return
00156     }
00157 
00158     /* -------------------------------------------------------------------*/
00159     /*  Constructor*/
00160 
00161     constructor {args} {
00162         $self configurelist $args
00163 
00164         if {[llength $options(-values)] == 0} {
00165             return -code error \
00166                 "invalid -values: \"\""
00167         }
00168     }
00169 
00170     /* -------------------------------------------------------------------*/
00171     /*  Public Methods*/
00172 
00173     ret  validate (type value) {
00174         if {[lsearch -exact $options(-values) $value] == -1} {
00175             return -code error \
00176     "invalid value \"$value\", should be one of: [join $options(-values) {, }]"
00177         }
00178     }
00179 }
00180 
00181 /* -----------------------------------------------------------------------*/
00182 /*  snit::fpixels*/
00183 
00184 snit::type ::snit::fpixels {
00185     /* -------------------------------------------------------------------*/
00186     /*  Options*/
00187 
00188     /*  -min value*/
00189     /* */
00190     /*  Minimum value*/
00191 
00192     option -min -default "" -readonly 1
00193 
00194     /*  -max value*/
00195     /* */
00196     /*  Maximum value*/
00197 
00198     option -max -default "" -readonly 1
00199 
00200     /* -------------------------------------------------------------------*/
00201     /*  Instance variables*/
00202 
00203     variable min ""  ;/*  -min, no suffix*/
00204     variable max ""  ;/*  -max, no suffix*/
00205 
00206     /* -------------------------------------------------------------------*/
00207     /*  Type Methods*/
00208 
00209     typeret  validate (type value) {
00210         if {[catch {winfo fpixels . $value} dummy]} {
00211             return -code error \
00212                 "invalid value \"$value\", expected fpixels"
00213         }
00214 
00215         return
00216     }
00217 
00218     /* -------------------------------------------------------------------*/
00219     /*  Constructor*/
00220 
00221     constructor {args} {
00222         /*  FIRST, get the options*/
00223         $self configurelist $args
00224 
00225         if {"" != $options(-min) && 
00226             [catch {winfo fpixels . $options(-min)} min]} {
00227             return -code error \
00228                 "invalid -min: \"$options(-min)\""
00229         }
00230 
00231         if {"" != $options(-max) && 
00232             [catch {winfo fpixels . $options(-max)} max]} {
00233             return -code error \
00234                 "invalid -max: \"$options(-max)\""
00235         }
00236 
00237         if {"" != $min &&
00238             "" != $max && 
00239             $max < $min} {
00240             return -code error "-max < -min"
00241         }
00242     }
00243 
00244     /* -------------------------------------------------------------------*/
00245     /*  Public Methods*/
00246 
00247     ret  validate (type value) {
00248         $type validate $value
00249         
00250         set val [winfo fpixels . $value]
00251 
00252         if {("" != $min && $val < $min) ||
00253             ("" != $max && $val > $max)} {
00254 
00255             set msg "invalid value \"$value\", expected fpixels"
00256 
00257             if {"" != $min && "" != $max} {
00258                 append msg " in range $options(-min), $options(-max)"
00259             } elseif {"" != $min} {
00260                 append msg " no less than $options(-min)"
00261             }
00262         
00263             return -code error $msg
00264         }
00265 
00266         return
00267     }
00268 }
00269 
00270 /* -----------------------------------------------------------------------*/
00271 /*  snit::integer*/
00272 
00273 snit::type ::snit::integer {
00274     /* -------------------------------------------------------------------*/
00275     /*  Options*/
00276 
00277     /*  -min value*/
00278     /* */
00279     /*  Minimum value*/
00280 
00281     option -min -default "" -readonly 1
00282 
00283     /*  -max value*/
00284     /* */
00285     /*  Maximum value*/
00286 
00287     option -max -default "" -readonly 1
00288 
00289     /* -------------------------------------------------------------------*/
00290     /*  Type Methods*/
00291 
00292     typeret  validate (type value) {
00293         if {![string is integer -strict $value]} {
00294             return -code error \
00295                 "invalid value \"$value\", expected integer"
00296         }
00297 
00298         return
00299     }
00300 
00301     /* -------------------------------------------------------------------*/
00302     /*  Constructor*/
00303 
00304     constructor {args} {
00305         /*  FIRST, get the options*/
00306         $self configurelist $args
00307 
00308         if {"" != $options(-min) && 
00309             ![string is integer -strict $options(-min)]} {
00310             return -code error \
00311                 "invalid -min: \"$options(-min)\""
00312         }
00313 
00314         if {"" != $options(-max) && 
00315             ![string is integer -strict $options(-max)]} {
00316             return -code error \
00317                 "invalid -max: \"$options(-max)\""
00318         }
00319 
00320         if {"" != $options(-min) &&
00321             "" != $options(-max) && 
00322             $options(-max) < $options(-min)} {
00323             return -code error "-max < -min"
00324         }
00325     }
00326 
00327     /* -------------------------------------------------------------------*/
00328     /*  Public Methods*/
00329 
00330     ret  validate (type value) {
00331         $type validate $value
00332 
00333         if {("" != $options(-min) && $value < $options(-min))       ||
00334             ("" != $options(-max) && $value > $options(-max))} {
00335 
00336             set msg "invalid value \"$value\", expected integer"
00337 
00338             if {"" != $options(-min) && "" != $options(-max)} {
00339                 append msg " in range $options(-min), $options(-max)"
00340             } elseif {"" != $options(-min)} {
00341                 append msg " no less than $options(-min)"
00342             }
00343         
00344             return -code error $msg
00345         }
00346 
00347         return
00348     }
00349 }
00350 
00351 /* -----------------------------------------------------------------------*/
00352 /*  snit::list*/
00353 
00354 snit::type ::snit::listtype {
00355     /* -------------------------------------------------------------------*/
00356     /*  Options*/
00357 
00358     /*  -type type*/
00359     /* */
00360     /*  Specifies a value type*/
00361 
00362     option -type -readonly 1
00363 
00364     /*  -minlen len*/
00365     /* */
00366     /*  Minimum list length*/
00367 
00368     option -minlen -readonly 1 -default 0
00369 
00370     /*  -maxlen len*/
00371     /* */
00372     /*  Maximum list length*/
00373 
00374     option -maxlen -readonly 1
00375 
00376     /* -------------------------------------------------------------------*/
00377     /*  Type Methods*/
00378 
00379     typeret  validate (type value) {
00380         if {[catch {llength $value} result]} {
00381             return -code error \
00382                 "invalid value \"$value\", expected list"
00383         }
00384 
00385         return
00386     }
00387 
00388     /* -------------------------------------------------------------------*/
00389     /*  Constructor*/
00390     
00391     constructor {args} {
00392         /*  FIRST, get the options*/
00393         $self configurelist $args
00394 
00395         if {"" != $options(-minlen) && 
00396             (![string is integer -strict $options(-minlen)] ||
00397              $options(-minlen) < 0)} {
00398             return -code error \
00399                 "invalid -minlen: \"$options(-minlen)\""
00400         }
00401 
00402         if {"" == $options(-minlen)} {
00403              options = (-minlen) 0
00404         }
00405 
00406         if {"" != $options(-maxlen) && 
00407             ![string is integer -strict $options(-maxlen)]} {
00408             return -code error \
00409                 "invalid -maxlen: \"$options(-maxlen)\""
00410         }
00411 
00412         if {"" != $options(-maxlen) && 
00413             $options(-maxlen) < $options(-minlen)} {
00414             return -code error "-maxlen < -minlen"
00415         }
00416     }
00417 
00418 
00419     /* -------------------------------------------------------------------*/
00420     /*  Methods*/
00421 
00422     ret  validate (type value) {
00423         $type validate $value
00424 
00425         set len [llength $value]
00426 
00427         if {$len < $options(-minlen)} {
00428             return -code error \
00429               "value has too few elements; at least $options(-minlen) expected"
00430         } elseif {"" != $options(-maxlen)} {
00431             if {$len > $options(-maxlen)} {
00432                 return -code error \
00433          "value has too many elements; no more than $options(-maxlen) expected"
00434             }
00435         }
00436 
00437         # NEXT, check each value
00438         if {"" != $options(-type)} {
00439             foreach item $value {
00440                 set cmd $options(-type)
00441                 lappend cmd validate $item
00442                 uplevel \#0 $cmd
00443             }
00444         }
00445     }
00446 }
00447 
00448 /* -----------------------------------------------------------------------*/
00449 /*  snit::pixels*/
00450 
00451 snit::type ::snit::pixels {
00452     /* -------------------------------------------------------------------*/
00453     /*  Options*/
00454 
00455     /*  -min value*/
00456     /* */
00457     /*  Minimum value*/
00458 
00459     option -min -default "" -readonly 1
00460 
00461     /*  -max value*/
00462     /* */
00463     /*  Maximum value*/
00464 
00465     option -max -default "" -readonly 1
00466 
00467     /* -------------------------------------------------------------------*/
00468     /*  Instance variables*/
00469 
00470     variable min ""  ;/*  -min, no suffix*/
00471     variable max ""  ;/*  -max, no suffix*/
00472 
00473     /* -------------------------------------------------------------------*/
00474     /*  Type Methods*/
00475 
00476     typeret  validate (type value) {
00477         if {[catch {winfo pixels . $value} dummy]} {
00478             return -code error \
00479                 "invalid value \"$value\", expected pixels"
00480         }
00481 
00482         return
00483     }
00484 
00485     /* -------------------------------------------------------------------*/
00486     /*  Constructor*/
00487 
00488     constructor {args} {
00489         /*  FIRST, get the options*/
00490         $self configurelist $args
00491 
00492         if {"" != $options(-min) && 
00493             [catch {winfo pixels . $options(-min)} min]} {
00494             return -code error \
00495                 "invalid -min: \"$options(-min)\""
00496         }
00497 
00498         if {"" != $options(-max) && 
00499             [catch {winfo pixels . $options(-max)} max]} {
00500             return -code error \
00501                 "invalid -max: \"$options(-max)\""
00502         }
00503 
00504         if {"" != $min &&
00505             "" != $max && 
00506             $max < $min} {
00507             return -code error "-max < -min"
00508         }
00509     }
00510 
00511     /* -------------------------------------------------------------------*/
00512     /*  Public Methods*/
00513 
00514     ret  validate (type value) {
00515         $type validate $value
00516         
00517         set val [winfo pixels . $value]
00518 
00519         if {("" != $min && $val < $min) ||
00520             ("" != $max && $val > $max)} {
00521 
00522             set msg "invalid value \"$value\", expected pixels"
00523 
00524             if {"" != $min && "" != $max} {
00525                 append msg " in range $options(-min), $options(-max)"
00526             } elseif {"" != $min} {
00527                 append msg " no less than $options(-min)"
00528             }
00529         
00530             return -code error $msg
00531         }
00532 
00533         return
00534     }
00535 }
00536 
00537 /* -----------------------------------------------------------------------*/
00538 /*  snit::stringtype*/
00539 
00540 snit::type ::snit::stringtype {
00541     /* -------------------------------------------------------------------*/
00542     /*  Options*/
00543 
00544     /*  -minlen len*/
00545     /* */
00546     /*  Minimum list length*/
00547 
00548     option -minlen -readonly 1 -default 0
00549 
00550     /*  -maxlen len*/
00551     /* */
00552     /*  Maximum list length*/
00553 
00554     option -maxlen -readonly 1
00555 
00556     /*  -nocase 0|1*/
00557     /* */
00558     /*  globs and regexps are case-insensitive if -nocase 1.*/
00559 
00560     option -nocase -readonly 1 -default 0
00561 
00562     /*  -glob pattern*/
00563     /* */
00564     /*  Glob-match pattern, or ""*/
00565 
00566     option -glob -readonly 1
00567 
00568     /*  -regexp regexp*/
00569     /* */
00570     /*  Regular expression to match*/
00571     
00572     option -regexp -readonly 1
00573     
00574     /* -------------------------------------------------------------------*/
00575     /*  Type Methods*/
00576 
00577     typeret  validate (type value) {
00578         # By default, any string (hence, any Tcl value) is valid.
00579         return
00580     }
00581 
00582     /* -------------------------------------------------------------------*/
00583     /*  Constructor*/
00584     
00585     constructor {args} {
00586         /*  FIRST, get the options*/
00587         $self configurelist $args
00588 
00589         /*  NEXT, validate -minlen and -maxlen*/
00590         if {"" != $options(-minlen) && 
00591             (![string is integer -strict $options(-minlen)] ||
00592              $options(-minlen) < 0)} {
00593             return -code error \
00594                 "invalid -minlen: \"$options(-minlen)\""
00595         }
00596 
00597         if {"" == $options(-minlen)} {
00598              options = (-minlen) 0
00599         }
00600 
00601         if {"" != $options(-maxlen) && 
00602             ![string is integer -strict $options(-maxlen)]} {
00603             return -code error \
00604                 "invalid -maxlen: \"$options(-maxlen)\""
00605         }
00606 
00607         if {"" != $options(-maxlen) && 
00608             $options(-maxlen) < $options(-minlen)} {
00609             return -code error "-maxlen < -minlen"
00610         }
00611 
00612         /*  NEXT, validate -nocase*/
00613         if {[catch {snit::boolean validate $options(-nocase)} result]} {
00614             return -code error "invalid -nocase: $result"
00615         }
00616 
00617         /*  Validate the glob*/
00618         if {"" != $options(-glob) && 
00619             [catch {string match $options(-glob) ""} dummy]} {
00620             return -code error \
00621                 "invalid -glob: \"$options(-glob)\""
00622         }
00623 
00624         /*  Validate the regexp*/
00625         if {"" != $options(-regexp) && 
00626             [catch {regexp $options(-regexp) ""} dummy]} {
00627             return -code error \
00628                 "invalid -regexp: \"$options(-regexp)\""
00629         }
00630     }
00631 
00632 
00633     /* -------------------------------------------------------------------*/
00634     /*  Methods*/
00635 
00636     ret  validate (type value) {
00637         # Usually we'd call [$type validate $value] here, but
00638         # as it's a no-op, don't bother.
00639 
00640         # FIRST, validate the length.
00641         set len [string length $value]
00642 
00643         if {$len < $options(-minlen)} {
00644             return -code error \
00645               "too short: at least $options(-minlen) characters expected"
00646         } elseif {"" != $options(-maxlen)} {
00647             if {$len > $options(-maxlen)} {
00648                 return -code error \
00649          "too long: no more than $options(-maxlen) characters expected"
00650             }
00651         }
00652 
00653         # NEXT, check the glob match, with or without case.
00654         if {"" != $options(-glob)} {
00655             if {$options(-nocase)} {
00656                 set result [string match -nocase $options(-glob) $value]
00657             } else {
00658                 set result [string match $options(-glob) $value]
00659             }
00660             
00661             if {!$result} {
00662                 return -code error \
00663                     "invalid value \"$value\""
00664             }
00665         }
00666         
00667         # NEXT, check regexp match with or without case
00668         if {"" != $options(-regexp)} {
00669             if {$options(-nocase)} {
00670                 set result [regexp -nocase -- $options(-regexp) $value]
00671             } else {
00672                 set result [regexp -- $options(-regexp) $value]
00673             }
00674             
00675             if {!$result} {
00676                 return -code error \
00677                     "invalid value \"$value\""
00678             }
00679         }
00680     }
00681 }
00682 
00683 /* -----------------------------------------------------------------------*/
00684 /*  snit::window*/
00685 
00686 snit::type ::snit::window {
00687     /* -------------------------------------------------------------------*/
00688     /*  Type Methods*/
00689 
00690     typeret  validate (type value) {
00691         if {![winfo exists $value]} {
00692             return -code error \
00693                 "invalid value \"$value\", value is not a window"
00694         }
00695 
00696         return
00697     }
00698 
00699     /* -------------------------------------------------------------------*/
00700     /*  Constructor*/
00701 
00702     /*  None needed; no options*/
00703 
00704     /* -------------------------------------------------------------------*/
00705     /*  Public Methods*/
00706 
00707     ret  validate (type value) {
00708         $type validate $value
00709     }
00710 }
00711 
00712 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1