/* This file is part of tagr. Copyright (C) 2009 Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include struct grid { struct grid_class *class; queue_t *q; double vmin; double vmax; double cur; char *str; void *data; }; grid_t grid_create (struct grid_class *class, queue_t *q, double vmin, double vmax, void *cdata) { grid_t grid; if (!class) return NULL; grid = xmalloc (sizeof (*grid)); grid->class = class; grid->q = q; grid->vmin = vmin; grid->vmax = vmax; grid->cur = 0; if (class->create) grid->data = class->create (grid, cdata); else grid->data = NULL; grid->str = NULL; return grid; } double grid_next (grid_t grid, char **str, int *mark) { return grid->class->next (grid, str, mark); } void grid_destroy (grid_t grid) { if (grid) { if (grid->str) free (grid->str); if (grid->class->dealloc) grid->class->dealloc (grid->data); free (grid); } } static void grid_free_data (void *ptr) { free (ptr); } /* FIXME: Suffixes not yet used. */ static char *short_suffix[] = {"", "k", "M", "G", "T"}; char **number_suffix = short_suffix; size_t number_suffix_count = sizeof (short_suffix) / sizeof (short_suffix[0]); struct ygrid_data { double step; }; static void * ygrid_create (grid_t grid, void *cdata) { struct monitor *mon = cdata; struct ygrid_data *gr = xmalloc (sizeof (*gr)); gr->step = mon->ystep; return gr; } static double ygrid_next (grid_t grid, char **str, int *mark) { struct ygrid_data *gr = grid->data; if (mark) *mark = 0; grid->cur += gr->step; if (grid->cur < grid->vmax) { if (grid->str) { free (grid->str); grid->str = NULL; } asprintf (&grid->str, "%6.1f", (double) grid->cur); *str = grid->str; } return grid->cur; } struct grid_class grid_class_y = { ygrid_create, ygrid_next, grid_free_data }; struct xgrid_data { time_t start; unsigned off; unsigned unit; }; #define TWOHRS (2*3600) static void * xgrid_2h_create (grid_t grid, void *cdata) { time_t start = *(time_t*)cdata; struct xgrid_data *gr = xmalloc (sizeof (*gr)); unsigned long frac = start % 3600; unsigned long h; struct tm *tm; gr->start = start - frac; tm = localtime (&gr->start); h = tm->tm_hour % 2; gr->off = frac + h * TWOHRS; gr->unit = tm->tm_hour - h; return gr; } static double xgrid_2h_next (grid_t grid, char **str, int *mark) { struct xgrid_data *gr = grid->data; double ret = gr->off; if (grid->str) { free (grid->str); grid->str = NULL; } asprintf (&grid->str, "%02d", gr->unit); *str = grid->str; if (mark) *mark = gr->unit == 0; gr->off += TWOHRS; gr->unit = (gr->unit + 24 - 2) % 24; return ret; } struct grid_class grid_class_x_2h = { xgrid_2h_create, xgrid_2h_next, grid_free_data }; #define TWENTYFOURHRS 86400 static void * xgrid_wday_create (grid_t grid, void *cdata) { time_t start = *(time_t*)cdata; struct xgrid_data *gr = xmalloc (sizeof (*gr)); struct tm *tm = localtime (&start); unsigned long frac; frac = (tm->tm_hour * 60 + tm->tm_min) * 60 + tm->tm_sec; gr->start = start - frac; gr->off = frac; gr->unit = tm->tm_wday; return gr; } static double xgrid_wday_next (grid_t grid, char **str, int *mark) { struct xgrid_data *gr = grid->data; double ret = gr->off; char buf[80]; struct tm *tm = localtime (&gr->start); if (grid->str) { free (grid->str); grid->str = NULL; } strftime (buf, sizeof buf, "%a", tm); grid->str = xstrdup (buf); *str = grid->str; if (mark) *mark = tm->tm_wday == 0; gr->start -= TWENTYFOURHRS; gr->off += TWENTYFOURHRS; return ret; } struct grid_class grid_class_x_wday = { xgrid_wday_create, xgrid_wday_next, grid_free_data }; #define SEVENDAYS (7*TWENTYFOURHRS) static void * xgrid_week_create (grid_t grid, void *cdata) { time_t start = *(time_t*)cdata; struct xgrid_data *gr = xmalloc (sizeof (*gr)); struct tm *tm = localtime (&start); unsigned long frac; frac = ((tm->tm_wday * 24 + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; gr->start = start - frac; gr->off = frac; gr->unit = 0; return gr; } static double xgrid_week_next (grid_t grid, char **str, int *mark) { struct xgrid_data *gr = grid->data; double ret = gr->off; struct tm *tm = localtime (&gr->start); if (tm->tm_mday && tm->tm_mday < 7 && mark && gr->unit == 0) { int diff = (tm->tm_mday - 1) * TWENTYFOURHRS; ret += diff; *mark = 1; *str = NULL; gr->unit = 1; } else { gr->unit = 0; if (grid->str) { free (grid->str); grid->str = NULL; } asprintf (&grid->str, _("Week %2d"), tm->tm_yday / 7 + 1); *str = grid->str; if (mark) *mark = 0; gr->start -= SEVENDAYS; gr->off += SEVENDAYS; } return ret; } struct grid_class grid_class_x_week = { xgrid_week_create, xgrid_week_next, grid_free_data }; static void * xgrid_month_create (grid_t grid, void *cdata) { time_t start = *(time_t*)cdata; struct xgrid_data *gr = xmalloc (sizeof (*gr)); struct tm *tm = localtime (&start); unsigned long frac; frac = (((tm->tm_mday - 1) * 24 + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; gr->start = start - frac; gr->off = frac; return gr; } static double xgrid_month_next (grid_t grid, char **str, int *mark) { struct xgrid_data *gr = grid->data; double ret = gr->off; unsigned long frac; struct tm *tm = localtime (&gr->start); int mon; char buf[80]; if (grid->str) { free (grid->str); grid->str = NULL; } strftime (buf, sizeof buf, "%b", tm); grid->str = xstrdup (buf); *str = grid->str; if (mark) *mark = tm->tm_mon == 0; if (tm->tm_mon == 0) mon = 11; else mon = tm->tm_mon - 1; do { gr->start -= TWENTYFOURHRS; gr->off += TWENTYFOURHRS; tm = localtime (&gr->start); } while (!(mon == tm->tm_mon && tm->tm_mday == 1)); frac = (((tm->tm_mday - 1) * 24 + tm->tm_hour) * 60 + tm->tm_min) * 60 + tm->tm_sec; gr->start -= frac; gr->off += frac; return ret; } struct grid_class grid_class_x_month = { xgrid_month_create, xgrid_month_next, grid_free_data };