Lazarus

Programming => General => Topic started by: ertank on April 16, 2018, 09:01:16 am

Title: CPP #define macro to Pascal conversion help
Post by: ertank on April 16, 2018, 09:01:16 am
Hello,

I am working on reading ext2/3/4 disc IMG files. I found some definitions in CPP that I do not know how to convert into Pascal. Any help is appreciated:
Code: C++  [Select][+][-]
  1. /* EXT2 Fragment Sizes */
  2. #define EXT2_MIN_FRAG_SIZE  1024
  3. #define EXT2_MAX_FRAG_SIZE  4096
  4. #define EXT2_MIN_FRAG_LOG_SIZE  10
  5.  
  6. #define EXT2_FRAG_SIZE(s)       (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
  7. #define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
  8.  

So, what would be Pascal code for above CPP macros?

Thanks & regards,
Ertan
Title: Re: CPP #define macro to Pascal conversion help
Post by: Thaddy on April 16, 2018, 09:23:23 am
The first three can be either const or $define macro's
The last two, because a parameter, need to be normal pascal functions.
Code: Pascal  [Select][+][-]
  1. program testdefine;
  2. {$mode delphi}{$H+}{$macro on}
  3. {* EXT2 Fragment Sizes *}
  4. // use simple consts or:
  5. {$define EXT2_MIN_FRAG_SIZE :=  1024}
  6. {$define EXT2_MAX_FRAG_SIZE:=  4096}
  7. {$define EXT2_MIN_FRAG_LOG_SIZE:= 10}
  8. // so this is also OK without macro's
  9. {const
  10.   EXT2_MIN_FRAG_SIZE =  1024;
  11.   EXT2_MAX_FRAG_SIZE =  4096;
  12.   EXT2_MIN_FRAG_LOG_SIZE = 10;}
  13. // this one is doubtful.. but compiles.
  14. function EXT2_FRAG_SIZE(s:cardinal):cardinal;inline;
  15. begin
  16.  Result :=EXT2_MIN_FRAG_SIZE << (s);{->s_log_frag_size} // have to look that one up
  17. end;
  18.  
  19. function EXT2_BLOCK_SIZE(s:cardinal):cardinal;inline;
  20. begin
  21.  Result := EXT2_BLOCK_SIZE(s) div EXT2_FRAG_SIZE(s);
  22. end;
  23.  
  24. function EXT2_FRAGS_PER_BLOCK(s:cardinal):cardinal;inline;
  25. begin
  26.  Result :=EXT2_BLOCK_SIZE(s) div EXT2_FRAG_SIZE(s)
  27. end;
  28. begin
  29. end.

Note, since the fuctions are inlined the generated code is similar - if not equal - to the C macro's

The unresolved one should probably be like this:
Code: Pascal  [Select][+][-]
  1. {probably ext2_sb_info is a record type, so s is a ext2_sb_info record, not a cardinal like in the other ones.}
  2. function EXT2_FRAG_SIZE(s: ext2_sb_info ):cardinal;inline;
  3. begin
  4.  Result :=EXT2_MIN_FRAG_SIZE << s.s_log_frag_size}
  5. end;
You did not provide the record ext2_sb_info.
Title: Re: CPP #define macro to Pascal conversion help
Post by: ertank on April 16, 2018, 10:28:33 am
Here is complete header file. I think EXT2_FRAG_SIZE should have EXT2_SUPER_BLOCK record as parameter:
Code: C++  [Select][+][-]
  1. /**
  2.  * Copyright (C) 2005 2010 by Manish Regmi   (regmi dot manish at gmail.com)
  3.  *
  4.  * This program is free software; you can redistribute it and/or modify
  5.  * it under the terms of the GNU General Public License as published by
  6.  * the Free Software Foundation; either version 2 of the License, or
  7.  * (at your option) any later version.
  8.  *
  9.  * This program 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
  12.  * GNU General Public License for more details.
  13.  *
  14.  * You should have received a copy of the GNU General Public License
  15.  * along with this program; if not, write to the
  16.  * Free Software Foundation, Inc.,
  17.  * 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  18.  **/
  19. /* Declarations for ext2 file system */
  20. /* Ripped from Linux Source. copyright Linus Trovaldis.*/
  21. /*         by RRM       */
  22.  
  23.  
  24. #ifndef __EXT2FS_H
  25. #define __EXT2FS_H
  26.  
  27. #include <stdint.h>
  28.  
  29. #define EXT2_DEFAULT_PREALLOC_BLOCKS    8
  30.  
  31. /* Special Inode Numbers  */
  32. #define EXT2_BAD_INO                    1
  33. #define EXT2_ROOT_INO                   2
  34. #define EXT2_ACL_IDX_INO                3
  35. #define EXT2_ACL_DATA_INO               4
  36. #define EXT2_BOOT_LOADER_INO    5
  37. #define EXT2_UNDEL_DIR_INO              6
  38.  
  39. #define EXT2_GOOD_OLD_FIRST_INO 11
  40.  
  41. #define EXT2_SUPER_MAGIC                0xEF53  /* EXT2 Fs Magic Number */
  42.  
  43. #define EXT2_LINK_MAX                   32000   /* Max count of links to the file */
  44.  
  45. /* Block Size Management */
  46. #define EXT2_MIN_BLOCK_SIZE             1024
  47. #define EXT2_MAX_BLOCK_SIZE             4096
  48. #define EXT2_MIN_BLOCK_LOG_SIZE 10
  49.  
  50. /* EXT2 Fragment Sizes */
  51. #define EXT2_MIN_FRAG_SIZE              1024
  52. #define EXT2_MAX_FRAG_SIZE              4096
  53. #define EXT2_MIN_FRAG_LOG_SIZE  10
  54.  
  55. #define EXT2_FRAG_SIZE(s)               (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size)
  56. #define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s))
  57.  
  58. /* Block Group Macros */
  59. # define EXT2_BLOCKS_PER_GROUP(s)       ((s)->s_blocks_per_group)
  60. # define EXT2_DESC_PER_BLOCK(s)         (EXT2_BLOCK_SIZE(s) / sizeof (EXT2_GROUP_DESC))
  61. # define EXT2_INODES_PER_GROUP(s)       ((s)->s_inodes_per_group)
  62. # define EXT2_INODES_PER_BLOCK(s)       (EXT2_BLOCK_SIZE(s) / sizeof (EXT2_INODE))
  63. # define EXT2_BLOCK_SIZE_BITS(s)        ((s)->s_log_block_size + 10)
  64.  
  65. /* Constants relative to the data blocks  */
  66. #define EXT2_NDIR_BLOCKS                12
  67. #define EXT2_IND_BLOCK                  EXT2_NDIR_BLOCKS
  68. #define EXT2_DIND_BLOCK                 (EXT2_IND_BLOCK + 1)
  69. #define EXT2_TIND_BLOCK                 (EXT2_DIND_BLOCK + 1)
  70. #define EXT2_N_BLOCKS                   (EXT2_TIND_BLOCK + 1)
  71.  
  72. /* Superblock Flags */
  73. #define EXT2_FEATURE_INCOMPAT_COMPRESSION 0x0001    /* disk/file compression is used */
  74. /*Inode flags  */
  75. #define EXT2_SECRM_FL                   0x00000001 /* Secure deletion */
  76. #define EXT2_UNRM_FL                            0x00000002 /* Undelete */
  77. #define EXT2_COMPR_FL                   0x00000004 /* Compress file */
  78. #define EXT2_SYNC_FL                    0x00000008 /* Synchronous updates */
  79. #define EXT2_IMMUTABLE_FL               0x00000010 /* Immutable file */
  80. #define EXT2_APPEND_FL                  0x00000020 /* writes to file may only append */
  81. #define EXT2_NODUMP_FL                  0x00000040 /* do not dump file */
  82. #define EXT2_NOATIME_FL                 0x00000080 /* do not update atime */
  83.  
  84. /* Reserved for compression usage... */
  85. #define EXT2_DIRTY_FL                           0x00000100
  86. #define EXT2_COMPRBLK_FL                        0x00000200 /* One or more compressed clusters */
  87. #define EXT2_NOCOMP_FL                          0x00000400 /* Don't compress */
  88. #define EXT2_ECOMPR_FL                          0x00000800 /* Compression error */
  89.  
  90. /* End compression flags --- maybe not all used */
  91. #define EXT2_BTREE_FL                           0x00001000 /* btree format dir */
  92. #define EXT2_IMAGIC_FL                  0x00002000 /* AFS directory */
  93. #define EXT2_JOURNAL_DATA_FL            0x00004000 /* file data should be journaled */
  94. #define EXT2_NOTAIL_FL                  0x00008000 /* file tail should not be merged */
  95. #define EXT2_DIRSYNC_FL                 0x00010000 /* dirsync behaviour (directories only) */
  96. #define EXT2_TOPDIR_FL                  0x00020000 /* Top of directory hierarchies*/
  97. #define EXT2_HUGE_FILE_FL               0x00040000 /* Set to each huge file */
  98. #define EXT2_EXTENTS_FL                 0x00080000 /* Inode uses extents */
  99. #define EXT2_RESERVED_FL                0x80000000 /* reserved for ext2 lib */
  100.  
  101. #define EXT2_FL_USER_VISIBLE            0x00001FFF /* User visible flags */
  102. #define EXT2_FL_USER_MODIFIABLE         0x000000FF /* User modifiable flags */
  103.  
  104. /* Codes for operating systems */
  105. #define EXT2_OS_LINUX           0
  106. #define EXT2_OS_HURD            1
  107. #define EXT2_OS_MASIX           2
  108. #define EXT2_OS_FREEBSD         3
  109. #define EXT2_OS_LITES           4
  110.  
  111. /* Revision levels  */
  112. #define EXT2_GOOD_OLD_REV       0       /* The good old (original) format */
  113. #define EXT2_DYNAMIC_REV        1       /* V2 format w/ dynamic inode sizes */
  114.  
  115. #define EXT2_CURRENT_REV        EXT2_GOOD_OLD_REV
  116. #define EXT2_MAX_SUPP_REV       EXT2_DYNAMIC_REV
  117.  
  118. #define EXT2_GOOD_OLD_INODE_SIZE 128
  119.  
  120. /* Default values for user and/or group using reserved blocks */
  121. #define EXT2_DEF_RESUID         0
  122. #define EXT2_DEF_RESGID         0
  123.  
  124. /* Structure of a directory entry */
  125. #define EXT2_NAME_LEN 255
  126.  
  127. #define  EXT2_BLOCK_SIZE(s)                     (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size)
  128. #define  EXT2_ACLE_PER_BLOCK(s)         (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry))
  129. #define  EXT2_ADDR_PER_BLOCK(s)         (EXT2_BLOCK_SIZE(s) / sizeof (uint16_t))
  130.  
  131. #define EXT2_INODE_SIZE(s)      (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
  132. EXT2_GOOD_OLD_INODE_SIZE : (s)->s_inode_size)
  133.  
  134. #define EXT2_FIRST_INO(s)       (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \
  135. EXT2_GOOD_OLD_FIRST_INO :  (s)->s_first_ino)
  136.  
  137. /* In Linux disk is divided into Blocks. These Blocks are divided into Groups. This   */
  138. /* Structure shows different types of groups but it is not implemented. Not Necessary */
  139. /*
  140. typedef struct tagBLOCK_GROUP
  141. {
  142.         1. The SuperBlock
  143.         2. The Group Descriptors
  144.         3. The block Bitmap
  145.         4. The Inode Bitmap
  146.         5. The Inode Table
  147.         6. Data Blocks and Fragments
  148.  
  149. }BLOCK_GROUP;
  150.  
  151. */
  152.  
  153. /* The Super Block comes first in the block group */
  154. typedef struct tagEXT2_SUPER_BLOCK
  155. {
  156.     uint32_t    s_inodes_count;         /* total no of inodes */
  157.     uint32_t    s_blocks_count;         /* total no of blocks */
  158.     uint32_t    s_r_blocks_count;       /* total no of blocks reserved for exclusive use  of superuser */
  159.     uint32_t    s_free_blocks_count;    /* total no of free blocks */
  160.     uint32_t    s_free_inodes_count;    /* total no of free inodes */
  161.     uint32_t    s_first_data_block;     /* position of the first data block */
  162.     uint32_t    s_log_block_size;       /* used to compute logical block size in bytes */
  163.     uint32_t    s_log_frag_size;                /* used to compute logical fragment size  */
  164.     uint32_t    s_blocks_per_group;     /* total number of blocks contained in the group  */
  165.     uint32_t    s_frags_per_group;      /* total number of fragments in a group */
  166.     uint32_t    s_inodes_per_group;     /* number of inodes in a group  */
  167.     uint32_t    s_mtime;                        /* time at which the last mount was performed */
  168.     uint32_t    s_wtime;                        /* time at which the last write was performed */
  169.     uint16_t    s_mnt_count;            /* number of time the fs system has been mounted in r/w mode without having checked */
  170.     uint16_t    s_max_mnt_count;        /* the max no of times the fs can be mounted in r/w mode before a check must be done */
  171.     uint16_t    s_magic;                        /* a number that identifies the fs (eg. 0xef53 for ext2) */
  172.     uint16_t    s_state;                        /* gives the state of fs (eg. 0x001 is Unmounted cleanly) */
  173.     uint16_t    s_pad;                          /* unused */
  174.     uint16_t    s_minor_rev_level;      /*      */
  175.     uint32_t    s_lastcheck;            /* the time of last check performed */
  176.     uint32_t    s_checkinterval;                /* the max possible time between checks on the fs */
  177.     uint32_t    s_creator_os;           /* os */
  178.     uint32_t    s_rev_level;                    /* Revision level */
  179.     uint16_t    s_def_resuid;           /* default uid for reserved blocks */
  180.     uint16_t    s_def_regid;            /* default gid for reserved blocks */
  181.  
  182.     /* for EXT2_DYNAMIC_REV superblocks only */
  183.     uint32_t    s_first_ino;            /* First non-reserved inode */
  184.     uint16_t    s_inode_size;           /* size of inode structure */
  185.     uint16_t    s_block_group_nr;       /* block group # of this superblock */
  186.     uint32_t    s_feature_compat;       /* compatible feature set */
  187.     uint32_t    s_feature_incompat;     /* incompatible feature set */
  188.     uint32_t    s_feature_ro_compat;    /* readonly-compatible feature set */
  189.     uint8_t     s_uuid[16];             /* 128-bit uuid for volume */
  190.     char        s_volume_name[16];              /* volume name */
  191.     char        s_last_mounted[64];             /* directory where last mounted */
  192.     uint32_t    s_algorithm_usage_bitmap; /* For compression */
  193.     uint8_t     s_prealloc_blocks;      /* Nr of blocks to try to preallocate*/
  194.     uint8_t     s_prealloc_dir_blocks;  /* Nr to preallocate for dirs */
  195.     uint16_t    s_padding1;
  196.     uint32_t    s_reserved[204];                /* unused */
  197. } __attribute__ ((__packed__)) EXT2_SUPER_BLOCK;
  198.  
  199. /* The Group Descriptors follow the Super Block. */
  200. typedef struct tagEXT2_GROUP_DESC
  201. {
  202.     uint32_t    bg_block_bitmap;        /* points to the blocks bitmap for the group */
  203.     uint32_t    bg_inode_bitmap;        /* points to the inodes bitmap for the group */
  204.     uint32_t    bg_inode_table;         /* points to the inode table first block     */
  205.     uint16_t    bg_free_blocks_count;   /* number of free blocks in the group        */
  206.     uint16_t    bg_free_inodes_count;   /* number of free inodes in the              */
  207.     uint16_t    bg_used_dirs_count;     /* number of inodes allocated to directories */
  208.     uint16_t    bg_pad;                 /* padding */
  209.     uint32_t    bg_reserved[3];         /* reserved */
  210. }__attribute__ ((__packed__)) EXT2_GROUP_DESC;
  211.  
  212. /* Structure of an inode on the disk  */
  213. typedef struct tagEXT2_INODE
  214. {
  215.     uint16_t    i_mode;         /* File mode */
  216.     uint16_t    i_uid;          /* Low 16 bits of Owner Uid */
  217.     uint32_t    i_size;         /* Size in bytes */
  218.     uint32_t    i_atime;                /* Access time */
  219.     uint32_t    i_ctime;                /* Creation time */
  220.     uint32_t    i_mtime;                /* Modification time */
  221.     uint32_t    i_dtime;                /* Deletion Time */
  222.     uint16_t    i_gid;          /* Low 16 bits of Group Id */
  223.     uint16_t    i_links_count;  /* Links count */
  224.     uint32_t    i_blocks;               /* Blocks count */
  225.     uint32_t    i_flags;                /* File flags */
  226.     union {
  227.         struct {
  228.             uint32_t  l_i_reserved1;
  229.         } linux1;
  230.         struct {
  231.             uint32_t  h_i_translator;
  232.         } hurd1;
  233.         struct {
  234.             uint32_t  m_i_reserved1;
  235.         } masix1;
  236.     } osd1;                             /* OS dependent 1 */
  237.     uint32_t    i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
  238.     uint32_t    i_generation;   /* File version (for NFS) */
  239.     uint32_t    i_file_acl;             /* File ACL */
  240. //    uint32_t  i_dir_acl;              /* Directory ACL */
  241.     uint32_t    i_size_high;            /* This is used store the high 32 bit of file size in large files */
  242.     uint32_t    i_faddr;                /* Fragment address */
  243.     union {
  244.         struct {
  245.             uint8_t     l_i_frag;       /* Fragment number */
  246.             uint8_t     l_i_fsize;      /* Fragment size */
  247.             uint16_t    i_pad1;
  248.             uint16_t    l_i_uid_high;   /* these 2 fields    */
  249.             uint16_t    l_i_gid_high;   /* were reserved2[0] */
  250.             uint32_t    l_i_reserved2;
  251.         } linux2;
  252.         struct {
  253.             uint8_t     h_i_frag;       /* Fragment number */
  254.             uint8_t     h_i_fsize;      /* Fragment size */
  255.             uint16_t    h_i_mode_high;
  256.             uint16_t    h_i_uid_high;
  257.             uint16_t    h_i_gid_high;
  258.             uint16_t    h_i_author;
  259.         } hurd2;
  260.         struct {
  261.             uint8_t     m_i_frag;       /* Fragment number */
  262.             uint8_t     m_i_fsize;      /* Fragment size */
  263.             uint16_t    m_pad1;
  264.             uint32_t    m_i_reserved2[2];
  265.         } masix2;
  266.     } osd2;                                     /* OS dependent 2 */
  267. } __attribute__ ((__packed__)) EXT2_INODE;
  268.  
  269. /* EXT2 directory structure */
  270. typedef struct tagEXT2_DIR_ENTRY {
  271.     uint32_t    inode;                  /* Inode number */
  272.     uint16_t    rec_len;                /* Directory entry length */
  273.     uint8_t     name_len;               /* Name length */
  274.     uint8_t     filetype;               /* File type */
  275.     char        name[EXT2_NAME_LEN];    /* File name */
  276. } __attribute__ ((__packed__)) EXT2_DIR_ENTRY;
  277.  
  278.  
  279. /*
  280.  * This is the extent on-disk structure.
  281.  * It's used at the bottom of the tree.
  282.  */
  283. typedef struct ext4_extent {
  284.     uint32_t ee_block; /* first logical block extent covers */
  285.     uint16_t ee_len; /* number of blocks covered by extent */
  286.     uint16_t ee_start_hi; /* high 16 bits of physical block */
  287.     uint32_t ee_start_lo; /* low 32 bits of physical block */
  288. } __attribute__ ((__packed__)) EXT4_EXTENT;
  289.  
  290. /*
  291.  * This is index on-disk structure.
  292.  * It's used at all the levels except the bottom.
  293.  */
  294. typedef struct ext4_extent_idx {
  295.     uint32_t  ei_block;       /* index covers logical blocks from 'block' */
  296.     uint32_t  ei_leaf_lo;     /* pointer to the physical block of the next *
  297.                                  * level. leaf or next index could be there */
  298.     uint16_t  ei_leaf_hi;     /* high 16 bits of physical block */
  299.     uint16_t   ei_unused;
  300. }__attribute__ ((__packed__)) EXT4_EXTENT_IDX;
  301.  
  302. /*
  303.  * Each block (leaves and indexes), even inode-stored has header.
  304.  */
  305. typedef struct ext4_extent_header {
  306.     uint16_t  eh_magic;       /* probably will support different formats */
  307.     uint16_t  eh_entries;     /* number of valid entries */
  308.     uint16_t  eh_max;         /* capacity of store in entries */
  309.     uint16_t  eh_depth;       /* has tree real underlying blocks? */
  310.     uint32_t  eh_generation;  /* generation of the tree */
  311. }__attribute__ ((__packed__)) EXT4_EXTENT_HEADER;
  312.  
  313.  
  314. #define EXT4_EXT_MAGIC          0xf30a
  315. #define get_ext4_header(i)      ((struct ext4_extent_header *) (i)->i_block)
  316.  
  317. #define EXT_FIRST_EXTENT(__hdr__) \
  318. ((struct ext4_extent *) (((char *) (__hdr__)) +         \
  319.                          sizeof(struct ext4_extent_header)))
  320.  
  321. #define EXT_FIRST_INDEX(__hdr__) \
  322.         ((struct ext4_extent_idx *) (((char *) (__hdr__)) +     \
  323.                                      sizeof(struct ext4_extent_header)))
  324.  
  325. #define INODE_HAS_EXTENT(i) ((i)->i_flags & EXT2_EXTENTS_FL)
  326.  
  327. static inline uint64_t ext_to_block(EXT4_EXTENT *extent)
  328. {
  329.     uint64_t block;
  330.  
  331.     block = (uint64_t)extent->ee_start_lo;
  332.     block |= ((uint64_t) extent->ee_start_hi << 31) << 1;
  333.  
  334.     return block;
  335. }
  336.  
  337. static inline uint64_t idx_to_block(EXT4_EXTENT_IDX *idx)
  338. {
  339.     uint64_t block;
  340.  
  341.     block = (uint64_t)idx->ei_leaf_lo;
  342.     block |= ((uint64_t) idx->ei_leaf_hi << 31) << 1;
  343.  
  344.     return block;
  345. }
  346.  
  347. #endif
  348.  
Title: Re: CPP #define macro to Pascal conversion help
Post by: Thaddy on April 16, 2018, 10:30:01 am
Well, you now know how to do it  :) So go ahead.... 8-) I added this to the code with same explanation: our posts crossed while editting.
Title: Re: CPP #define macro to Pascal conversion help
Post by: ertank on April 16, 2018, 10:50:27 am
Well, you now know how to do it  :) So go ahead.... 8-) I added this to the code with same explanation: our posts crossed while editting.
I just do not know how to identify Cardinal or other return type for functions that I will be converting from a C++ macro
Title: Re: CPP #define macro to Pascal conversion help
Post by: Thaddy on April 16, 2018, 11:45:09 am
The parameter type for macro's is inferred from its use, I usually look up where it is used or first use a C preprocessor, e.g  cpp -E will resolve the macro's
Title: Re: CPP #define macro to Pascal conversion help
Post by: ertank on April 16, 2018, 12:02:21 pm
I am in need for additional help for converting below code:
Code: C++  [Select][+][-]
  1. typedef struct tagEXT2_INODE
  2. {
  3.     uint16_t    i_mode;         /* File mode */
  4.     uint16_t    i_uid;          /* Low 16 bits of Owner Uid */
  5.     uint32_t    i_size;         /* Size in bytes */
  6.     uint32_t    i_atime;                /* Access time */
  7.     uint32_t    i_ctime;                /* Creation time */
  8.     uint32_t    i_mtime;                /* Modification time */
  9.     uint32_t    i_dtime;                /* Deletion Time */
  10.     uint16_t    i_gid;          /* Low 16 bits of Group Id */
  11.     uint16_t    i_links_count;  /* Links count */
  12.     uint32_t    i_blocks;               /* Blocks count */
  13.     uint32_t    i_flags;                /* File flags */
  14.     union {
  15.         struct {
  16.             uint32_t  l_i_reserved1;
  17.         } linux1;
  18.         struct {
  19.             uint32_t  h_i_translator;
  20.         } hurd1;
  21.         struct {
  22.             uint32_t  m_i_reserved1;
  23.         } masix1;
  24.     } osd1;                             /* OS dependent 1 */
  25.     uint32_t    i_block[EXT2_N_BLOCKS];/* Pointers to blocks */
  26.     uint32_t    i_generation;   /* File version (for NFS) */
  27.     uint32_t    i_file_acl;             /* File ACL */
  28. //    uint32_t  i_dir_acl;              /* Directory ACL */
  29.     uint32_t    i_size_high;            /* This is used store the high 32 bit of file size in large files */
  30.     uint32_t    i_faddr;                /* Fragment address */
  31.     union {
  32.         struct {
  33.             uint8_t     l_i_frag;       /* Fragment number */
  34.             uint8_t     l_i_fsize;      /* Fragment size */
  35.             uint16_t    i_pad1;
  36.             uint16_t    l_i_uid_high;   /* these 2 fields    */
  37.             uint16_t    l_i_gid_high;   /* were reserved2[0] */
  38.             uint32_t    l_i_reserved2;
  39.         } linux2;
  40.         struct {
  41.             uint8_t     h_i_frag;       /* Fragment number */
  42.             uint8_t     h_i_fsize;      /* Fragment size */
  43.             uint16_t    h_i_mode_high;
  44.             uint16_t    h_i_uid_high;
  45.             uint16_t    h_i_gid_high;
  46.             uint16_t    h_i_author;
  47.         } hurd2;
  48.         struct {
  49.             uint8_t     m_i_frag;       /* Fragment number */
  50.             uint8_t     m_i_fsize;      /* Fragment size */
  51.             uint16_t    m_pad1;
  52.             uint32_t    m_i_reserved2[2];
  53.         } masix2;
  54.     } osd2;                                     /* OS dependent 2 */
  55. } __attribute__ ((__packed__)) EXT2_INODE;
  56.  

So far, I came up with something as following. It compiles OK. I just cannot be sure if it is the way to go:
Code: Pascal  [Select][+][-]
  1. //* Structure of an inode on the disk  */
  2. type EXT2_INODE = packed record
  3.   i_mode: UInt16;               //* File mode */
  4.   i_uid: UInt16;                //* Low 16 bits of Owner Uid */
  5.   i_size: UInt32;               //* Size in bytes */
  6.   i_atime: UInt32;              //* Access time */
  7.   i_ctime: UInt32;              //* Creation time */
  8.   i_mtime: UInt32;              //* Modification time */
  9.   i_dtime: UInt32;              //* Deletion Time */
  10.   i_gid: UInt16;                //* Low 16 bits of Group Id */
  11.   i_links_count: UInt16;        //* Links count */
  12.   i_blocks: UInt32;             //* Blocks count */
  13.   i_flags: UInt32;              //* File flags */
  14.   osd1: packed record
  15.     linux1: packed record
  16.       l_i_reserved1: UInt32;
  17.     end;
  18.     hurd1: packed record
  19.       h_i_translator: UInt32;
  20.     end;
  21.     masix1: packed record
  22.       m_i_reserved1: UInt32;
  23.     end;
  24.   end;                          //* OS dependent 1 */
  25.   i_block: array [0..Pred(EXT2_N_BLOCKS)] of UInt32; //* Pointers to blocks */
  26.   i_generation: UInt32; //* File version (for NFS) */
  27.   i_file_acl: UInt32;           //* File ACL */
  28. //    uint32_t  i_dir_acl;              //* Directory ACL */
  29.   i_size_high: UInt32;            //* This is used store the high 32 bit of file size in large files */
  30.   i_faddr: UInt32;              //* Fragment address */
  31.   osd2: packed record
  32.     linux2: packed record
  33.       l_i_frag: UInt8;          //* Fragment number */
  34.       l_i_fsize: UInt8; //* Fragment size */
  35.       i_pad1: UInt16;
  36.       l_i_uid_high: UInt16;     //* these 2 fields    */
  37.       l_i_gid_high: UInt16;     //* were reserved2[0] */
  38.       l_i_reserved2: UInt32;
  39.     end;
  40.     hurd2: packed record
  41.       h_i_frag: UInt8;  //* Fragment number */
  42.       h_i_fsize: UInt8; //* Fragment size */
  43.       h_i_mode_high: UInt16;
  44.       h_i_uid_high: UInt16;
  45.       h_i_gid_high: UInt16;
  46.       h_i_author: UInt16;
  47.     end;
  48.     masix2: packed record
  49.       m_i_frag: UInt8;  //* Fragment number */
  50.       m_i_fsize: UInt8; //* Fragment size */
  51.       m_pad1: UInt16;
  52.       m_i_reserved2: array [0..1] of UInt32;
  53.     end;
  54.   end;                                  //* OS dependent 2 */
  55. end;
  56.  
Title: Re: CPP #define macro to Pascal conversion help
Post by: Mr.Madguy on April 16, 2018, 01:23:34 pm
No, unions are defined like this in Pascal:
Code: Pascal  [Select][+][-]
  1. type
  2.   TUnionType = (utLinux, utHurd, utMasix);
  3.  
  4.   TOSD = record
  5.     ...
  6.     case TUnionType of
  7.       utLinux: (Linux1:record...end);
  8.       utHurd: (Hurd1:record...end);
  9.       utMasix: (Masix1:record...end);
  10.     ...
  11.   end;
Title: Re: CPP #define macro to Pascal conversion help
Post by: ertank on April 16, 2018, 03:04:50 pm
I hope that I am almost there. I seemingly have 3 problems left and I need help fixing them:
1- EXT2_ACLE_PER_BLOCK macro function I could not convert.
2- get_ext4_header macro function I could not convert.
3- EXT_FIRST_EXTENT macro function I could not convert.

When these are remarked, unit compile fine. Below is current status of my conversion:
Code: Pascal  [Select][+][-]
  1. unit ext2fs;
  2.  
  3. interface
  4.  
  5. const EXT2_DEFAULT_PREALLOC_BLOCKS = 8;
  6.  
  7. ///* Special Inode Numbers  */
  8. const EXT2_BAD_INO = 1;
  9. const EXT2_ROOT_INO = 2;
  10. const EXT2_ACL_IDX_INO = 3;
  11. const EXT2_ACL_DATA_INO = 4;
  12. const EXT2_BOOT_LOADER_INO = 5;
  13. const EXT2_UNDEL_DIR_INO = 6;
  14.  
  15. const EXT2_GOOD_OLD_FIRST_INO = 11;
  16. const EXT2_SUPER_MAGIC = $EF53; //* EXT2 Fs Magic Number */
  17. const EXT2_LINK_MAX = 32000; //* Max count of links to the file */
  18.  
  19. //* Block Size Management */
  20. const EXT2_MIN_BLOCK_SIZE = 1024;
  21. const EXT2_MAX_BLOCK_SIZE = 4096;
  22. const EXT2_MIN_BLOCK_LOG_SIZE = 10;
  23.  
  24. //* EXT2 Fragment Sizes */
  25. const EXT2_MIN_FRAG_SIZE = 1024;
  26. const EXT2_MAX_FRAG_SIZE = 4096;
  27. const EXT2_MIN_FRAG_LOG_SIZE = 10;
  28.  
  29.  
  30. //* Constants relative to the data blocks  */
  31. const EXT2_NDIR_BLOCKS = 12;
  32. const EXT2_IND_BLOCK = EXT2_NDIR_BLOCKS;
  33. const EXT2_DIND_BLOCK = (EXT2_IND_BLOCK + 1);
  34. const EXT2_TIND_BLOCK = (EXT2_DIND_BLOCK + 1);
  35. const EXT2_N_BLOCKS = (EXT2_TIND_BLOCK + 1);
  36.  
  37. //* Superblock Flags */
  38. const EXT2_FEATURE_INCOMPAT_COMPRESSION = $0001;    //* disk/file compression is used */
  39. //*Inode flags  */
  40. const EXT2_SECRM_FL = $00000001; //* Secure deletion */
  41. const EXT2_UNRM_FL = $00000002; //* Undelete */
  42. const EXT2_COMPR_FL = $00000004; //* Compress file */
  43. const EXT2_SYNC_FL = $00000008; //* Synchronous updates */
  44. const EXT2_IMMUTABLE_FL = $00000010; //* Immutable file */
  45. const EXT2_APPEND_FL = $00000020; //* writes to file may only append */
  46. const EXT2_NODUMP_FL = $00000040; //* do not dump file */
  47. const EXT2_NOATIME_FL = $00000080; //* do not update atime */
  48.  
  49. //* Reserved for compression usage... */
  50. const EXT2_DIRTY_FL = $00000100;
  51. const EXT2_COMPRBLK_FL = $00000200; //* One or more compressed clusters */
  52. const EXT2_NOCOMP_FL = $00000400; //* Don't compress */
  53. const EXT2_ECOMPR_FL = $00000800; //* Compression error */
  54.  
  55. //* End compression flags --- maybe not all used */
  56. const EXT2_BTREE_FL = $00001000; //* btree format dir */
  57. const EXT2_IMAGIC_FL = $00002000; //* AFS directory */
  58. const EXT2_JOURNAL_DATA_FL = $00004000; //* file data should be journaled */
  59. const EXT2_NOTAIL_FL = $00008000; //* file tail should not be merged */
  60. const EXT2_DIRSYNC_FL = $00010000; //* dirsync behaviour (directories only) */
  61. const EXT2_TOPDIR_FL = $00020000; //* Top of directory hierarchies*/
  62. const EXT2_HUGE_FILE_FL = $00040000; //* Set to each huge file */
  63. const EXT2_EXTENTS_FL = $00080000; //* Inode uses extents */
  64. const EXT2_RESERVED_FL = $80000000; //* reserved for ext2 lib */
  65.  
  66. const EXT2_FL_USER_VISIBLE = $00001FFF; //* User visible flags */
  67. const EXT2_FL_USER_MODIFIABLE = $000000FF; //* User modifiable flags */
  68.  
  69. //* Codes for operating systems */
  70. const EXT2_OS_LINUX = 0;
  71. const EXT2_OS_HURD = 1;
  72. const EXT2_OS_MASIX = 2;
  73. const EXT2_OS_FREEBSD = 3;
  74. const EXT2_OS_LITES = 4;
  75.  
  76. //* Revision levels  */
  77. const EXT2_GOOD_OLD_REV = 0; //* The good old (original) format */
  78. const EXT2_DYNAMIC_REV = 1;  //* V2 format w/ dynamic inode sizes */
  79.  
  80. const EXT2_CURRENT_REV = EXT2_GOOD_OLD_REV;
  81. const EXT2_MAX_SUPP_REV = EXT2_DYNAMIC_REV;
  82.  
  83. const EXT2_GOOD_OLD_INODE_SIZE = 128;
  84.  
  85. //* Default values for user and/or group using reserved blocks */
  86. const EXT2_DEF_RESUID = 0;
  87. const EXT2_DEF_RESGID = 0;
  88.  
  89. //* Structure of a directory entry */
  90. const EXT2_NAME_LEN = 255;
  91.  
  92. const EXT4_EXT_MAGIC = $f30a;
  93.  
  94. (*
  95. /* In Linux disk is divided into Blocks. These Blocks are divided into Groups. This   */
  96. /* Structure shows different types of groups but it is not implemented. Not Necessary */
  97. /*
  98. typedef struct tagBLOCK_GROUP
  99. {
  100.         1. The SuperBlock
  101.         2. The Group Descriptors
  102.         3. The block Bitmap
  103.         4. The Inode Bitmap
  104.         5. The Inode Table
  105.         6. Data Blocks and Fragments
  106.  
  107. }BLOCK_GROUP;
  108.  
  109. */
  110. *)
  111.  
  112. //* The Super Block comes first in the block group */
  113. type EXT2_SUPER_BLOCK = packed record
  114.     s_inodes_count: UInt32;     //* total no of inodes */
  115.     s_blocks_count: UInt32;     //* total no of blocks */
  116.     s_r_blocks_count: UInt32;   //* total no of blocks reserved for exclusive use  of superuser */
  117.     s_free_blocks_count: UInt32;        //* total no of free blocks */
  118.     s_free_inodes_count: UInt32;        //* total no of free inodes */
  119.     s_first_data_block: UInt32; //* position of the first data block */
  120.     s_log_block_size: UInt32;   //* used to compute logical block size in bytes */
  121.     s_log_frag_size: UInt32;            //* used to compute logical fragment size  */
  122.     s_blocks_per_group: UInt32; //* total number of blocks contained in the group  */
  123.     s_frags_per_group: UInt32;  //* total number of fragments in a group */
  124.     s_inodes_per_group: UInt32; //* number of inodes in a group  */
  125.     s_mtime: UInt32;                    //* time at which the last mount was performed */
  126.     s_wtime: UInt32;                    //* time at which the last write was performed */
  127.     s_mnt_count: UInt16;                //* number of time the fs system has been mounted in r/w mode without having checked */
  128.     s_max_mnt_count: UInt16;    //* the max no of times the fs can be mounted in r/w mode before a check must be done */
  129.     s_magic: UInt16;                    //* a number that identifies the fs (eg. 0xef53 for ext2) */
  130.     s_state: UInt16;                    //* gives the state of fs (eg. 0x001 is Unmounted cleanly) */
  131.     s_pad: UInt16;                              //* unused */
  132.     s_minor_rev_level: UInt16;  //*     */
  133.     s_lastcheck: UInt32;                //* the time of last check performed */
  134.     s_checkinterval: UInt32;            //* the max possible time between checks on the fs */
  135.     s_creator_os: UInt32;               //* os */
  136.     s_rev_level: UInt32;                        //* Revision level */
  137.     s_def_resuid: UInt16;               //* default uid for reserved blocks */
  138.     s_def_regid: UInt16;                //* default gid for reserved blocks */
  139.  
  140.     //* for EXT2_DYNAMIC_REV superblocks only */
  141.     s_first_ino: UInt32;                //* First non-reserved inode */
  142.     s_inode_size: UInt16;               //* size of inode structure */
  143.     s_block_group_nr: UInt16;   //* block group # of this superblock */
  144.     s_feature_compat: UInt32;   //* compatible feature set */
  145.     s_feature_incompat: UInt32;         //* incompatible feature set */
  146.     s_feature_ro_compat: UInt32;        //* readonly-compatible feature set */
  147.     s_uuid: array [0..15] of UInt8;             //* 128-bit uuid for volume */
  148.     s_volume_name: array [0..15] of AnsiChar;           //* volume name */
  149.     s_last_mounted: array [0..63] of AnsiChar;          //* directory where last mounted */
  150.     s_algorithm_usage_bitmap: UInt32; //* For compression */
  151.     s_prealloc_blocks: UInt8;   //* Nr of blocks to try to preallocate*/
  152.     s_prealloc_dir_blocks: UInt8;       //* Nr to preallocate for dirs */
  153.     s_padding1: UInt16;
  154.     s_reserved: array [0..203] of UInt32;               //* unused */
  155. end;
  156.  
  157.  
  158. //* The Group Descriptors follow the Super Block. */
  159. type EXT2_GROUP_DESC = packed record
  160.   bg_block_bitmap: UInt32;      //* points to the blocks bitmap for the group */
  161.   bg_inode_bitmap: UInt32;      //* points to the inodes bitmap for the group */
  162.   bg_inode_table: UInt32;               //* points to the inode table first block     */
  163.   bg_free_blocks_count: UInt16; //* number of free blocks in the group       */
  164.   bg_free_inodes_count: UInt16; //* number of free inodes in the                     */
  165.   bg_used_dirs_count: UInt16;   //* number of inodes allocated to directories */
  166.   bg_pad: UInt16;                       //* padding */
  167.   bg_reserved: array [0..2] of UInt32;          //* reserved */
  168. end;
  169.  
  170. type
  171.   TUnionType1 = (utLinux, utHurd, utMasix);
  172.   TUnionType2 = (utLinux2, utHurd2, utMasix2);
  173.  
  174. //* Structure of an inode on the disk  */
  175. type EXT2_INODE = packed record
  176.   i_mode: UInt16;               //* File mode */
  177.   i_uid: UInt16;                //* Low 16 bits of Owner Uid */
  178.   i_size: UInt32;               //* Size in bytes */
  179.   i_atime: UInt32;              //* Access time */
  180.   i_ctime: UInt32;              //* Creation time */
  181.   i_mtime: UInt32;              //* Modification time */
  182.   i_dtime: UInt32;              //* Deletion Time */
  183.   i_gid: UInt16;                //* Low 16 bits of Group Id */
  184.   i_links_count: UInt16;        //* Links count */
  185.   i_blocks: UInt32;             //* Blocks count */
  186.   i_flags: UInt32;              //* File flags */
  187.   osd1: packed record //* OS dependent 1 */
  188.     case TUnionType1 of
  189.       utLinux: (linux1: packed record l_i_reserved1: UInt32; end; );
  190.       utHurd:  (hurd1: packed record h_i_translator: UInt32; end; );
  191.       utMasix: (masix1: packed record m_i_reserved1: UInt32; end; );
  192.   end;
  193.   i_block: array [0..Pred(EXT2_N_BLOCKS)] of UInt32; //* Pointers to blocks */
  194.   i_generation: UInt32; //* File version (for NFS) */
  195.   i_file_acl: UInt32;           //* File ACL */
  196. //    uint32_t  i_dir_acl;              //* Directory ACL */
  197.   i_size_high: UInt32;            //* This is used store the high 32 bit of file size in large files */
  198.   i_faddr: UInt32;              //* Fragment address */
  199.   osd2: packed record //* OS dependent 2 */
  200.     case TUnionType2 of
  201.       utLinux2: (
  202.         linux2: packed record
  203.           l_i_frag: UInt8;              //* Fragment number */
  204.           l_i_fsize: UInt8;     //* Fragment size */
  205.           i_pad1: UInt16;
  206.           l_i_uid_high: UInt16; //* these 2 fields    */
  207.           l_i_gid_high: UInt16; //* were reserved2[0] */
  208.           l_i_reserved2: UInt32;
  209.         end;
  210.       );
  211.       utHurd2: (
  212.         hurd2: packed record
  213.           h_i_frag: UInt8;      //* Fragment number */
  214.           h_i_fsize: UInt8;     //* Fragment size */
  215.           h_i_mode_high: UInt16;
  216.           h_i_uid_high: UInt16;
  217.           h_i_gid_high: UInt16;
  218.           h_i_author: UInt16;
  219.         end;
  220.       );
  221.       utMasix2: (
  222.         masix2: packed record
  223.           m_i_frag: UInt8;      //* Fragment number */
  224.           m_i_fsize: UInt8;     //* Fragment size */
  225.           m_pad1: UInt16;
  226.           m_i_reserved2: array [0..1] of UInt32;
  227.         end;
  228.       );
  229.   end;
  230. end;
  231.  
  232.  
  233. //* EXT2 directory structure */
  234. type EXT2_DIR_ENTRY = packed record
  235.   inode: UInt32;                        //* Inode number */
  236.   rec_len: UInt16;              //* Directory entry length */
  237.   name_len: UInt8;              //* Name length */
  238.   filetype: UInt8;              //* File type */
  239.   name: array [0..Pred(EXT2_NAME_LEN)] of AnsiChar;     //* File name */
  240. end;
  241.  
  242.  
  243. //*
  244. // * This is the extent on-disk structure.
  245. // * It's used at the bottom of the tree.
  246. // */
  247. type EXT4_EXTENT = packed record
  248.   ee_block: UInt32; //* first logical block extent covers */
  249.   ee_len: UInt16; //* number of blocks covered by extent */
  250.   ee_start_hi: UInt16; //* high 16 bits of physical block */
  251.   ee_start_lo: UInt32; //* low 32 bits of physical block */
  252. end;
  253.  
  254. //*
  255. // * This is index on-disk structure.
  256. // * It's used at all the levels except the bottom.
  257. // */
  258. type EXT4_EXTENT_IDX = packed record
  259.   ei_block: UInt32;       //* index covers logical blocks from 'block' */
  260.   ei_leaf_lo: UInt32;     //* pointer to the physical block of the next *
  261.                           //* level. leaf or next index could be there */
  262.   ei_leaf_hi: UInt16;     ///* high 16 bits of physical block */
  263.   ei_unused: UInt16;
  264. end;
  265.  
  266. //*
  267. // * Each block (leaves and indexes), even inode-stored has header.
  268. // */
  269. type EXT4_EXTENT_HEADER = packed record
  270.   eh_magic: UInt16;       //* probably will support different formats */
  271.   eh_entries: UInt16;     //* number of valid entries */
  272.   eh_max: UInt16;         //* capacity of store in entries */
  273.   eh_depth: UInt16;       //* has tree real underlying blocks? */
  274.   eh_generation: UInt32;  //* generation of the tree */
  275. end;
  276.  
  277. function EXT2_BLOCK_SIZE(S: EXT2_SUPER_BLOCK): UInt32; inline;
  278. function EXT2_ACLE_PER_BLOCK(S: EXT2_SUPER_BLOCK): UInt32; inline;
  279. function EXT2_ADDR_PER_BLOCK(S: EXT2_SUPER_BLOCK): UInt32; inline;
  280. function EXT2_INODE_SIZE(S: EXT2_SUPER_BLOCK): UInt32; inline;
  281. function EXT2_FIRST_INO(S: EXT2_SUPER_BLOCK): UInt32; inline;
  282.  
  283. function EXT2_FRAG_SIZE(S: EXT2_SUPER_BLOCK): UInt32; inline;
  284. function EXT2_FRAGS_PER_BLOCK(S: EXT2_SUPER_BLOCK): UInt32; inline;
  285.  
  286. //* Block Group Macros */
  287. function EXT2_BLOCKS_PER_GROUP(S: EXT2_SUPER_BLOCK): UInt32; inline;
  288. function EXT2_DESC_PER_BLOCK(S: EXT2_SUPER_BLOCK): UInt32; inline;
  289. function EXT2_INODES_PER_GROUP(S: EXT2_SUPER_BLOCK): UInt32; inline;
  290. function EXT2_INODES_PER_BLOCK(S: EXT2_SUPER_BLOCK): UInt32; inline;
  291. function EXT2_BLOCK_SIZE_BITS(S: EXT2_SUPER_BLOCK): UInt32; inline;
  292.  
  293. function get_ext4_header(I: EXT2_INODE): UInt32; inline;
  294. function EXT_FIRST_EXTENT(__hdr__: EXT4_EXTENT_HEADER): UInt32; inline;
  295. function INODE_HAS_EXTENT(i: EXT2_INODE): UInt32; inline;
  296.  
  297. function ext_to_block(extent: EXT4_EXTENT): UInt64; inline;
  298. function idx_to_block(idx: EXT4_EXTENT_IDX): UInt64; inline;
  299.  
  300.  
  301. implementation
  302.  
  303. { ext2fs }
  304.  
  305. function EXT2_BLOCK_SIZE; inline;
  306. begin
  307.   Result := EXT2_MIN_BLOCK_SIZE shl S.s_log_block_size;
  308. end;
  309.  
  310.  
  311. function EXT2_ACLE_PER_BLOCK; inline;
  312. begin
  313. //  Result := EXT2_BLOCK_SIZE(S) div SizeOf(ext2_acl_entry);
  314. end;
  315.  
  316.  
  317. function EXT2_ADDR_PER_BLOCK; inline;
  318. begin
  319.   Result := EXT2_BLOCK_SIZE(s) div SizeOf(UInt16);
  320. end;
  321.  
  322.  
  323. function EXT2_INODE_SIZE; inline;
  324. begin
  325.   if S.s_rev_level = EXT2_GOOD_OLD_REV then
  326.     Result := EXT2_GOOD_OLD_INODE_SIZE
  327.   else
  328.     Result := S.s_inode_size;
  329. end;
  330.  
  331.  
  332. function EXT2_FIRST_INO; inline;
  333. begin
  334.   if S.s_rev_level = EXT2_GOOD_OLD_REV then
  335.     Result := EXT2_GOOD_OLD_FIRST_INO
  336.   else
  337.     Result := S.s_first_ino;
  338. end;
  339.  
  340.  
  341. function EXT2_FRAG_SIZE; inline;
  342. begin
  343.   Result := (EXT2_MIN_FRAG_SIZE shl S.s_log_frag_size);
  344. end;
  345.  
  346.  
  347. function EXT2_FRAGS_PER_BLOCK; inline;
  348. begin
  349.   Result := EXT2_BLOCK_SIZE(S) div EXT2_FRAG_SIZE(S);
  350. end;
  351.  
  352.  
  353. function EXT2_BLOCKS_PER_GROUP; inline;
  354. begin
  355.   Result := S.s_blocks_per_group;
  356. end;
  357.  
  358.  
  359. function EXT2_DESC_PER_BLOCK; inline;
  360. begin
  361.   Result := EXT2_BLOCK_SIZE(s) div SizeOf(EXT2_GROUP_DESC);
  362. end;
  363.  
  364.  
  365. function EXT2_INODES_PER_GROUP; inline;
  366. begin
  367.   Result := S.s_inodes_per_group;
  368. end;
  369.  
  370.  
  371. function EXT2_INODES_PER_BLOCK; inline;
  372. begin
  373.   Result := EXT2_BLOCK_SIZE(s) div SizeOf(EXT2_INODE);
  374. end;
  375.  
  376.  
  377. function EXT2_BLOCK_SIZE_BITS; inline;
  378. begin
  379.   Result := S.s_log_block_size + 10;
  380. end;
  381.  
  382.  
  383. function get_ext4_header; inline;
  384. begin
  385. //  Result := (ext4_extent_header((i).i_block));
  386. end;
  387.  
  388.  
  389. function ext_to_block; inline;
  390. begin
  391.   Result := UInt64(extent.ee_start_lo);
  392.   Result := Result or (UInt64(extent.ee_start_hi) shl 31) shl 1;
  393. end;
  394.  
  395.  
  396. function idx_to_block; inline;
  397. begin
  398.   Result := UInt64(idx.ei_leaf_lo);
  399.   Result := Result or (UInt64(idx.ei_leaf_hi) shl 31) shl 1;
  400. end;
  401.  
  402.  
  403. function EXT_FIRST_EXTENT; inline;
  404. begin
  405. //  Result := ext4_extent(__hdr__) + SizeOf(EXT4_EXTENT_HEADER);
  406. end;
  407.  
  408.  
  409. function INODE_HAS_EXTENT; inline;
  410. begin
  411.   Result := (i.i_flags and EXT2_EXTENTS_FL);
  412. end;
  413.  
  414.  
  415. end.
  416.  
Title: Re: CPP #define macro to Pascal conversion help
Post by: marcov on April 16, 2018, 03:35:53 pm
I hope that I am almost there. I seemingly have 3 problems left and I need help fixing them:
1- EXT2_ACLE_PER_BLOCK macro function I could not convert.
2- get_ext4_header macro function I could not convert.
3- EXT_FIRST_EXTENT macro function I could not convert.

Some rough conversions to get the discussion started (others: please check)

1 has same problem as (2), dereferencing an anonymous type. Nested via a different function even. The only record with the said field (s_log_block_size) is tagEXT2_SUPER_BLOCK.  Return type is also unclear, but int32 is probably safe, since these are sizes of simple structures.

Code: Pascal  [Select][+][-]
  1. function EXT2_ACLE_PER_BLOCK (const s:tagEXT2_SUPER_BLOCK):int32; inline;
  2. begin
  3.    result :=(EXT2_MIN_BLOCK_SIZE  shl s.s_log_block_size) div  sizeof (struct ext2_acl_entry);
  4. end;
  5.  

2 is harder because an untyped parameter (i) is dereferenced (->i_block) without knowing what it was. Exact meaning depends on use, and might require overloads for varying types of i. But since the header only has one,  (tagext2_inode) we'll take that:

However something is wrong, it seems to indicate a pointer as return type, but the type of tagext2_inode->I_block is uint32. Not 64-bit safe. 

Code: Pascal  [Select][+][-]
  1. function get_ext4_header (const i:tagEXT2_INODE):pext4_extent_header; inline;
  2. begin
  3.   result:=pext4_extent_header(i->i_block[0]); // no index means first in C, ptr<-> array equivalence
  4. end;
  5.  
#define get_ext4_header(i)      ((struct ext4_extent_header *) (i)->i_block)


3. is easier. The parameter must be typecastable to pointer, so simply "pointer" is a good type for it:

Code: Pascal  [Select][+][-]
  1. function EXIT_FIRST_EXTENT(hdr:pointer):pext4_extent; inline;
  2. begin
  3.   result:=pext4_extent(pbyte(hdr)+sizeof(ext4_extent_header));
  4. end;

Title: Re: CPP #define macro to Pascal conversion help
Post by: ykot on April 16, 2018, 03:55:13 pm
Note that unless in original C code the structures were marked with __attribute__((packed)) or surrounded by #pragma pack, the use of "packed record" would be incorrect, leading to some obscure, difficult to find bugs. You might want to change that to just "record" and make sure to add "{$PACKRECORDS C}" at top of the unit.
Title: Re: CPP #define macro to Pascal conversion help
Post by: ertank on April 16, 2018, 04:53:11 pm
Note that unless in original C code the structures were marked with __attribute__((packed)) or surrounded by #pragma pack, the use of "packed record" would be incorrect, leading to some obscure, difficult to find bugs. You might want to change that to just "record" and make sure to add "{$PACKRECORDS C}" at top of the unit.

All structures in C++ code are marked with attribute packed. But, there are structures in structures (together with unions). These internal ones are not marked. Should I convert them just to plain record. Currently they are also defined as packed record.
Title: Re: CPP #define macro to Pascal conversion help
Post by: Thaddy on April 16, 2018, 06:20:41 pm
Note that unless in original C code the structures were marked with __attribute__((packed)) or surrounded by #pragma pack, the use of "packed record" would be incorrect, leading to some obscure, difficult to find bugs. You might want to change that to just "record" and make sure to add "{$PACKRECORDS C}" at top of the unit.

All structures in C++ code are marked with attribute packed. But, there are structures in structures (together with unions). These internal ones are not marked. Should I convert them just to plain record. Currently they are also defined as packed record.
No, you should specify just once {$packrecords C} at the top of the unit. The internal structures will also be packed in C style..
Title: Re: CPP #define macro to Pascal conversion help
Post by: ertank on April 16, 2018, 10:15:10 pm
I just realize that I need to do such work for 9 more files...
Title: Re: CPP #define macro to Pascal conversion help
Post by: avra on April 17, 2018, 08:38:01 am
I am working on reading ext2/3/4 disc IMG files.
Maybe this can help you: https://ultibo.org/wiki/Unit_EXTFS
Title: Re: CPP #define macro to Pascal conversion help
Post by: ertank on April 18, 2018, 08:30:00 pm
Maybe this can help you: https://ultibo.org/wiki/Unit_EXTFS
It seems Ext2/3/4 features is incomplete. However, quite interesting project that is. Thank you for sharing.
TinyPortal © 2005-2018