summary refs log tree commit diff stats
path: root/tools/detect
Commit message (Expand)AuthorAgeFilesLines
* Add Linux constant SO_BINDTODEVICE (#22468)Emery Hemingway2023-08-141-0/+1
* add const RLIMIT_STACK (#21772)Qinsi (James) ZHU2023-06-091-0/+1
* make koch and tools work with `nimPreviewSlimSystem` (#20459)ringabout2022-09-301-1/+4
* Patch #14716 - add missing `when` (#14792)Euan2020-06-241-2/+2
* Fix #14715 - detect tool fails on FreeBSD (#14716)Euan2020-06-241-3/+3
* Use cc on OpenBSD and link to libm when building result (#14672)Euan2020-06-161-5/+16
* Linux updates (#14170)wltsmrz2020-05-041-5/+16
* Make file descriptors from stdlib non-inheritable by default (#13201)alaviss2020-04-201-0/+3
* dynlib: use posix module (#11623)Jacek Sieka2019-07-081-1/+4
* RLIMIT_NOFILE as posix constJacek Sieka2018-04-011-0/+3
* add back SIG_IGN, SIG_DFL and friends to posix.nim (#5820)Jacek Sieka2017-05-161-1/+10
* Posix from detect (#5697)Jacek Sieka2017-04-123-1386/+789
* tools: Trim .nim files trailing whitespaceAdam Strzelecki2015-09-042-213/+213
* posix.nim compiles againAraq2014-08-291-2/+2
* attempt to merge newtemplAraq2013-12-241-0/+631
* NoFakeVars progressAraq2013-12-243-0/+877
* vm: FFI improvementsAraq2013-12-231-1/+1
* new VM: some progress for the FFI supportAraq2013-12-231-7/+14
* Removes executable bit for text files.Grzegorz Adam Hankiewicz2013-03-162-0/+0
* added detect.nim; bugfix: build.sh templateAraq2010-08-172-0/+833
ight .mi { color: #0000DD; font-weight: bold } /* Literal.Number.Integer */ .highlight .mo { color: #0000DD; font-weight: bold } /* Literal.Number.Oct */ .highlight .sa { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Affix */ .highlight .sb { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Backtick */ .highlight .sc { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Char */ .highlight .dl { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Delimiter */ .highlight .sd { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Doc */ .highlight .s2 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Double */ .highlight .se { color: #0044dd; background-color: #fff0f0 } /* Literal.String.Escape */ .highlight .sh { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Heredoc */ .highlight .si { color: #3333bb; background-color: #fff0f0 } /* Literal.String.Interpol */ .highlight .sx { color: #22bb22; background-color: #f0fff0 } /* Literal.String.Other */ .highlight .sr { color: #008800; background-color: #fff0ff } /* Literal.String.Regex */ .highlight .s1 { color: #dd2200; background-color: #fff0f0 } /* Literal.String.Single */ .highlight .ss { color: #aa6600; background-color: #fff0f0 } /* Literal.String.Symbol */ .highlight .bp { color: #003388 } /* Name.Builtin.Pseudo */ .highlight .fm { color: #0066bb; font-weight: bold } /* Name.Function.Magic */ .highlight .vc { color: #336699 } /* Name.Variable.Class */ .highlight .vg { color: #dd7700 } /* Name.Variable.Global */ .highlight .vi { color: #3333bb } /* Name.Variable.Instance */ .highlight .vm { color: #336699 } /* Name.Variable.Magic */ .highlight .il { color: #0000DD; font-weight: bold } /* Literal.Number.Integer.Long */
#
#
#           The Nim Compiler
#        (c) Copyright 2012 Andreas Rumpf
#
#    See the file "copying.txt", included in this
#    distribution, for details about the copyright.
#

# Identifier handling
# An identifier is a shared immutable string that can be compared by its
# id. This module is essential for the compiler's performance.

import wordrecg
import std/hashes

when defined(nimPreviewSlimSystem):
  import std/assertions

type
  PIdent* = ref TIdent
  TIdent*{.acyclic.} = object
    id*: int # unique id; use this for comparisons and not the pointers
    s*: string
    next*: PIdent             # for hash-table chaining
    h*: Hash                 # hash value of s

  IdentCache* = ref object
    buckets: array[0..4096 * 2 - 1, PIdent]
    wordCounter: int
    idAnon*, idDelegator*, emptyIdent*: PIdent

proc resetIdentCache*() = discard

proc cmpIgnoreStyle*(a, b: cstring, blen: int): int =
  if a[0] != b[0]: return 1
  var i = 0
  var j = 0
  result = 1
  while j < blen:
    while a[i] == '_': inc(i)
    while b[j] == '_': inc(j)
    # tolower inlined:
    var aa = a[i]
    var bb = b[j]
    if aa >= 'A' and aa <= 'Z': aa = chr(ord(aa) + (ord('a') - ord('A')))
    if bb >= 'A' and bb <= 'Z': bb = chr(ord(bb) + (ord('a') - ord('A')))
    result = ord(aa) - ord(bb)
    if (result != 0) or (aa == '\0'): break
    inc(i)
    inc(j)
  if result == 0:
    if a[i] != '\0': result = 1

proc cmpExact(a, b: cstring, blen: int): int =
  var i = 0
  var j = 0
  result = 1
  while j < blen:
    var aa = a[i]
    var bb = b[j]
    result = ord(aa) - ord(bb)
    if (result != 0) or (aa == '\0'): break
    inc(i)
    inc(j)
  if result == 0:
    if a[i] != '\0': result = 1

proc getIdent*(ic: IdentCache; identifier: cstring, length: int, h: Hash): PIdent =
  var idx = h and high(ic.buckets)
  result = ic.buckets[idx]
  var last: PIdent = nil
  var id = 0
  while result != nil:
    if cmpExact(cstring(result.s), identifier, length) == 0:
      if last != nil:
        # make access to last looked up identifier faster:
        last.next = result.next
        result.next = ic.buckets[idx]
        ic.buckets[idx] = result
      return
    elif cmpIgnoreStyle(cstring(result.s), identifier, length) == 0:
      assert((id == 0) or (id == result.id))
      id = result.id
    last = result
    result = result.next
  new(result)
  result.h = h
  result.s = newString(length)
  for i in 0..<length: result.s[i] = identifier[i]
  result.next = ic.buckets[idx]
  ic.buckets[idx] = result
  if id == 0:
    inc(ic.wordCounter)
    result.id = -ic.wordCounter
  else:
    result.id = id

proc getIdent*(ic: IdentCache; identifier: string): PIdent =
  result = getIdent(ic, cstring(identifier), identifier.len,
                    hashIgnoreStyle(identifier))

proc getIdent*(ic: IdentCache; identifier: string, h: Hash): PIdent =
  result = getIdent(ic, cstring(identifier), identifier.len, h)

proc newIdentCache*(): IdentCache =
  result = IdentCache()
  result.idAnon = result.getIdent":anonymous"
  result.wordCounter = 1
  result.idDelegator = result.getIdent":delegator"
  result.emptyIdent = result.getIdent("")
  # initialize the keywords:
  for s in succ(low(TSpecialWord))..high(TSpecialWord):
    result.getIdent($s, hashIgnoreStyle($s)).id = ord(s)

proc whichKeyword*(id: PIdent): TSpecialWord =
  if id.id < 0: result = wInvalid
  else: result = TSpecialWord(id.id)

proc hash*(x: PIdent): Hash {.inline.} = x.h
proc `==`*(a, b: PIdent): bool {.inline.} =
  if a.isNil or b.isNil: result = system.`==`(a, b)
  else: result = a.id == b.id