api: add function file_copy (issue #1667)

This commit is contained in:
Sébastien Helleu 2021-07-03 16:04:50 +02:00
parent 9432b44a2b
commit 8a11a18dc5
11 changed files with 271 additions and 18 deletions

View File

@ -21,6 +21,7 @@ https://weechat.org/files/releasenotes/ReleaseNotes-devel.html[release notes]
New features::
* core: add option "certs" in command /debug
* api: add function file_copy (issue #1667)
* api: remember insertion order in hashtables
* api: add keys/values with tags in output of irc_message_parse_to_hashtable (issue #1654)
* irc: allow signals "irc_raw_in" and "irc_in" to eat messages (issue #1657)

View File

@ -3887,6 +3887,41 @@ free (content);
[NOTE]
This function is not available in scripting API.
==== file_copy
_WeeChat ≥ 3.3._
Copy a file to another location.
Prototype:
[source,C]
----
int weechat_file_copy (const char *from, const char *to);
----
Arguments:
* _from_: source file
* _to_: destination file
Return value:
* 1 if OK, 0 if error
C example:
[source,C]
----
if (weechat_file_copy ("/tmp/test.txt", "/path/to/test2.txt"))
{
/* OK */
}
----
[NOTE]
This function is not available in scripting API.
[[util]]
=== Util

View File

@ -3953,6 +3953,41 @@ free (contenu);
[NOTE]
Cette fonction n'est pas disponible dans l'API script.
==== file_copy
_WeeChat ≥ 3.3._
Copier un fichier vers une autre destination.
Prototype :
[source,C]
----
int weechat_file_copy (const char *from, const char *to);
----
Paramètres :
* _from_ : fichier source
* _to_ : fichier cible
Valeur de retour :
* 1 si OK, 0 si erreur
Exemple en C :
[source,C]
----
if (weechat_file_copy ("/tmp/test.txt", "/path/to/test2.txt"))
{
/* OK */
}
----
[NOTE]
Cette fonction n'est pas disponible dans l'API script.
[[util]]
=== Util

View File

@ -4026,6 +4026,42 @@ free (content);
[NOTE]
Questa funzione non è disponibile nelle API per lo scripting.
// TRANSLATION MISSING
==== file_copy
_WeeChat ≥ 3.3._
Copy a file to another location.
Prototipo:
[source,C]
----
int weechat_file_copy (const char *from, const char *to);
----
Argomenti:
* _from_: source file
* _to_: destination file
Valore restituito:
* 1 if OK, 0 if error
Esempio in C:
[source,C]
----
if (weechat_file_copy ("/tmp/test.txt", "/path/to/test2.txt"))
{
/* OK */
}
----
[NOTE]
Questa funzione non è disponibile nelle API per lo scripting.
[[util]]
=== Utilità

View File

@ -3933,6 +3933,42 @@ free (content);
[NOTE]
スクリプト API ではこの関数を利用できません。
// TRANSLATION MISSING
==== file_copy
_WeeChat ≥ 3.3._
Copy a file to another location.
プロトタイプ:
[source,C]
----
int weechat_file_copy (const char *from, const char *to);
----
引数:
* _from_: source file
* _to_: destination file
戻り値:
* 1 if OK, 0 if error
C 言語での使用例:
[source,C]
----
if (weechat_file_copy ("/tmp/test.txt", "/path/to/test2.txt"))
{
/* OK */
}
----
[NOTE]
スクリプト API ではこの関数を利用できません。
[[util]]
=== ユーティリティ

View File

@ -3745,6 +3745,42 @@ free (content);
[NOTE]
Ова функција није доступна у API скриптовања.
// TRANSLATION MISSING
==== file_copy
_WeeChat ≥ 3.3._
Copy a file to another location.
Прототип:
[source,C]
----
int weechat_file_copy (const char *from, const char *to);
----
Аргументи:
* _from_: source file
* _to_: destination file
Повратна вредност:
* 1 if OK, 0 if error
C пример:
[source,C]
----
if (weechat_file_copy ("/tmp/test.txt", "/path/to/test2.txt"))
{
/* OK */
}
----
[NOTE]
Ова функција није доступна у API скриптовања.
[[util]]
=== Алати

View File

@ -555,6 +555,62 @@ error:
return NULL;
}
/*
* Copies a file to another location.
*
* Returns:
* 1: OK
* 0: error
*/
int
dir_file_copy (const char *from, const char *to)
{
FILE *src, *dst;
char *buffer;
int rc;
size_t count;
rc = 0;
buffer = NULL;
src = NULL;
dst = NULL;
if (!from || !from[0] || !to || !to[0])
goto end;
buffer = malloc (65536);
if (!buffer)
goto end;
src = fopen (from, "rb");
if (!src)
goto end;
dst = fopen (to, "wb");
if (!dst)
goto end;
while (!feof (src))
{
count = fread (buffer, 1, 65535, src);
if (count <= 0)
goto end;
if (fwrite (buffer, 1, count, dst) <= 0)
goto end;
}
rc = 1;
end:
if (buffer)
free (buffer);
if (src)
fclose (src);
if (dst)
fclose (dst);
return rc;
}
/*
* Uses one or four different paths for WeeChat home directories.
*

View File

@ -33,6 +33,7 @@ extern void dir_exec_on_files (const char *directory, int recurse_subdirs,
extern char *dir_search_full_lib_name (const char *filename,
const char *sys_directory);
extern char *dir_file_get_content (const char *filename);
extern int dir_file_copy (const char *from, const char *to);
extern void dir_create_home_dirs ();
extern void dir_remove_home_dirs ();
extern char *dir_get_string_home_dirs ();

View File

@ -672,6 +672,7 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv)
new_plugin->mkdir_parents = &dir_mkdir_parents;
new_plugin->exec_on_files = &dir_exec_on_files;
new_plugin->file_get_content = &dir_file_get_content;
new_plugin->file_copy = &dir_file_copy;
new_plugin->util_timeval_cmp = &util_timeval_cmp;
new_plugin->util_timeval_diff = &util_timeval_diff;

View File

@ -68,7 +68,7 @@ struct timeval;
* please change the date with current one; for a second change at same
* date, increment the 01, otherwise please keep 01.
*/
#define WEECHAT_PLUGIN_API_VERSION "20210601-01"
#define WEECHAT_PLUGIN_API_VERSION "20210703-01"
/* macros for defining plugin infos */
#define WEECHAT_PLUGIN_NAME(__name) \
@ -395,6 +395,7 @@ struct t_weechat_plugin
void (*callback)(void *data, const char *filename),
void *callback_data);
char *(*file_get_content) (const char *filename);
int (*file_copy) (const char *from, const char *to);
/* util */
int (*util_timeval_cmp) (struct timeval *tv1, struct timeval *tv2);
@ -1374,6 +1375,8 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
__callback, __callback_data)
#define weechat_file_get_content(__filename) \
(weechat_plugin->file_get_content)(__filename)
#define weechat_file_copy(__from, __to) \
(weechat_plugin->file_copy)(__from, __to)
/* util */
#define weechat_util_timeval_cmp(__time1, __time2) \

View File

@ -90,33 +90,41 @@ TEST(CoreDir, SearchFullLibName)
/*
* Tests functions:
* dir_file_get_content
* dir_file_copy
*/
TEST(CoreDir, FileGetContent)
TEST(CoreDir, FileGetContentCopy)
{
char *path, *content, *content_read;
char *path1, *path2, *content, *content_read1, *content_read2;
const char *content_small = "line 1\nline 2\nend";
int length, i;
FILE *f;
/* file not found */
POINTERS_EQUAL(NULL, dir_file_get_content (NULL));
POINTERS_EQUAL(NULL, dir_file_get_content (""));
POINTERS_EQUAL(NULL, dir_file_get_content ("/tmp/does/not/exist.xyz"));
LONGS_EQUAL(0, dir_file_copy (NULL, NULL));
LONGS_EQUAL(0, dir_file_copy ("", ""));
LONGS_EQUAL(0, dir_file_copy ("/tmp/does/not/exist.xyz", "/tmp/test.txt"));
path = string_eval_path_home ("${weechat_data_dir}/test_file.txt",
NULL, NULL, NULL);
path1 = string_eval_path_home ("${weechat_data_dir}/test_file.txt",
NULL, NULL, NULL);
path2 = string_eval_path_home ("${weechat_data_dir}/test_file2.txt",
NULL, NULL, NULL);
/* small file */
length = strlen (content_small);
f = fopen (path, "wb");
f = fopen (path1, "wb");
CHECK(f);
LONGS_EQUAL(length, fwrite (content_small, 1, length, f));
fclose (f);
content_read = dir_file_get_content (path);
STRCMP_EQUAL(content_small, content_read);
free (content_read);
unlink (path);
LONGS_EQUAL(1, dir_file_copy (path1, path2));
content_read1 = dir_file_get_content (path1);
content_read2 = dir_file_get_content (path2);
STRCMP_EQUAL(content_small, content_read1);
MEMCMP_EQUAL(content_read1, content_read2, length);
free (content_read1);
free (content_read2);
unlink (path1);
unlink (path2);
/* bigger file: 26 lines of 5000 bytes */
length = 26 * 5001;
@ -128,14 +136,19 @@ TEST(CoreDir, FileGetContent)
content[(i * 5001) + 5000] = '\n';
}
content[26 * 5001] = '\0';
f = fopen (path, "wb");
f = fopen (path1, "wb");
CHECK(f);
LONGS_EQUAL(length, fwrite (content, 1, length, f));
fclose (f);
content_read = dir_file_get_content (path);
STRCMP_EQUAL(content, content_read);
free (content_read);
unlink (path);
LONGS_EQUAL(1, dir_file_copy (path1, path2));
content_read1 = dir_file_get_content (path1);
content_read2 = dir_file_get_content (path2);
STRCMP_EQUAL(content, content_read1);
MEMCMP_EQUAL(content_read1, content_read2, length);
free (content_read1);
free (content_read2);
unlink (path1);
unlink (path2);
free (content);
}