From bfae111579dda5f08427b4c55c591c5c21643244 Mon Sep 17 00:00:00 2001 From: Dave Davenport Date: Wed, 11 Jan 2017 09:11:19 +0100 Subject: [PATCH] Fix indenting and header commenting. --- include/widgets/textbox.h | 20 +-- source/dialogs/ssh.c | 2 +- source/helper.c | 2 +- source/rofi.c | 2 +- source/view.c | 265 +++++++++++++++++++++++--------------- 5 files changed, 176 insertions(+), 115 deletions(-) diff --git a/include/widgets/textbox.h b/include/widgets/textbox.h index d81d8806..f8469ead 100644 --- a/include/widgets/textbox.h +++ b/include/widgets/textbox.h @@ -48,16 +48,16 @@ typedef struct */ typedef enum { - TB_AUTOHEIGHT = 1 << 0, - TB_AUTOWIDTH = 1 << 1, - TB_LEFT = 1 << 16, - TB_RIGHT = 1 << 17, - TB_CENTER = 1 << 18, - TB_EDITABLE = 1 << 19, - TB_MARKUP = 1 << 20, - TB_WRAP = 1 << 21, - TB_PASSWORD = 1 << 22, - TB_INDICATOR = 1 << 23, + TB_AUTOHEIGHT = 1 << 0, + TB_AUTOWIDTH = 1 << 1, + TB_LEFT = 1 << 16, + TB_RIGHT = 1 << 17, + TB_CENTER = 1 << 18, + TB_EDITABLE = 1 << 19, + TB_MARKUP = 1 << 20, + TB_WRAP = 1 << 21, + TB_PASSWORD = 1 << 22, + TB_INDICATOR = 1 << 23, } TextboxFlags; /** * Flags indicating current state of the textbox. diff --git a/source/dialogs/ssh.c b/source/dialogs/ssh.c index 8cfe68fd..c0ba2f8c 100644 --- a/source/dialogs/ssh.c +++ b/source/dialogs/ssh.c @@ -198,7 +198,7 @@ static char **read_hosts_file ( char ** retv, unsigned int *length ) // Reading one line per time. while ( getline ( &buffer, &buffer_length, fd ) > 0 ) { // Evaluate one line. - unsigned int index = 0, ti = 0; + unsigned int index = 0, ti = 0; char *token = buffer; // Tokenize it. diff --git a/source/helper.c b/source/helper.c index c7d417db..cb30a22d 100644 --- a/source/helper.c +++ b/source/helper.c @@ -248,7 +248,7 @@ GRegex **tokenize ( const char *input, int case_sensitive ) } char *saveptr = NULL, *token; - GRegex **retv = NULL; + GRegex **retv = NULL; if ( !config.tokenize ) { retv = g_malloc0 ( sizeof ( GRegex* ) * 2 ); retv[0] = (GRegex *) create_regex ( input, case_sensitive ); diff --git a/source/rofi.c b/source/rofi.c index ea155f2b..63b3edc8 100644 --- a/source/rofi.c +++ b/source/rofi.c @@ -416,7 +416,7 @@ static int add_mode ( const char * token ) } else #endif // WINDOW_MODE - // SSh dialog + // SSh dialog if ( strcasecmp ( token, "ssh" ) == 0 ) { modi[num_modi] = &ssh_mode; num_modi++; diff --git a/source/view.c b/source/view.c index 2e4f889f..8c6f0dfb 100644 --- a/source/view.c +++ b/source/view.c @@ -62,18 +62,28 @@ #include "theme.h" /** The Rofi View log domain */ -#define LOG_DOMAIN "View" +#define LOG_DOMAIN "View" -#define FUZZY_SCORER_MAX_LENGTH 256 -#define MIN_SCORE (INT_MIN / 2) -#define LEADING_GAP_SCORE -4 -#define GAP_SCORE -5 -#define WORD_START_SCORE 50 -#define NON_WORD_SCORE 40 -#define CAMEL_SCORE (WORD_START_SCORE + GAP_SCORE - 1) -#define CONSECUTIVE_SCORE (WORD_START_SCORE + GAP_SCORE) -#define PATTERN_NON_START_MULTIPLIER 1 -#define PATTERN_START_MULTIPLIER 2 +/** Max length of input to score. */ +#define FUZZY_SCORER_MAX_LENGTH 256 +/** minimum score */ +#define MIN_SCORE ( INT_MIN / 2 ) +/** Leading gap score */ +#define LEADING_GAP_SCORE -4 +/** gap score */ +#define GAP_SCORE -5 +/** start of word score */ +#define WORD_START_SCORE 50 +/** non-word score */ +#define NON_WORD_SCORE 40 +/** CamelCase score */ +#define CAMEL_SCORE ( WORD_START_SCORE + GAP_SCORE - 1 ) +/** Consecutive score */ +#define CONSECUTIVE_SCORE ( WORD_START_SCORE + GAP_SCORE ) +/** non-start multiplier */ +#define PATTERN_NON_START_MULTIPLIER 1 +/** start multiplier */ +#define PATTERN_START_MULTIPLIER 2 #include "xcb.h" /** @@ -552,132 +562,183 @@ static void rofi_view_call_thread ( gpointer data, gpointer user_data ) g_mutex_unlock ( t->mutex ); } -enum CharClass { LOWER, UPPER, DIGIT, NON_WORD }; - -static enum CharClass rofi_scorer_get_character_class(gunichar c) +/** + * Character classification. + */ +enum CharClass { - if (g_unichar_islower(c)) - return LOWER; - if (g_unichar_isupper(c)) - return UPPER; - if (g_unichar_isdigit(c)) - return DIGIT; - return NON_WORD; -} + /* Lower case */ + LOWER, + /* Upper case */ + UPPER, + /* Number */ + DIGIT, + /* non word character */ + NON_WORD +}; -static int rofi_scorer_get_score_for(enum CharClass prev, enum CharClass curr) +/** + * @param c The character to determine class of + * + * @returns the class of the character c. + */ +static enum CharClass rofi_scorer_get_character_class ( gunichar c ) { - if (prev == NON_WORD && curr != NON_WORD) - return WORD_START_SCORE; - if ((prev == LOWER && curr == UPPER) || - (prev != DIGIT && curr == DIGIT)) - return CAMEL_SCORE; - if (curr == NON_WORD) - return NON_WORD_SCORE; - return 0; -} - -/* -rofi_scorer_fuzzy_evaluate implements a global sequence alignment algorithm to find the maximum accumulated score by aligning `pattern` to `str`. It applies when `pattern` is a subsequence of `str`. - -Scoring criteria -- Prefer matches at the start of a word, or the start of subwords in CamelCase/camelCase/camel123 words. See WORD_START_SCORE/CAMEL_SCORE. -- Non-word characters matter. See NON_WORD_SCORE. -- The first characters of words of `pattern` receive bonus because they usually have more significance than the rest. See PATTERN_START_MULTIPLIER/PATTERN_NON_START_MULTIPLIER. -- Superfluous characters in `str` will reduce the score (gap penalty). See GAP_SCORE. -- Prefer early occurrence of the first character. See LEADING_GAP_SCORE/GAP_SCORE. - -The recurrence of the dynamic programming: -dp[i][j]: maximum accumulated score by aligning pattern[0..i] to str[0..j] -dp[0][j] = leading_gap_penalty(0, j) + score[j] -dp[i][j] = max(dp[i-1][j-1] + CONSECUTIVE_SCORE, max(dp[i-1][k] + gap_penalty(k+1, j) + score[j] : k < j)) - -The first dimension can be suppressed since we do not need a matching scheme, which reduces the space complexity from O(N*M) to O(M) -*/ -static int rofi_scorer_fuzzy_evaluate(const char *pattern, glong plen, const char *str, glong slen) -{ - if (plen == 5) - plen = plen; - glong pi, si; - gboolean pfirst = TRUE, // whether we are aligning the first character of pattern - pstart = TRUE; // whether the start of a word in pattern - int *score = g_malloc_n(slen, sizeof(int)), // score for each position - *dp = g_malloc_n(slen, sizeof(int)), // dp[i]: maximum value by aligning pattern[0..pi] to str[0..si] - uleft = 0, ulefts = 0, // uleft: value of the upper left cell; ulefts: maximum value of uleft and cells on the left. The arbitrary initial values suppress warnings. - left, lefts; // uleft & ulefts for the next row - const gchar *pit = pattern, *sit; - enum CharClass prev = NON_WORD, cur; - for (si = 0, sit = str; si < slen; si++, sit = g_utf8_next_char(sit)) { - cur = rofi_scorer_get_character_class(g_utf8_get_char(sit)); - score[si] = rofi_scorer_get_score_for(prev, cur); - prev = cur; - dp[si] = MIN_SCORE; + if ( g_unichar_islower ( c ) ) { + return LOWER; } - for (pi = 0; pi < plen; pi++, pit = g_utf8_next_char(pit)) { - gunichar pc = g_utf8_get_char(pit), sc; - if (g_unichar_isspace(pc)) { + if ( g_unichar_isupper ( c ) ) { + return UPPER; + } + if ( g_unichar_isdigit ( c ) ) { + return DIGIT; + } + return NON_WORD; +} + +/** + * @param prev The previous character. + * @param curr The current character + * + * Scrore the transition. + * + * @returns score of the transition. + */ +static int rofi_scorer_get_score_for ( enum CharClass prev, enum CharClass curr ) +{ + if ( prev == NON_WORD && curr != NON_WORD ) { + return WORD_START_SCORE; + } + if ( ( prev == LOWER && curr == UPPER ) || + ( prev != DIGIT && curr == DIGIT ) ) { + return CAMEL_SCORE; + } + if ( curr == NON_WORD ) { + return NON_WORD_SCORE; + } + return 0; +} + +/** + * @param pattern The user input to match against. + * @param plen Pattern length. + * @param str The input to match against pattern. + * @param slen Lenght of str. + * + * rofi_scorer_fuzzy_evaluate implements a global sequence alignment algorithm to find the maximum accumulated score by + * aligning `pattern` to `str`. It applies when `pattern` is a subsequence of `str`. + * + * Scoring criteria + * - Prefer matches at the start of a word, or the start of subwords in CamelCase/camelCase/camel123 words. See WORD_START_SCORE/CAMEL_SCORE. + * - Non-word characters matter. See NON_WORD_SCORE. + * - The first characters of words of `pattern` receive bonus because they usually have more significance than the rest. + * See PATTERN_START_MULTIPLIER/PATTERN_NON_START_MULTIPLIER. + * - Superfluous characters in `str` will reduce the score (gap penalty). See GAP_SCORE. + * - Prefer early occurrence of the first character. See LEADING_GAP_SCORE/GAP_SCORE. + * + * The recurrence of the dynamic programming: + * dp[i][j]: maximum accumulated score by aligning pattern[0..i] to str[0..j] + * dp[0][j] = leading_gap_penalty(0, j) + score[j] + * dp[i][j] = max(dp[i-1][j-1] + CONSECUTIVE_SCORE, max(dp[i-1][k] + gap_penalty(k+1, j) + score[j] : k < j)) + * + * The first dimension can be suppressed since we do not need a matching scheme, which reduces the space complexity from + * O(N*M) to O(M) + * + * @returns the sorting weight. + */ +static int rofi_scorer_fuzzy_evaluate ( const char *pattern, glong plen, const char *str, glong slen ) +{ + if ( plen == 5 ) { + plen = plen; + } + glong pi, si; + // whether we are aligning the first character of pattern + gboolean pfirst = TRUE; + // whether the start of a word in pattern + gboolean pstart = TRUE; + // score for each position + int *score = g_malloc_n ( slen, sizeof ( int ) ); + // dp[i]: maximum value by aligning pattern[0..pi] to str[0..si] + int *dp = g_malloc_n ( slen, sizeof ( int ) ); + // uleft: value of the upper left cell; ulefts: maximum value of uleft and cells on the left. The arbitrary initial + // values suppress warnings. + int uleft = 0, ulefts = 0, left, lefts; + const gchar *pit = pattern, *sit; + enum CharClass prev = NON_WORD, cur; + for ( si = 0, sit = str; si < slen; si++, sit = g_utf8_next_char ( sit ) ) { + cur = rofi_scorer_get_character_class ( g_utf8_get_char ( sit ) ); + score[si] = rofi_scorer_get_score_for ( prev, cur ); + prev = cur; + dp[si] = MIN_SCORE; + } + for ( pi = 0; pi < plen; pi++, pit = g_utf8_next_char ( pit ) ) { + gunichar pc = g_utf8_get_char ( pit ), sc; + if ( g_unichar_isspace ( pc ) ) { pstart = TRUE; continue; } lefts = MIN_SCORE; - for (si = 0, sit = str; si < slen; si++, sit = g_utf8_next_char(sit)) { - left = dp[si]; - lefts = MAX(lefts + GAP_SCORE, left); - sc = g_utf8_get_char(sit); - if (config.case_sensitive - ? pc == sc - : g_unichar_tolower(pc) == g_unichar_tolower(sc)) { - int t = score[si] * (pstart ? PATTERN_START_MULTIPLIER : PATTERN_NON_START_MULTIPLIER); + for ( si = 0, sit = str; si < slen; si++, sit = g_utf8_next_char ( sit ) ) { + left = dp[si]; + lefts = MAX ( lefts + GAP_SCORE, left ); + sc = g_utf8_get_char ( sit ); + if ( config.case_sensitive + ? pc == sc + : g_unichar_tolower ( pc ) == g_unichar_tolower ( sc ) ) { + int t = score[si] * ( pstart ? PATTERN_START_MULTIPLIER : PATTERN_NON_START_MULTIPLIER ); dp[si] = pfirst - ? LEADING_GAP_SCORE * si + t - : MAX(uleft + CONSECUTIVE_SCORE, ulefts + t); - } else { + ? LEADING_GAP_SCORE * si + t + : MAX ( uleft + CONSECUTIVE_SCORE, ulefts + t ); + } + else { dp[si] = MIN_SCORE; } - uleft = left; + uleft = left; ulefts = lefts; } pfirst = pstart = FALSE; } lefts = MIN_SCORE; - for (si = 0; si < slen; si++) - lefts = MAX(lefts + GAP_SCORE, dp[si]); - g_free(score); - g_free(dp); + for ( si = 0; si < slen; si++ ) { + lefts = MAX ( lefts + GAP_SCORE, dp[si] ); + } + g_free ( score ); + g_free ( dp ); return lefts; } static void filter_elements ( thread_state *t, G_GNUC_UNUSED gpointer user_data ) { - char *pattern = NULL; - glong plen; - if (config.matching_method == MM_FUZZY || config.levenshtein_sort) { - pattern = mode_preprocess_input(t->state->sw, t->state->text->text); - plen = g_utf8_strlen(pattern, -1); + char *pattern = NULL; + glong plen = 0; + if ( config.matching_method == MM_FUZZY || config.levenshtein_sort ) { + pattern = mode_preprocess_input ( t->state->sw, t->state->text->text ); + plen = g_utf8_strlen ( pattern, -1 ); } for ( unsigned int i = t->start; i < t->stop; i++ ) { int match = mode_token_match ( t->state->sw, t->state->tokens, i ); // If each token was matched, add it to list. if ( match ) { t->state->line_map[t->start + t->count] = i; - if (config.matching_method == MM_FUZZY) { - char *str = mode_get_completion(t->state->sw, i); - glong slen = g_utf8_strlen(str, -1); + if ( config.matching_method == MM_FUZZY ) { + char *str = mode_get_completion ( t->state->sw, i ); + glong slen = g_utf8_strlen ( str, -1 ); t->state->distance[i] = slen > FUZZY_SCORER_MAX_LENGTH - ? - MIN_SCORE - : - rofi_scorer_fuzzy_evaluate(pattern, plen, str, slen); - g_free(str); - } else if ( config.levenshtein_sort ) { + ? -MIN_SCORE + : -rofi_scorer_fuzzy_evaluate ( pattern, plen, str, slen ); + g_free ( str ); + } + else if ( config.levenshtein_sort ) { // This is inefficient, need to fix it. - char * str = mode_get_completion ( t->state->sw, i ); + char * str = mode_get_completion ( t->state->sw, i ); t->state->distance[i] = levenshtein ( pattern, str ); g_free ( str ); } t->count++; } } - if (pattern) { - g_free(pattern); + if ( pattern ) { + g_free ( pattern ); } }