Added a safe_malloc and removed the cast when using it.
[selector.git] / selector.c
index d7e0820..a5b620e 100644 (file)
@@ -35,6 +35,7 @@
 #include <stdlib.h>
 #include <unistd.h>
 #include <string.h>
+#include <errno.h>
 #include <ncurses.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
@@ -65,6 +66,19 @@ int error_flash = 0;
 
 int attr_modeline, attr_focus_line, attr_error;
 
+/********************************************************************/
+
+/* malloc with error checking.  */
+
+void *safe_malloc(size_t n) {
+  void *p = malloc(n);
+  if (!p && n != 0) {
+    printf("Can not allocate memory: %s\n", strerror(errno));
+    exit(EXIT_FAILURE);
+  }
+  return p;
+}
+
 /*********************************************************************/
 
 void inject_into_tty_buffer(char *string, int add_control_qs) {
@@ -93,7 +107,7 @@ void check_opt(int argc, char **argv, int n_opt, int n, const char *help) {
   if(n_opt + n >= argc) {
     fprintf(stderr, "Selector: Missing argument for %s, expecting %s.\n",
             argv[n_opt], help);
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 }
 
@@ -114,7 +128,7 @@ int string_to_positive_integer(char *string) {
     fprintf(stderr,
             "Selector: Value `%s' is not a positive integer.\n",
             string);
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 
   return result;
@@ -136,19 +150,19 @@ void error_feedback() {
    table. When a string is added, if it was already in the table, the
    new index replaces the previous one.  */
 
-typedef struct {
+struct hash_table_t {
   int size;
   int *entries;
-} hash_table_t;
+};
 
-hash_table_t *new_hash_table(int size) {
+struct hash_table_t *new_hash_table(int size) {
   int k;
-  hash_table_t *hash_table;
+  struct hash_table_t *hash_table;
 
-  hash_table = (hash_table_t *) malloc(sizeof(hash_table_t));
+  hash_table = safe_malloc(sizeof(struct hash_table_t));
 
   hash_table->size = size;
-  hash_table->entries = (int *) malloc(hash_table->size * sizeof(int));
+  hash_table->entries = safe_malloc(hash_table->size * sizeof(int));
 
   for(k = 0; k < hash_table->size; k++) {
     hash_table->entries[k] = -1;
@@ -157,7 +171,7 @@ hash_table_t *new_hash_table(int size) {
   return hash_table;
 }
 
-void free_hash_table(hash_table_t *hash_table) {
+void free_hash_table(struct hash_table_t *hash_table) {
   free(hash_table->entries);
   free(hash_table);
 }
@@ -166,7 +180,7 @@ void free_hash_table(hash_table_t *hash_table) {
    string was not already in the table, returns -1. Otherwise, returns
    the previous index it had. */
 
-int add_and_get_previous_index(hash_table_t *hash_table,
+int add_and_get_previous_index(struct hash_table_t *hash_table,
                                const char *new_string, int new_index,
                                char **strings) {
 
@@ -266,10 +280,10 @@ void initialize_matcher(int use_regexp, int case_sensitive,
     }
 
     matcher->splitted_patterns =
-      (char *) malloc((strlen(pattern) + 1) * sizeof(char));
+      safe_malloc((strlen(pattern) + 1) * sizeof(char));
 
     matcher->patterns =
-      (char **) malloc(matcher->nb_patterns * sizeof(char *));
+      safe_malloc(matcher->nb_patterns * sizeof(char *));
 
     strcpy(matcher->splitted_patterns, pattern);
 
@@ -617,7 +631,7 @@ void update_screen(int *current_focus_line, int *displayed_focus_line,
 
 /*********************************************************************/
 
-void store_line(hash_table_t *hash_table,
+void store_line(struct hash_table_t *hash_table,
                 const char *new_line,
                 int *nb_lines, char **lines) {
   int dup;
@@ -648,7 +662,7 @@ void store_line(hash_table_t *hash_table,
   }
 
   if(dup < 0) {
-    lines[*nb_lines] = (char *) malloc((strlen(new_line) + 1) * sizeof(char));
+    lines[*nb_lines] = safe_malloc((strlen(new_line) + 1) * sizeof(char));
     strcpy(lines[*nb_lines], new_line);
   } else {
     /* The string was already in there, so we do not allocate a new
@@ -660,7 +674,7 @@ void store_line(hash_table_t *hash_table,
   (*nb_lines)++;
 }
 
-void read_file(hash_table_t *hash_table,
+void read_file(struct hash_table_t *hash_table,
                const char *input_filename,
                int nb_lines_max, int *nb_lines, char **lines) {
 
@@ -672,7 +686,7 @@ void read_file(hash_table_t *hash_table,
 
   if(!file) {
     fprintf(stderr, "Selector: Can not open `%s'.\n", input_filename);
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 
   start = 0;
@@ -708,7 +722,7 @@ void read_file(hash_table_t *hash_table,
               BUFFER_SIZE);
       fprintf(stderr, raw_line);
       fprintf(stderr, "\n");
-      exit(1);
+      exit(EXIT_FAILURE);
     }
 
     /* If we got a line, we replace the carriage return by a \0 to
@@ -743,11 +757,11 @@ int main(int argc, char **argv) {
 
   char **lines, **labels;
   int nb_lines;
-  hash_table_t *hash_table;
+  struct hash_table_t *hash_table;
 
-  if(!ttyname(STDIN_FILENO)) {
+  if(!isatty(STDIN_FILENO)) {
     fprintf(stderr, "Selector: The standard input is not a tty.\n");
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 
   color_fg_modeline  = COLOR_WHITE;
@@ -763,8 +777,8 @@ int main(int argc, char **argv) {
   i = 1;
 
   while(!error && !show_help &&
-        i < argc && argv[i][0] == '-' &&
-        !rest_are_files) {
+        i < argc &&
+        argv[i][0] == '-' && !rest_are_files) {
 
     if(strcmp(argv[i], "-o") == 0) {
       check_opt(argc, argv, i, 1, "<output filename>");
@@ -843,7 +857,7 @@ int main(int argc, char **argv) {
     else if(strcmp(argv[i], "-t") == 0) {
       check_opt(argc, argv, i, 1, "<title>");
       free(title);
-      title = (char *) malloc((strlen(argv[i+1]) + 1) * sizeof(char));
+      title = safe_malloc((strlen(argv[i+1]) + 1) * sizeof(char));
       strcpy(title, argv[i+1]);
       i += 2;
     }
@@ -888,7 +902,7 @@ int main(int argc, char **argv) {
       out = stderr;
     }
 
-    fprintf(out, "Selector version %s-R%s\n", VERSION, REVISION_NUMBER);
+    fprintf(out, "Selector version %s-R%s (%s)\n", VERSION, REVISION_NUMBER, UNAME);
     fprintf(out, "Written by Francois Fleuret <francois@fleuret.org>.\n");
     fprintf(out, "\n");
     fprintf(out, "Usage: %s [options] [<filename1> [<filename2> ...]]\n",
@@ -922,7 +936,7 @@ int main(int argc, char **argv) {
     exit(error);
   }
 
-  lines = (char **) malloc(nb_lines_max * sizeof(char *));
+  lines = safe_malloc(nb_lines_max * sizeof(char *));
 
   nb_lines = 0;
 
@@ -972,7 +986,7 @@ int main(int argc, char **argv) {
      label_separator and transform control characters to printable
      ones */
 
-  labels = (char **) malloc(nb_lines * sizeof(char *));
+  labels = safe_malloc(nb_lines * sizeof(char *));
 
   for(l = 0; l < nb_lines; l++) {
     char *s, *t;
@@ -985,7 +999,7 @@ int main(int argc, char **argv) {
       e += strlen(u);
     }
 
-    labels[l] = (char *) malloc((e + 1) * sizeof(char));
+    labels[l] = safe_malloc((e + 1) * sizeof(char));
     t = lines[l];
     s = labels[l];
     while(*t && *t != label_separator) {
@@ -1025,7 +1039,7 @@ int main(int argc, char **argv) {
       endwin();
       fprintf(stderr, "Selector: Color numbers have to be between 0 and %d.\n",
               COLORS - 1);
-      exit(1);
+      exit(EXIT_FAILURE);
     }
 
     init_pair(1, color_fg_modeline, color_bg_modeline);
@@ -1177,7 +1191,7 @@ int main(int argc, char **argv) {
         fprintf(stderr,
                 "Selector: Can not open %s for writing.\n",
                 output_filename);
-        exit(1);
+        exit(EXIT_FAILURE);
       }
       fclose(out);
     }
@@ -1195,5 +1209,5 @@ int main(int argc, char **argv) {
   free(lines);
   free(title);
 
-  exit(0);
+  exit(EXIT_SUCCESS);
 }