about summary refs log tree commit diff stats
path: root/src/otr/otrlibv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/otr/otrlibv4.c')
-rw-r--r--src/otr/otrlibv4.c12
1 files changed, 12 insertions, 0 deletions
diff --git a/src/otr/otrlibv4.c b/src/otr/otrlibv4.c
index 27b99f06..62379d0f 100644
--- a/src/otr/otrlibv4.c
+++ b/src/otr/otrlibv4.c
@@ -18,6 +18,18 @@
  * You should have received a copy of the GNU General Public License
  * along with Profanity.  If not, see <http://www.gnu.org/licenses/>.
  *
+ * In addition, as a special exception, the copyright holders give permission to
+ * link the code of portions of this program with the OpenSSL library under
+ * certain conditions as described in each individual source file, and
+ * distribute linked combinations including the two.
+ *
+ * You must obey the GNU General Public License in all respects for all of the
+ * code used other than OpenSSL. If you modify file(s) with this exception, you
+ * may extend this exception to your version of the file(s), but you are not
+ * obligated to do so. If you do not wish to do so, delete this exception
+ * statement from your version. If you delete this exception statement from all
+ * source files in the program, then also delete it here.
+ *
  */
 
 #include <libotr/proto.h>
'n121' href='#n121'>121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
#
#
#            Nimrod's Runtime Library
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

## This module provides the standard Nimrod command line parser.
## It supports one convenience iterator over all command line options and some
## lower-level features.

{.push debugger: off.}

include "system/inclrtl"

import 
  os, strutils

type 
  TCmdLineKind* = enum        ## the detected command line token
    cmdEnd,                   ## end of command line reached
    cmdArgument,              ## argument detected
    cmdLongoption,            ## a long option ``--option`` detected
    cmdShortOption            ## a short option ``-c`` detected
  TOptParser* = 
      object of TObject ## this object implements the command line parser  
    cmd: string
    pos: int
    inShortState: bool
    kind*: TCmdLineKind       ## the dected command line token
    key*, val*: TaintedString ## key and value pair; ``key`` is the option
                              ## or the argument, ``value`` is not "" if
                              ## the option was given a value

when defined(os.ParamCount):
  # we cannot provide this for NimRtl creation on Posix, because we can't 
  # access the command line arguments then!

  proc initOptParser*(cmdline = ""): TOptParser =
    ## inits the option parser. If ``cmdline == ""``, the real command line
    ## (as provided by the ``OS`` module) is taken.
    result.pos = 0
    result.inShortState = false
    if cmdline != "": 
      result.cmd = cmdline
    else: 
      result.cmd = ""
      for i in countup(1, ParamCount()): 
        result.cmd = result.cmd & quoteIfContainsWhite(paramStr(i).string) & ' '
    result.kind = cmdEnd
    result.key = TaintedString""
    result.val = TaintedString""

proc parseWord(s: string, i: int, w: var string, 
               delim: TCharSet = {'\x09', ' ', '\0'}): int = 
  result = i
  if s[result] == '\"': 
    inc(result)
    while not (s[result] in {'\0', '\"'}): 
      add(w, s[result])
      inc(result)
    if s[result] == '\"': inc(result)
  else: 
    while not (s[result] in delim): 
      add(w, s[result])
      inc(result)

proc handleShortOption(p: var TOptParser) = 
  var i = p.pos
  p.kind = cmdShortOption
  add(p.key.string, p.cmd[i])
  inc(i)
  p.inShortState = true
  while p.cmd[i] in {'\x09', ' '}: 
    inc(i)
    p.inShortState = false
  if p.cmd[i] in {':', '='}: 
    inc(i)
    p.inShortState = false
    while p.cmd[i] in {'\x09', ' '}: inc(i)
    i = parseWord(p.cmd, i, p.val.string)
  if p.cmd[i] == '\0': p.inShortState = false
  p.pos = i

proc next*(p: var TOptParser) {.
  rtl, extern: "npo$1".} = 
  ## parses the first or next option; ``p.kind`` describes what token has been
  ## parsed. ``p.key`` and ``p.val`` are set accordingly.
  var i = p.pos
  while p.cmd[i] in {'\x09', ' '}: inc(i)
  p.pos = i
  setlen(p.key.string, 0)
  setlen(p.val.string, 0)
  if p.inShortState: 
    handleShortOption(p)
    return 
  case p.cmd[i]
  of '\0': 
    p.kind = cmdEnd
  of '-': 
    inc(i)
    if p.cmd[i] == '-': 
      p.kind = cmdLongOption
      inc(i)
      i = parseWord(p.cmd, i, p.key.string, {'\0', ' ', '\x09', ':', '='})
      while p.cmd[i] in {'\x09', ' '}: inc(i)
      if p.cmd[i] in {':', '='}: 
        inc(i)
        while p.cmd[i] in {'\x09', ' '}: inc(i)
        p.pos = parseWord(p.cmd, i, p.val.string)
      else: 
        p.pos = i
    else: 
      p.pos = i
      handleShortOption(p)
  else:
    p.kind = cmdArgument
    p.pos = parseWord(p.cmd, i, p.key.string)

proc cmdLineRest*(p: TOptParser): TaintedString {.
  rtl, extern: "npo$1".} = 
  ## retrieves the rest of the command line that has not been parsed yet.
  result = strip(substr(p.cmd, p.pos, len(p.cmd) - 1)).TaintedString

when defined(initOptParser):

  iterator getopt*(): tuple[kind: TCmdLineKind, key, val: TaintedString] =
    ## This is an convenience iterator for iterating over the command line.
    ## This uses the TOptParser object. Example:
    ##
    ## .. code-block:: nimrod
    ##   var
    ##     filename = ""
    ##   for kind, key, val in getopt():
    ##     case kind
    ##     of cmdArgument: 
    ##       filename = key
    ##     of cmdLongOption, cmdShortOption:
    ##       case key
    ##       of "help", "h": writeHelp()
    ##       of "version", "v": writeVersion()
    ##     of cmdEnd: assert(false) # cannot happen
    ##   if filename == "":
    ##     # no filename has been given, so we show the help:
    ##     writeHelp()
    var p = initOptParser()
    while true:
      next(p)
      if p.kind == cmdEnd: break
      yield (p.kind, p.key, p.val)

{.pop.}