1 /* -*- mode: c; c-basic-offset: 4; tab-width: 4; indent-tabs-mode: t -*-
2 * vim: ts=4 sw=4 noet ai cindent syntax=c
4 * Conky, a system monitor, based on torsmo
6 * Any original torsmo code is licensed under the BSD license
8 * All code written since the fork of torsmo is licensed under the GPL
10 * Please see COPYING for details
12 * Copyright (c) 2004, Hannu Saransaari and Lauri Hakkarainen
13 * Copyright (c) 2005-2010 Brenden Matthews, Philip Kovacs, et. al.
15 * All rights reserved.
17 * This program is free software: you can redistribute it and/or modify
18 * it under the terms of the GNU General Public License as published by
19 * the Free Software Foundation, either version 3 of the License, or
20 * (at your option) any later version.
22 * This program is distributed in the hope that it will be useful,
23 * but WITHOUT ANY WARRANTY; without even the implied warranty of
24 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program. If not, see <http://www.gnu.org/licenses/>.
32 #include "text_object.h"
39 char print_times_in_seconds = 0;
42 char *tz; /* timezone variable */
43 char *fmt; /* time display formatting */
46 void set_times_in_seconds(char val)
48 print_times_in_seconds = val;
51 char times_in_seconds(void)
53 return print_times_in_seconds;
56 void scan_time(struct text_object *obj, const char *arg)
58 obj->data.opaque = strndup(arg ? arg : "%F %T", text_buffer_size);
61 void scan_tztime(struct text_object *obj, const char *arg)
63 char buf1[256], buf2[256], *fmt, *tz;
68 int nArgs = sscanf(arg, "%255s %255[^\n]", buf1, buf2);
78 ts = malloc(sizeof(struct tztime_s));
79 memset(ts, 0, sizeof(struct tztime_s));
80 ts->fmt = strndup(fmt ? fmt : "%F %T", text_buffer_size);
81 ts->tz = tz ? strndup(tz, text_buffer_size) : NULL;
82 obj->data.opaque = ts;
85 void print_time(struct text_object *obj, char *p, int p_max_size)
87 time_t t = time(NULL);
88 struct tm *tm = localtime(&t);
90 setlocale(LC_TIME, "");
91 strftime(p, p_max_size, (char *)obj->data.opaque, tm);
94 void print_utime(struct text_object *obj, char *p, int p_max_size)
96 time_t t = time(NULL);
97 struct tm *tm = gmtime(&t);
99 setlocale(LC_TIME, "");
100 strftime(p, p_max_size, (char *)obj->data.opaque, tm);
103 void print_tztime(struct text_object *obj, char *p, int p_max_size)
108 struct tztime_s *ts = obj->data.opaque;
114 oldTZ = getenv("TZ");
115 setenv("TZ", ts->tz, 1);
121 setlocale(LC_TIME, "");
122 strftime(p, p_max_size, ts->fmt, tm);
124 setenv("TZ", oldTZ, 1);
129 // Needless to free oldTZ since getenv gives ptr to static data
132 void free_time(struct text_object *obj)
134 if (!obj->data.opaque)
136 free(obj->data.opaque);
137 obj->data.opaque = NULL;
140 void free_tztime(struct text_object *obj)
142 struct tztime_s *ts = obj->data.opaque;
152 free(obj->data.opaque);
153 obj->data.opaque = NULL;
156 //all chars after the ending " and between the seconds and the starting " are silently
157 //ignored, this is wanted behavior, not a bug, so don't "fix" this.
158 void print_format_time(struct text_object *obj, char *p, unsigned int p_max_size) {
160 char *currentchar, *temp;
161 unsigned int output_length = 0;
162 int minutes, hours, days, weeks;
163 char show_minutes = 0, show_hours = 0, show_days = 0, show_weeks = 0, hidestring;
165 if (!times_in_seconds()) {
166 NORM_ERR("Enable \"times_in_seconds\" to use $format_time");
171 seconds = strtod(obj->data.s, ¤tchar);
172 if(errno == 0 && obj->data.s != currentchar) {
173 while(*currentchar != 0 && *currentchar != '"') {
176 if(*currentchar != 0) {
178 minutes = seconds / 60;
179 seconds -= minutes * 60;
180 hours = minutes / 60;
186 for(temp = currentchar; *temp != 0 && *temp != '"'; temp++) {
207 if(show_weeks == 0) days += weeks * 7;
208 if(show_days == 0) hours += days * 24;
209 if(show_hours == 0) minutes += hours * 60;
210 if(show_minutes == 0) seconds += minutes * 60;
212 while(output_length < p_max_size - 1) {
213 if(*currentchar != 0 && *currentchar != '"') {
215 if(*currentchar == '\\' && hidestring == 0) {
217 switch(*currentchar){
219 asprintf(&temp, "%d", weeks);
222 asprintf(&temp, "%d", days);
225 asprintf(&temp, "%d", hours);
228 asprintf(&temp, "%d", minutes);
231 asprintf(&temp, "%d", (int) seconds);
235 if(*currentchar >= '0' && *currentchar <= '9') {
236 asprintf(&temp, "%.*f", (*currentchar) - '0', seconds);
237 } else if(*currentchar == 'x') {
238 if(seconds == (int) seconds ) {
239 asprintf(&temp, "%d", (int) seconds);
241 asprintf(&temp, "%.9f", seconds);
242 while(*(temp + strlen(temp) - 1) == '0' || *(temp + strlen(temp) - 1) == '.') {
243 *(temp + strlen(temp) - 1) = 0;
248 NORM_ERR("$format_time needs a digit behind 'S' to specify precision")
254 p[output_length] = *currentchar;
258 NORM_ERR("$format_time doesn't have a special char '%c'", *currentchar)
260 } else if(*currentchar == '(') {
261 for(temp = currentchar + 1; *temp != 0 && *temp != ')'; temp++) {
262 if(*(temp-1) == '\\') {
265 if(weeks == 0) hidestring = 1;
268 if(days == 0) hidestring = 1;
271 if(hours == 0) hidestring = 1;
274 if(minutes == 0) hidestring = 1;
278 if(seconds == 0) hidestring = 1;
284 } else if(*currentchar == ')') {
286 } else if(hidestring == 0) {
287 p[output_length] = *currentchar;
291 if(output_length + strlen(temp) < p_max_size - 1) {
292 strcpy(p + output_length, temp);
293 output_length += strlen(temp);
294 } else NORM_ERR("The format string for $format_time is too long")
300 p[output_length] = 0;
302 NORM_ERR("$format_time needs a output-format starting with a \"-char as 2nd argument")
305 NORM_ERR("$format_time didn't receive a time in seconds as first argument")