improved table_end
[NeonServV5.git] / tools.c
1 #include "tools.h"
2 #include "UserNode.h"
3 #include "lang.h"
4
5 static const struct default_language_entry msgtab[] = {
6     {"TIME_MASK_2_ITEMS", "%s and %s"},
7     {"TIME_MASK_3_ITEMS", "%s, %s and %s"},
8     {"TIME_YEAR", "%d year"},
9     {"TIME_YEARS", "%d years"},
10     {"TIME_DAY", "%d day"},
11     {"TIME_DAYS", "%d days"},
12     {"TIME_HOUR", "%d hour"},
13     {"TIME_HOURS", "%d hours"},
14     {"TIME_MINUTE", "%d minute"},
15     {"TIME_MINUTES", "%d minutes"},
16     {"TIME_SECOND", "%d second"},
17     {"TIME_SECONDS", "%d seconds"},
18     {NULL, NULL}
19 };
20
21 /* copied from IRCU 2.10.12 match.c */
22 /*
23  * Compare if a given string (name) matches the given
24  * mask (which can contain wild cards: '*' - match any
25  * number of chars, '?' - match any single character.
26  *
27  * return  0, if match
28  *         1, if no match
29  *
30  *  Originally by Douglas A Lewis (dalewis@acsu.buffalo.edu)
31  *  Rewritten by Timothy Vogelsang (netski), net@astrolink.org
32  */
33 int match(const char *mask, const char *name)
34 {
35   const char *m = mask, *n = name;
36   const char *m_tmp = mask, *n_tmp = name;
37   int star_p;
38
39   for (;;) switch (*m) {
40   case '\0':
41     if (!*n)
42       return 0;
43   backtrack:
44     if (m_tmp == mask)
45       return 1;
46     m = m_tmp;
47     n = ++n_tmp;
48     if (*n == '\0')
49       return 1;
50     break;
51   case '\\':
52     m++;
53     /* allow escaping to force capitalization */
54     if (*m++ != *n++)
55       goto backtrack;
56     break;
57   case '*': case '?':
58     for (star_p = 0; ; m++) {
59       if (*m == '*')
60         star_p = 1;
61       else if (*m == '?') {
62         if (!*n++)
63           goto backtrack;
64       } else break;
65     }
66     if (star_p) {
67       if (!*m)
68         return 0;
69       else if (*m == '\\') {
70         m_tmp = ++m;
71         if (!*m)
72           return 1;
73         for (n_tmp = n; *n && *n != *m; n++) ;
74       } else {
75         m_tmp = m;
76         for (n_tmp = n; *n && tolower(*n) != tolower(*m); n++) ;
77       }
78     }
79     /* and fall through */
80   default:
81     if (!*n)
82       return *m != '\0';
83     if (tolower(*m) != tolower(*n))
84       goto backtrack;
85     m++;
86     n++;
87     break;
88   }
89 }
90
91
92 //TABLES
93 struct Table *table_init(int width, int length, int flags) {
94     int row;
95     struct Table *table = malloc(sizeof(*table));
96     table->contents = malloc(length * sizeof(*table->contents));
97     for(row = 0; row < length; row++) {
98         table->contents[row] = calloc(width, sizeof(*table->contents[row]));
99     }
100     table->length = length;
101     table->width = width;
102     table->flags = flags;
103     table->col_flags = calloc(length, sizeof(int));
104     table->entrys = 0;
105     table->maxwidth = calloc(length, sizeof(int));
106     table->table_lines = NULL;
107     return table;
108 }
109
110 int table_add(struct Table *table, char **entry) {
111     int col;
112     if(table->entrys == table->length) return 0;
113     for(col = 0; col < table->width; col++) {
114         table->contents[table->entrys][col] = ((table->flags & TABLE_FLAG_USE_POINTER) ? entry[col] : strdup(entry[col]));
115         if(strlen(entry[col]) > table->maxwidth[col])
116             table->maxwidth[col] = strlen(entry[col]);
117     }
118     table->entrys++;
119     return 1;
120 }
121
122 int table_set_bold(struct Table *table, int collum, int bold) {
123     if(bold)
124         table->col_flags[collum] |= TABLE_FLAG_COL_BOLD;
125     else
126         table->col_flags[collum] &= ~TABLE_FLAG_COL_BOLD;
127     return 1;
128 }
129
130 char **table_end(struct Table *table) {
131     int row, col, tablewidth = 0, pos,i;
132     if(!table->entrys) return NULL;
133     for(col = 0; col < table->width; col++) {
134         tablewidth += table->maxwidth[col]+1;
135         if(table->col_flags[col] & TABLE_FLAG_COL_BOLD)
136             tablewidth += 2;
137     }
138     table->table_lines = malloc(table->entrys * sizeof(table->table_lines));
139     for(row = 0; row < table->entrys; row++) {
140         table->table_lines[row] = malloc(tablewidth * sizeof(*table->table_lines[row]));
141         pos = 0;
142         for(col = 0; col < table->width; col++) {
143             if(table->col_flags[col] & TABLE_FLAG_COL_BOLD)
144                 table->table_lines[row][pos++] = '\002';
145             for(i = 0; i < strlen(table->contents[row][col]); i++) {
146                 table->table_lines[row][pos++] = table->contents[row][col][i];
147             }
148             if(col < table->width-1) {
149                 for(;i < table->maxwidth[col]; i++) {
150                     table->table_lines[row][pos++] = ' ';
151                 }
152                 table->table_lines[row][pos++] = ' ';
153             } else
154                 table->table_lines[row][pos++] = '\0';
155             
156             if(table->col_flags[col] & TABLE_FLAG_COL_BOLD)
157                 table->table_lines[row][pos++] = '\002';
158         }
159     }
160     return table->table_lines;
161 }
162
163 void table_free(struct Table *table) {
164     int row, col;
165     for(row = 0; row < table->length; row++) {
166         if(!(table->flags & TABLE_FLAG_USE_POINTER) && table->entrys > row) {
167             for(col = 0; col < table->width; col++) {
168                 free(table->contents[row][col]);
169             }
170         }
171         free(table->contents[row]);
172     }
173     free(table->contents);
174     free(table->col_flags);
175     free(table->maxwidth);
176     if(table->table_lines) {
177         for(row = 0; row < table->entrys; row++) {
178             free(table->table_lines[row]);
179         }
180         free(table->table_lines);
181     }
182     free(table);
183 }
184
185 int timeToStr(struct UserNode *user, int seconds, int items, char *buf) {
186     char *item[items];
187     int tmp, citem = 0;
188     if(citem != items && seconds >= 31536000) { //60*60*24*365 = 31536000
189         
190         tmp = seconds / 31536000;
191         item[citem++] = build_language_string(user, NULL, (tmp == 1 ? "TIME_YEAR" : "TIME_YEARS"), tmp);
192         seconds -= tmp * 31536000;
193     }
194     if(citem != items && seconds >= 86400) { //60*60*24 = 86400
195         tmp = seconds / 86400;
196         item[citem++] = build_language_string(user, NULL, (tmp == 1 ? "TIME_DAY" : "TIME_DAYS"), tmp);
197         seconds -= tmp * 86400;
198     }
199     if(citem != items && seconds >= 3600) { //60*60 = 3600
200         tmp = seconds / 3600;
201         item[citem++] = build_language_string(user, NULL, (tmp == 1 ? "TIME_HOUR" : "TIME_HOURS"), tmp);
202         seconds -= tmp * 3600;
203     }
204     if(citem != items && seconds >= 60) {
205         tmp = seconds / 60;
206         item[citem++] = build_language_string(user, NULL, (tmp == 1 ? "TIME_MINUTE" : "TIME_MINUTES"), tmp);
207         seconds -= tmp * 60;
208     }
209     if(citem != items && seconds >= 1) {
210         item[citem++] = build_language_string(user, NULL, (seconds == 1 ? "TIME_SECOND" : "TIME_SECONDS"), seconds);
211     }
212     if(items == 2) {
213         build_language_string(user, buf, "TIME_MASK_2_ITEMS", item[0], item[1]);
214     } else if(items == 3) {
215         build_language_string(user, buf, "TIME_MASK_3_ITEMS", item[0], item[1], item[2]);
216     } else {
217         int i, ii, p = 0;
218         for(i = 0; i < items; i++) {
219             for(ii = 0; ii < strlen(item[i]); ii++) {
220                 buf[p++] = item[i][ii];
221             }
222             buf[p++] = ' ';
223         }
224         buf[p-1] = '\0';
225     }
226     return 1;
227 }
228
229
230
231
232 void init_tools() {
233     register_default_language_table(msgtab);
234 }