<commit_before># Copyright (c) 2012, <NAME>
package API::Base::UserCommands;

use warnings;
use strict;
use v5.10;

use utils qw(log2 col trim);

use Scalar::Util 'looks_like_number';

sub register_user_command {
    my ($mod, %opts) = @_;

    # make sure all required options are present
    foreach my $what (qw|name description code|) {
        next if exists $opts{$what};
        $opts{name} ||= 'unknown';
        log2("user command $opts{name} does not have '$what' option.");
        return
    }
    
    $mod->{user_commands} ||= [];
    my $CODE       = $opts{code};
    my $parameters = 0;
    
    # parameters:
    #     channel channel name lookup
    #     source  global name (checks for nicks, channel names, server names) lookup
    #     server  server name lookup
    #     user    nickname lookup
    #     :rest   the rest of the message with colon removed
    #     @rest   the rest of the message as a space-separated list
    #     any     plain old string
    #     ts      timestamp
    
    # attributes:
    #
    #   opt
    #       indicates an optional parameter
    #       this parameter will not be taken account when counting the number of
    #       parameters (used to determine whether or not enough parameters are given)
    #
    #   inchan
    #       for channels, gives up and sends ERR_NOTONCHANNEL if the user sending the
    #       command is not in the channel. Ex: channel(inchan)     

    # if parameters is present and does not look like a number...
    if ($opts{parameters} && !looks_like_number($opts{parameters})) {

        # if it is not an array reference, it's a whitespace-separated string.
        if (ref $opts{parameters} ne 'ARRAY') {
            $opts{parameters} = [ split /\s/, $opts{parameters} ];
        }

        # parse argument type attributes.
        my $required_parameters;
        my @argttributes; my $i = -1;
        foreach (@{$opts{parameters}}) { $i++;
        
            # type(attribute1,att2:val,att3)
            if (/(.+)\((.+)\)/) {
                $opts{parameters}[$i] = $1;
                my $attributes = {};
                
                # get the values of each attribute.
                foreach (split ',', $2) {
                    my $attr = trim($_);
                    my ($name, $val) = split ':', $attr, 2;
                    $attributes->{$name} = defined $val ? $val : 1;
                }
                
                $argttributes[$i] = $attributes;
            }
            
            # no attribute list, no attributes.
            else {
                $argttributes[$i] = {};
            }
            
            # unless there is an 'opt' (optional) attribute,
            # increase required parameter count.
            unless ($argttributes[$i]{opt}) {
                $required_parameters++;
            }
            
        }

        # create the new handler.
        $CODE = sub {
            my ($user, $data, @args) = @_;
            my ($i, @final_parameters, %param_id) = -1;
            
            # check argument count.
            if (scalar @args < $required_parameters) {
                $user->numeric(ERR_NEEDMOREPARAMS => $args[0]);
                return;
            }

            $i = -1;
            foreach (@{$opts{parameters}}) { $i++;

                my $type = $_;
                my $arg = $args[$i];
                return unless defined $arg;
                
                # if $type has an identifier, filter it out first.
                my ($id, $name) = split '.', $arg, 2;
                if (defined $name) { $type = $name }
                else               { $id   = $arg  }
                
                # global lookup
                given ($type) {
                when ('source') {
                    my $source =
                         server::lookup_by_name($arg)  ||
                        channel::lookup_by_name($arg)  ||
                           user::lookup_by_nick($arg);<commit_msg>trying it a different way.<commit_after># Copyright (c) 2012, <NAME>
package API::Base::UserCommands;

use warnings;
use strict;
use v5.10;

use utils qw(log2 col trim);

use Scalar::Util 'looks_like_number';

sub register_user_command {
    my ($mod, %opts) = @_;

    # make sure all required options are present
    foreach my $what (qw|name description code|) {
        next if exists $opts{$what};
        $opts{name} ||= 'unknown';
        log2("user command $opts{name} does not have '$what' option.");
        return
    }
    
    $mod->{user_commands} ||= [];
    my $CODE       = $opts{code};
    my $parameters = 0;
    
    # parameters:
    #     channel channel name lookup
    #     source  global name (checks for nicks, channel names, server names) lookup
    #     server  server name lookup
    #     user    nickname lookup
    #     :rest   the rest of the message with colon removed
    #     @rest   the rest of the message as a space-separated list
    #     any     plain old string
    #     ts      timestamp
    
    # attributes:
    #
    #   opt
    #       indicates an optional parameter
    #       this parameter will not be taken account when counting the number of
    #       parameters (used to determine whether or not enough parameters are given)
    #
    #   inchan
    #       for channels, gives up and sends ERR_NOTONCHANNEL if the user sending the
    #       command is not in the channel. Ex: channel(inchan)     

    # if parameters is present and does not look like a number...
    if ($opts{parameters} && !looks_like_number($opts{parameters})) {

        # if it is not an array reference, it's a whitespace-separated string.
        if (ref $opts{parameters} ne 'ARRAY') {
            $opts{parameters} = [ split /\s/, $opts{parameters} ];
        }

        # parse argument type attributes.
        my $required_parameters;
        my @argttributes; my $i = -1;
        foreach (@{$opts{parameters}}) { $i++;
        
            # type(attribute1,att2:val,att3)
            if (/(.+)\((.+)\)/) {
                $opts{parameters}[$i] = $1;
                my $attributes = {};
                
                # get the values of each attribute.
                foreach (split ',', $2) {
                    my $attr = trim($_);
                    my ($name, $val) = split ':', $attr, 2;
                    $attributes->{$name} = defined $val ? $val : 1;
                }
                
                $argttributes[$i] = $attributes;
            }
            
            # no attribute list, no attributes.
            else {
                $argttributes[$i] = {};
            }
            
            # unless there is an 'opt' (optional) attribute,
            # increase required parameter count.
            unless ($argttributes[$i]{opt}) {
                $required_parameters++;
            }
            
        }

        # create the new handler.
        $CODE = sub {
            my ($user, $data, @args) = @_;
            my ($i, @final_parameters, %param_id) = -1;
            
            # check argument count.
            if (scalar @args < $required_parameters) {
                $user->numeric(ERR_NEEDMOREPARAMS => $args[0]);
                return;
            }

            $i = -1;
            foreach $t (@{$opts{parameters}}) { $i++;
                my ($type, $id);
                my $arg = $args[$i];
                my @s   = split '.', $arg, 2;
                
                # if @s has two elements, it had an identifier.
                if (scalar @s == 2) {
                    $id   = $s[0];
                    $type = $s[1];
                }
                
                # otherwise, it didn't.
                else {
                    $id   = 1;
                    $type = $t;
                }
               
                # if $type has an identifier, filter it out first.
                my ($id, $name) = split '.', $arg, 2;
                if (defined $name) { $type = $name }
                else               { $id   = $arg  }
                
                # global lookup
                given ($type) {
                when ('source') {
                    my $source =
                         server::lookup_by_name($arg)  ||
                        channel::lookup_by_name($arg)  ||
                           user::lookup_by_nick($arg);
{'fraction_non_alphanumeric': 0.11412523900573614, 'fraction_numerical': 0.005855640535372849, 'mean_word_length': 1.3508426966292135, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3193480', 'n_tokens_mistral': 2316, 'n_tokens_neox': 2205, 'n_words': 695}