logo

utils-std

Collection of commonly available Unix tools git clone https://anongit.hacktivis.me/git/utils-std.git

strtodur.c (1795B)


  1. // utils-std: Collection of commonly available Unix tools
  2. // SPDX-FileCopyrightText: 2017 Haelwenn (lanodan) Monnier <contact+utils@hacktivis.me>
  3. // SPDX-License-Identifier: MPL-2.0
  4. #define _POSIX_C_SOURCE 200809L
  5. #include "strtodur.h"
  6. #include <assert.h>
  7. #include <errno.h> // errno
  8. #include <stdio.h> // fprintf, perror, sscanf
  9. int
  10. strtodur(char *s, struct timespec *dur)
  11. {
  12. if(s == 0 || s[0] == '\0') return 0;
  13. assert(dur);
  14. float in = 0.0;
  15. if(s[0] != '.' && s[0] != ',')
  16. {
  17. int parsed = 0;
  18. assert(errno == 0);
  19. if(sscanf(s, "%10f%n", &in, &parsed) < 1)
  20. {
  21. if(errno == 0)
  22. {
  23. fprintf(stderr, "strtodur: error: Not a number: %s\n", s);
  24. }
  25. else
  26. {
  27. perror("strtodur: error: sscanf");
  28. errno = 0;
  29. }
  30. return -1;
  31. }
  32. s += parsed;
  33. }
  34. if((s[0] == '.' || s[0] == ',') && s[1] != '\0')
  35. {
  36. float fraction = 0.0;
  37. if(s[0] == ',') s[0] = '.';
  38. int parsed = 0;
  39. assert(errno == 0);
  40. if(sscanf(s, "%10f%n", &fraction, &parsed) < 1)
  41. {
  42. if(errno == 0)
  43. {
  44. fprintf(stderr, "strtodur: error: Decimal part is not a number: %s\n", s);
  45. }
  46. else
  47. {
  48. perror("strtodur: error: sscanf");
  49. errno = 0;
  50. }
  51. return -1;
  52. }
  53. in += fraction;
  54. s += parsed;
  55. }
  56. if(s[0] != '\0' && s[0] != ',' && s[0] != '.')
  57. {
  58. if(s[1] != '\0')
  59. {
  60. fprintf(
  61. stderr, "strtodur: error: suffix '%s' is too long, should be only one character\n", s);
  62. return -1;
  63. }
  64. switch(s[0])
  65. {
  66. case 's': // seconds
  67. break;
  68. case 'm': // minutes
  69. in *= 60;
  70. break;
  71. case 'h': // hours
  72. in *= 60 * 60;
  73. break;
  74. case 'd': // days
  75. in *= 24 * 60 * 60;
  76. break;
  77. default:
  78. fprintf(stderr, "strtodur: error: Unknown suffix '%c'\n", s[0]);
  79. return -1;
  80. }
  81. }
  82. dur->tv_sec = in;
  83. dur->tv_nsec = (in - dur->tv_sec) * 1000000000;
  84. return 0;
  85. }