1 /* GNU Mailutils -- a suite of utilities for electronic mail
2 Copyright (C) 2020-2021 Free Software Foundation, Inc.
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 3 of the License, or (at your option) any later version.
8
9 This library 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 GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */
17
18 /*
19 * Functions for dealing with message part coordinates.
20 */
21
22 #include <config.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <mailutils/message.h>
26
27 int
mu_coord_alloc(mu_coord_t * ptr,size_t n)28 mu_coord_alloc (mu_coord_t *ptr, size_t n)
29 {
30 mu_coord_t p = calloc (n + 1, sizeof (p[0]));
31 if (!p)
32 return errno;
33 p[0] = n;
34 *ptr = p;
35 return 0;
36 }
37
38 int
mu_coord_realloc(mu_coord_t * ptr,size_t n)39 mu_coord_realloc (mu_coord_t *ptr, size_t n)
40 {
41 if (!ptr)
42 return EINVAL;
43 if (!*ptr)
44 return mu_coord_alloc (ptr, n);
45 else
46 {
47 size_t i = mu_coord_length (*ptr);
48 if (i != n)
49 {
50 mu_coord_t nc = realloc (*ptr, (n + 1) * sizeof (nc[0]));
51 if (nc == NULL)
52 return ENOMEM;
53 while (++i <= n)
54 nc[i] = 0;
55 nc[0] = n;
56 *ptr = nc;
57 }
58 }
59 return 0;
60 }
61
62 int
mu_coord_dup(mu_coord_t orig,mu_coord_t * copy)63 mu_coord_dup (mu_coord_t orig, mu_coord_t *copy)
64 {
65 size_t i, n = mu_coord_length (orig);
66 int rc = mu_coord_alloc (copy, n);
67 if (rc)
68 return rc;
69 for (i = 1; i <= n; i++)
70 (*copy)[i] = orig[i];
71 return 0;
72 }
73
74 static void
revstr(char * s,char * e)75 revstr (char *s, char *e)
76 {
77 while (s < e)
78 {
79 char t = *s;
80 *s++ = *--e;
81 *e = t;
82 }
83 }
84
85 char *
mu_coord_part_string(mu_coord_t c,size_t dim)86 mu_coord_part_string (mu_coord_t c, size_t dim)
87 {
88 size_t len = 0;
89 size_t i;
90 char *result, *p;
91
92 for (i = 1; i <= dim; i++)
93 {
94 size_t n = c[i];
95 do
96 len++;
97 while (n /= 10);
98 len++;
99 }
100
101 result = malloc (len);
102 if (!result)
103 return NULL;
104 p = result;
105
106 for (i = 1; i <= dim; i++)
107 {
108 char *s;
109 size_t n = c[i];
110 if (i > 1)
111 *p++ = '.';
112 s = p;
113 do
114 {
115 unsigned x = n % 10;
116 *p++ = x + '0';
117 }
118 while (n /= 10);
119 revstr(s, p);
120 }
121 *p = 0;
122
123 return result;
124 }
125