fix another keymap (FS#10237 by Tomer Shalev)
[kugel-rb.git] / firmware / general.c
blob1ff3340d2782310cacc04373fe1778afb0b80e18
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
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 ****************************************************************************/
22 #include "config.h"
23 #include "general.h"
25 #include "dir.h"
26 #include "limits.h"
27 #include "sprintf.h"
28 #include "stdlib.h"
29 #include "string.h"
30 #include "system.h"
31 #include "time.h"
32 #include "timefuncs.h"
34 #if CONFIG_CODEC == SWCODEC
35 int round_value_to_list32(unsigned long value,
36 const unsigned long list[],
37 int count,
38 bool signd)
40 unsigned long dmin = ULONG_MAX;
41 int idmin = -1, i;
43 for (i = 0; i < count; i++)
45 unsigned long diff;
47 if (list[i] == value)
49 idmin = i;
50 break;
53 if (signd ? ((long)list[i] < (long)value) : (list[i] < value))
54 diff = value - list[i];
55 else
56 diff = list[i] - value;
58 if (diff < dmin)
60 dmin = diff;
61 idmin = i;
65 return idmin;
66 } /* round_value_to_list32 */
68 /* Number of bits set in src_mask should equal src_list length */
69 int make_list_from_caps32(unsigned long src_mask,
70 const unsigned long *src_list,
71 unsigned long caps_mask,
72 unsigned long *caps_list)
74 int i, count;
75 unsigned long mask;
77 for (mask = src_mask, count = 0, i = 0;
78 mask != 0;
79 src_mask = mask, i++)
81 unsigned long test_bit;
82 mask &= mask - 1; /* Zero lowest bit set */
83 test_bit = mask ^ src_mask; /* Isolate the bit */
84 if (test_bit & caps_mask) /* Add item if caps has test bit set */
85 caps_list[count++] = src_list ? src_list[i] : (unsigned long)i;
88 return count;
89 } /* make_list_from_caps32 */
90 #endif /* CONFIG_CODEC == SWCODEC */
92 /* Create a filename with a number part in a way that the number is 1
93 * higher than the highest numbered file matching the same pattern.
94 * It is allowed that buffer and path point to the same memory location,
95 * saving a strcpy(). Path must always be given without trailing slash.
96 * "num" can point to an int specifying the number to use or NULL or a value
97 * less than zero to number automatically. The final number used will also
98 * be returned in *num. If *num is >= 0 then *num will be incremented by
99 * one. */
100 char *create_numbered_filename(char *buffer, const char *path,
101 const char *prefix, const char *suffix,
102 int numberlen IF_CNFN_NUM_(, int *num))
104 DIR *dir;
105 struct dirent *entry;
106 int max_num;
107 int pathlen;
108 int prefixlen = strlen(prefix);
109 char fmtstring[12];
111 if (buffer != path)
112 strncpy(buffer, path, MAX_PATH);
114 pathlen = strlen(buffer);
116 #ifdef IF_CNFN_NUM
117 if (num && *num >= 0)
119 /* number specified */
120 max_num = *num;
122 else
123 #endif
125 /* automatic numbering */
126 max_num = 0;
128 dir = opendir(pathlen ? buffer : "/");
129 if (!dir)
130 return NULL;
132 while ((entry = readdir(dir)))
134 int curr_num;
136 if (strncasecmp((char *)entry->d_name, prefix, prefixlen)
137 || strcasecmp((char *)entry->d_name + prefixlen + numberlen, suffix))
138 continue;
140 curr_num = atoi((char *)entry->d_name + prefixlen);
141 if (curr_num > max_num)
142 max_num = curr_num;
145 closedir(dir);
148 max_num++;
150 snprintf(fmtstring, sizeof(fmtstring), "/%%s%%0%dd%%s", numberlen);
151 snprintf(buffer + pathlen, MAX_PATH - pathlen, fmtstring, prefix,
152 max_num, suffix);
154 #ifdef IF_CNFN_NUM
155 if (num)
156 *num = max_num;
157 #endif
159 return buffer;
163 #if CONFIG_RTC
164 /* Create a filename with a date+time part.
165 It is allowed that buffer and path point to the same memory location,
166 saving a strcpy(). Path must always be given without trailing slash.
167 unique_time as true makes the function wait until the current time has
168 changed. */
169 char *create_datetime_filename(char *buffer, const char *path,
170 const char *prefix, const char *suffix,
171 bool unique_time)
173 struct tm *tm = get_time();
174 static struct tm last_tm;
175 int pathlen;
177 while (unique_time && !memcmp(get_time(), &last_tm, sizeof (struct tm)))
178 sleep(HZ/10);
180 last_tm = *tm;
182 if (buffer != path)
183 strncpy(buffer, path, MAX_PATH);
185 pathlen = strlen(buffer);
186 snprintf(buffer + pathlen, MAX_PATH - pathlen,
187 "/%s%02d%02d%02d-%02d%02d%02d%s", prefix,
188 tm->tm_year % 100, tm->tm_mon + 1, tm->tm_mday,
189 tm->tm_hour, tm->tm_min, tm->tm_sec, suffix);
191 return buffer;
193 #endif /* CONFIG_RTC */