2 * Copyright 2018 Fabian Maurer
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library 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 GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
23 #include "wine/heap.h"
24 #include "wine/debug.h"
25 #include "resources.h"
27 WINE_DEFAULT_DEBUG_CHANNEL(find
);
29 static BOOL
read_char_from_handle(HANDLE handle
, char *char_out
)
31 static char buffer
[4096];
32 static UINT buffer_max
= 0;
33 static UINT buffer_pos
= 0;
35 /* Read next content into buffer */
36 if (buffer_pos
>= buffer_max
)
38 BOOL success
= ReadFile(handle
, buffer
, 4096, &buffer_max
, NULL
);
39 if (!success
|| !buffer_max
)
44 *char_out
= buffer
[buffer_pos
++];
48 /* Read a line from a handle, returns NULL if the end is reached */
49 static WCHAR
* read_line_from_handle(HANDLE handle
)
53 WCHAR
*line_converted
;
54 int line_converted_length
;
56 char *line
= heap_alloc(line_max
);
61 success
= read_char_from_handle(handle
, &c
);
75 /* Make sure buffer is large enough */
76 if (length
+ 1 >= line_max
)
79 line
= heap_realloc(line
, line_max
);
86 if (length
- 1 >= 0 && line
[length
- 1] == '\r') /* Strip \r of windows line endings */
89 line_converted_length
= MultiByteToWideChar(CP_ACP
, 0, line
, -1, 0, 0);
90 line_converted
= heap_alloc(line_converted_length
* sizeof(WCHAR
));
91 MultiByteToWideChar(CP_ACP
, 0, line
, -1, line_converted
, line_converted_length
);
95 return line_converted
;
98 static void write_to_stdout(const WCHAR
*str
)
101 UINT str_converted_length
;
103 UINT str_length
= lstrlenW(str
);
104 int codepage
= CP_ACP
;
106 str_converted_length
= WideCharToMultiByte(codepage
, 0, str
, str_length
, NULL
, 0, NULL
, NULL
);
107 str_converted
= heap_alloc(str_converted_length
);
108 WideCharToMultiByte(codepage
, 0, str
, str_length
, str_converted
, str_converted_length
, NULL
, NULL
);
110 WriteFile(GetStdHandle(STD_OUTPUT_HANDLE
), str_converted
, str_converted_length
, &bytes_written
, NULL
);
111 if (bytes_written
< str_converted_length
)
112 ERR("Failed to write output\n");
114 heap_free(str_converted
);
117 static BOOL
run_find_for_line(const WCHAR
*line
, const WCHAR
*tofind
)
120 WCHAR lineending
[] = {'\r', '\n', 0};
122 if (lstrlenW(line
) == 0 || lstrlenW(tofind
) == 0)
125 found
= wcsstr(line
, tofind
);
129 write_to_stdout(line
);
130 write_to_stdout(lineending
);
137 static void output_resource_message(int id
)
140 LoadStringW(GetModuleHandleW(NULL
), id
, buffer
, ARRAY_SIZE(buffer
));
141 write_to_stdout(buffer
);
144 int __cdecl
wmain(int argc
, WCHAR
*argv
[])
147 WCHAR
*tofind
= NULL
;
152 TRACE("running find:");
153 for (i
= 0; i
< argc
; i
++)
155 TRACE(" %s", wine_dbgstr_w(argv
[i
]));
159 input
= GetStdHandle(STD_INPUT_HANDLE
);
161 for (i
= 1; i
< argc
; i
++)
163 if (argv
[i
][0] == '/')
165 output_resource_message(IDS_INVALID_SWITCH
);
168 else if(tofind
== NULL
)
174 FIXME("Searching files not supported yet\n");
181 output_resource_message(IDS_INVALID_PARAMETER
);
186 while ((line
= read_line_from_handle(input
)) != NULL
)
188 if (run_find_for_line(line
, tofind
))