mirror of
https://github.com/lcn2/calc.git
synced 2025-08-16 01:03:29 +03:00
Removed use of HAVE_MEMMOVE as well have_memmv.c. Removed the building and including of have_memmv.h. Removed the memmove() function in blkcpy.c, used when HAVE_MEMMOVE was NOT defined. The libc memmove(3) function as defined by <string.h> is now required to compile calc because the replacement code in blkcpy.c q was problematic, especially when regions overlap. The HAVE_MEMMOVE make symbol was removed from Makefile.config. Thanks to GitHub user @skeeto for reporting this problem.
287 lines
10 KiB
C
287 lines
10 KiB
C
/*
|
|
* fposval - Determine information about the file position type
|
|
*
|
|
* Copyright (C) 1999,2021,2023,2025 Landon Curt Noll
|
|
*
|
|
* Calc is open software; you can redistribute it and/or modify it under
|
|
* the terms of the version 2.1 of the GNU Lesser General Public License
|
|
* as published by the Free Software Foundation.
|
|
*
|
|
* Calc is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
|
|
* Public License for more details.
|
|
*
|
|
* A copy of version 2.1 of the GNU Lesser General Public License is
|
|
* distributed with calc under the filename COPYING-LGPL. You should have
|
|
* received a copy with calc; if not, write to Free Software Foundation, Inc.
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*
|
|
* Under source code control: 1994/11/05 03:19:52
|
|
* File existed as early as: 1994
|
|
*
|
|
* chongo <was here> /\oo/\ http://www.isthe.com/chongo/
|
|
* Share and enjoy! :-) http://www.isthe.com/chongo/tech/comp/calc/
|
|
*/
|
|
|
|
/*
|
|
* The include file have_pos.h, as built during the make process will
|
|
* define the type FILEPOS as the type used to describe file positions.
|
|
* We will print information regarding the size and byte order
|
|
* of this definition.
|
|
*
|
|
* The stat system call returns a stat structure. One of the elements
|
|
* of the stat structure is the st_size element. We will print information
|
|
* regarding the size and byte order of st_size.
|
|
*
|
|
* We will #define of 8 symbols:
|
|
*
|
|
* FILEPOS_BITS length in bits of the type FILEPOS
|
|
* FILEPOS_LEN length in octets of the type FILEPOS
|
|
* SWAP_HALF_IN_FILEPOS will copy/swap FILEPOS into an HALF array
|
|
* OFF_T_BITS length in bits of the st_size stat element
|
|
* OFF_T_LEN length in octets of the st_size stat element
|
|
* SWAP_HALF_IN_OFF_T will copy/swap st_size into an HALF array
|
|
* DEV_BITS length in bits of the st_dev stat element
|
|
* DEV_LEN length in bits of the st_dev stat element
|
|
* SWAP_HALF_IN_DEV will copy/swap st_dev into an HALF array
|
|
* INODE_BITS length in bits of the st_ino stat element
|
|
* INODE_LEN length in octets of the st_ino stat element
|
|
* SWAP_HALF_IN_INODE will copy/swap st_ino into an HALF array
|
|
*
|
|
* With regards to 'will copy/swap ... into an HALF array'. Such macros
|
|
* will either be a copy or a copy with HALFs swapped depending on the
|
|
* Endian order of the hardware.
|
|
*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <sys/types.h>
|
|
#include <sys/stat.h>
|
|
#include "have_string.h"
|
|
#ifdef HAVE_STRING_H
|
|
# include <string.h>
|
|
#endif
|
|
#include "decl.h"
|
|
#include "have_fgetsetpos.h"
|
|
#include "endian_calc.h"
|
|
#include "have_offscl.h"
|
|
#include "have_posscl.h"
|
|
#include "have_fpos_pos.h"
|
|
#include "alloc.h"
|
|
#include "have_unused.h"
|
|
#include "zmath.h"
|
|
|
|
|
|
#include "banned.h" /* include after system header <> includes */
|
|
|
|
|
|
char *program; /* our name */
|
|
|
|
int
|
|
main(int UNUSED(argc), char **argv)
|
|
{
|
|
int stsizelen; /* bit length of st_size in buf */
|
|
int fileposlen; /* bit length of FILEPOS */
|
|
int devlen; /* bit length of st_dev in buf */
|
|
int inodelen; /* bit length of st_ino in buf */
|
|
struct stat buf; /* file status */
|
|
|
|
/*
|
|
* parse args
|
|
*/
|
|
program = argv[0];
|
|
|
|
/*
|
|
* print the file position information
|
|
*/
|
|
#if defined(HAVE_FPOS_POS) && defined(FPOS_POS_BITS)
|
|
fileposlen = FPOS_POS_BITS;
|
|
#else /* ! HAVE_FPOS_POS */
|
|
# if defined(FPOS_BITS)
|
|
fileposlen = FPOS_BITS;
|
|
# else
|
|
fileposlen = sizeof(FILEPOS)*8;
|
|
# endif
|
|
#endif /* ! HAVE_FPOS_POS */
|
|
printf("#undef FILEPOS_BITS\n");
|
|
printf("#define FILEPOS_BITS %d\n", fileposlen);
|
|
printf("#undef FILEPOS_LEN\n");
|
|
printf("#define FILEPOS_LEN %d\n", fileposlen/8);
|
|
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
|
/*
|
|
* Big Endian
|
|
*/
|
|
/*
|
|
* Use casts to (HALF *) because SWAP_HALF_IN_B* might expand to
|
|
* a simple assignment and SWAP_HALF_IN_FILEPOS might get a
|
|
* (HALF *) and a (FILEPOS *) which are not assignment-compatible.
|
|
*/
|
|
if (fileposlen == 64) {
|
|
printf("#define SWAP_HALF_IN_FILEPOS(dest, src) \\\n"
|
|
"\tSWAP_HALF_IN_B64((HALF *)dest, (HALF *)src)\n");
|
|
} else if (fileposlen == 32) {
|
|
printf("#define SWAP_HALF_IN_FILEPOS(dest, src) \\\n"
|
|
"\tSWAP_HALF_IN_B32((HALF *)dest, (HALF *)src)\n");
|
|
} else if (fileposlen%BASEB == 0) {
|
|
printf("#define SWAP_HALF_IN_FILEPOS(dest, src) \\\n"
|
|
"\tswap_HALFs((HALF *)dest, (HALF *)src, %d)\n",
|
|
fileposlen/BASEB);
|
|
} else {
|
|
fprintf(stderr, "%s: unexpected BIG_ENDIAN FILEPOS bit size: %d\n",
|
|
program, fileposlen);
|
|
exit(1);
|
|
}
|
|
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
|
/*
|
|
* Little Endian
|
|
*/
|
|
#if defined(HAVE_FILEPOS_SCALAR)
|
|
printf("#define SWAP_HALF_IN_FILEPOS(dest, src) \\\n"
|
|
"\t(*((HALF *)(dest)) = *((HALF *)(src)))\n");
|
|
#else /* HAVE_FILEPOS_SCALAR */
|
|
/*
|
|
* Normally a "(*(dest) = *(src))" would do, but on some
|
|
* systems a FILEPOS is not a scalar hence we must memcpy.
|
|
*/
|
|
printf("#define SWAP_HALF_IN_FILEPOS(dest, src) \\\n"
|
|
"\tmemcpy((void *)(dest), (void *)(src), FILEPOS_LEN)\n");
|
|
#endif /* HAVE_FILEPOS_SCALAR */
|
|
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
|
putchar('\n');
|
|
|
|
/*
|
|
* print the stat file size information
|
|
*/
|
|
#if defined(OFF_T_BITS)
|
|
stsizelen = OFF_T_BITS;
|
|
#else
|
|
stsizelen = sizeof(buf.st_size)*8;
|
|
#endif
|
|
printf("#undef OFF_T_BITS\n");
|
|
printf("#define OFF_T_BITS %d\n", stsizelen);
|
|
printf("#undef OFF_T_LEN\n");
|
|
printf("#define OFF_T_LEN %d\n", stsizelen/8);
|
|
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
|
/*
|
|
* Big Endian
|
|
*/
|
|
if (stsizelen == 64) {
|
|
printf("#define SWAP_HALF_IN_OFF_T(dest, src)\t\t%s\n",
|
|
"SWAP_HALF_IN_B64(dest, src)");
|
|
} else if (stsizelen == 32) {
|
|
printf("#define SWAP_HALF_IN_OFF_T(dest, src)\t\t%s\n",
|
|
"SWAP_HALF_IN_B32(dest, src)");
|
|
} else {
|
|
fprintf(stderr, "%s: unexpected st_size bit size: %d\n",
|
|
program, stsizelen);
|
|
exit(2);
|
|
}
|
|
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
|
/*
|
|
* Little Endian
|
|
*
|
|
* Normally a "(*(dest) = *(src))" would do, but on some
|
|
* systems an off_t is not a scalar hence we must memcpy.
|
|
*/
|
|
#if defined(HAVE_OFF_T_SCALAR)
|
|
printf("#define SWAP_HALF_IN_OFF_T(dest, src)\t\t%s\n",
|
|
"(*(dest) = *(src))");
|
|
#else /* HAVE_OFF_T_SCALAR */
|
|
/*
|
|
* Normally a "(*(dest) = *(src))" would do, but on some
|
|
* systems, a off_t is not a scalar hence we must memcpy.
|
|
*/
|
|
printf("#define SWAP_HALF_IN_OFF_T(dest, src)\t%s%d%s\n",
|
|
"memcpy((void *)(dest), (void *)(src), ", stsizelen/8, ")");
|
|
#endif /* HAVE_OFF_T_SCALAR */
|
|
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
|
putchar('\n');
|
|
|
|
/*
|
|
* print the dev_t size
|
|
*/
|
|
#if defined(DEV_BITS)
|
|
devlen = DEV_BITS;
|
|
#else
|
|
devlen = sizeof(buf.st_dev)*8;
|
|
#endif
|
|
printf("#undef DEV_BITS\n");
|
|
printf("#define DEV_BITS %d\n", devlen);
|
|
printf("#undef DEV_LEN\n");
|
|
printf("#define DEV_LEN %d\n", devlen/8);
|
|
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
|
/*
|
|
* Big Endian
|
|
*/
|
|
if (devlen == 64) {
|
|
printf("#define SWAP_HALF_IN_DEV(dest, src)\t\t%s\n",
|
|
"SWAP_HALF_IN_B64(dest, src)");
|
|
} else if (devlen == 32) {
|
|
printf("#define SWAP_HALF_IN_DEV(dest, src)\t\t%s\n",
|
|
"SWAP_HALF_IN_B32(dest, src)");
|
|
} else if (devlen == 16) {
|
|
printf("#define SWAP_HALF_IN_DEV(dest, src)\t\t%s\n",
|
|
"(*(dest) = *(src))");
|
|
} else {
|
|
fprintf(stderr, "%s: unexpected st_dev bit size: %d\n",
|
|
program, devlen);
|
|
exit(3);
|
|
}
|
|
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
|
/*
|
|
* Little Endian
|
|
*
|
|
* Normally a "(*(dest) = *(src))" would do, but on some
|
|
* systems, a DEV is not a scalar hence we must memcpy.
|
|
*/
|
|
printf("#define SWAP_HALF_IN_DEV(dest, src)\t%s%d%s\n",
|
|
"memcpy((void *)(dest), (void *)(src), ", devlen/8, ")");
|
|
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
|
putchar('\n');
|
|
|
|
/*
|
|
* print the ino_t size
|
|
*/
|
|
#if defined(INODE_BITS)
|
|
inodelen = INODE_BITS;
|
|
#else
|
|
inodelen = sizeof(buf.st_ino)*8;
|
|
#endif
|
|
printf("#undef INODE_BITS\n");
|
|
printf("#define INODE_BITS %d\n", inodelen);
|
|
printf("#undef INODE_LEN\n");
|
|
printf("#define INODE_LEN %d\n", inodelen/8);
|
|
#if CALC_BYTE_ORDER == BIG_ENDIAN
|
|
/*
|
|
* Big Endian
|
|
*/
|
|
if (inodelen == 64) {
|
|
printf("#define SWAP_HALF_IN_INODE(dest, src)\t\t%s\n",
|
|
"SWAP_HALF_IN_B64(dest, src)");
|
|
} else if (inodelen == 32) {
|
|
printf("#define SWAP_HALF_IN_INODE(dest, src)\t\t%s\n",
|
|
"SWAP_HALF_IN_B32(dest, src)");
|
|
} else if (inodelen == 16) {
|
|
printf("#define SWAP_HALF_IN_INODE(dest, src)\t\t%s\n",
|
|
"(*(dest) = *(src))");
|
|
} else {
|
|
fprintf(stderr, "%s: unexpected st_ino bit size: %d\n",
|
|
program, inodelen);
|
|
exit(4);
|
|
}
|
|
#else /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
|
/*
|
|
* Little Endian
|
|
*
|
|
* Normally a "(*(dest) = *(src))" would do, but on some
|
|
* systems, a INODE is not a scalar hence we must memcpy.
|
|
*/
|
|
printf("#define SWAP_HALF_IN_INODE(dest, src)\t%s%d%s\n",
|
|
"memcpy((void *)(dest), (void *)(src), ", inodelen/8, ")");
|
|
#endif /* CALC_BYTE_ORDER == BIG_ENDIAN */
|
|
/* exit(0); */
|
|
return 0;
|
|
}
|