1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (C) 2006 by Michael Sevakis
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
30 #include "string-extra.h"
33 #include "timefuncs.h"
35 #if CONFIG_CODEC == SWCODEC
36 int round_value_to_list32(unsigned long value
,
37 const unsigned long list
[],
41 unsigned long dmin
= ULONG_MAX
;
44 for (i
= 0; i
< count
; i
++)
54 if (signd
? ((long)list
[i
] < (long)value
) : (list
[i
] < value
))
55 diff
= value
- list
[i
];
57 diff
= list
[i
] - value
;
67 } /* round_value_to_list32 */
69 /* Number of bits set in src_mask should equal src_list length */
70 int make_list_from_caps32(unsigned long src_mask
,
71 const unsigned long *src_list
,
72 unsigned long caps_mask
,
73 unsigned long *caps_list
)
78 for (mask
= src_mask
, count
= 0, i
= 0;
82 unsigned long test_bit
;
83 mask
&= mask
- 1; /* Zero lowest bit set */
84 test_bit
= mask
^ src_mask
; /* Isolate the bit */
85 if (test_bit
& caps_mask
) /* Add item if caps has test bit set */
86 caps_list
[count
++] = src_list
? src_list
[i
] : (unsigned long)i
;
90 } /* make_list_from_caps32 */
91 #endif /* CONFIG_CODEC == SWCODEC */
93 /* Create a filename with a number part in a way that the number is 1
94 * higher than the highest numbered file matching the same pattern.
95 * It is allowed that buffer and path point to the same memory location,
96 * saving a strcpy(). Path must always be given without trailing slash.
97 * "num" can point to an int specifying the number to use or NULL or a value
98 * less than zero to number automatically. The final number used will also
99 * be returned in *num. If *num is >= 0 then *num will be incremented by
101 char *create_numbered_filename(char *buffer
, const char *path
,
102 const char *prefix
, const char *suffix
,
103 int numberlen
IF_CNFN_NUM_(, int *num
))
106 struct dirent
*entry
;
109 int prefixlen
= strlen(prefix
);
110 int suffixlen
= strlen(suffix
);
114 strlcpy(buffer
, path
, MAX_PATH
);
116 pathlen
= strlen(buffer
);
119 if (num
&& *num
>= 0)
121 /* number specified */
127 /* automatic numbering */
130 dir
= opendir(pathlen
? buffer
: HOME_DIR
);
134 while ((entry
= readdir(dir
)))
136 int curr_num
, namelen
;
138 if (strncasecmp((char *)entry
->d_name
, prefix
, prefixlen
))
141 namelen
= strlen((char *)entry
->d_name
);
142 if ((namelen
<= prefixlen
+ suffixlen
)
143 || strcasecmp((char *)entry
->d_name
+ namelen
- suffixlen
, suffix
))
146 curr_num
= atoi((char *)entry
->d_name
+ prefixlen
);
147 if (curr_num
> max_num
)
156 snprintf(fmtstring
, sizeof(fmtstring
), "/%%s%%0%dd%%s", numberlen
);
157 snprintf(buffer
+ pathlen
, MAX_PATH
- pathlen
, fmtstring
, prefix
,
170 /* Create a filename with a date+time part.
171 It is allowed that buffer and path point to the same memory location,
172 saving a strcpy(). Path must always be given without trailing slash.
173 unique_time as true makes the function wait until the current time has
175 char *create_datetime_filename(char *buffer
, const char *path
,
176 const char *prefix
, const char *suffix
,
179 struct tm
*tm
= get_time();
180 static struct tm last_tm
;
183 while (unique_time
&& !memcmp(get_time(), &last_tm
, sizeof (struct tm
)))
189 strlcpy(buffer
, path
, MAX_PATH
);
191 pathlen
= strlen(buffer
);
192 snprintf(buffer
+ pathlen
, MAX_PATH
- pathlen
,
193 "/%s%02d%02d%02d-%02d%02d%02d%s", prefix
,
194 tm
->tm_year
% 100, tm
->tm_mon
+ 1, tm
->tm_mday
,
195 tm
->tm_hour
, tm
->tm_min
, tm
->tm_sec
, suffix
);
199 #endif /* CONFIG_RTC */
202 ** Compacted pointer lists
204 ** N-length list requires N+1 elements to ensure NULL-termination.
207 /* Find a pointer in a pointer array. Returns the addess of the element if
208 * found or the address of the terminating NULL otherwise. This can be used
209 * to bounds check and add items. */
210 void ** find_array_ptr(void **arr
, void *ptr
)
213 for (curr
= *arr
; curr
!= NULL
&& curr
!= ptr
; curr
= *(++arr
));
217 /* Remove a pointer from a pointer array if it exists. Compacts it so that
218 * no gaps exist. Returns 0 on success and -1 if the element wasn't found. */
219 int remove_array_ptr(void **arr
, void *ptr
)
222 arr
= find_array_ptr(arr
, ptr
);
227 /* Found. Slide up following items. */
230 void **arr1
= arr
+ 1;
231 *arr
++ = curr
= *arr1
;
233 while (curr
!= NULL
);