/* * 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 /\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 #include #include #include #include "have_string.h" #ifdef HAVE_STRING_H # include #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; }