about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorbptato <nincsnevem662@gmail.com>2023-06-24 23:39:55 +0200
committerbptato <nincsnevem662@gmail.com>2023-06-24 23:39:55 +0200
commitc7bfcef7e0b5b216300622b085bea417478d9c92 (patch)
tree0c63a658e656b52b3f2317c9766d42a10dd48c60
parent7d7f97b6da90bfed93f9dcab4b480e67715d5d5d (diff)
downloadchawan-c7bfcef7e0b5b216300622b085bea417478d9c92.tar.gz
Option -> Opt in config, return error in compileSearchRegex
-rw-r--r--src/config/config.nim72
-rw-r--r--src/display/pager.nim13
-rw-r--r--src/js/regex.nim22
-rw-r--r--src/main.nim5
-rw-r--r--src/utils/opt.nim6
5 files changed, 63 insertions, 55 deletions
diff --git a/src/config/config.nim b/src/config/config.nim
index 48c0dde9..533ac93f 100644
--- a/src/config/config.nim
+++ b/src/config/config.nim
@@ -26,32 +26,32 @@ type
   ActionMap = Table[string, string]
 
   StaticSiteConfig = object
-    url: Option[string]
-    host: Option[string]
-    rewrite_url: Option[string]
-    cookie: Option[bool]
+    url: Opt[string]
+    host: Opt[string]
+    rewrite_url: Opt[string]
+    cookie: Opt[bool]
     third_party_cookie: seq[string]
-    share_cookie_jar: Option[string]
-    referer_from*: Option[bool]
-    scripting: Option[bool]
+    share_cookie_jar: Opt[string]
+    referer_from*: Opt[bool]
+    scripting: Opt[bool]
     document_charset: seq[Charset]
-    images: Option[bool]
+    images: Opt[bool]
 
   StaticOmniRule = object
     match: string
     substitute_url: string
 
   SiteConfig* = object
-    url*: Option[Regex]
-    host*: Option[Regex]
+    url*: Opt[Regex]
+    host*: Opt[Regex]
     rewrite_url*: (proc(s: URL): Opt[URL])
-    cookie*: Option[bool]
+    cookie*: Opt[bool]
     third_party_cookie*: seq[Regex]
-    share_cookie_jar*: Option[string]
-    referer_from*: Option[bool]
-    scripting*: Option[bool]
+    share_cookie_jar*: Opt[string]
+    referer_from*: Opt[bool]
+    scripting*: Opt[bool]
     document_charset*: seq[Charset]
-    images*: Option[bool]
+    images*: Opt[bool]
 
   OmniRule* = object
     match*: Regex
@@ -69,7 +69,7 @@ type
     wrap*: bool
 
   EncodingConfig = object
-    display_charset*: Option[Charset]
+    display_charset*: Opt[Charset]
     document_charset*: seq[Charset]
 
   ExternalConfig = object
@@ -81,11 +81,11 @@ type
     prepend_https*: bool
 
   DisplayConfig = object
-    color_mode*: Option[ColorMode]
-    format_mode*: Option[FormatMode]
+    color_mode*: Opt[ColorMode]
+    format_mode*: Opt[FormatMode]
     no_format_mode*: FormatMode
     emulate_overline*: bool
-    alt_screen*: Option[bool]
+    alt_screen*: Opt[bool]
     highlight_color*: RGBAColor
     double_width_ambiguous*: bool
     minimum_contrast*: int32
@@ -165,9 +165,9 @@ proc getSiteConfig*(config: Config, jsctx: JSContext): seq[SiteConfig] =
       images: sc.images
     )
     if sc.url.isSome:
-      conf.url = compileRegex(sc.url.get, 0)
+      conf.url = opt(compileRegex(sc.url.get, 0))
     elif sc.host.isSome:
-      conf.host = compileRegex(sc.host.get, 0)
+      conf.host = opt(compileRegex(sc.host.get, 0))
     for rule in sc.third_party_cookie:
       conf.third_party_cookie.add(compileRegex(rule, 0).get)
     if sc.rewrite_url.isSome:
@@ -296,11 +296,11 @@ proc parseConfigValue[T](x: var seq[T], v: TomlValue, k: string)
 proc parseConfigValue(x: var Charset, v: TomlValue, k: string)
 proc parseConfigValue(x: var int32, v: TomlValue, k: string)
 proc parseConfigValue(x: var int64, v: TomlValue, k: string)
-proc parseConfigValue(x: var Option[ColorMode], v: TomlValue, k: string)
-proc parseConfigValue(x: var Option[FormatMode], v: TomlValue, k: string)
+proc parseConfigValue(x: var Opt[ColorMode], v: TomlValue, k: string)
+proc parseConfigValue(x: var Opt[FormatMode], v: TomlValue, k: string)
 proc parseConfigValue(x: var FormatMode, v: TomlValue, k: string)
 proc parseConfigValue(x: var RGBAColor, v: TomlValue, k: string)
-proc parseConfigValue[T](x: var Option[T], v: TomlValue, k: string)
+proc parseConfigValue[T](x: var Opt[T], v: TomlValue, k: string)
 proc parseConfigValue(x: var ActionMap, v: TomlValue, k: string)
 proc parseConfigValue(x: var CSSConfig, v: TomlValue, k: string)
 
@@ -362,26 +362,26 @@ proc parseConfigValue(x: var int64, v: TomlValue, k: string) =
   typeCheck(v, VALUE_INTEGER, k)
   x = v.i
 
-proc parseConfigValue(x: var Option[ColorMode], v: TomlValue, k: string) =
+proc parseConfigValue(x: var Opt[ColorMode], v: TomlValue, k: string) =
   typeCheck(v, VALUE_STRING, k)
   case v.s
-  of "auto": x = none(ColorMode)
-  of "monochrome": x = some(MONOCHROME)
-  of "ansi": x = some(ANSI)
-  of "8bit": x = some(EIGHT_BIT)
-  of "24bit": x = some(TRUE_COLOR)
+  of "auto": x.err()
+  of "monochrome": x.ok(MONOCHROME)
+  of "ansi": x.ok(ANSI)
+  of "8bit": x.ok(EIGHT_BIT)
+  of "24bit": x.ok(TRUE_COLOR)
   else:
     raise newException(ValueError, "unknown color mode '" & v.s &
       "' for key " & k)
 
-proc parseConfigValue(x: var Option[FormatMode], v: TomlValue, k: string) =
+proc parseConfigValue(x: var Opt[FormatMode], v: TomlValue, k: string) =
   typeCheck(v, {VALUE_STRING, VALUE_ARRAY}, k)
   if v.vt == VALUE_STRING and v.s == "auto":
-    x = none(FormatMode)
+    x.err()
   else:
     var y: FormatMode
     parseConfigValue(y, v, k)
-    x = some(y)
+    x.ok(y)
 
 proc parseConfigValue(x: var FormatMode, v: TomlValue, k: string) =
   typeCheck(v, VALUE_ARRAY, k)
@@ -408,13 +408,13 @@ proc parseConfigValue(x: var RGBAColor, v: TomlValue, k: string) =
         "' for key " & k)
   x = c.get
 
-proc parseConfigValue[T](x: var Option[T], v: TomlValue, k: string) =
+proc parseConfigValue[T](x: var Opt[T], v: TomlValue, k: string) =
   if v.vt == VALUE_STRING and v.s == "auto":
-    x = none(T)
+    x.err()
   else:
     var y: T
     parseConfigValue(y, v, k)
-    x = some(y)
+    x.ok(y)
 
 proc parseConfigValue(x: var ActionMap, v: TomlValue, k: string) =
   typeCheck(v, VALUE_TABLE, k)
diff --git a/src/display/pager.nim b/src/display/pager.nim
index 857b93dd..073d68be 100644
--- a/src/display/pager.nim
+++ b/src/display/pager.nim
@@ -29,6 +29,7 @@ import types/color
 import types/cookie
 import types/dispatcher
 import types/url
+import utils/opt
 import utils/twtstr
 
 type
@@ -52,8 +53,8 @@ type
     username: string
     scommand*: string
     config: Config
-    regex: Option[Regex]
-    iregex: Option[Regex]
+    regex: Opt[Regex]
+    iregex: Opt[Regex]
     reverseSearch: bool
     statusgrid*: FixedGrid
     tty: File
@@ -696,12 +697,12 @@ proc updateReadLineISearch(pager: Pager, linemode: LineMode) =
   let lineedit = pager.lineedit.get
   case lineedit.state
   of CANCEL:
-    pager.iregex = none(Regex)
+    pager.iregex.err()
     pager.container.popCursorPos()
     pager.container.clearSearchHighlights()
   of EDIT:
     let x = $lineedit.news
-    if x != "": pager.iregex = compileSearchRegex(x)
+    if x != "": pager.iregex = opt(compileSearchRegex(x))
     pager.container.popCursorPos(true)
     if pager.iregex.isSome:
       pager.container.hlon = true
@@ -744,12 +745,12 @@ proc updateReadLine*(pager: Pager) =
       of BUFFER: pager.container.readSuccess(s)
       of SEARCH_F:
         let x = s
-        if x != "": pager.regex = compileSearchRegex(x)
+        if x != "": pager.regex = opt(compileSearchRegex(x))
         pager.reverseSearch = false
         pager.searchNext()
       of SEARCH_B:
         let x = s
-        if x != "": pager.regex = compileSearchRegex(x)
+        if x != "": pager.regex = opt(compileSearchRegex(x))
         pager.reverseSearch = true
         pager.searchNext()
       of GOTO_LINE:
diff --git a/src/js/regex.nim b/src/js/regex.nim
index f34f88e1..f61708ec 100644
--- a/src/js/regex.nim
+++ b/src/js/regex.nim
@@ -6,6 +6,7 @@ import unicode
 import bindings/libregexp
 import bindings/quickjs
 import js/javascript
+import utils/opt
 import utils/twtstr
 
 export
@@ -113,22 +114,21 @@ proc `=copy`*(dest: var Regex, source: Regex) =
 func `$`*(regex: Regex): string =
   regex.buf
 
-proc compileRegex*(buf: string, flags: int): Option[Regex] =
+proc compileRegex*(buf: string, flags: int): Result[Regex, string] =
   var regex: Regex
   var error_msg_size = 64
-  var error_msg = cast[cstring](alloc0(error_msg_size))
-  let bytecode = lre_compile(addr regex.plen, error_msg, cint(error_msg_size), cstring(buf), csize_t(buf.len), cint(flags), dummyContext)
-  regex.buf = buf
-  if error_msg != nil:
-    #TODO error handling?
-    dealloc(error_msg)
-    error_msg = nil
+  var error_msg = newString(error_msg_size)
+  prepareMutation(error_msg)
+  let bytecode = lre_compile(addr regex.plen, cstring(error_msg),
+    cint(error_msg_size), cstring(buf), csize_t(buf.len), cint(flags),
+    dummyContext)
   if bytecode == nil:
-    return none(Regex) # Failed to compile.
+    return err(error_msg.until('\0')) # Failed to compile.
+  regex.buf = buf
   regex.bytecode = bytecode
-  return some(regex)
+  return ok(regex)
 
-proc compileSearchRegex*(str: string): Option[Regex] =
+proc compileSearchRegex*(str: string): Result[Regex, string] =
   # Parse any applicable flags in regex/<flags>. The last forward slash is
   # dropped when <flags> is empty, and interpreted as a character when the
   # flags are is invalid.
diff --git a/src/main.nim b/src/main.nim
index 605fba94..225a7578 100644
--- a/src/main.nim
+++ b/src/main.nim
@@ -12,6 +12,7 @@ import config/config
 import data/charset
 import display/client
 import ips/forkserver
+import utils/opt
 import utils/twtstr
 
 let conf = readConfig()
@@ -66,7 +67,7 @@ while i < params.len:
     echo version(true)
     quit(0)
   of "-M", "--monochrome":
-    conf.display.colormode = some(MONOCHROME)
+    conf.display.colormode.ok(MONOCHROME)
   of "-V", "--visual":
     visual = true
   of "-T", "--type":
@@ -92,7 +93,7 @@ while i < params.len:
       if c == CHARSET_UNKNOWN:
         stderr.write("Unknown charset " & params[i] & "\n")
         quit(1)
-      conf.encoding.display_charset = some(c)
+      conf.encoding.display_charset.ok(c)
     else:
       help(1)
   of "-":
diff --git a/src/utils/opt.nim b/src/utils/opt.nim
index 1a86af8e..15100c2e 100644
--- a/src/utils/opt.nim
+++ b/src/utils/opt.nim
@@ -69,6 +69,12 @@ template opt*[T](v: T): auto =
 template opt*(t: typedesc): auto =
   err(Result[t, void])
 
+template opt*[T, E: not void](r: Result[T, E]): Opt[T] =
+  if r.isOk:
+    Opt[T].ok(r.get)
+  else:
+    Opt[T].err()
+
 template isOk*(res: Result): bool = res.has
 template isErr*(res: Result): bool = not res.has
 template isSome*(res: Result): bool = res.isOk