summaryrefslogtreecommitdiff
path: root/src/common.c
blob: 5f1ba3eb58784b80267cdede566b570d88f8d150 (plain)
    1 /**
    2  * Copyright (C) 2015 Aaron Ball <nullspoon@iohq.net>
    3  *
    4  * Noteless is free software: you can redistribute it and/or modify
    5  * it under the terms of the GNU General Public License as published by
    6  * the Free Software Foundation, either version 3 of the License, or
    7  * (at your option) any later version.
    8  *
    9  * Noteless is distributed in the hope that it will be useful,
   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   12  * GNU General Public License for more details.
   13  *
   14  * You should have received a copy of the GNU General Public License
   15  * along with Noteless.  If not, see <http://www.gnu.org/licenses/>.
   16  */
   17 #include "common.h"
   18 
   19 
   20 /**
   21  * Determins the text editor that should be used. Checks the environmental
   22  * variable EDITOR for this.
   23  *
   24  * @return char* Path to the editor binary to be used (stored in heap)
   25  */
   26 void get_user_editor(char* editor) {
   27   if(getenv("EDITOR") != NULL) {
   28     /* If the EDITOR variable is set, use that */
   29     //int editor_len = strlen(getenv("EDITOR"));
   30     // *editor = calloc(editor_len, sizeof(char));
   31     strcpy(editor, getenv("EDITOR"));
   32   } else {
   33     strcpy(editor, "vi");
   34   }
   35 }
   36 
   37 
   38 /**
   39  * Converts an integer to its equivelant char array
   40  *
   41  * @param i The integer to be converted
   42  * @param out Char array pointer to the output variable. Must be large enough
   43  *            to hold the output or unpredictable behavior may result.
   44  *
   45  * @return int The char count, not including the terminating null byte char
   46  */
   47 int itoc(int num, char* out) {
   48   int count = 0;
   49 
   50   int tmp_num = num;
   51   // Get a char count.  This is necessary becasue the numbers come out
   52   // backwards. We need to start from the end and work back.
   53   while(tmp_num > 0) {
   54     //int n = tmp_num%10;
   55     tmp_num /= 10;
   56     count++;
   57   }
   58 
   59   int out_count = count;
   60 
   61   // Set the last char as a null byte
   62   out[count] = '\0';
   63   count--;
   64 
   65   while(count >= 0) {
   66     int n = num%10;
   67 
   68     // Add 48 to the int to get its char equivelant ascii index
   69     out[count] = n + 48;
   70 
   71     num /= 10;
   72     count--;
   73   }
   74 
   75   return out_count;
   76 }
   77 
   78 
   79 /**
   80  * Returns the current localtime in format YYYYMMDD.HHmmss. Useful for "random"
   81  * non-conflicting filenames.
   82  *
   83  * @param date Output variable for the date string.  The output variable must
   84  *             have space for the date to be stored, otherwise unexpected
   85  *             behavior may occur.
   86  */
   87 void get_current_date_time(char* date) {
   88   time_t rawtime;
   89   time(&rawtime);
   90   struct tm* now = localtime(&rawtime);
   91 
   92   // Date
   93   // Year
   94   int year = now->tm_year + 1900;
   95   char c_year[5];
   96   itoc(year, c_year);
   97   strcpy(date, c_year);
   98 
   99   // Month
  100   int mon = now->tm_mon + 1;
  101   char c_mon[3];
  102   itoc(mon, c_mon);
  103   if(mon < 10) { strcat(date, "0"); }
  104   strcat(date, c_mon);
  105 
  106   // Day
  107   int day = now->tm_mday;
  108   char c_day[3];
  109   if(day < 10) { strcat(date, "0"); }
  110   strcat(date, c_day);
  111 
  112   // A delimiter to make it easier for humans to read.
  113   strcat(date, ".");
  114 
  115   // Time
  116   // Hour
  117   int hour = now->tm_hour;
  118   char c_hour[3];
  119   itoc(hour, c_hour);
  120   if(hour < 10) { strcat(date, "0"); }
  121   strcat(date, c_hour);
  122  
  123   // Minute
  124   int min = now->tm_min;
  125   char c_min[3];
  126   itoc(min, c_min);
  127   if(min < 10) { strcat(date, "0"); }
  128   strcat(date, c_min);
  129 
  130   // Second
  131   int sec = now->tm_sec;
  132   char c_sec[3];
  133   itoc(sec, c_sec);
  134   if(sec < 10) { strcat(date, "0"); }
  135   strcat(date, c_sec);
  136 }
  137 
  138 
  139 /**
  140  * TODO: Write this function description
  141  *
  142  * @return int Extension char length
  143  */
  144 int get_extension(char* path, char* extension) {
  145   int path_len = strlen(path);
  146   // Start from the right and move left
  147   for(int i = path_len; i > 0; i--) {
  148     // Copy if an extension delimiter (a period) is found
  149     if(path[i] == '.') {
  150       int ext_len = path_len - i;
  151       strncpy(extension, &path[i+1], ext_len);
  152       return ext_len;
  153     }
  154   }
  155   return -1;
  156 }
  157 
  158 
  159 /**
  160  * Opens a note using the specified editor
  161  *
  162  * @param string editor Path to the editor binary to use for editing.
  163  *
  164  * @return int Success or failure of the command
  165  */
  166 int file_edit(char* path, char* editor) {
  167   char cmd[strlen(editor) + 3 + strlen(path)];
  168   sprintf(cmd, "%s %s", editor, path);
  169   return system(cmd);
  170 }
  171 
  172 
  173 /**
  174  * Yup, wrote my own.
  175  * TODO: Make this work with escaped path delimiters
  176  * TODO: Write this function description
  177  *
  178  * @return int Basename path length
  179  */
  180 int basename(char* path, char* out) {
  181   int path_len = strlen(path);
  182   // Start from the right and move left
  183   for(int i = path_len; i > 0; i--) {
  184     // Copy if an extension delimiter (a period) is found
  185     if(path[i] == '/') {
  186       strcpy(out, &path[i + 1]);
  187       return i;
  188     }
  189   }
  190   return -1;
  191 }
  192 
  193 
  194 /**
  195  * Just a wrapper function to call the specified line search function for case
  196  * insensitive or case sensitive matching.
  197  *
  198  * @param line Line to check for the search term
  199  * @param term Search term to find in line
  200  *
  201  * @return int Search term found (1) or not (0)
  202  */
  203 int str_contains(char* line, char* term, int case_insensitive) {
  204   if(case_insensitive == 1) {
  205     return str_contains_case_insensitive(line, term);
  206   } else {
  207     return str_contains_case_sensitive(line, term);
  208   }
  209 }
  210 
  211 
  212 /**
  213  * Performs a case insensitive search in the given line for the specified term.
  214  *
  215  * Note that for the sake of efficiency, this function is fairly confusing
  216  * (sorry).  Learning how chars and ints relate in c will help tremendously
  217  * to understand this function.
  218  *
  219  * @param str String to check for the search term
  220  * @param term Search term to find in line
  221  *
  222  * @return int Search term found (1) or not (0)
  223  */
  224 int str_contains_case_insensitive(char* str, char* term) {
  225   // String char index
  226   int si = 0;
  227   // Term char index
  228   int ti = 0;
  229   int term_len = strlen(term);
  230 
  231   // Compare one char at a time
  232   while(str[si] != '\0') {
  233     // Current str char
  234     char lc;
  235     // Current term char
  236     char tc;
  237 
  238     // Welcome to the confusing part (see function description)
  239 
  240     // Convert current term char to lowercase
  241     if(term[ti] >= 97 && term[ti] <= 122)  {
  242       // Already lower case
  243       tc = term[ti];
  244     } else if(term[ti] >= 65 && term[ti] <= 90) {
  245       // Uppercase. Add 32 to get lowercase equivelant.
  246       tc = term[ti] + 32;
  247     } else {
  248       // Term char isn't a letter. Must be a symbol or something ELSE...
  249       // Take it as it is.
  250       tc = term[ti];
  251     }
  252 
  253     // Convert current str char to lowercase
  254     if(str[si] >= 97 && str[si] <= 122)  {
  255       // Already lower case
  256       lc = str[si];
  257     } else if(str[si] >= 65 && str[si] <= 90) {
  258       // Uppercase. Add 32 to get lowercase equivelant.
  259       lc = str[si] + 32;
  260     } else {
  261       // Term char isn't a letter. Must be a symbol or something ELSE...
  262       // Take it as it is.
  263       lc = str[si];
  264     }
  265 
  266     // Compare the temp lowercase version of the current str and term chars
  267     if(lc == tc) {
  268       ti++;
  269     } else {
  270       ti = 0;
  271     }
  272 
  273     // Return if we've matched the entire search term
  274     if(ti == term_len) { return 1; }
  275 
  276     si++;
  277   }
  278   return 0;
  279 }
  280 
  281 
  282 /**
  283  * Performs a case sensitive search in the given string for the specified term.
  284  *
  285  * @param str String to check for the search term
  286  * @param term Search term to find in str
  287  *
  288  * @return int Search term found (1) or not (0)
  289  */
  290 int str_contains_case_sensitive(char* str, char* term) {
  291   int s = 0;
  292   int t = 0;
  293   int term_len = strlen(term);
  294 
  295   // Compare one char at a time
  296   while(str[s] != '\0') {
  297     if(t == term_len) {
  298       return 1;
  299     } else if(term[t] == str[s]) {
  300       // Found a single char match. Increment to the next term char
  301       t++;
  302     } else {
  303       // Reset the match counter if a partial or no match was made
  304       t = 0;
  305     }
  306     s++;
  307   }
  308   return 0;
  309 }
  310 
  311 
  312 /**
  313  * Removes the extension from the given string filename
  314  *
  315  * @param filename Filename/path to strip extension from
  316  *
  317  * @return int Result of the strip operation
  318  */
  319 int strip_extension(char* filename) {
  320   for(int i = strlen(filename); i > 0; i--) {
  321     if(filename[i] == '.') {
  322       filename[i] = '\0';
  323       return 0;
  324     }
  325   }
  326   return -1;
  327 }

Generated by cgit