summary refs log blame commit diff stats
path: root/lib/pure/matchers.nim
blob: d55963c15527b3610653e0360761ec9aea886db1 (plain) (tree)
e> 2014-02-06 00:27:01 +0100 committer Araq <rumpf_a@web.de> 2014-02-06 00:27:01 +0100 stdlib compiles mostly without warnings again' href='/ahoang/Nim/commit/lib/pure/matchers.nim?h=devel&id=550b5d9aeac9afda613406e3fe4bc243ea7f78d4'>550b5d9ae ^
1
2
3
4

 
                                  
                                         












                                                                         
                           














                                                                   

                                          








                                                                      
                    
 
                                                                    






                                                                           
                                        
                       
           

                               
                  
                                                      


       
#
#
#            Nim's Runtime Library
#        (c) Copyright 2015 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## This module contains various string matchers for email addresses, etc.
{.deadCodeElim: on.}

{.push debugger:off .} # the user does not want to trace a part
                       # of the standard library!

include "system/inclrtl"

import parseutils, strutils

proc validEmailAddress*(s: string): bool {.noSideEffect,
  rtl, extern: "nsuValidEmailAddress".} = 
  ## returns true if `s` seems to be a valid e-mail address. 
  ## The checking also uses a domain list.
  const
    chars = Letters + Digits + {'!','#','$','%','&',
      '\'','*','+','/','=','?','^','_','`','{','}','|','~','-','.'}
  var i = 0
  if s[i] notin chars or s[i] == '.': return false
  while s[i] in chars: 
    if s[i] == '.' and s[i+1] == '.': return false
    inc(i)
  if s[i] != '@': return false
  var j = len(s)-1
  if s[j] notin Letters: return false
  while j >= i and s[j] in Letters: dec(j)
  inc(i) # skip '@'
  while s[i] in {'0'..'9', 'a'..'z', '-', '.'}: inc(i) 
  if s[i] != '\0': return false
  
  var x = substr(s, j+1)
  if len(x) == 2 and x[0] in Letters and x[1] in Letters: return true
  case toLower(x)
  of "com", "org", "net", "gov", "mil", "biz", "info", "mobi", "name",
     "aero", "jobs", "museum": return true
  else: return false

proc parseInt*(s: string, value: var int, validRange: Slice[int]) {.
  noSideEffect, rtl, extern: "nmatchParseInt".} =
  ## parses `s` into an integer in the range `validRange`. If successful,
  ## `value` is modified to contain the result. Otherwise no exception is
  ## raised and `value` is not touched; this way a reasonable default value
  ## won't be overwritten.
  var x = value
  try:
    discard parseutils.parseInt(s, x, 0)
  except OverflowError:
    discard
  if x in validRange: value = x

when isMainModule:
  doAssert "wuseldusel@codehome.com".validEmailAddress
  
{.pop.}