jamlib_build.py 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. from cffi import FFI
  2. ffibuilder = FFI()
  3. import pathlib
  4. this_dir = pathlib.Path().absolute()
  5. # cdef() expects a single string declaring the C types, functions and
  6. # globals needed to use the shared object. It must be in valid C syntax.
  7. ffibuilder.cdef("""
  8. typedef struct {
  9. FILE* HdrFile_PS; /* File handle for .JHR file */
  10. FILE* TxtFile_PS; /* File handle for .JDT file */
  11. FILE* IdxFile_PS; /* File handle for .JDX file */
  12. FILE* LrdFile_PS; /* File handle for .JLR file */
  13. int Errno_I; /* last i/o error */
  14. int Locked_I; /* is area locked? */
  15. uint32_t LastUserPos_I; /* last position of lastread record */
  16. uint32_t LastUserId_I; /* userid for the last read lastread record */
  17. } s_JamBase;
  18. int JAM_OpenMB ( char* Basename_PC, s_JamBase** NewArea_PPS );
  19. int JAM_CloseMB ( s_JamBase* Area_PS );
  20. typedef struct {
  21. char Signature[4]; /* <J><A><M> followed by <NUL> */
  22. uint32_t DateCreated; /* Creation date */
  23. uint32_t ModCounter; /* Last processed counter */
  24. uint32_t ActiveMsgs; /* Number of active (not deleted) msgs */
  25. uint32_t PasswordCRC; /* CRC-32 of password to access */
  26. uint32_t BaseMsgNum; /* Lowest message number in index file */
  27. char RSRVD[1000]; /* Reserved space */
  28. } s_JamBaseHeader;
  29. typedef struct {
  30. char Signature[4]; /* <J><A><M> followed by <NUL> */
  31. uint16_t Revision; /* CURRENTREVLEV */
  32. uint16_t ReservedWord; /* Reserved */
  33. uint32_t SubfieldLen; /* Length of Subfields */
  34. uint32_t TimesRead; /* Number of times message read */
  35. uint32_t MsgIdCRC; /* CRC-32 of MSGID line */
  36. uint32_t ReplyCRC; /* CRC-32 of REPLY line */
  37. uint32_t ReplyTo; /* This msg is a reply to.. */
  38. uint32_t Reply1st; /* First reply to this msg */
  39. uint32_t ReplyNext; /* Next msg in reply chain */
  40. uint32_t DateWritten; /* When msg was written */
  41. uint32_t DateReceived; /* When msg was received/read */
  42. uint32_t DateProcessed; /* When msg was processed by packer */
  43. uint32_t MsgNum; /* Message number (1-based) */
  44. uint32_t Attribute; /* Msg attribute, see "Status bits" */
  45. uint32_t Attribute2; /* Reserved for future use */
  46. uint32_t TxtOffset; /* Offset of text in text file */
  47. uint32_t TxtLen; /* Length of message text */
  48. uint32_t PasswordCRC; /* CRC-32 of password to access msg */
  49. uint32_t Cost; /* Cost of message */
  50. } s_JamMsgHeader;
  51. typedef struct {
  52. uint16_t LoID; /* Field ID, 0 - 0xffff */
  53. uint16_t HiID; /* Reserved for future use */
  54. uint32_t DatLen; /* Length of buffer that follows */
  55. char* Buffer; /* DatLen bytes of data */
  56. } s_JamSubfield;
  57. typedef struct {
  58. uint16_t LoID; /* Field ID, 0 - 0xffff */
  59. uint16_t HiID; /* Reserved for future use */
  60. uint32_t DatLen; /* Length of buffer that follows */
  61. } s_JamSaveSubfield;
  62. typedef struct {
  63. uint32_t UserCRC; /* CRC-32 of destination username */
  64. uint32_t HdrOffset; /* Offset of header in .JHR file */
  65. } s_JamIndex;
  66. typedef struct {
  67. uint32_t UserCRC; /* CRC-32 of user name (lowercase) */
  68. uint32_t UserID; /* Unique UserID */
  69. uint32_t LastReadMsg; /* Last read message number */
  70. uint32_t HighReadMsg; /* Highest read message number */
  71. } s_JamLastRead;
  72. typedef struct {
  73. s_JamSubfield** Fields;
  74. uint32_t NumFields;
  75. uint32_t NumAlloc;
  76. } s_JamSubPacket;
  77. int JAM_LockMB( s_JamBase* Area_PS, int Timeout_I );
  78. int JAM_UnlockMB( s_JamBase* Area_PS );
  79. int JAM_ReadMBHeader( s_JamBase* Area_PS, s_JamBaseHeader* Header_PS );
  80. int JAM_WriteMBHeader( s_JamBase* Area_PS, s_JamBaseHeader* Header_PS );
  81. int JAM_GetMBSize( s_JamBase* Area_PS, uint32_t* Messages_PI );
  82. int JAM_ReadMsgHeader ( s_JamBase* Area_PS,
  83. uint32_t MsgNo_I,
  84. s_JamMsgHeader* Header_PS,
  85. s_JamSubPacket** SubfieldPack_PPS );
  86. int JAM_ReadMsgText ( s_JamBase* Area_PS,
  87. uint32_t Offset_I,
  88. uint32_t Length_I,
  89. char* Buffer_PC );
  90. int JAM_AddMessage ( s_JamBase* Area_PS,
  91. s_JamMsgHeader* Header_PS,
  92. s_JamSubPacket* SubPack_PS,
  93. char* Text_PC,
  94. uint32_t TextLen_I );
  95. int JAM_AddEmptyMessage ( s_JamBase* Area_PS );
  96. int JAM_DeleteMessage ( s_JamBase* Base_PS,
  97. uint32_t MsgNo_I );
  98. int JAM_ChangeMsgHeader ( s_JamBase* Area_PS,
  99. uint32_t MsgNo_I,
  100. s_JamMsgHeader* Header_PS );
  101. int JAM_ClearMsgHeader ( s_JamMsgHeader* Header_PS );
  102. int JAM_Errno ( s_JamBase* Area_PS );
  103. s_JamSubPacket* JAM_NewSubPacket ( void );
  104. int JAM_DelSubPacket ( s_JamSubPacket* SubPack_PS );
  105. s_JamSubfield* JAM_GetSubfield ( s_JamSubPacket* SubPack_PS );
  106. s_JamSubfield* JAM_GetSubfield_R ( s_JamSubPacket* SubPack_PS ,
  107. uint32_t* Count_PI);
  108. int JAM_PutSubfield ( s_JamSubPacket* SubPack_PS,
  109. s_JamSubfield* Field_PS );
  110. uint32_t JAM_Crc32 ( char* Buffer_PC, uint32_t Length_I );
  111. void free(void*);
  112. """)
  113. # int JAM_CloseMB ( s_JamBase* Area_PS );
  114. #
  115. # """)
  116. # set_source() gives the name of the python extension module to
  117. # produce, and some C source code as a string. This C code needs
  118. # to make the declarated functions, types and globals available,
  119. # so it is often just the "#include".
  120. ffibuilder.set_source("_pi_cffi",
  121. """
  122. #include "jam.h" // the C header of the library
  123. """,
  124. # libraries=['jamlib.a'],
  125. # library_dirs=[this_dir.as_posix()],
  126. # extra_link_args=["-Wl,-rpath,."],
  127. extra_link_args=["jamlib.a"],
  128. ) # library name, for the linker
  129. if __name__ == "__main__":
  130. ffibuilder.compile(verbose=True)