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