From 0acbc06c4308576c50e7c4929f35fd09ff069ac7 Mon Sep 17 00:00:00 2001
From: Lukas Fleischer <calcurse@cryptocrack.de>
Date: Wed, 5 Oct 2011 09:06:18 +0200
Subject: src/utils.c: Introduce parse_{time,duration}()

These helpers can be used in a fashion similar to parse_date(). In
addition to check_time(), parse_time() and parse_duration() support
short forms such as "23:" (instead of "23:00") and ":45" (instead of
"00:45").

Signed-off-by: Lukas Fleischer <calcurse@cryptocrack.de>
---
 src/calcurse.h |  2 ++
 src/utils.c    | 85 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)

(limited to 'src')

diff --git a/src/calcurse.h b/src/calcurse.h
index 3214271..5a8bfe9 100644
--- a/src/calcurse.h
+++ b/src/calcurse.h
@@ -904,6 +904,8 @@ const char  *get_tempdir (void);
 char        *new_tempfile (const char *, int);
 int          parse_date (const char *, enum datefmt, int *, int *, int *,
                          struct date *);
+int          parse_time (const char *, unsigned *, unsigned *);
+int          parse_duration (const char *, unsigned *);
 void         str_toupper (char *);
 void         file_close (FILE *, const char *);
 void         psleep (unsigned);
diff --git a/src/utils.c b/src/utils.c
index 398233c..510f4dd 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -689,6 +689,91 @@ parse_date (const char *date_string, enum datefmt datefmt, int *year,
   return 1;
 }
 
+/*
+ * Converts a time string into hours and minutes. Short forms like "23:"
+ * (23:00) or ":45" (0:45) are allowed.
+ *
+ * Returns 1 on success and 0 on failure.
+ */
+int
+parse_time (const char *string, unsigned *hour, unsigned *minute)
+{
+  const char *p;
+  unsigned in[2] = {0, 0}, n = 0;
+
+  if (!string)
+    return 0;
+
+  /* parse string into in[], read up to two integers */
+  for (p = string; *p; p++)
+    {
+      if (*p == ':')
+        {
+          if ((++n) > 1)
+            return 0;
+        }
+      else if ((*p >= '0') && (*p <= '9'))
+        in[n] = in[n] * 10 + (int)(*p - '0');
+      else
+        return 0;
+    }
+
+  if (n != 1 || in[0] >= DAYINHOURS || in[1] >= HOURINMIN)
+    return 0;
+
+  *hour = in[0];
+  *minute = in[1];
+  return 1;
+}
+
+/*
+ * Converts a duration string into minutes. Both "hh:mm" (e.g.  "23:42") and
+ * "mmm" (e.g. "100") formats are accepted. Short forms like "23:" (23:00) or
+ * ":45" (0:45) are allowed as well.
+ *
+ * Returns 1 on success and 0 on failure.
+ */
+int
+parse_duration (const char *string, unsigned *duration)
+{
+  const char *p;
+  unsigned in[2] = {0, 0}, n = 0;
+
+  if (!string || *string == '\0')
+    return 0;
+
+  /* parse string into in[], read up to two integers */
+  for (p = string; *p; p++)
+    {
+      if (*p == ':')
+        {
+          if ((++n) > 1)
+            return 0;
+        }
+      else if ((*p >= '0') && (*p <= '9'))
+        in[n] = in[n] * 10 + (int)(*p - '0');
+      else
+        return 0;
+    }
+
+  if (n == 0)
+    {
+      if (in[0] > 999)
+        return 0;
+      *duration = in[0];
+    }
+  else if (n == 1)
+    {
+      if (in[0] > DAYINHOURS || in[1] >= HOURINMIN)
+        return 0;
+      *duration = in[0] * HOURINMIN + in[1];
+    }
+  else
+    return 0;
+
+  return 1;
+}
+
 void
 str_toupper (char *s)
 {
-- 
cgit v1.2.3-70-g09d2