diff --git a/osdd-file.c b/osdd-file.c index b35fd0142080a6a4bfa2d900481f6f06f26c679b..a6ca2b1d6d41d8afd8d15889b458f2fd186b8cbb 100644 --- a/osdd-file.c +++ b/osdd-file.c @@ -134,105 +134,80 @@ struct file_state static void file_show(struct file_state *state, struct osd_line * lines, int num_lines) { - FILE * f = fopen(state->file_name,state->open_mode); - if(f) - { - switch(state->time_mode) + VECTOR(char) out = NULL; + switch(state->time_mode) + { + case FILE_TIME_NO: + break; + case FILE_TIME_UNIX: + vprint(&out,"%lld%s",(long long)time(0),state->time_separator); + break; + case FILE_TIME_ISO: { - case FILE_TIME_NO: - break; - case FILE_TIME_UNIX: - fprintf(f,"%lld%s",(long long)time(0),state->time_separator); - break; - case FILE_TIME_ISO: - { - time_t t = time(NULL); - struct tm tm = *localtime(&t); - fprintf(f,"%04d-%02d-%02d %02d:%02d:%02d%s", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,state->time_separator); - } - break; + time_t t = time(NULL); + struct tm tm = *localtime(&t); + vprint(&out,"%04d-%02d-%02d %02d:%02d:%02d%s", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec,state->time_separator); } - for(int i=0;i<num_lines;i++) - { - struct osd_line * line = lines+i; - //if(!(line->log & 1)) continue; - if(line->type!=OSD_TYPE_TEXT) continue; - int r,g,b; - char text[1024]; - char color[30]; - color[0]=0; - char * end_color = ""; - - snprintf(text,1000,"%s",line->u.text); - if(state->replace_no_text) replace_no_text(text); - switch(state->color_mode) - { - case FILE_COLOR_RGB_DEC: - case FILE_COLOR_RGB_HEX: - case FILE_COLOR_RGB_HASHTAG_HEX: - case FILE_COLOR_TERM_RGB: - colorToRGB(line->fg_color,&r,&g,&b); - break; - default: - break; - } - switch(state->color_mode) - { - case FILE_COLOR_RGB_DEC: - sprintf(color,"%d %d %d ",r/256,g/256,b/256); - break; - case FILE_COLOR_RGB_HEX: - sprintf(color,"%02x%02x%02x ",r/256,g/256,b/256); - break; - case FILE_COLOR_RGB_HASHTAG_HEX: - sprintf(color,"#%02x%02x%02x ",r/256,g/256,b/256); - break; - case FILE_COLOR_TERM_RGB: - sprintf(color,"\e[38;2;%d;%d;%dm",r/256,g/256,b/256); - end_color = "\e[0m"; - break; - case FILE_COLOR_ORIGINAL: - sprintf(color,"%s ",line->fg_color); - break; - case FILE_COLOR_NO: - break; - } - fprintf(f,"%s%s%s%s", color, text, end_color,state->line_separator); - // fprintf(f,"%s\n",text); - //fprintf(stderr,"FO FILE: %d %d %d %s\n",r,g,b,text); + break; + } + for(int i=0;i<num_lines;i++) + { + struct osd_line * line = lines+i; + //if(!(line->log & 1)) continue; + if(line->type!=OSD_TYPE_TEXT) continue; + int r,g,b; + VECTOR(char) text=0; + VRESERVE(text,strlen(line->u.text)+1); + char color[30]; + color[0]=0; + char * end_color = ""; - } - fprintf(f,"%s", state->msq_separator); - fclose(f); + vprint(&text,"%s",line->u.text); + if(state->replace_no_text) replace_no_text(text); + switch(state->color_mode) + { + case FILE_COLOR_RGB_DEC: + case FILE_COLOR_RGB_HEX: + case FILE_COLOR_RGB_HASHTAG_HEX: + case FILE_COLOR_TERM_RGB: + colorToRGB(line->fg_color,&r,&g,&b); + break; + default: + break; } - /* - char name[MAXIMUM_FILE_MANE_LEN]; - snprintf(name,MAXIMUM_FILE_MANE_LEN,"%s/.osdd_log",getenv("HOME")); - FILE * f = fopen(name,"a"); - if(f) + switch(state->color_mode) { - time_t t = time(NULL); - struct tm tm = *localtime(&t); - fprintf(f,"%04d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec); - for(int i=0;i<display->num_lines;i++) - { - struct osd_line * line = display->lines[i].line; - if(!(line->log & 2)) continue; - // Allocate colors - XftColor outline_color; - XRenderColor mask_rc = { .red = 0xffff, .green = 0xffff, .blue = 0xffff, .alpha = 0xffff }; - if (!XftColorAllocName(display->dpy, display->visual, display->cmap, line->fg_color, &display->fg_color) || - !XftColorAllocName(display->dpy, display->visual, display->cmap, line->outline_color, &outline_color) || - !XftColorAllocValue(display->dpy, display->visual, display->cmap, &mask_rc, &display->mask_color)) - die("Cannot allocate colors"); - typeof(display->fg_color.color) c = display->fg_color.color; - //fprintf(stderr,"%02x%02x%02x %s\n",c.red/256,c.green/256,c.blue/256,display->lines[i].u.text); - fprintf(f," \x1b[38;2;%d;%d;%dm%s\e[0m",c.red/256,c.green/256,c.blue/256,display->lines[i].line->u.text); - } - fprintf(f,"\n"); - fclose(f); + case FILE_COLOR_RGB_DEC: + sprintf(color,"%d %d %d ",r/256,g/256,b/256); + break; + case FILE_COLOR_RGB_HEX: + sprintf(color,"%02x%02x%02x ",r/256,g/256,b/256); + break; + case FILE_COLOR_RGB_HASHTAG_HEX: + sprintf(color,"#%02x%02x%02x ",r/256,g/256,b/256); + break; + case FILE_COLOR_TERM_RGB: + sprintf(color,"\e[38;2;%d;%d;%dm",r/256,g/256,b/256); + end_color = "\e[0m"; + break; + case FILE_COLOR_ORIGINAL: + sprintf(color,"%s ",line->fg_color); + break; + case FILE_COLOR_NO: + break; } - */ + vprint(&out,"%s%s%s%s", color, text, end_color,state->line_separator); + VFREE(text); + + } + vprint(&out,"%s",state->msq_separator); + FILE * f = fopen(state->file_name,state->open_mode); + if(f) + { + fprintf(f,"%s", out); + fclose(f); + } + VFREE(out); } static diff --git a/osdd-set.c b/osdd-set.c index 6e0c35a0ec1ac3b90572f971c25d77d127b5899a..3436952e4b4a53973e985c170dc20188079d3fa8 100644 --- a/osdd-set.c +++ b/osdd-set.c @@ -56,13 +56,8 @@ struct osd_set_trie * osd_set_trie_find(struct osd_set_trie * root, char * str, struct osd_line *osd_set_add_line(struct osd_set *set, enum osd_line_type type) { - if (set->num_lines >= set->max_lines) - { - set->max_lines = 2 * set->max_lines + 1; - set->lines = xrealloc(set->lines, sizeof(struct osd_line) * set->max_lines); - } - - struct osd_line *l = &set->lines[set->num_lines++]; + VADDSIZE(set->lines, 1); + struct osd_line *l = &VLAST(set->lines); l->type = type; l->fg_color = "green"; l->outline_color = "black"; @@ -86,20 +81,20 @@ struct osd_line *osd_set_add_line(struct osd_set *set, enum osd_line_type type) void osd_set_show(struct osd_set *set) { - for(int i=0;i<set->len;i++) + for(int i=0;i<VSIZE(set->elements);i++) { - if(set->is_active[i]) if(set->elements[i].show) set->elements[i].show(set->elements[i].context,set->lines,set->num_lines); + if(set->is_active[i]) if(set->elements[i].show) set->elements[i].show(set->elements[i].context,set->lines,VSIZE(set->lines)); } } void osd_set_clear(struct osd_set *set) { - for(int i=0;i<set->len;i++) + for(int i=0;i<VSIZE(set->elements);i++) { if(set->elements[i].clear) set->elements[i].clear(set->elements[i].context); } - set->num_lines = 0; - memset(set->is_active,0,sizeof(bool)*set->max); + VSETSIZE(set->lines, 0); + memset(set->is_active,0,sizeof(bool)*VSIZE(set->is_active)); } void osd_set_active_outputs(struct osd_set *set, char * name, bool val) @@ -107,14 +102,14 @@ void osd_set_active_outputs(struct osd_set *set, char * name, bool val) struct osd_set_trie *trie = osd_set_trie_find(&set->trie,name,0); if(trie) { - for(int i=0;i<trie->num_vals;i++) set->is_active[trie->vals[i]]=val; + for(int i=0;i<VSIZE(trie->vals);i++) set->is_active[trie->vals[i]]=val; } } bool osd_set_handle_event(struct osd_set *set, XEvent *ev) { bool r=0; - for(int i=0;i<set->len;i++) + for(int i=0;i<VSIZE(set->elements);i++) { if(set->elements[i].handle_event) r |= set->elements[i].handle_event(set->elements[i].context,ev); } @@ -125,10 +120,7 @@ struct osd_set osd_set_new(void) { struct osd_set set; memset(&set, 0, sizeof(set)); - set.len=0; - - set.num_lines=0; - set.max_lines=0; + set.elements=0; set.lines=0; return set; } @@ -139,17 +131,9 @@ void osd_set_add(struct osd_set *set, struct osd_abstract abs, int names_len, ch { fprintf(stderr,"NAME |%s|\n",names[i]); struct osd_set_trie *trie = osd_set_trie_find(&set->trie,names[i],1); - trie->vals = xrealloc(trie->vals,sizeof(trie->vals[0])*(trie->num_vals+1)); - trie->vals[trie->num_vals++] = set->len; - } - if(set->len>=set->max) - { - set->max *= 2; - if(set->max < 4) set->max=4; - set->elements = xrealloc(set->elements,sizeof(set->elements[0])*set->max); - set->is_active = xrealloc(set->is_active,sizeof(set->is_active[0])*set->max); - memset(set->is_active,0,sizeof(bool)*set->max); + VPB(trie->vals, VSIZE(set->elements)); } - set->elements[set->len++] = abs; + VPB(set->elements, abs); + VPB(set->is_active, 0); } diff --git a/osdd-set.h b/osdd-set.h index de729c39c2f880c529bae2ba5bd900b666ab5be8..7caa0ae0481cdf6967249311359001c2e4a01800 100644 --- a/osdd-set.h +++ b/osdd-set.h @@ -9,6 +9,8 @@ #define OSDD_SET_H #include <stdbool.h> +#include "util.h" + typedef struct _XDisplay Display; typedef union _XEvent XEvent; typedef struct _IO_FILE FILE; @@ -22,8 +24,7 @@ struct display_state; struct osd_set_trie { struct osd_set_trie *next[OSD_TRIE_LEN]; - int num_vals; - int *vals; + VECTOR(int) vals; }; int osd_set_trie_char_to_index(char in); @@ -57,15 +58,11 @@ struct osd_abstract { }; struct osd_set { - struct osd_abstract * elements; - bool * is_active; - int len; - int max; + VECTOR(struct osd_abstract) elements; + VECTOR(bool) is_active; struct osd_set_trie trie; - struct osd_line *lines; - int num_lines; - int max_lines; + VECTOR(struct osd_line) lines; }; struct osd_creator_abstract { diff --git a/osdd.c b/osdd.c index d1d93e79cbbe3124f5500a7971ef759a05f4b488..705c330b8085d8e763ac2f12737bb4d8360401de 100644 --- a/osdd.c +++ b/osdd.c @@ -43,21 +43,7 @@ enum long_opt { }; -static struct osd_creator_abstract * creator=NULL; -int num_creator=0; -int max_creator=0; - -static -void add_creator(struct osd_creator_abstract in) -{ - if(num_creator <= max_creator) - { - max_creator *= 2; - if(max_creator < 4) max_creator=4; - creator = xrealloc(creator,sizeof(creator[0])*max_creator); - } - creator[num_creator++]=in; -} +static VECTOR(struct osd_creator_abstract) creator=NULL; static const char short_opts[] = "+c:d:Df:m:o:O:s:"; static const struct option long_opts[] = { @@ -95,7 +81,7 @@ user_name is name of module instance, that could by used by osdc --output=\n\ optional arg is really in '[' ']'. Backet should be separate arguments\n\ \n\ "); - for(int i=0;i<num_creator;i++) if(creator[i].help) creator[i].help(stderr); + for(int i=0;i<VSIZE(creator);i++) if(creator[i].help) creator[i].help(stderr); exit(1); } @@ -144,7 +130,7 @@ parse_opts(int argc, char **argv) int ind = optind; while(ind < argc) { - for(int i=0;i<num_creator;i++) + for(int i=0;i<VSIZE(creator);i++) { if(!strcmp(creator[i].name,argv[ind])) { @@ -442,9 +428,9 @@ do_test(void) int main(int argc, char **argv) { - add_creator(display_creator_new()); - add_creator(display_by_outputs_creator_new()); - add_creator(file_creator_new()); + VPB(creator,display_creator_new()); + VPB(creator,display_by_outputs_creator_new()); + VPB(creator,file_creator_new()); setlocale(LC_CTYPE, ""); diff --git a/util.c b/util.c index dd4bb37bdfff555feaec6ebc95c8fe787eae2c4a..c1044135bd1db829f7e07ef67916a83e8a68d7d9 100644 --- a/util.c +++ b/util.c @@ -8,6 +8,7 @@ #include <stdlib.h> #include <stdarg.h> #include <sys/time.h> +#include <string.h> #include "osd.h" #include "util.h" @@ -48,3 +49,114 @@ get_current_time(void) gettimeofday(&tv, NULL); return (timestamp_t) tv.tv_sec * 1000 + tv.tv_usec / 1000; } + +struct v +{ + int size; + int max; + char data[]; +}; + +void vsetsize(void ** v, int s) +{ + if(s<0) s = 0; + if(!*v) + { + int max = s; + struct v *this = xmalloc(sizeof(struct v) + max); + *v = &this->data; + memset(*v, 0, max); + this->max = max; + this->size = s; + } + else + { + struct v *this = (struct v*)*v - 1; + if(this->max < s) + { + int max = this->max * 2; + if(max < s) max = s; + this = xrealloc(this,sizeof(struct v) + max); + *v = &this->data; + if(this->max < max) memset(*v + this->max, 0, max - this->max); + this->max = max; + } + this->size = s; + } +} + +void vreserve(void ** v, int max) +{ + if(max<0) max=0; + if(!*v) + { + struct v *this = xmalloc(sizeof(struct v) + max); + *v = &this->data; + memset(*v, 0, max); + this->max = max; + this->size = 0; + } + else + { + struct v *this = (struct v*)*v - 1; + if(max < this->size) max = this->size; + if(max == this->max) return; + this = xrealloc(this,sizeof(struct v) + max); + *v = &this->data; + if(this->max < max) memset(*v + this->max, 0, max - this->max); + this->max = max; + } +} + +void vaddsize(void ** v, int s) +{ + vsetsize(v,vsize(*v)+s); +} + +int vsize(void * v) +{ + if(!v) return 0; + struct v *this = (struct v*)v - 1; + return this->size; +} + +int vmax(void * v) +{ + if(!v) return 0; + struct v *this = (struct v*)v - 1; + return this->max; +} + +void vfree(void ** v) +{ + if(!v) return; + struct v *this = (struct v*)*v - 1; + free(this); + *v = 0; +} + + + +int FORMAT_CHECK(printf,2,3) vprint(VECTOR(char) *out , char *fmt, ...) +{ + va_list args; + int size = VSIZE(*out); + if(size <= 0) + { + VSETSIZE(*out,++size); + } + int max = VMAX(*out); + int n = max-size+1; + va_start(args, fmt); + int r = vsnprintf(*out+size-1, max-size+1, fmt, args); + va_end(args); + if(r >= n) + { + VRESERVE(*out, size+r); + va_start(args, fmt); + r = vsprintf(*out+size-1, fmt, args); + va_end(args); + } + if(r>0) VADDSIZE(*out, r); + return r; +} diff --git a/util.h b/util.h index 957baaf98b525b794816e015dfbe6be9e93fad38..40f0edb6ab9ff8365d3f0eec9983d266e616a484 100644 --- a/util.h +++ b/util.h @@ -4,6 +4,9 @@ * (c) 2010--2013 Martin Mares <mj@ucw.cz> */ +#ifndef UTIL_H +#define UTIL_H + #include <inttypes.h> #define NONRET __attribute__((noreturn)) @@ -25,3 +28,33 @@ void *xmalloc(int size); void *xrealloc(void *ptr, int size); timestamp_t get_current_time(void); + +// Vector data contain header (size and allocated size - max) and data array with unspecified size +// +// All vector function take pointer to first element of data part of vector +// (null pointer represent unallocated vector) +// or pointer to pointer to first element if vector can be reallocated +// +// size in number of bites +void vsetsize(void ** v, int s); +void vaddsize(void ** v, int s); +void vreserve(void ** v, int s); +int vsize(void * v); +int vmax(void * v); +void vfree(void ** v); + +// Macros for multiple size by size of element +#define VSETSIZE(v,s) {vsetsize((void **)&(v),sizeof(*(v))*(s));} +#define VADDSIZE(v,s) {vaddsize((void **)&(v),sizeof(*(v))*(s));} +#define VRESERVE(v,s) {vreserve((void **)&(v),sizeof(*(v))*(s));} +#define VSIZE(v) (vsize(v)/(int)sizeof(*(v))) +#define VMAX(v) (vmax(v)/(int)sizeof(*(v))) +#define VLAST(v) ((v)[VSIZE(v)-1]) +#define VPB(v,a) {VADDSIZE(v,1);VLAST(v)=a;} +#define VFREE(v) vfree((void **)&(v)) +#define VECTOR(a) a * + + +int FORMAT_CHECK(printf,2,3) vprint(VECTOR(char) *out , char *fmt, ...); + +#endif