basename.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. /**
  2. * \file basename.c
  3. *
  4. * \brief GIS Library - Program basename routines.
  5. *
  6. * (C) 2001-2008 by the GRASS Development Team
  7. *
  8. * This program is free software under the GNU General Public License
  9. * (>=v2). Read the file COPYING that comes with GRASS for details.
  10. *
  11. * \author GRASS GIS Development Team
  12. *
  13. * \date 1999-2007
  14. */
  15. #include <grass/gis.h>
  16. #include <math.h>
  17. #include <stdio.h>
  18. #include <ctype.h>
  19. #include <string.h>
  20. #include <stdlib.h>
  21. /**
  22. * \brief Truncates filename to the base part (before the last '.')
  23. * if it matches the extension, otherwise leaves it unchanged.
  24. *
  25. * Checks if a filename matches a certain file extension
  26. * (case insensitive) and if so, truncates the string to the
  27. * base file name (cf. basename Unix command)
  28. *
  29. * \param[in] filename string containing filename
  30. * \param[in] desired_ext string containing extension to look for (case
  31. * insensitive)
  32. * \return Pointer to filename
  33. */
  34. char *G_basename(char *filename, const char *desired_ext)
  35. {
  36. /* Find the last . in the filename */
  37. char *dot = strrchr(filename, '.');
  38. if (dot && G_strcasecmp(dot + 1, desired_ext) == 0)
  39. *dot = '\0';
  40. return filename;
  41. }
  42. /*!
  43. * \brief Get number of decimals from a string
  44. *
  45. * \param str String to analyse
  46. *
  47. * \return number of decimals
  48. */
  49. size_t G_get_num_decimals(const char *str)
  50. {
  51. int sep = '.';
  52. size_t len;
  53. char *sep_ptr = strchr(str, sep);
  54. if (sep_ptr == NULL)
  55. return 0;
  56. len = strlen(str);
  57. return len - (size_t)(sep_ptr - str) - 1;
  58. }
  59. /*!
  60. * \brief Convert a double to a string substituting the dot with underscore
  61. * 12.3456 => '12_3456'
  62. *
  63. * \param number the double number that will be convert to string
  64. * \param ndigits the number of integer digits in the output string
  65. * \param ndecimals the number of decimals in the output string
  66. *
  67. * \return a formatted string
  68. */
  69. char *G_double_to_basename_format(double number,
  70. size_t ndigits, size_t ndecimals)
  71. {
  72. double integer, decimal;
  73. integer = floor(number);
  74. char intfmt[GNAME_MAX] = "%d";
  75. char intstr[GNAME_MAX];
  76. char decfmt[GNAME_MAX] = "";
  77. char decstr[GNAME_MAX] = "";
  78. char *result;
  79. if (ndigits != 0){
  80. sprintf(intfmt, "%%0%zud", ndigits);
  81. }
  82. sprintf(intstr, intfmt, (int)integer);
  83. if (ndecimals != 0){
  84. sprintf(decfmt, "_%%0%zud", ndecimals);
  85. decimal = ((number - integer) * pow(10., (double)ndecimals));
  86. sprintf(decstr, decfmt, (int)decimal);
  87. }
  88. result = G_malloc(strlen(intstr) + strlen(decstr) + 1);
  89. sprintf(result, "%s%s", intstr, decstr);
  90. return result;
  91. }
  92. /*!
  93. * \brief Return the environmental basename variable or the default value
  94. */
  95. char *G_get_basename_separator(){
  96. char *envvar = "GRASS_BASENAME_SEPARATOR";
  97. char *envsep;
  98. envsep = getenv(envvar);
  99. return (envsep != NULL && strlen(envsep) > 0) ? envsep: GBASENAME_SEP;
  100. }
  101. /*!
  102. * \brief join an array of strings using the basename separator
  103. *
  104. * \param strings is an array of strings
  105. * \param len is the length of the array
  106. *
  107. * \return a joined string
  108. */
  109. char *G_join_basename_strings(const char**strings, size_t len)
  110. {
  111. size_t i, length, lensep;
  112. char *result;
  113. char *separator;
  114. separator = G_get_basename_separator();
  115. lensep = strlen(separator);
  116. length = lensep * (len - 1) + 1;
  117. for (i = 0; i < len; i++){
  118. length += strlen(strings[i]);
  119. }
  120. result = G_malloc(length);
  121. if (result)
  122. {
  123. strcpy(result, strings[0]);
  124. for (i = 1; i < len; i++){
  125. strcat(result, separator);
  126. strcat(result, strings[i]);
  127. }
  128. }
  129. return result;
  130. }
  131. /*!
  132. * \brief Generate the format string
  133. *
  134. * \param basename String with the basename
  135. * \param digits Number of digits number
  136. * \param decimals Number of decimal number
  137. * \param filler String used to fill, default is 0
  138. *
  139. * \return Format string
  140. */
  141. char *G_generate_basename(const char *basename, double number,
  142. size_t ndigits, size_t ndecimals)
  143. {
  144. char *separator, *numberstr, *result;
  145. separator = G_get_basename_separator();
  146. numberstr = G_double_to_basename_format(number, ndigits, ndecimals);
  147. result = G_malloc(strlen(basename) + strlen(separator) + strlen(numberstr) + 1);
  148. if (result)
  149. sprintf(result, "%s%s%s", basename, separator, numberstr);
  150. return result;
  151. }