Use of stat instead of d_type from dirent struct.
[ohcount] / src / loc.c
1 // loc.c written by Mitchell Foral. mitchell<att>caladbolg.net.
2 // See COPYING for license information.
3
4 #include <stdlib.h>
5 #include <string.h>
6
7 #include "loc.h"
8
9 // Loc
10
11 Loc *ohcount_loc_new(const char *language, int code, int comments, int blanks,
12                      int filecount) {
13   Loc *loc = malloc(sizeof(Loc));
14   loc->language = language;
15   loc->code = code;
16   loc->comments = comments;
17   loc->blanks = blanks;
18   loc->filecount = filecount;
19   return loc;
20 }
21
22 int ohcount_loc_total(Loc *loc) {
23   return loc->code + loc->comments + loc->blanks;
24 }
25
26 void ohcount_loc_add_loc(Loc *loc, Loc *other) {
27   if (strcmp(loc->language, other->language) == 0) {
28     loc->code += other->code;
29     loc->comments += other->comments;
30     loc->blanks += other->blanks;
31     loc->filecount += other->filecount;
32   }
33 }
34
35 int ohcount_loc_is_equal(Loc *loc, Loc *other) {
36   return strcmp(loc->language, other->language) == 0 &&
37          loc->code == other->code && loc->comments == other->comments &&
38          loc->blanks == other->blanks && loc->filecount == other->filecount;
39 }
40
41 void ohcount_loc_free(Loc *loc) {
42   free(loc);
43 }
44
45 // LocList
46
47 LocList *ohcount_loc_list_new() {
48   LocList *list = malloc(sizeof(LocList));
49   list->loc = NULL;
50   list->next = NULL;
51   list->head = NULL;
52   list->tail = NULL;
53   return list;
54 }
55
56 void ohcount_loc_list_add_loc(LocList *list, Loc *loc) {
57   if (list->head == NULL) { // empty list
58     list->head = list;
59     list->tail = list;
60     list->head->loc = ohcount_loc_new(loc->language, loc->code, loc->comments,
61                                       loc->blanks, loc->filecount);
62     list->head->next = NULL;
63   } else {
64     LocList *iter = list->head;
65     while (iter) {
66       if (iter->loc && strcmp(iter->loc->language, loc->language) == 0) break;
67       iter = iter->next;
68     }
69     if (iter == NULL) { // new language
70       LocList *item = ohcount_loc_list_new();
71       item->loc = ohcount_loc_new(loc->language, loc->code, loc->comments,
72                                   loc->blanks, loc->filecount);
73       list->tail->next = item;
74       list->tail = item;
75     } else ohcount_loc_add_loc(iter->loc, loc); // existing language
76   }
77 }
78
79 void ohcount_loc_list_add_loc_list(LocList *list, LocList *other) {
80   LocList *iter = other->head;
81   while (iter) {
82     ohcount_loc_list_add_loc(list, iter->loc);
83     iter = iter->next;
84   }
85 }
86
87 Loc *ohcount_loc_list_get_loc(LocList *list, const char *language) {
88   LocList *iter = list->head;
89   while (iter) {
90     if (strcmp(iter->loc->language, language) == 0) return iter->loc;
91     iter = iter->next;
92   }
93   return NULL;
94 }
95
96 int ohcount_loc_list_code(LocList *list) {
97   int sum = 0;
98   LocList *iter = list->head;
99   while (iter) {
100     sum += iter->loc->code;
101     iter = iter->next;
102   }
103   return sum;
104 }
105
106 int ohcount_loc_list_comments(LocList *list) {
107   int sum = 0;
108   LocList *iter = list->head;
109   while (iter) {
110     sum += iter->loc->comments;
111     iter = iter->next;
112   }
113   return sum;
114 }
115
116 int ohcount_loc_list_blanks(LocList *list) {
117   int sum = 0;
118   LocList *iter = list->head;
119   while (iter) {
120     sum += iter->loc->blanks;
121     iter = iter->next;
122   }
123   return sum;
124 }
125
126 int ohcount_loc_list_total(LocList *list) {
127   int sum = 0;
128   LocList *iter = list->head;
129   while (iter) {
130     sum += ohcount_loc_total(iter->loc);
131     iter = iter->next;
132   }
133   return sum;
134 }
135
136 int ohcount_loc_list_filecount(LocList *list) {
137   int sum = 0;
138   LocList *iter = list->head;
139   while (iter) {
140     sum += iter->loc->filecount;
141     iter = iter->next;
142   }
143   return sum;
144 }
145
146 LocList *ohcount_loc_list_new_compact(LocList *list) {
147   LocList *new_list = ohcount_loc_list_new();
148   LocList *iter = list->head;
149   while (iter) {
150     if (ohcount_loc_total(iter->loc) != 0)
151       ohcount_loc_list_add_loc(new_list, iter->loc);
152     iter = iter->next;
153   }
154   return new_list;
155 }
156
157 void ohcount_loc_list_free(LocList *list) {
158   if (list->head) {
159     LocList *iter = list->head;
160     while (iter) {
161       LocList *next = iter->next;
162       ohcount_loc_free(iter->loc);
163       free(iter);
164       iter = next;
165     }
166   } else free(list);
167 }
168
169 // LocDelta
170
171 LocDelta *ohcount_loc_delta_new(const char *language, int code_added,
172                                 int code_removed, int comments_added,
173                                 int comments_removed, int blanks_added,
174                                 int blanks_removed) {
175   LocDelta *delta = malloc(sizeof(LocDelta));
176   delta->language = language;
177   delta->code_added = code_added;
178   delta->code_removed = code_removed;
179   delta->comments_added = comments_added;
180   delta->comments_removed = comments_removed;
181   delta->blanks_added = blanks_added;
182   delta->blanks_removed = blanks_removed;
183   return delta;
184 }
185
186 int ohcount_loc_delta_net_code(LocDelta *delta) {
187   return delta->code_added - delta->code_removed;
188 }
189
190 int ohcount_loc_delta_net_comments(LocDelta *delta) {
191   return delta->comments_added - delta->comments_removed;
192 }
193
194 int ohcount_loc_delta_net_blanks(LocDelta *delta) {
195   return delta->blanks_added - delta->blanks_removed;
196 }
197
198 int ohcount_loc_delta_net_total(LocDelta *delta) {
199   return ohcount_loc_delta_net_code(delta) +
200          ohcount_loc_delta_net_comments(delta) +
201          ohcount_loc_delta_net_blanks(delta);
202 }
203
204 void ohcount_loc_delta_add_loc_delta(LocDelta *delta, LocDelta *other) {
205   if (strcmp(delta->language, other->language) == 0) {
206     delta->code_added += other->code_added;
207     delta->code_removed += other->code_removed;
208     delta->comments_added += other->comments_added;
209     delta->comments_removed += other->comments_removed;
210     delta->blanks_added += other->blanks_added;
211     delta->blanks_removed += other->blanks_removed;
212   }
213 }
214
215 int ohcount_loc_delta_is_changed(LocDelta *delta) {
216   return delta->code_added != 0 || delta->code_removed != 0 ||
217          delta->comments_added != 0 || delta->comments_removed != 0 ||
218          delta->blanks_added != 0 || delta->blanks_removed != 0;
219 }
220
221 int ohcount_loc_delta_is_equal(LocDelta *delta, LocDelta *other) {
222   return strcmp(delta->language, other->language) == 0 &&
223          delta->code_added == other->code_added &&
224          delta->code_removed == other->code_removed &&
225          delta->comments_added == other->comments_added &&
226          delta->comments_removed == other->comments_removed &&
227          delta->blanks_added == other->blanks_added &&
228          delta->blanks_removed == other->blanks_removed;
229 }
230
231 void ohcount_loc_delta_free(LocDelta *delta) {
232   free(delta);
233 }
234
235 // LocDeltaList
236
237 LocDeltaList *ohcount_loc_delta_list_new() {
238   LocDeltaList *list = malloc(sizeof(LocDeltaList));
239   list->delta = NULL;
240   list->next = NULL;
241   list->head = NULL;
242   list->tail = NULL;
243   return list;
244 }
245
246 void ohcount_loc_delta_list_add_loc_delta(LocDeltaList *list, LocDelta *delta) {
247   if (list->head == NULL) { // empty list
248     list->head = list;
249     list->tail = list;
250     list->head->delta = ohcount_loc_delta_new(delta->language,
251                                               delta->code_added,
252                                               delta->code_removed,
253                                               delta->comments_added,
254                                               delta->comments_removed,
255                                               delta->blanks_added,
256                                               delta->blanks_removed);
257     list->head->next = NULL;
258   } else {
259     LocDeltaList *iter = list->head;
260     while (iter) {
261       if (list->delta && strcmp(list->delta->language, delta->language) == 0) break;
262       iter = iter->next;
263     }
264     if (iter == NULL) { // new language
265       LocDeltaList *item = ohcount_loc_delta_list_new();
266       item->delta = ohcount_loc_delta_new(delta->language,
267                                           delta->code_added,
268                                           delta->code_removed,
269                                           delta->comments_added,
270                                           delta->comments_removed,
271                                           delta->blanks_added,
272                                           delta->blanks_removed);
273       list->tail->next = item;
274       list->tail = item;
275     } else ohcount_loc_delta_add_loc_delta(iter->delta, delta); // existing
276   }
277 }
278
279 void ohcount_loc_delta_list_add_loc_delta_list(LocDeltaList *list,
280                                                LocDeltaList *loc_delta_list) {
281   LocDeltaList *iter = loc_delta_list->head;
282   while (iter) {
283     ohcount_loc_delta_list_add_loc_delta(list, iter->delta);
284     iter = iter->next;
285   }
286 }
287
288 LocDelta *ohcount_loc_delta_list_get_loc_delta(LocDeltaList *list,
289                                                const char *language) {
290   LocDeltaList *iter = list->head;
291   while (iter) {
292     if (strcmp(iter->delta->language, language) == 0) return iter->delta;
293     iter = iter->next;
294   }
295   return NULL;
296 }
297
298 int ohcount_loc_delta_list_code_added(LocDeltaList *list) {
299   int sum = 0;
300   LocDeltaList *iter = list->head;
301   while (iter) {
302     sum += iter->delta->code_added;
303     iter = iter->next;
304   }
305   return sum;
306 }
307
308 int ohcount_loc_delta_list_code_removed(LocDeltaList *list) {
309   int sum = 0;
310   LocDeltaList *iter = list->head;
311   while (iter) {
312     sum += iter->delta->code_removed;
313     iter = iter->next;
314   }
315   return sum;
316 }
317
318 int ohcount_loc_delta_list_comments_added(LocDeltaList *list) {
319   int sum = 0;
320   LocDeltaList *iter = list->head;
321   while (iter) {
322     sum += iter->delta->comments_added;
323     iter = iter->next;
324   }
325   return sum;
326 }
327
328 int ohcount_loc_delta_list_comments_removed(LocDeltaList *list) {
329   int sum = 0;
330   LocDeltaList *iter = list->head;
331   while (iter) {
332     sum += iter->delta->comments_removed;
333     iter = iter->next;
334   }
335   return sum;
336 }
337
338 int ohcount_loc_delta_list_blanks_added(LocDeltaList *list) {
339   int sum = 0;
340   LocDeltaList *iter = list->head;
341   while (iter) {
342     sum += iter->delta->blanks_added;
343     iter = iter->next;
344   }
345   return sum;
346 }
347
348 int ohcount_loc_delta_list_blanks_removed(LocDeltaList *list) {
349   int sum = 0;
350   LocDeltaList *iter = list->head;
351   while (iter) {
352     sum += iter->delta->blanks_removed;
353     iter = iter->next;
354   }
355   return sum;
356 }
357
358 int ohcount_loc_delta_list_net_code(LocDeltaList *list) {
359   int sum = 0;
360   LocDeltaList *iter = list->head;
361   while (iter) {
362     sum += ohcount_loc_delta_net_code(iter->delta);
363     iter = iter->next;
364   }
365   return sum;
366 }
367
368 int ohcount_loc_delta_list_net_comments(LocDeltaList *list) {
369   int sum = 0;
370   LocDeltaList *iter = list->head;
371   while (iter) {
372     sum += ohcount_loc_delta_net_comments(iter->delta);
373     iter = iter->next;
374   }
375   return sum;
376 }
377
378 int ohcount_loc_delta_list_net_blanks(LocDeltaList *list) {
379   int sum = 0;
380   LocDeltaList *iter = list->head;
381   while (iter) {
382     sum += ohcount_loc_delta_net_blanks(iter->delta);
383     iter = iter->next;
384   }
385   return sum;
386 }
387
388 int ohcount_loc_delta_list_net_total(LocDeltaList *list) {
389   int sum = 0;
390   LocDeltaList *iter = list->head;
391   while (iter) {
392     sum += ohcount_loc_delta_net_total(iter->delta);
393     iter = iter->next;
394   }
395   return sum;
396 }
397
398 LocDeltaList *ohcount_loc_delta_list_new_compact(LocDeltaList *list) {
399   LocDeltaList *new_list = ohcount_loc_delta_list_new();
400   LocDeltaList *iter = list->head;
401   while (iter) {
402     if (ohcount_loc_delta_is_changed(iter->delta))
403       ohcount_loc_delta_list_add_loc_delta(new_list, iter->delta);
404     iter = iter->next;
405   }
406   return new_list;
407 }
408
409 void ohcount_loc_delta_list_free(LocDeltaList *list) {
410   if (list->head) {
411     LocDeltaList *iter = list->head;
412     while (iter) {
413       LocDeltaList *next = iter->next;
414       ohcount_loc_delta_free(iter->delta);
415       free(iter);
416       iter = next;
417     }
418   } else free(list);
419 }