<URL: http://bugs.freeciv.org/Ticket/Display.html?id=40196 >
On 08/04/2008, Marko Lindqvist wrote: > > - Only strings both starting and ending with '"' are considered > quoted and these starting and ending quotes are only ones ignored > during matching > - Correct string length comparison for quoted strings implemented and used - S2_1 version - Handle quoted connection names - ML
diff -Nurd -X.diff_ignore freeciv/common/connection.c freeciv/common/connection.c --- freeciv/common/connection.c 2008-01-15 04:04:30.000000000 +0200 +++ freeciv/common/connection.c 2008-04-15 11:18:43.000000000 +0300 @@ -441,7 +441,8 @@ *result = match_prefix(connection_accessor, conn_list_size(game.all_connections), - MAX_LEN_NAME-1, mystrncasecmp, user_name, &ind); + MAX_LEN_NAME-1, mystrncasequotecmp, + effectivestrlenquote, user_name, &ind); if (*result < M_PRE_AMBIGUOUS) { return conn_list_get(game.all_connections, ind); diff -Nurd -X.diff_ignore freeciv/common/player.c freeciv/common/player.c --- freeciv/common/player.c 2008-01-15 04:04:30.000000000 +0200 +++ freeciv/common/player.c 2008-04-15 11:16:15.000000000 +0300 @@ -360,7 +360,7 @@ int ind; *result = match_prefix(pname_accessor, game.info.nplayers, MAX_LEN_NAME-1, - mystrncasequotecmp, name, &ind); + mystrncasequotecmp, effectivestrlenquote, name, &ind); if (*result < M_PRE_AMBIGUOUS) { return player_by_number(ind); diff -Nurd -X.diff_ignore freeciv/server/stdinhand.c freeciv/server/stdinhand.c --- freeciv/server/stdinhand.c 2008-04-02 22:48:51.000000000 +0300 +++ freeciv/server/stdinhand.c 2008-04-15 11:17:07.000000000 +0300 @@ -175,7 +175,7 @@ int ind; result = match_prefix(cmdname_accessor, CMD_NUM, 0, - mystrncasecmp, token, &ind); + mystrncasecmp, NULL, token, &ind); if (result < M_PRE_AMBIGUOUS) { return ind; @@ -1517,7 +1517,7 @@ } result = match_prefix(optname_accessor, SETTINGS_NUM, 0, mystrncasecmp, - name, &ind); + NULL, name, &ind); return ((result < M_PRE_AMBIGUOUS) ? ind : (result == M_PRE_AMBIGUOUS) ? -2 : -1); @@ -4003,7 +4003,7 @@ /* no commands means no help, either */ match_result = match_prefix(helparg_accessor, HELP_ARG_NUM, 0, - mystrncasecmp, arg, &ind); + mystrncasecmp, NULL, arg, &ind); if (match_result==M_PRE_EMPTY) { show_help_intro(caller, CMD_HELP); @@ -4077,7 +4077,7 @@ remove_leading_trailing_spaces(arg); match_result = match_prefix(listarg_accessor, LIST_ARG_NUM, 0, - mystrncasecmp, arg, &ind_int); + mystrncasecmp, NULL, arg, &ind_int); ind = ind_int; if (match_result > M_PRE_EMPTY) { diff -Nurd -X.diff_ignore freeciv/utility/shared.c freeciv/utility/shared.c --- freeciv/utility/shared.c 2008-03-11 11:27:29.000000000 +0200 +++ freeciv/utility/shared.c 2008-04-15 11:15:10.000000000 +0300 @@ -1473,12 +1473,17 @@ size_t n_names, size_t max_len_name, m_pre_strncmp_fn_t cmp_fn, + m_strlen_fn_t len_fn, const char *prefix, int *ind_result) { int i, len, nmatches; - len = strlen(prefix); + if (len_fn == NULL) { + len = strlen(prefix); + } else { + len = len_fn(prefix); + } if (len == 0) { return M_PRE_EMPTY; } diff -Nurd -X.diff_ignore freeciv/utility/shared.h freeciv/utility/shared.h --- freeciv/utility/shared.h 2008-01-15 04:04:10.000000000 +0200 +++ freeciv/utility/shared.h 2008-04-15 11:15:10.000000000 +0300 @@ -224,10 +224,14 @@ /* function type to compare prefix: */ typedef int (*m_pre_strncmp_fn_t)(const char *, const char *, size_t n); +/* function type to calculate effective string length: */ +typedef size_t (m_strlen_fn_t)(const char *str); + enum m_pre_result match_prefix(m_pre_accessor_fn_t accessor_fn, size_t n_names, size_t max_len_name, m_pre_strncmp_fn_t cmp_fn, + m_strlen_fn_t len_fn, const char *prefix, int *ind_result); diff -Nurd -X.diff_ignore freeciv/utility/support.c freeciv/utility/support.c --- freeciv/utility/support.c 2008-01-31 17:13:29.000000000 +0200 +++ freeciv/utility/support.c 2008-04-15 11:15:10.000000000 +0300 @@ -135,24 +135,66 @@ } /*************************************************************** - Compare strings like strncasecmp() but ignoring quotes in - either string. Quotes still count towards n. + Count length of string without possible surrounding quotes. +***************************************************************/ +size_t effectivestrlenquote(const char *str) +{ + int len = strlen(str); + + if (str[0] == '"' && str[len-1] == '"') { + return len - 2; + } + + return len; +} + +/*************************************************************** + Compare strings like strncasecmp() but ignoring surrounding + quotes in either string. ***************************************************************/ int mystrncasequotecmp(const char *str0, const char *str1, size_t n) { size_t i; - char c; + size_t len0 = strlen(str0); /* TODO: We iterate string once already here, */ + size_t len1 = strlen(str1); /* could iterate only once */ + size_t cmplen; - for (i = 0; i < n && *str0 != '\0'; i++) { - if (my_tolower(*str0) != my_tolower(*str1) - && *str0 != '"' && *str1 != '"') { + if (str0[0] == '"') { + if (str0[len0 - 1] == '"') { + /* Surrounded with quotes */ + str0++; + len0 -= 2; + } + } + + if (str1[0] == '"') { + if (str1[len1 - 1] == '"') { + /* Surrounded with quotes */ + str1++; + len1 -= 2; + } + } + + if (len0 < n || len1 < n) { + /* One of the strings is shorter than what should be compared... */ + if (len0 != len1) { + /* ...and another is longer than it. */ + return len0 - len1; + } + + cmplen = len0; /* This avoids comparing ending quote */ + } else { + cmplen = n; + } + + for (i = 0; i < cmplen ; i++, str0++, str1++) { + if (my_tolower(*str0) != my_tolower(*str1)) { return ((int) (unsigned char) my_tolower(*str0)) - ((int) (unsigned char) my_tolower(*str1)); } - c = *str0; - str0 += (*str1 != '"'); - str1 += (c != '"'); } + + /* All characters compared and all matched */ return 0; } diff -Nurd -X.diff_ignore freeciv/utility/support.h freeciv/utility/support.h --- freeciv/utility/support.h 2007-08-01 19:18:30.000000000 +0300 +++ freeciv/utility/support.h 2008-04-15 11:17:43.000000000 +0300 @@ -74,6 +74,8 @@ int mystrncasecmp(const char *str0, const char *str1, size_t n); int mystrncasequotecmp(const char *str0, const char *str1, size_t n); +size_t effectivestrlenquote(const char *str); + const char *mystrerror(void); void myusleep(unsigned long usec);
diff -Nurd -X.diff_ignore freeciv/common/connection.c freeciv/common/connection.c --- freeciv/common/connection.c 2008-03-08 16:32:49.000000000 +0200 +++ freeciv/common/connection.c 2008-04-15 11:19:57.000000000 +0300 @@ -440,7 +440,8 @@ *result = match_prefix(connection_accessor, conn_list_size(game.all_connections), - MAX_LEN_NAME-1, mystrncasecmp, user_name, &ind); + MAX_LEN_NAME-1, mystrncasequotecmp, + effectivestrlenquote, user_name, &ind); if (*result < M_PRE_AMBIGUOUS) { return conn_list_get(game.all_connections, ind); diff -Nurd -X.diff_ignore freeciv/common/player.c freeciv/common/player.c --- freeciv/common/player.c 2008-03-08 16:32:49.000000000 +0200 +++ freeciv/common/player.c 2008-04-15 11:19:15.000000000 +0300 @@ -396,7 +396,8 @@ int ind; *result = match_prefix(player_name_by_number, game.info.nplayers, - MAX_LEN_NAME-1, mystrncasequotecmp, name, &ind); + MAX_LEN_NAME-1, mystrncasequotecmp, + effectivestrlenquote, name, &ind); if (*result < M_PRE_AMBIGUOUS) { return player_by_number(ind); diff -Nurd -X.diff_ignore freeciv/server/stdinhand.c freeciv/server/stdinhand.c --- freeciv/server/stdinhand.c 2008-04-06 11:24:53.000000000 +0300 +++ freeciv/server/stdinhand.c 2008-04-15 11:19:15.000000000 +0300 @@ -173,7 +173,7 @@ int ind; result = match_prefix(command_name_by_number, CMD_NUM, 0, - mystrncasecmp, token, &ind); + mystrncasecmp, NULL, token, &ind); if (result < M_PRE_AMBIGUOUS) { return ind; @@ -1486,7 +1486,7 @@ } result = match_prefix(optname_accessor, SETTINGS_NUM, 0, mystrncasecmp, - name, &ind); + NULL, name, &ind); return ((result < M_PRE_AMBIGUOUS) ? ind : (result == M_PRE_AMBIGUOUS) ? -2 : -1); @@ -4008,7 +4008,7 @@ /* no commands means no help, either */ match_result = match_prefix(helparg_accessor, HELP_ARG_NUM, 0, - mystrncasecmp, arg, &ind); + mystrncasecmp, NULL, arg, &ind); if (match_result==M_PRE_EMPTY) { show_help_intro(caller, CMD_HELP); @@ -4082,7 +4082,7 @@ remove_leading_trailing_spaces(arg); match_result = match_prefix(listarg_accessor, LIST_ARG_NUM, 0, - mystrncasecmp, arg, &ind_int); + mystrncasecmp, NULL, arg, &ind_int); ind = ind_int; if (match_result > M_PRE_EMPTY) { diff -Nurd -X.diff_ignore freeciv/utility/shared.c freeciv/utility/shared.c --- freeciv/utility/shared.c 2008-03-11 11:27:15.000000000 +0200 +++ freeciv/utility/shared.c 2008-04-15 11:19:15.000000000 +0300 @@ -1485,12 +1485,17 @@ size_t n_names, size_t max_len_name, m_pre_strncmp_fn_t cmp_fn, + m_strlen_fn_t len_fn, const char *prefix, int *ind_result) { int i, len, nmatches; - len = strlen(prefix); + if (len_fn == NULL) { + len = strlen(prefix); + } else { + len = len_fn(prefix); + } if (len == 0) { return M_PRE_EMPTY; } diff -Nurd -X.diff_ignore freeciv/utility/shared.h freeciv/utility/shared.h --- freeciv/utility/shared.h 2008-03-08 16:32:11.000000000 +0200 +++ freeciv/utility/shared.h 2008-04-15 11:19:15.000000000 +0300 @@ -224,10 +224,14 @@ /* function type to compare prefix: */ typedef int (*m_pre_strncmp_fn_t)(const char *, const char *, size_t n); +/* function type to calculate effective string length: */ +typedef size_t (m_strlen_fn_t)(const char *str); + enum m_pre_result match_prefix(m_pre_accessor_fn_t accessor_fn, size_t n_names, size_t max_len_name, m_pre_strncmp_fn_t cmp_fn, + m_strlen_fn_t len_fn, const char *prefix, int *ind_result); diff -Nurd -X.diff_ignore freeciv/utility/support.c freeciv/utility/support.c --- freeciv/utility/support.c 2008-01-31 01:26:00.000000000 +0200 +++ freeciv/utility/support.c 2008-04-15 11:19:15.000000000 +0300 @@ -135,24 +135,66 @@ } /*************************************************************** - Compare strings like strncasecmp() but ignoring quotes in - either string. Quotes still count towards n. + Count length of string without possible surrounding quotes. +***************************************************************/ +size_t effectivestrlenquote(const char *str) +{ + int len = strlen(str); + + if (str[0] == '"' && str[len-1] == '"') { + return len - 2; + } + + return len; +} + +/*************************************************************** + Compare strings like strncasecmp() but ignoring surrounding + quotes in either string. ***************************************************************/ int mystrncasequotecmp(const char *str0, const char *str1, size_t n) { size_t i; - char c; + size_t len0 = strlen(str0); /* TODO: We iterate string once already here, */ + size_t len1 = strlen(str1); /* could iterate only once */ + size_t cmplen; - for (i = 0; i < n && *str0 != '\0'; i++) { - if (my_tolower(*str0) != my_tolower(*str1) - && *str0 != '"' && *str1 != '"') { + if (str0[0] == '"') { + if (str0[len0 - 1] == '"') { + /* Surrounded with quotes */ + str0++; + len0 -= 2; + } + } + + if (str1[0] == '"') { + if (str1[len1 - 1] == '"') { + /* Surrounded with quotes */ + str1++; + len1 -= 2; + } + } + + if (len0 < n || len1 < n) { + /* One of the strings is shorter than what should be compared... */ + if (len0 != len1) { + /* ...and another is longer than it. */ + return len0 - len1; + } + + cmplen = len0; /* This avoids comparing ending quote */ + } else { + cmplen = n; + } + + for (i = 0; i < cmplen ; i++, str0++, str1++) { + if (my_tolower(*str0) != my_tolower(*str1)) { return ((int) (unsigned char) my_tolower(*str0)) - ((int) (unsigned char) my_tolower(*str1)); } - c = *str0; - str0 += (*str1 != '"'); - str1 += (c != '"'); } + + /* All characters compared and all matched */ return 0; } diff -Nurd -X.diff_ignore freeciv/utility/support.h freeciv/utility/support.h --- freeciv/utility/support.h 2008-01-15 04:53:30.000000000 +0200 +++ freeciv/utility/support.h 2008-04-15 11:19:15.000000000 +0300 @@ -74,6 +74,8 @@ int mystrncasecmp(const char *str0, const char *str1, size_t n); int mystrncasequotecmp(const char *str0, const char *str1, size_t n); +size_t effectivestrlenquote(const char *str); + char *mystrcasestr(const char *haystack, const char *needle); const char *mystrerror(void);
_______________________________________________ Freeciv-dev mailing list Freeciv-dev@gna.org https://mail.gna.org/listinfo/freeciv-dev