Line data Source code
1 : /*
2 : * This file is part of rmlint.
3 : *
4 : * rmlint is free software: you can redistribute it and/or modify
5 : * it under the terms of the GNU General Public License as published by
6 : * the Free Software Foundation, either version 3 of the License, or
7 : * (at your option) any later version.
8 : *
9 : * rmlint is distributed in the hope that it will be useful,
10 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 : * GNU General Public License for more details.
13 : *
14 : * You should have received a copy of the GNU General Public License
15 : * along with rmlint. If not, see <http://www.gnu.org/licenses/>.
16 : *
17 : * Authors:
18 : *
19 : * - Christopher <sahib> Pahl 2010-2015 (https://github.com/sahib)
20 : * - Daniel <SeeSpotRun> T. 2014-2015 (https://github.com/SeeSpotRun)
21 : *
22 : * Hosted on http://github.com/sahib/rmlint
23 : *
24 : */
25 :
26 : #include "../formats.h"
27 :
28 : #include <glib.h>
29 : #include <stdio.h>
30 : #include <string.h>
31 :
32 : typedef struct RmFmtHandlerFdupes {
33 : /* must be first */
34 : RmFmtHandler parent;
35 :
36 : /* Storage for all strings */
37 : GStringChunk *text_chunks;
38 :
39 : /* Pointers into text_chunks */
40 : GQueue *text_lines;
41 :
42 : /* Do not print original (fdupes emulation) */
43 : bool omit_first_line;
44 :
45 : /* Do not print newlines between files */
46 : bool use_same_line;
47 : } RmFmtHandlerFdupes;
48 :
49 116 : static void rm_fmt_elem(_U RmSession *session, _U RmFmtHandler *parent, _U FILE *out,
50 : RmFile *file) {
51 116 : RmFmtHandlerFdupes *self = (RmFmtHandlerFdupes *)parent;
52 :
53 : char line[512 + 32];
54 116 : memset(line, 0, sizeof(line));
55 :
56 116 : if(file->lint_type == RM_LINT_TYPE_UNFINISHED_CKSUM) {
57 : /* we do not want to list unfinished files. */
58 0 : return;
59 : }
60 :
61 116 : RM_DEFINE_PATH(file);
62 :
63 116 : switch(file->lint_type) {
64 : case RM_LINT_TYPE_DUPE_DIR_CANDIDATE:
65 : case RM_LINT_TYPE_DUPE_CANDIDATE:
66 116 : if(self->omit_first_line && file->is_original) {
67 0 : strcpy(line, "\n");
68 : } else {
69 464 : g_snprintf(line, sizeof(line), "%s%s%s%s%c", (file->is_original) ? "\n" : "",
70 174 : (file->is_original) ? MAYBE_GREEN(out, session) : "", file_path,
71 174 : (file->is_original) ? MAYBE_RESET(out, session) : "",
72 116 : (self->use_same_line) ? ' ' : '\n');
73 : }
74 116 : break;
75 : default:
76 0 : g_snprintf(line, sizeof(line), "%s%s%s%c", MAYBE_BLUE(out, session), file_path,
77 0 : MAYBE_RESET(out, session), (self->use_same_line) ? ' ' : '\n');
78 0 : break;
79 : }
80 :
81 116 : if(self->text_chunks == NULL) {
82 58 : self->text_chunks = g_string_chunk_new(PATH_MAX / 2);
83 58 : self->text_lines = g_queue_new();
84 : }
85 :
86 : /* remember the line (use GStringChunk for effiecient storage) */
87 116 : g_queue_push_tail(self->text_lines, g_string_chunk_insert(self->text_chunks, line));
88 : }
89 :
90 870 : static void rm_fmt_prog(RmSession *session,
91 : _U RmFmtHandler *parent,
92 : FILE *out,
93 : RmFmtProgressState state) {
94 870 : RmFmtHandlerFdupes *self = (RmFmtHandlerFdupes *)parent;
95 :
96 870 : if(state == RM_PROGRESS_STATE_INIT) {
97 58 : self->omit_first_line =
98 58 : (rm_fmt_get_config_value(session->formats, "fdupes", "omitfirst") != NULL);
99 58 : self->use_same_line =
100 58 : (rm_fmt_get_config_value(session->formats, "fdupes", "sameline") != NULL);
101 : }
102 :
103 : extern RmFmtHandler *PROGRESS_HANDLER;
104 870 : g_assert(PROGRESS_HANDLER->prog);
105 870 : PROGRESS_HANDLER->prog(session, (RmFmtHandler *)PROGRESS_HANDLER, out, state);
106 :
107 : /* Print all cached lines on shutdown. */
108 870 : if(state == RM_PROGRESS_STATE_PRE_SHUTDOWN && self->text_lines) {
109 174 : for(GList *iter = self->text_lines->head; iter; iter = iter->next) {
110 116 : char *line = iter->data;
111 116 : if(line != NULL) {
112 116 : fprintf(out, "%s", line);
113 : }
114 : }
115 58 : g_queue_free(self->text_lines);
116 58 : g_string_chunk_free(self->text_chunks);
117 58 : fprintf(out, "\n");
118 : }
119 :
120 : extern RmFmtHandler *SUMMARY_HANDLER;
121 870 : g_assert(SUMMARY_HANDLER->prog);
122 870 : SUMMARY_HANDLER->prog(session, (RmFmtHandler *)SUMMARY_HANDLER, out, state);
123 870 : }
124 :
125 : static RmFmtHandlerFdupes FDUPES_HANDLER_IMPL = {
126 : /* Initialize parent */
127 : .parent =
128 : {
129 : .size = sizeof(FDUPES_HANDLER_IMPL),
130 : .name = "fdupes",
131 : .head = NULL,
132 : .elem = rm_fmt_elem,
133 : .prog = rm_fmt_prog,
134 : .foot = NULL,
135 : .valid_keys = {"omitfirst", "sameline", NULL},
136 : },
137 : .text_lines = NULL,
138 : .use_same_line = false,
139 : .omit_first_line = false
140 :
141 : };
142 :
143 : RmFmtHandler *FDUPES_HANDLER = (RmFmtHandler *)&FDUPES_HANDLER_IMPL;
|