mirror of
https://github.com/profanity-im/profanity.git
synced 2024-09-01 19:24:15 -04:00
Added parser module
This commit is contained in:
parent
2fe5e7bd59
commit
824eaa1678
@ -8,14 +8,14 @@ profanity_SOURCES = src/command.c src/contact.c src/history.c src/jabber.h \
|
|||||||
src/main.c src/profanity.h src/prof_history.h src/chat_log.c \
|
src/main.c src/profanity.h src/prof_history.h src/chat_log.c \
|
||||||
src/chat_log.h src/tinyurl.c src/tinyurl.h src/chat_session.c \
|
src/chat_log.h src/tinyurl.c src/tinyurl.h src/chat_session.c \
|
||||||
src/chat_session.h src/release.c src/release.h src/room_chat.c \
|
src/chat_session.h src/release.c src/release.h src/room_chat.c \
|
||||||
src/room_chat.h src/stanza.c src/stanza.h
|
src/room_chat.h src/stanza.c src/stanza.h src/parser.c src/parser.h
|
||||||
|
|
||||||
TESTS = tests/testsuite
|
TESTS = tests/testsuite
|
||||||
check_PROGRAMS = tests/testsuite
|
check_PROGRAMS = tests/testsuite
|
||||||
tests_testsuite_SOURCES = tests/test_contact_list.c src/contact_list.c src/contact.c \
|
tests_testsuite_SOURCES = tests/test_contact_list.c src/contact_list.c src/contact.c \
|
||||||
tests/test_common.c tests/test_prof_history.c src/prof_history.c src/common.c \
|
tests/test_common.c tests/test_prof_history.c src/prof_history.c src/common.c \
|
||||||
tests/test_prof_autocomplete.c src/prof_autocomplete.c tests/testsuite.c \
|
tests/test_prof_autocomplete.c src/prof_autocomplete.c tests/testsuite.c \
|
||||||
src/log.c
|
tests/test_parser.c src/parser.c
|
||||||
tests_testsuite_LDADD = -lheadunit -lstdc++
|
tests_testsuite_LDADD = -lheadunit -lstdc++
|
||||||
|
|
||||||
man_MANS = docs/profanity.1
|
man_MANS = docs/profanity.1
|
||||||
|
@ -36,6 +36,7 @@
|
|||||||
#include "history.h"
|
#include "history.h"
|
||||||
#include "jabber.h"
|
#include "jabber.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "parser.h"
|
||||||
#include "preferences.h"
|
#include "preferences.h"
|
||||||
#include "prof_autocomplete.h"
|
#include "prof_autocomplete.h"
|
||||||
#include "tinyurl.h"
|
#include "tinyurl.h"
|
||||||
@ -835,7 +836,7 @@ _cmd_connect(const char * const inp, struct cmd_help_t help)
|
|||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
int num_args = 0;
|
int num_args = 0;
|
||||||
gchar **args = _cmd_parse_args(inp, 1, 1, &num_args);
|
gchar **args = parse_args(inp, 1, 1, &num_args);
|
||||||
|
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
cons_show("Usage: %s", help.usage);
|
cons_show("Usage: %s", help.usage);
|
||||||
@ -882,7 +883,7 @@ _cmd_sub(const char * const inp, struct cmd_help_t help)
|
|||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
int num_args = 0;
|
int num_args = 0;
|
||||||
gchar **args = _cmd_parse_args(inp, 1, 2, &num_args);
|
gchar **args = parse_args(inp, 1, 2, &num_args);
|
||||||
|
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
cons_show("Usage: %s", help.usage);
|
cons_show("Usage: %s", help.usage);
|
||||||
@ -1220,7 +1221,7 @@ _cmd_info(const char * const inp, struct cmd_help_t help)
|
|||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
int num_args = 0;
|
int num_args = 0;
|
||||||
gchar **args = _cmd_parse_args(inp, 1, 1, &num_args);
|
gchar **args = parse_args(inp, 1, 1, &num_args);
|
||||||
|
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
cons_show("Usage: %s", help.usage);
|
cons_show("Usage: %s", help.usage);
|
||||||
@ -1252,7 +1253,7 @@ _cmd_join(const char * const inp, struct cmd_help_t help)
|
|||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
int num_args = 0;
|
int num_args = 0;
|
||||||
gchar **args = _cmd_parse_args(inp, 1, 2, &num_args);
|
gchar **args = parse_args(inp, 1, 2, &num_args);
|
||||||
|
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
cons_show("Usage: %s", help.usage);
|
cons_show("Usage: %s", help.usage);
|
||||||
@ -1296,7 +1297,7 @@ _cmd_tiny(const char * const inp, struct cmd_help_t help)
|
|||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
int num_args = 0;
|
int num_args = 0;
|
||||||
gchar **args = _cmd_parse_args(inp, 1, 1, &num_args);
|
gchar **args = parse_args(inp, 1, 1, &num_args);
|
||||||
|
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
cons_show("Usage: %s", help.usage);
|
cons_show("Usage: %s", help.usage);
|
||||||
@ -1401,7 +1402,7 @@ _cmd_set_notify(const char * const inp, struct cmd_help_t help)
|
|||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
int num_args = 0;
|
int num_args = 0;
|
||||||
gchar **args = _cmd_parse_args(inp, 2, 2, &num_args);
|
gchar **args = parse_args(inp, 2, 2, &num_args);
|
||||||
|
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
cons_show("Usage: %s", help.usage);
|
cons_show("Usage: %s", help.usage);
|
||||||
@ -1463,7 +1464,7 @@ _cmd_set_log(const char * const inp, struct cmd_help_t help)
|
|||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
int num_args = 0;
|
int num_args = 0;
|
||||||
gchar **args = _cmd_parse_args(inp, 2, 2, &num_args);
|
gchar **args = parse_args(inp, 2, 2, &num_args);
|
||||||
|
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
cons_show("Usage: %s", help.usage);
|
cons_show("Usage: %s", help.usage);
|
||||||
@ -1496,7 +1497,7 @@ _cmd_set_priority(const char * const inp, struct cmd_help_t help)
|
|||||||
{
|
{
|
||||||
gboolean result = FALSE;
|
gboolean result = FALSE;
|
||||||
int num_args = 0;
|
int num_args = 0;
|
||||||
gchar **args = _cmd_parse_args(inp, 1, 1, &num_args);
|
gchar **args = parse_args(inp, 1, 1, &num_args);
|
||||||
|
|
||||||
if (args == NULL) {
|
if (args == NULL) {
|
||||||
cons_show("Usage: %s", help.usage);
|
cons_show("Usage: %s", help.usage);
|
||||||
@ -1805,30 +1806,3 @@ _strtoi(char *str, int *saveptr, int min, int max)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
gchar **
|
|
||||||
_cmd_parse_args(const char * const inp, int min, int max, int *num)
|
|
||||||
{
|
|
||||||
char *copy = strdup(inp);
|
|
||||||
gchar **args = NULL;
|
|
||||||
g_strstrip(copy);
|
|
||||||
gchar **split = g_strsplit(copy, " ", 0);
|
|
||||||
*num = g_strv_length(split) - 1;
|
|
||||||
|
|
||||||
if ((*num < min) || (*num > max)) {
|
|
||||||
g_strfreev(split);
|
|
||||||
free(copy);
|
|
||||||
return NULL;
|
|
||||||
} else {
|
|
||||||
args = malloc((*num + 1) * sizeof(*args));
|
|
||||||
int i;
|
|
||||||
for (i = 0; i < *num; i++) {
|
|
||||||
args[i] = strdup(split[i+1]);
|
|
||||||
}
|
|
||||||
args[i] = NULL;
|
|
||||||
g_strfreev(split);
|
|
||||||
free(copy);
|
|
||||||
|
|
||||||
return args;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
#include "contact.h"
|
#include "contact.h"
|
||||||
#include "log.h"
|
|
||||||
#include "prof_autocomplete.h"
|
#include "prof_autocomplete.h"
|
||||||
|
|
||||||
static PAutocomplete ac;
|
static PAutocomplete ac;
|
||||||
@ -80,7 +79,6 @@ contact_list_update_contact(const char * const jid, const char * const presence,
|
|||||||
PContact contact = g_hash_table_lookup(contacts, jid);
|
PContact contact = g_hash_table_lookup(contacts, jid);
|
||||||
|
|
||||||
if (contact == NULL) {
|
if (contact == NULL) {
|
||||||
log_warning("Contact not in list: %s", jid);
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
96
src/parser.c
Normal file
96
src/parser.c
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/*
|
||||||
|
* parser.c
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 James Booth <boothj5@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Profanity.
|
||||||
|
*
|
||||||
|
* Profanity is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Profanity is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Profanity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
gchar **
|
||||||
|
parse_args(const char * const inp, int min, int max, int *num)
|
||||||
|
{
|
||||||
|
if (inp == NULL) {
|
||||||
|
*num = 0;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// copy and strip input of leading/trailing whitepsace
|
||||||
|
char *copy = strdup(inp);
|
||||||
|
g_strstrip(copy);
|
||||||
|
|
||||||
|
int inp_size = strlen(copy);
|
||||||
|
gboolean in_token = FALSE;
|
||||||
|
char *token_start = ©[0];
|
||||||
|
int token_size = 0;
|
||||||
|
GSList *tokens = NULL;
|
||||||
|
|
||||||
|
// add tokens to GSList
|
||||||
|
int i;
|
||||||
|
for (i = 0; i <= inp_size; i++) {
|
||||||
|
if (!in_token) {
|
||||||
|
if (copy[i] == ' ') {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
in_token = TRUE;
|
||||||
|
token_start = ©[i];
|
||||||
|
token_size++;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (copy[i] == ' ' || copy[i] == '\0') {
|
||||||
|
tokens = g_slist_append(tokens, g_strndup(token_start,
|
||||||
|
token_size));
|
||||||
|
token_size = 0;
|
||||||
|
in_token = FALSE;
|
||||||
|
} else {
|
||||||
|
token_size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*num = g_slist_length(tokens) - 1;
|
||||||
|
|
||||||
|
// if num args not valid return NULL
|
||||||
|
if ((*num < min) || (*num > max)) {
|
||||||
|
g_slist_free_full(tokens, free);
|
||||||
|
free(copy);
|
||||||
|
*num = 0;
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
// otherwise return args array
|
||||||
|
} else {
|
||||||
|
gchar **args = malloc((*num + 1) * sizeof(*args));
|
||||||
|
GSList *token = tokens;
|
||||||
|
token = g_slist_next(token);
|
||||||
|
int arg_count = 0;
|
||||||
|
|
||||||
|
while (token != NULL) {
|
||||||
|
args[arg_count++] = strdup(token->data);
|
||||||
|
token = g_slist_next(token);
|
||||||
|
}
|
||||||
|
|
||||||
|
args[arg_count] = NULL;
|
||||||
|
g_slist_free_full(tokens, free);
|
||||||
|
free(copy);
|
||||||
|
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
}
|
30
src/parser.h
Normal file
30
src/parser.h
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* parser.h
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012 James Booth <boothj5@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of Profanity.
|
||||||
|
*
|
||||||
|
* Profanity is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Profanity is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with Profanity. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef PARSER_H
|
||||||
|
#define PARSER_H
|
||||||
|
|
||||||
|
#include <glib.h>
|
||||||
|
|
||||||
|
gchar** parse_args(const char * const inp, int min, int max, int *num);
|
||||||
|
|
||||||
|
#endif
|
127
tests/test_parser.c
Normal file
127
tests/test_parser.c
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <head-unit.h>
|
||||||
|
#include "parser.h"
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_null_returns_null(void)
|
||||||
|
{
|
||||||
|
char *inp = NULL;
|
||||||
|
int num = 0;
|
||||||
|
gchar **result = parse_args(inp, 1, 2, &num);
|
||||||
|
|
||||||
|
assert_is_null(result);
|
||||||
|
g_strfreev(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_empty_returns_null(void)
|
||||||
|
{
|
||||||
|
char *inp = "";
|
||||||
|
int num = 0;
|
||||||
|
gchar **result = parse_args(inp, 1, 2, &num);
|
||||||
|
|
||||||
|
assert_is_null(result);
|
||||||
|
g_strfreev(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_space_returns_null(void)
|
||||||
|
{
|
||||||
|
char *inp = " ";
|
||||||
|
int num = 0;
|
||||||
|
gchar **result = parse_args(inp, 1, 2, &num);
|
||||||
|
|
||||||
|
assert_is_null(result);
|
||||||
|
g_strfreev(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_cmd_no_args_returns_null(void)
|
||||||
|
{
|
||||||
|
char *inp = "/cmd";
|
||||||
|
int num = 0;
|
||||||
|
gchar **result = parse_args(inp, 1, 2, &num);
|
||||||
|
|
||||||
|
assert_is_null(result);
|
||||||
|
g_strfreev(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_cmd_with_space_returns_null(void)
|
||||||
|
{
|
||||||
|
char *inp = "/cmd ";
|
||||||
|
int num = 0;
|
||||||
|
gchar **result = parse_args(inp, 1, 2, &num);
|
||||||
|
|
||||||
|
assert_is_null(result);
|
||||||
|
g_strfreev(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_cmd_one_arg(void)
|
||||||
|
{
|
||||||
|
char *inp = "/cmd arg1";
|
||||||
|
int num = 0;
|
||||||
|
gchar **result = parse_args(inp, 1, 2, &num);
|
||||||
|
|
||||||
|
assert_int_equals(1, num);
|
||||||
|
assert_string_equals("arg1", result[0]);
|
||||||
|
g_strfreev(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_cmd_two_args(void)
|
||||||
|
{
|
||||||
|
char *inp = "/cmd arg1 arg2";
|
||||||
|
int num = 0;
|
||||||
|
gchar **result = parse_args(inp, 1, 2, &num);
|
||||||
|
|
||||||
|
assert_int_equals(2, num);
|
||||||
|
assert_string_equals("arg1", result[0]);
|
||||||
|
assert_string_equals("arg2", result[1]);
|
||||||
|
g_strfreev(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_cmd_three_args(void)
|
||||||
|
{
|
||||||
|
char *inp = "/cmd arg1 arg2 arg3";
|
||||||
|
int num = 0;
|
||||||
|
gchar **result = parse_args(inp, 3, 3, &num);
|
||||||
|
|
||||||
|
assert_int_equals(3, num);
|
||||||
|
assert_string_equals("arg1", result[0]);
|
||||||
|
assert_string_equals("arg2", result[1]);
|
||||||
|
assert_string_equals("arg3", result[2]);
|
||||||
|
g_strfreev(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
parse_cmd_three_args_with_spaces(void)
|
||||||
|
{
|
||||||
|
char *inp = " /cmd arg1 arg2 arg3 ";
|
||||||
|
int num = 0;
|
||||||
|
gchar **result = parse_args(inp, 3, 3, &num);
|
||||||
|
|
||||||
|
assert_int_equals(3, num);
|
||||||
|
assert_string_equals("arg1", result[0]);
|
||||||
|
assert_string_equals("arg2", result[1]);
|
||||||
|
assert_string_equals("arg3", result[2]);
|
||||||
|
g_strfreev(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
register_parser_tests(void)
|
||||||
|
{
|
||||||
|
TEST_MODULE("parser tests");
|
||||||
|
TEST(parse_null_returns_null);
|
||||||
|
TEST(parse_empty_returns_null);
|
||||||
|
TEST(parse_space_returns_null);
|
||||||
|
TEST(parse_cmd_no_args_returns_null);
|
||||||
|
TEST(parse_cmd_with_space_returns_null);
|
||||||
|
TEST(parse_cmd_one_arg);
|
||||||
|
TEST(parse_cmd_two_args);
|
||||||
|
TEST(parse_cmd_three_args);
|
||||||
|
TEST(parse_cmd_three_args_with_spaces);
|
||||||
|
}
|
@ -7,6 +7,7 @@ int main(void)
|
|||||||
register_contact_list_tests();
|
register_contact_list_tests();
|
||||||
register_common_tests();
|
register_common_tests();
|
||||||
register_prof_autocomplete_tests();
|
register_prof_autocomplete_tests();
|
||||||
|
register_parser_tests();
|
||||||
run_suite();
|
run_suite();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -5,5 +5,6 @@ void register_prof_history_tests(void);
|
|||||||
void register_contact_list_tests(void);
|
void register_contact_list_tests(void);
|
||||||
void register_common_tests(void);
|
void register_common_tests(void);
|
||||||
void register_prof_autocomplete_tests(void);
|
void register_prof_autocomplete_tests(void);
|
||||||
|
void register_parser_tests(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user