A Simple X Image Viewer
 
 
 
 
 
 

194 lines
3.9 KiB

  1. /* sxiv: util.c
  2. * Copyright (c) 2011 Bert Muennich <muennich at informatik.hu-berlin.de>
  3. *
  4. * This program 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 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program 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 this program; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  17. */
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <unistd.h>
  21. #include <errno.h>
  22. #include "options.h"
  23. #include "util.h"
  24. #define FNAME_LEN 1024
  25. void cleanup();
  26. void* s_malloc(size_t size) {
  27. void *ptr;
  28. if (!(ptr = malloc(size)))
  29. die("could not allocate memory");
  30. return ptr;
  31. }
  32. void* s_realloc(void *ptr, size_t size) {
  33. if (!(ptr = realloc(ptr, size)))
  34. die("could not allocate memory");
  35. return ptr;
  36. }
  37. void warn(const char* fmt, ...) {
  38. va_list args;
  39. if (!fmt || options->quiet)
  40. return;
  41. va_start(args, fmt);
  42. fprintf(stderr, "sxiv: warning: ");
  43. vfprintf(stderr, fmt, args);
  44. fprintf(stderr, "\n");
  45. va_end(args);
  46. }
  47. void die(const char* fmt, ...) {
  48. va_list args;
  49. if (!fmt)
  50. return;
  51. va_start(args, fmt);
  52. fprintf(stderr, "sxiv: error: ");
  53. vfprintf(stderr, fmt, args);
  54. fprintf(stderr, "\n");
  55. va_end(args);
  56. cleanup();
  57. exit(1);
  58. }
  59. void size_readable(float *size, const char **unit) {
  60. const char *units[] = { "", "K", "M", "G" };
  61. int i;
  62. for (i = 0; i < LEN(units) && *size > 1024; ++i)
  63. *size /= 1024;
  64. *unit = units[MIN(i, LEN(units) - 1)];
  65. }
  66. char* absolute_path(const char *filename) {
  67. size_t len;
  68. char *path = NULL;
  69. const char *basename;
  70. char *dirname = NULL;
  71. char *cwd = NULL;
  72. char *twd = NULL;
  73. char *dir;
  74. char *s;
  75. if (!filename || *filename == '\0' || *filename == '/')
  76. return NULL;
  77. len = FNAME_LEN;
  78. cwd = (char*) s_malloc(len);
  79. while (!(s = getcwd(cwd, len)) && errno == ERANGE) {
  80. len *= 2;
  81. cwd = (char*) s_realloc(cwd, len);
  82. }
  83. if (!s)
  84. goto error;
  85. s = strrchr(filename, '/');
  86. if (s) {
  87. len = s - filename;
  88. dirname = (char*) s_malloc(len + 1);
  89. strncpy(dirname, filename, len);
  90. dirname[len] = '\0';
  91. basename = s + 1;
  92. if (chdir(cwd))
  93. /* we're not able to come back afterwards */
  94. goto error;
  95. if (chdir(dirname))
  96. goto error;
  97. len = FNAME_LEN;
  98. twd = (char*) s_malloc(len);
  99. while (!(s = getcwd(twd, len)) && errno == ERANGE) {
  100. len *= 2;
  101. twd = (char*) s_realloc(twd, len);
  102. }
  103. if (chdir(cwd))
  104. die("could not revert to working directory");
  105. if (!s)
  106. goto error;
  107. dir = twd;
  108. } else {
  109. /* only a single filename given */
  110. basename = filename;
  111. dir = cwd;
  112. }
  113. len = strlen(dir) + strlen(basename) + 2;
  114. path = (char*) s_malloc(len);
  115. snprintf(path, len, "%s/%s", dir, basename);
  116. goto end;
  117. error:
  118. if (path) {
  119. free(path);
  120. path = NULL;
  121. }
  122. end:
  123. if (dirname)
  124. free(dirname);
  125. if (cwd)
  126. free(cwd);
  127. if (twd)
  128. free(twd);
  129. return path;
  130. }
  131. char* readline(FILE *stream) {
  132. size_t len;
  133. char *buf, *s, *end;
  134. if (!stream || feof(stream) || ferror(stream))
  135. return NULL;
  136. len = FNAME_LEN;
  137. s = buf = (char*) s_malloc(len * sizeof(char));
  138. do {
  139. *s = '\0';
  140. fgets(s, len - (s - buf), stream);
  141. if ((end = strchr(s, '\n'))) {
  142. *end = '\0';
  143. } else if (strlen(s) + 1 == len - (s - buf)) {
  144. buf = (char*) s_realloc(buf, 2 * len * sizeof(char));
  145. s = buf + len - 1;
  146. len *= 2;
  147. } else {
  148. s += strlen(s);
  149. }
  150. } while (!end && !feof(stream) && !ferror(stream));
  151. if (ferror(stream)) {
  152. s = NULL;
  153. } else {
  154. s = (char*) s_malloc((strlen(buf) + 1) * sizeof(char));
  155. strcpy(s, buf);
  156. }
  157. free(buf);
  158. return s;
  159. }