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

Generated by cgit