/* $Id: t_tmpfileplus.c $ */
/*
* $Date: 2024-07-01 12:19Z $
* $Revision: 2.1.0 $
* $Author: dai $
*/
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) 2012-24 David Ireland, DI Management Services Pty Ltd
* <https://di-mgt.com.au/contact/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <errno.h>
#include <assert.h>
#include "tmpfileplus.h"
/* Choose test directory suitable for Windows or Linux */
#ifdef _WIN32
#define TEST_DIR "C:\\Test"
#else
#define TEST_DIR "./Test"
#endif
int test_tempfile(FILE *fp, char *pathname)
{
time_t now;
clock_t clk;
printf("\nTESTING: ");
printf("pathname=[%s]\n", (pathname ? pathname : "NULL"));
if (fp) {
int i;
int c;
printf("fp is valid\n");
/* Write the time now and the alphabet to our temp file */
time(&now);
fprintf(fp, "%s", ctime(&now));
clk = clock();
fprintf(fp, "clock=%#x ms\n", (unsigned)clk);
for (i = 0; i < 26; i++)
fputc('A'+i, fp);
rewind(fp);
printf("DATA:\n");
while ((c = fgetc(fp)) != EOF)
{
putchar(c);
}
printf("\n");
}
else {
printf("ERROR: fp is not valid!\n");
assert(fp);
}
return 0;
}
int test_closedfile(const char *tempfile, int keep)
{
FILE *fp;
if (tempfile) {
printf("After closing...\n");
/* See if file still exists */
fp = fopen(tempfile, "rb");
if (fp) {
printf("File '%s' EXISTS%s\n", tempfile, (keep ? ", as expected" : " ERROR!"));
fclose(fp);
assert(keep);
}
else {
printf("File '%s' DOES NOT exist%s\n", tempfile, (!keep ? ", as expected" : " ERROR!"));
assert(!keep);
}
}
return 0;
}
int main(void)
{
FILE *fp;
char *pathname;
char pathbuf[FILENAME_MAX];
size_t flen;
/* Test with no pathname, like tmpfile() */
fp = tmpfileplus(NULL, NULL, NULL, 0);
test_tempfile(fp, NULL);
fclose(fp);
fp = tmpfileplus_f(NULL, NULL, NULL, 0, 0);
test_tempfile(fp, NULL);
fclose(fp);
/* Test with a pathname */
fp = tmpfileplus(NULL, NULL, &pathname, 0);
test_tempfile(fp, pathname);
fclose(fp);
test_closedfile(pathname, 0);
if (pathname) free(pathname);
fp = tmpfileplus_f(NULL, NULL, pathbuf, sizeof(pathbuf), 0);
test_tempfile(fp, pathbuf);
fclose(fp);
test_closedfile(pathbuf, 0);
/* Remember this "standard" length for later */
flen = strlen(pathbuf);
assert(flen > 0);
/* Test with a given prefix */
fp = tmpfileplus(NULL, "THIS-", &pathname, 0);
test_tempfile(fp, pathname);
fclose(fp);
test_closedfile(pathname, 0);
if (pathname) free(pathname);
/* Use fixed-length buffer - no need to free pathname */
fp = tmpfileplus_f(NULL, "THIS-", pathbuf, sizeof(pathbuf), 0);
test_tempfile(fp, pathbuf);
fclose(fp);
test_closedfile(pathbuf, 0);
/* Test with a specified directory
-- directory "C:\Test" (Windows) or "./Test" (Linux) must exist
-- otherwise default is used */
fp = tmpfileplus(TEST_DIR, "THAT~", &pathname, 0);
test_tempfile(fp, pathname);
fclose(fp);
test_closedfile(pathname, 0);
if (pathname) free(pathname);
fp = tmpfileplus_f(TEST_DIR, "THAT~", pathbuf, sizeof(pathbuf), 0);
test_tempfile(fp, pathbuf);
fclose(fp);
test_closedfile(pathbuf, 0);
/* Test with a specified directory but keep the file */
fp = tmpfileplus(TEST_DIR, NULL, &pathname, TMPFILE_KEEP);
test_tempfile(fp, pathname);
fclose(fp);
test_closedfile(pathname, TMPFILE_KEEP);
if (pathname) free(pathname);
fp = tmpfileplus_f(TEST_DIR, NULL, pathbuf, sizeof(pathbuf), TMPFILE_KEEP);
test_tempfile(fp, pathbuf);
fclose(fp);
test_closedfile(pathbuf, TMPFILE_KEEP);
// New in v2.1 - specify filename extension
/* Test with a pathname */
fp = tmpfileplus_ex(NULL, NULL, ".txt", &pathname, 0);
test_tempfile(fp, pathname);
fclose(fp);
test_closedfile(pathname, 0);
if (pathname) free(pathname);
fp = tmpfileplus_ex_f(NULL, NULL, ".txt", pathbuf, sizeof(pathbuf), 0);
test_tempfile(fp, pathbuf);
fclose(fp);
test_closedfile(pathbuf, 0);
fp = tmpfileplus_ex_f(TEST_DIR, "TMPFILEPLUS-", ".txt", pathbuf, sizeof(pathbuf), TMPFILE_KEEP);
test_tempfile(fp, pathbuf);
fclose(fp);
test_closedfile(pathbuf, TMPFILE_KEEP);
/* Test with too short buffer - this should fail */
printf("\nTest with too short buffer...\n");
pathbuf[0] = 0;
fp = tmpfileplus_f(NULL, NULL, pathbuf, 5, 0);
printf("fp=%p, errno=%d\n", fp, errno);
assert(!fp);
assert(0 == pathbuf[0]);
/* Try an off-by-one error */
pathbuf[0] = 0;
fp = tmpfileplus_f(NULL, NULL, pathbuf, flen, 1);
printf("fp=%p, errno=%d\n", fp, errno);
assert(!fp);
assert(0 == pathbuf[0]);
printf("\nALL DONE.\n");
return 0;
}