-
-
Save justjanne/baa4eca94c8063288941e70b96096a10 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
declare -A tags | |
clear_message() { | |
start=0 | |
source="" | |
fragment="" | |
tags=() | |
prefix="" | |
command="" | |
params=() | |
} | |
extract_fragment() { | |
local end=${1:-"-1"} | |
local prefix=${2:-""} | |
# Try to set find the end of the space-delimited fragment | |
if [ "$end" == "-1" ]; then | |
local tmp=${source:$start} | |
local tmp=${tmp%% *} | |
end=$(($start + ${#tmp})) | |
fi | |
# If no space comes after this point, use the remainder of the string | |
if [ "$end" == "-1" ]; then | |
end=${#source} | |
fi | |
fragment="" | |
# If a prefix is set | |
if [ "$prefix" != "" ]; then | |
# And the fragment starts with the prefix | |
if [ "$start" -lt "${#source}" ] && [ "${source:$start:1}" == "$prefix" ]; then | |
# return the fragment without the prefix, advancing the string | |
fragment=${source:$(($start + 1)):$(($end - $start - 1))} | |
start=$end | |
fi | |
else | |
# otherwise return the entire fragment | |
fragment=${source:$start:$(($end - $start))} | |
start=$end | |
fi | |
} | |
skip_empty_parts() { | |
while [ "$start" -lt "${#source}" ] && [ "${source:$start:1}" == " " ]; do | |
start=$((start + 1)) | |
done | |
} | |
parse_tag_value() { | |
local value=${1} | |
local result="" | |
local escaped=0 | |
for (( i=0; i<${#value}; i++ )); do | |
c=${value:$i:1} | |
if [ $escaped -ne 0 ]; then | |
if [ "$c" == "\\" ]; then | |
result+="\\" | |
elif [ "$c" == "s" ]; then | |
result+=" " | |
elif [ "$c" == ":" ]; then | |
result+=";" | |
elif [ "$c" == "r" ]; then | |
result+="\r" | |
elif [ "$c" == "n" ]; then | |
result+="\n" | |
else | |
result+="$c" | |
fi | |
escaped=0 | |
elif [ $c == "\\" ]; then | |
escaped=1 | |
else | |
result+="$c" | |
fi | |
done | |
echo $result | |
} | |
parse_tags() { | |
extract_fragment "-1" "@" | |
local raw_tag_str=$fragment | |
# Tags are delimited with ; according to spec | |
local IFS=";" | |
for raw_tag in $raw_tag_str; do | |
if [ "$raw_tag" != "" ]; then | |
local raw_key=${raw_tag%%=*} | |
local raw_value=${raw_tag:$((${#raw_key}+1))} | |
tags[$raw_key]=$(parse_tag_value $raw_value) | |
fi | |
done | |
} | |
parse_prefix() { | |
extract_fragment "-1" ":" | |
prefix=$fragment | |
} | |
parse_command() { | |
extract_fragment "-1" | |
command=$fragment | |
} | |
parse_parameter() { | |
if [ $start -lt ${#source} ] && [ ${source:$start:1} == ':' ]; then | |
start=$(($start + 1)) | |
extract_fragment ${#source} | |
else | |
extract_fragment | |
fi | |
params+=( "$fragment" ) | |
} | |
parse_message() { | |
clear_message | |
source=${1} | |
parse_tags | |
skip_empty_parts | |
parse_prefix | |
skip_empty_parts | |
parse_command | |
skip_empty_parts | |
unset params | |
while [ $start -lt ${#source} ]; do | |
parse_parameter | |
skip_empty_parts | |
done | |
} | |
print_message() { | |
echo "tags: " | |
for i in "${!tags[@]}" | |
do | |
echo " ${i}=${tags[$i]}" | |
done | |
echo "prefix: $prefix" | |
echo "command: $command" | |
echo "params: " | |
for i in "${params[@]}" | |
do | |
echo " ${i}" | |
done | |
} | |
parse_message "@a=b;c=32;k;rt=ql7 :source PRIVMSG #channel :test a thing" | |
print_message | |
echo "---" | |
parse_message ":coolguy!ag@net\x035w\x03ork.admin PRIVMSG foo :bar baz" | |
print_message | |
echo "---" | |
parse_message "@tag1=value\\\\ntest COMMAND" | |
print_message | |
echo "---" | |
parse_message "@tag1=value1;tag2;vendor1/tag3=value2;vendor2/tag4 COMMAND param1 param2 :param3 param3" | |
print_message | |
echo "---" | |
parse_message ":gravel.mozilla.org 432 #momo :Erroneous Nickname: Illegal characters" | |
print_message |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment