Automatic commit
[selector.git] / selector.c
index 6c0f7f5..30f3f19 100644 (file)
@@ -91,7 +91,7 @@ void inject_into_tty_buffer(char *string) {
 
 void check_opt(int argc, char **argv, int n_opt, int n, const char *help) {
   if(n_opt + n >= argc) {
-    fprintf(stderr, "Missing argument for %s, expecting %s.\n",
+    fprintf(stderr, "Selector: Missing argument for %s, expecting %s.\n",
             argv[n_opt], help);
     exit(1);
   }
@@ -111,7 +111,7 @@ int string_to_positive_integer(char *string) {
   } else error = 1;
 
   if(error) {
-    fprintf(stderr, "Value `%s' is not a positive integer.\n", string);
+    fprintf(stderr, "Selector: Value `%s' is not a positive integer.\n", string);
     exit(1);
   }
 
@@ -126,62 +126,78 @@ void error_feedback() {
   }
 }
 
-/*********************************************************************
- A quick and dirty hash table
+/* A quick and dirty hash table */
+
+/* The table itself stores indexes of the strings taken in a char
+   **table. When a string is added, if it was already in the table,
+   **the new index replaces the previous one.  */
+
+typedef struct {
+  int size;
+  int *entries;
+} hash_table_t;
 
- The table itself stores indexes of the strings taken in a char
- **table. When a string is added, if it was already in the table, the
- new index replaces the previous one. */
+hash_table_t *new_hash_table(int size) {
+  int k;
+  hash_table_t *hash_table;
+
+  hash_table = (hash_table_t *) malloc(sizeof(hash_table_t));
 
-int *new_hash_table(int hash_table_size) {
-  int *result, k;
-  result = (int *) malloc(hash_table_size * sizeof(int));
-  for(k = 0; k < hash_table_size; k++) {
-    result[k] = -1;
+  hash_table->size = size;
+  hash_table->entries = (int *) malloc(hash_table->size * sizeof(int));
+
+  for(k = 0; k < hash_table->size; k++) {
+    hash_table->entries[k] = -1;
   }
-  return result;
+
+  return hash_table;
+}
+
+void free_hash_table(hash_table_t *hash_table) {
+  free(hash_table->entries);
+  free(hash_table);
 }
 
 /* Adds new_string in the table, associated to new_index. If this
    string was not already in the table, returns -1. Otherwise, returns
    the previous index it had. */
 
-int add_and_get_previous_index(const char *new_string, int new_index,
-                               char **strings,
-                               int *hash_table, int hash_table_size) {
+int add_and_get_previous_index(hash_table_t *hash_table,
+                               const char *new_string, int new_index,
+                               char **strings) {
 
   unsigned int code = 0;
   int k;
 
   /* This is my recipe. I checked, it seems to work (as long as
-     hash_table_size is not a multiple of 387433 that should be
+     hash_table->size is not a multiple of 387433 that should be
      okay) */
 
   for(k = 0; new_string[k]; k++) {
     code = code * 387433 + (unsigned int) (new_string[k]);
   }
 
-  code = code % hash_table_size;
+  code = code % hash_table->size;
 
-  while(hash_table[code] >= 0) {
+  while(hash_table->entries[code] >= 0) {
     /* There is a string with that code */
-    if(strcmp(new_string, strings[hash_table[code]]) == 0) {
+    if(strcmp(new_string, strings[hash_table->entries[code]]) == 0) {
       /* It is the same string, we keep a copy of the stored index */
-      int result = hash_table[code];
+      int result = hash_table->entries[code];
       /* Put the new one */
-      hash_table[code] = new_index;
+      hash_table->entries[code] = new_index;
       /* And return the previous one */
       return result;
     }
     /* This collision was not the same string, let's move to the next
        in the table */
-    code = (code + 1) % hash_table_size;
+    code = (code + 1) % hash_table->size;
   }
 
   /* This string was not already in there, store the index in the
      table and return -1 */
 
-  hash_table[code] = new_index;
+  hash_table->entries[code] = new_index;
   return -1;
 }
 
@@ -574,9 +590,9 @@ void update_screen(int *current_focus_line, int *displayed_focus_line,
 
 /*********************************************************************/
 
-void store_line(const char *t,
-                int nb_lines_max, int *nb_lines, char **lines,
-                int hash_table_size, int *hash_table) {
+void store_line(hash_table_t *hash_table,
+                const char *t,
+                int nb_lines_max, int *nb_lines, char **lines) {
   int dup;
 
   /* Remove the zsh history prefix */
@@ -598,7 +614,7 @@ void store_line(const char *t,
      the list if necessary */
 
   if(hash_table) {
-    dup = add_and_get_previous_index(t, *nb_lines, lines, hash_table, hash_table_size);
+    dup = add_and_get_previous_index(hash_table, t, *nb_lines, lines);
   } else {
     dup = -1;
   }
@@ -616,9 +632,9 @@ void store_line(const char *t,
   (*nb_lines)++;
 }
 
-void read_file(const char *input_filename,
-               int nb_lines_max, int *nb_lines, char **lines,
-               int hash_table_size, int *hash_table) {
+void read_file(hash_table_t *hash_table,
+               const char *input_filename,
+               int nb_lines_max, int *nb_lines, char **lines) {
 
   char raw_line[BUFFER_SIZE];
   int start, end, k;
@@ -627,7 +643,7 @@ void read_file(const char *input_filename,
   file = fopen(input_filename, "r");
 
   if(!file) {
-    fprintf(stderr, "Can not open `%s'.\n", input_filename);
+    fprintf(stderr, "Selector: Can not open `%s'.\n", input_filename);
     exit(1);
   }
 
@@ -651,7 +667,7 @@ void read_file(const char *input_filename,
 
     if(eol == BUFFER_SIZE) {
       raw_line[BUFFER_SIZE - 1] = '\0';
-      fprintf(stderr, "Line too long (max is %d characters):\n", BUFFER_SIZE);
+      fprintf(stderr, "Selector: Line too long (max is %d characters):\n", BUFFER_SIZE);
       fprintf(stderr, raw_line);
       fprintf(stderr, "\n");
       exit(1);
@@ -659,9 +675,8 @@ void read_file(const char *input_filename,
 
     raw_line[eol] = '\0';
 
-    store_line(raw_line + start,
-               nb_lines_max, nb_lines, lines,
-               hash_table_size, hash_table);
+    store_line(hash_table, raw_line + start,
+               nb_lines_max, nb_lines, lines);
 
     start = eol + 1;
   }
@@ -686,10 +701,11 @@ int main(int argc, char **argv) {
   int color_fg_highlight, color_bg_highlight;
 
   char **lines, **labels;
-  int nb_lines, hash_table_size, *hash_table;
+  int nb_lines;
+  hash_table_t *hash_table;
 
   if(!ttyname(STDIN_FILENO)) {
-    fprintf(stderr, "The standard input is not a tty.\n");
+    fprintf(stderr, "Selector: The standard input is not a tty.\n");
     exit(1);
   }
 
@@ -814,7 +830,7 @@ int main(int argc, char **argv) {
     }
 
     else {
-      fprintf(stderr, "Unknown option %s.\n", argv[i]);
+      fprintf(stderr, "Selector: Unknown option %s.\n", argv[i]);
       error = 1;
     }
   }
@@ -855,27 +871,29 @@ int main(int argc, char **argv) {
   lines = (char **) malloc(nb_lines_max * sizeof(char *));
 
   nb_lines = 0;
-  hash_table_size = nb_lines_max * 10;
-  hash_table = 0;
 
   if(remove_duplicates) {
-    hash_table = new_hash_table(hash_table_size);
+    hash_table = new_hash_table(nb_lines_max * 10);
+  } else {
+    hash_table = 0;
   }
 
   if(input_filename[0]) {
-    read_file(input_filename,
-              nb_lines_max, &nb_lines, lines,
-              hash_table_size, hash_table);
+    read_file(hash_table,
+              input_filename,
+              nb_lines_max, &nb_lines, lines);
   }
 
   while(i < argc) {
-    read_file(argv[i],
-              nb_lines_max, &nb_lines, lines,
-              hash_table_size, hash_table);
+    read_file(hash_table,
+              argv[i],
+              nb_lines_max, &nb_lines, lines);
     i++;
   }
 
-  free(hash_table);
+  if(hash_table) {
+    free_hash_table(hash_table);
+  }
 
   /* Now remove the null strings */
 
@@ -950,7 +968,7 @@ int main(int argc, char **argv) {
        color_bg_highlight < 0 || color_bg_highlight >= COLORS) {
       echo();
       endwin();
-      fprintf(stderr, "Color numbers have to be between 0 and %d.\n", COLORS - 1);
+      fprintf(stderr, "Selector: Color numbers have to be between 0 and %d.\n", COLORS - 1);
       exit(1);
     }
 
@@ -1099,7 +1117,7 @@ int main(int argc, char **argv) {
         }
         fprintf(out, "\n");
       } else {
-        fprintf(stderr, "Can not open %s for writing.\n", output_filename);
+        fprintf(stderr, "Selector: Can not open %s for writing.\n", output_filename);
         exit(1);
       }
       fclose(out);