<commit_before>#!python
"""
rcping - ping a remote robotcomm instance with messages, commands and rt-commands
Author: JMJ
"""
import argparse
import sys
import re

def generate_argparser():
    """Generate the argument parser for this utility"""
    parser = argparse.ArgumentParser(description='Robotcomm ping utility',
                                     allow_abbrev=False)

    # Just one positional argument
    parser.add_argument('address', help='hostname[:port] of destination')

    # Number of messages - mutually exclusive options
    numgroup = parser.add_mutually_exclusive_group()
    numgroup.add_argument('-n', metavar='count', action='store', type=int,
                          default=4, help='count of things to send')
    numgroup.add_argument('-t', action='store_true', help='send indifinitely')

    # Message size or explicit message - mutually exclusive options
    sizegroup = parser.add_mutually_exclusive_group()
    sizegroup.add_argument('-l', metavar='size', action='store', type=int,
                           help='size of auto payload')
    payload_help = "send PAYLOAD, which has the form mytype[::mybody] or ::mybody"
    sizegroup.add_argument('-payload', help=payload_help)

    # Type of command - mutually exclusive, and exactly must be specified
    cmdgroup = parser.add_mutually_exclusive_group(required=True)
    cmdgroup.add_argument('-msg', action='store_true', help='send messages')
    cmdgroup.add_argument('-cmd', action='store_true', help='send commands')
    cmdgroup.add_argument('-rtcmd', action='store_true', help='send rt-commands')

    parser.add_argument('-c', metavar='CHANNEL', help='name of channel')

    return parser


def parse_args(args):
    """Parse input args, including all error handling.
    Returns a parameters object on success. Exits program
    on failure.
    """
    parser = generate_argparser()
    params = parser.parse_args(args)
    try:
        hostname, port = parse_address(params.address)
        params.hostname = hostname
        params.port = port
        msgtype, msgbody = parse_payload(params.payload)
        params.msgtype = msgtype
        params.msgbody = msgbody
    except ValueError as exp:
        parser.error(str(exp))
    return params


_HOSTNAME_REGEX = re.compile(r'^(\w\.)+$')
_PORTRANGE = 41 # Range 41000-41999
def parse_address(address):
    """Parse address of the form hostname[:port]"""
    errmsg = '\n'.join(("Invalid address '{}'".format(address),
                        "Hostname should have the form name_or_ip[:port]"))
    hostname, *rest = address.split(':')
    if not _HOSTNAME_REGEX.match(hostname) or len(rest) > 1:
        raise ValueError(errmsg)
    port = int(rest[0]) if rest else None
    if port is not None and port//1000 != _PORTRANGE:
        msg = "Port must be in the range %d to %d"
        minport = _PORTRANGE*1000
        raise ValueError(msg.format(minport, minport+999))
    return (hostname, port)


def parse_payload(payload):
    """Parse payload, which has the form type or ::body or type::body"""
    if payload:
        return ("mytype", "mybody")
    return(None, None)
    #raise ValueError("Invalid payload. Payload is like msgtype or msgtype::body or ::body")


def main(args):
    """Main entry point"""
    params = parse_args(args)
    print(params)
    # client = EchoClient(...)
    if params.msg:
        print('send_messages(params)')
    elif params.cmd:
        print('send_commands(params)')
    elif params.rtcmd:
        print('send_rtcommands(params)')
    # client.shutdown()

print(parse_address('localhost'))

#main(sys.argv[1:])
#ARGS1 = [""]
#ARGS2 = ["localhost"]
#ARGS3 = "-msg localhost".split()
#ARGS4 = "-msg -n 7 -payload msgtype rpi0:4900".split()
#main(ARGS4)<commit_msg>rcping: parse hostname and port<commit_after>#!python
"""
rcping - ping a remote robotcomm instance with messages, commands and rt-commands
Author: JMJ
"""
import argparse
import sys
import re

def generate_argparser():
    """Generate the argument parser for this utility"""
    parser = argparse.ArgumentParser(description='Robotcomm ping utility',
                                     allow_abbrev=False)

    # Just one positional argument
    parser.add_argument('address', help='hostname[:port] of destination')

    # Number of messages - mutually exclusive options
    numgroup = parser.add_mutually_exclusive_group()
    numgroup.add_argument('-n', metavar='count', action='store', type=int,
                          default=4, help='count of things to send')
    numgroup.add_argument('-t', action='store_true', help='send indifinitely')

    # Message size or explicit message - mutually exclusive options
    sizegroup = parser.add_mutually_exclusive_group()
    sizegroup.add_argument('-l', metavar='size', action='store', type=int,
                           help='size of auto payload')
    payload_help = "send PAYLOAD, which has the form mytype[::mybody] or ::mybody"
    sizegroup.add_argument('-payload', help=payload_help)

    # Type of command - mutually exclusive, and exactly must be specified
    cmdgroup = parser.add_mutually_exclusive_group(required=True)
    cmdgroup.add_argument('-msg', action='store_true', help='send messages')
    cmdgroup.add_argument('-cmd', action='store_true', help='send commands')
    cmdgroup.add_argument('-rtcmd', action='store_true', help='send rt-commands')

    parser.add_argument('-c', metavar='CHANNEL', help='name of channel')

    return parser


def parse_args(args):
    """Parse input args, including all error handling.
    Returns a parameters object on success. Exits program
    on failure.
    """
    parser = generate_argparser()
    params = parser.parse_args(args)
    try:
        hostname, port = parse_address(params.address)
        params.hostname = hostname
        params.port = port
        msgtype, msgbody = parse_payload(params.payload)
        params.msgtype = msgtype
        params.msgbody = msgbody
    except ValueError as exp:
        parser.error(str(exp))
    return params


# Note: IPV6 addresses are not supported - it would
# be extra work to distinguish a port from a ':' inside
# the IPv6 address.
_HOSTNAME_REGEX = re.compile(r'(\w|\.)+')
_PORTRANGE = 41 # Range 41000-41999
def parse_address(address):
    """Parse address of the form hostname[:port]"""
    errmsg = '\n'.join(("Invalid address '{}'".format(address),
                        "Hostname should have the form name_or_ip[:port]"))
    hostname, *rest = address.split(':')
    if not _HOSTNAME_REGEX.fullmatch(hostname) or len(rest) > 1:
        raise ValueError(errmsg)
    port = int(rest[0]) if rest else None
    if port is not None and port//1000 != _PORTRANGE:
        msg = "Port must be in the range {} to {}"
        minport = _PORTRANGE*1000
        raise ValueError(msg.format(minport, minport+999))
    return (hostname, port)


def parse_payload(payload):
    """Parse payload, which has the form type or ::body or type::body"""
    if payload:
        return ("mytype", "mybody")
    return(None, None)
    #raise ValueError("Invalid payload. Payload is like msgtype or msgtype::body or ::body")


def main(args):
    """Main entry point"""
    params = parse_args(args)
    print(params)
    # client = EchoClient(...)
    if params.msg:
        print('send_messages(params)')
    elif params.cmd:
        print('send_commands(params)')
    elif params.rtcmd:
        print('send_rtcommands(params)')
    # client.shutdown()


main(sys.argv[1:])
#ARGS1 = [""]
#ARGS2 = ["localhost"]
#ARGS3 = "-msg localhost".split()
#ARGS4 = "-msg -n 7 -payload msgtype rpi0:4900".split()
#main(ARGS4)
{'fraction_non_alphanumeric': 0.12404930500917913, 'fraction_numerical': 0.010228166797797011, 'mean_word_length': 3.378300803673938, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3129797', 'n_tokens_mistral': 2325, 'n_tokens_neox': 2232, 'n_words': 629}