~aleteoryx/tclircc

808c49fc47c5f69fdc687dc6625bb189096d6678 — aleteoryx 1 year, 1 month ago 534b37f
add support for message intercepting, bugfix in irc::extern remove
1 files changed, 44 insertions(+), 1 deletions(-)

M irc.tcl
M irc.tcl => irc.tcl +44 -1
@@ 24,6 24,7 @@ namespace eval ::irc {
  variable logp [logger::init tclircc::irc::proto]
  variable chan.meta
  variable chan.handlers
  variable chan.interceptors

  # documented
  proc is {type value {cap {}}} {


@@ 130,9 131,11 @@ namespace eval ::irc {
  proc enroll {chan {meta {}}} {
    variable chan.meta
    variable chan.handlers
    variable chan.interceptors
    fconfigure $chan -translation crlf -blocking 0
    set chan.meta($chan) $meta
    set chan.handlers($chan) {}
    set chan.interceptors($chan) {}
  }

  # documented


@@ 231,6 234,14 @@ namespace eval ::irc {
                              params $params]

    set matchedany false
    foreach interceptor [set chan.interceptors($chan)] {
      lassign $interceptor id procname
      if {[$procname $dispatch]} {
        ${logd}::debug "message intercepted by interceptor \"$id\", procname \"$procname\""
        ${logd}::debug "contents: $msg"
        return
      }
    }
    foreach handler [set chan.handlers($chan)] {
      set rest [lassign $handler patlist type id]



@@ 238,6 249,8 @@ namespace eval ::irc {
      foreach msgpat $patlist {
        set parampats [lassign $patlist cmdpat]

        # don't care about extra args to a command, so that the pattern
        # for e.g. a message can just be "PRIVMSG"
        if {[llength $parampats] > [llength $params]} { continue }
        if ![string match $cmdpat $cmd] { continue }



@@ 296,7 309,7 @@ namespace eval ::irc {
      }
    }
    if !$matchedany {
      puts stderr "irc warning: unmatched command on channel \"$chan\": $msg"
      ${logd}::warn "unmatched command on channel \"$chan\": $msg"
    }
  }



@@ 448,6 461,7 @@ namespace eval ::irc {
      }
      remove {
        if {[llength $args] != 1} { return -code error "wrong # args: should be \"irc::extern remove chan id\"" }
        lassign $args rmid
        set newlist ""
        foreach handler [set chan.handlers($chan)] {
          lassign $handler _ type handlerid ochan ichan


@@ 466,6 480,35 @@ namespace eval ::irc {
  }

  # documented
  proc interceptor {subcommand chan args} {
    variable chan.interceptors
    switch -- $subcommand {
      add {
        if {[llength $args] != 1} { return -code error "wrong # args: should be \"irc::interceptor add chan procname\"" }
        lassign $args procname
        set id [format "%016x" [expr {round(rand() * (2**64))}]]

        lappend chan.interceptors($chan) [list $id $procname]

        return $id
      }
      remove {
        if {[llength $args] != 1} { return -code error "wrong # args: should be \"irc::interceptor remove chan id\"" }
        lassign $args rmid
        set newlist ""
        foreach interceptor [set chan.interceptor($chan)] {
          lassign $interceptor id procname
          if {$id != $rmid} {
            lappend newlist $interceptor
          }
        }
        set chan.interceptors($chan) $newlist
      }
      default { return -code error "unknown subcommand \"$subcommand\": must be add or remove" }
    }
  }

  # documented
  proc patlist {chan id {patlist {}}} {
    if {$patlist != ""} {
      set newlist ""